From b3657fb0249555feebe9f5b6fc15c82ad99a3025 Mon Sep 17 00:00:00 2001 From: zc Date: Thu, 5 Jun 2025 09:51:30 +0800 Subject: [PATCH] first commit --- .idea/.gitignore | 0 .idea/ApifoxUploaderProjectSetting.xml | 6 + .idea/compiler.xml | 29 + .idea/encodings.xml | 49 + .idea/jarRepositories.xml | 25 + .idea/misc.xml | 20 + .idea/workspace.xml | 199 ++ .idea/xa-master-prod.iml | 9 + dcsoft-api/dcsoft-api-system/pom.xml | 28 + .../system/api/RemoteAuthApplication.java | 23 + .../dcsoft/system/api/RemoteAuthService.java | 31 + .../dcsoft/system/api/RemoteFileService.java | 63 + .../dcsoft/system/api/RemoteLogService.java | 41 + .../system/api/RemoteStudentService.java | 73 + .../dcsoft/system/api/RemoteUserService.java | 62 + .../system/api/domain/FaceStudentBody.java | 180 ++ .../dcsoft/system/api/domain/LoginBody.java | 74 + .../com/dcsoft/system/api/domain/SysAuth.java | 70 + .../com/dcsoft/system/api/domain/SysDept.java | 215 +++ .../dcsoft/system/api/domain/SysDictData.java | 176 ++ .../dcsoft/system/api/domain/SysDictType.java | 96 + .../com/dcsoft/system/api/domain/SysFile.java | 64 + .../system/api/domain/SysLogininfor.java | 102 + .../dcsoft/system/api/domain/SysOperLog.java | 255 +++ .../com/dcsoft/system/api/domain/SysRole.java | 241 +++ .../com/dcsoft/system/api/domain/SysUser.java | 355 ++++ .../factory/RemoteAuthFallbackFactory.java | 37 + .../RemoteAuthServiceFallbackFactory.java | 27 + .../factory/RemoteFileFallbackFactory.java | 59 + .../api/factory/RemoteLogFallbackFactory.java | 42 + .../factory/RemoteStudentFallbackFactory.java | 94 + .../factory/RemoteUserFallbackFactory.java | 53 + .../dcsoft/system/api/model/LoginUser.java | 150 ++ ...ot.autoconfigure.AutoConfiguration.imports | 3 + dcsoft-api/pom.xml | 22 + dcsoft-auth/pom.xml | 100 + .../com/dcsoft/auth/DCSAuthApplication.java | 26 + .../com/dcsoft/auth/bean/CheckParams.java | 27 + .../dcsoft/auth/bean/ValidateCodeEnum.java | 22 + .../com/dcsoft/auth/bean/ValidateResult.java | 38 + .../dcsoft/auth/controller/ApiController.java | 187 ++ .../auth/controller/TokenController.java | 205 ++ .../java/com/dcsoft/auth/form/AuthBody.java | 35 + .../java/com/dcsoft/auth/form/IDaasBody.java | 35 + .../java/com/dcsoft/auth/form/LoginBody.java | 74 + .../com/dcsoft/auth/form/RegisterBody.java | 11 + .../dcsoft/auth/service/SysAuthService.java | 45 + .../dcsoft/auth/service/SysLoginService.java | 212 +++ .../auth/service/SysPasswordService.java | 85 + .../auth/service/SysRecordLogService.java | 48 + .../java/com/dcsoft/auth/test/CreateSign.java | 108 ++ .../java/com/dcsoft/auth/utils/AESUtils.java | 97 + .../java/com/dcsoft/auth/utils/DateUtils.java | 28 + .../com/dcsoft/auth/utils/KeyGenerator.java | 54 + .../com/dcsoft/auth/utils/LicenseManager.java | 167 ++ .../com/dcsoft/auth/utils/LicenseThread.java | 59 + .../java/com/dcsoft/auth/utils/RSAUtils.java | 67 + .../com/dcsoft/auth/utils/Systemutils.java | 102 + dcsoft-auth/src/main/resources/banner.txt | 7 + dcsoft-auth/src/main/resources/bootstrap.yml | 25 + .../main/resources/lib/JWT-SDK-1.1.1_1.8.jar | Bin 0 -> 4711 bytes .../src/main/resources/lib/jose4j-0.4.3.jar | Bin 0 -> 230567 bytes dcsoft-auth/src/main/resources/logback.xml | 74 + dcsoft-common/dcsoft-common-core/pom.xml | 128 ++ .../dcsoft/common/core/annotation/Excel.java | 187 ++ .../dcsoft/common/core/annotation/Excels.java | 18 + .../common/core/constant/CacheConstants.java | 75 + .../common/core/constant/Constants.java | 220 +++ .../common/core/constant/GenConstants.java | 117 ++ .../common/core/constant/HttpStatus.java | 94 + .../core/constant/ScheduleConstants.java | 50 + .../core/constant/SecurityConstants.java | 49 + .../core/constant/ServiceNameConstants.java | 24 + .../common/core/constant/TokenConstants.java | 25 + .../common/core/constant/UserConstants.java | 80 + .../core/context/SecurityContextHolder.java | 98 + .../java/com/dcsoft/common/core/domain/R.java | 115 ++ .../dcsoft/common/core/enums/CompanyType.java | 29 + .../dcsoft/common/core/enums/UserStatus.java | 30 + .../enums/exception/CommonExceptionEnum.java | 27 + .../core/exception/CaptchaException.java | 16 + .../core/exception/CheckedException.java | 31 + .../core/exception/DemoModeException.java | 15 + .../core/exception/GlobalException.java | 58 + .../core/exception/InnerAuthException.java | 16 + .../core/exception/PreAuthorizeException.java | 15 + .../core/exception/ServiceException.java | 74 + .../common/core/exception/UtilException.java | 26 + .../exception/auth/NotLoginException.java | 16 + .../auth/NotPermissionException.java | 23 + .../core/exception/auth/NotRoleException.java | 23 + .../core/exception/base/BaseException.java | 79 + .../core/exception/file/FileException.java | 19 + .../FileNameLengthLimitExceededException.java | 16 + .../file/FileSizeLimitExceededException.java | 16 + .../exception/file/FileUploadException.java | 61 + .../file/InvalidExtensionException.java | 80 + .../core/exception/job/TaskException.java | 34 + .../user/CaptchaExpireException.java | 16 + .../core/exception/user/UserException.java | 18 + .../user/UserPasswordNotMatchException.java | 16 + .../dcsoft/common/core/text/CharsetKit.java | 86 + .../com/dcsoft/common/core/text/Convert.java | 1006 ++++++++++ .../dcsoft/common/core/text/StrFormatter.java | 92 + .../dcsoft/common/core/utils/CollUtil.java | 19 + .../dcsoft/common/core/utils/DateUtils.java | 209 +++ .../common/core/utils/ExceptionUtil.java | 39 + .../dcsoft/common/core/utils/JsonUtils.java | 111 ++ .../dcsoft/common/core/utils/JwtUtils.java | 130 ++ .../dcsoft/common/core/utils/PageUtils.java | 35 + .../common/core/utils/ServletUtils.java | 333 ++++ .../dcsoft/common/core/utils/SpringUtils.java | 114 ++ .../dcsoft/common/core/utils/StringUtils.java | 561 ++++++ .../common/core/utils/bean/BeanUtils.java | 110 ++ .../core/utils/bean/BeanValidators.java | 24 + .../common/core/utils/file/FileTypeUtils.java | 95 + .../common/core/utils/file/FileUtils.java | 293 +++ .../common/core/utils/file/ImageUtils.java | 84 + .../common/core/utils/file/MimeTypeUtils.java | 59 + .../common/core/utils/html/EscapeUtil.java | 167 ++ .../common/core/utils/html/HTMLFilter.java | 570 ++++++ .../dcsoft/common/core/utils/ip/IpUtils.java | 382 ++++ .../core/utils/poi/ExcelHandlerAdapter.java | 19 + .../common/core/utils/poi/ExcelUtil.java | 1486 +++++++++++++++ .../core/utils/reflect/ReflectUtils.java | 410 ++++ .../dcsoft/common/core/utils/sign/Base64.java | 291 +++ .../dcsoft/common/core/utils/sql/SqlUtil.java | 61 + .../common/core/utils/uuid/IdUtils.java | 49 + .../dcsoft/common/core/utils/uuid/Seq.java | 86 + .../dcsoft/common/core/utils/uuid/UUID.java | 484 +++++ .../core/web/controller/BaseController.java | 152 ++ .../common/core/web/domain/AjaxResult.java | 206 ++ .../common/core/web/domain/BaseEntity.java | 118 ++ .../common/core/web/domain/HkResult.java | 91 + .../common/core/web/domain/TreeEntity.java | 79 + .../common/core/web/page/PageDomain.java | 101 + .../common/core/web/page/TableDataInfo.java | 96 + .../core/web/page/TableDataInfoPage.java | 52 + .../common/core/web/page/TableDatasInfo.java | 108 ++ .../common/core/web/page/TableSupport.java | 56 + .../java/com/dcsoft/common/core/xss/Xss.java | 27 + .../dcsoft/common/core/xss/XssValidator.java | 34 + ...ot.autoconfigure.AutoConfiguration.imports | 1 + dcsoft-common/dcsoft-common-datascope/pom.xml | 27 + .../datascope/annotation/DataScope.java | 33 + .../datascope/aspect/DataScopeAspect.java | 167 ++ ...ot.autoconfigure.AutoConfiguration.imports | 1 + .../dcsoft-common-datasource/pom.xml | 35 + .../common/datasource/annotation/Master.java | 22 + .../common/datasource/annotation/Slave.java | 22 + dcsoft-common/dcsoft-common-log/pom.xml | 27 + .../com/dcsoft/common/log/annotation/Log.java | 51 + .../dcsoft/common/log/aspect/LogAspect.java | 249 +++ .../common/log/enums/BusinessStatus.java | 20 + .../dcsoft/common/log/enums/BusinessType.java | 59 + .../dcsoft/common/log/enums/OperatorType.java | 24 + .../log/filter/PropertyPreExcludeFilter.java | 24 + .../common/log/service/AsyncLogService.java | 29 + ...ot.autoconfigure.AutoConfiguration.imports | 2 + dcsoft-common/dcsoft-common-redis/pom.xml | 33 + .../FastJson2JsonRedisSerializer.java | 49 + .../common/redis/configure/RedisConfig.java | 43 + .../common/redis/service/RedisService.java | 268 +++ ...ot.autoconfigure.AutoConfiguration.imports | 2 + dcsoft-common/dcsoft-common-seata/pom.xml | 27 + dcsoft-common/dcsoft-common-security/pom.xml | 39 + .../annotation/EnableCustomConfig.java | 31 + .../annotation/EnableRyFeignClients.java | 27 + .../common/security/annotation/InnerAuth.java | 19 + .../common/security/annotation/Logical.java | 20 + .../security/annotation/RequiresLogin.java | 18 + .../annotation/RequiresPermissions.java | 27 + .../security/annotation/RequiresRoles.java | 26 + .../security/aspect/InnerAuthAspect.java | 51 + .../security/aspect/PreAuthorizeAspect.java | 97 + .../common/security/auth/AuthLogic.java | 373 ++++ .../dcsoft/common/security/auth/AuthUtil.java | 167 ++ .../security/config/ApplicationConfig.java | 22 + .../common/security/config/WebMvcConfig.java | 33 + .../feign/FeignAutoConfiguration.java | 20 + .../feign/FeignRequestInterceptor.java | 54 + .../handler/GlobalExceptionHandler.java | 136 ++ .../interceptor/HeaderInterceptor.java | 54 + .../common/security/service/TokenService.java | 169 ++ .../common/security/utils/DictUtils.java | 75 + .../common/security/utils/SecurityUtils.java | 117 ++ ...ot.autoconfigure.AutoConfiguration.imports | 5 + dcsoft-common/dcsoft-common-sms/pom.xml | 42 + .../sms/config/SmsAutoConfiguration.java | 49 + .../sms/config/properties/SmsProperties.java | 89 + .../dcsoft/common/sms/entity/SmsResult.java | 31 + .../common/sms/exception/SmsException.java | 16 + .../common/sms/service/SmsTemplate.java | 25 + .../sms/service/impl/AliyunSmsTemplate.java | 65 + .../sms/service/impl/TencentSmsTemplate.java | 82 + ...ot.autoconfigure.AutoConfiguration.imports | 1 + dcsoft-common/dcsoft-common-swagger/pom.xml | 34 + .../annotation/EnableCustomSwagger2.java | 20 + .../config/SwaggerAutoConfiguration.java | 129 ++ .../config/SwaggerBeanPostProcessor.java | 54 + .../swagger/config/SwaggerProperties.java | 345 ++++ .../config/SwaggerWebConfiguration.java | 22 + ...ot.autoconfigure.AutoConfiguration.imports | 3 + dcsoft-common/pom.xml | 31 + dcsoft-gateway/pom.xml | 117 ++ .../dcsoft/gateway/DCSGatewayApplication.java | 24 + .../dcsoft/gateway/config/CaptchaConfig.java | 83 + .../com/dcsoft/gateway/config/CorsConfig.java | 62 + .../dcsoft/gateway/config/GatewayConfig.java | 23 + .../gateway/config/KaptchaTextCreator.java | 75 + .../config/RouterFunctionConfiguration.java | 31 + .../gateway/config/SwaggerProvider.java | 79 + .../config/properties/CaptchaProperties.java | 46 + .../properties/IgnoreWhiteProperties.java | 33 + .../config/properties/XssProperties.java | 48 + .../com/dcsoft/gateway/filter/AuthFilter.java | 151 ++ .../gateway/filter/BlackListUrlFilter.java | 65 + .../gateway/filter/CacheRequestFilter.java | 87 + .../gateway/filter/ValidateCodeFilter.java | 81 + .../com/dcsoft/gateway/filter/XssFilter.java | 129 ++ .../handler/GatewayExceptionHandler.java | 56 + .../handler/SentinelFallbackHandler.java | 41 + .../gateway/handler/SwaggerHandler.java | 56 + .../gateway/handler/ValidateCodeHandler.java | 41 + .../gateway/service/ValidateCodeService.java | 23 + .../service/impl/ValidateCodeServiceImpl.java | 130 ++ dcsoft-gateway/src/main/resources/banner.txt | 7 + .../src/main/resources/bootstrap.yml | 40 + dcsoft-gateway/src/main/resources/logback.xml | 74 + dcsoft-modules/dcsoft-file/pom.xml | 89 + .../dcsoft-file/src/main/java/com/Main.java | 159 ++ .../com/dcsoft/file/DCSFileApplication.java | 61 + .../com/dcsoft/file/config/FileListener.java | 83 + .../com/dcsoft/file/config/MinioConfig.java | 82 + .../dcsoft/file/config/ResourcesConfig.java | 50 + .../com/dcsoft/file/controller/MinIO.java | 81 + .../file/controller/SysFileController.java | 436 +++++ .../java/com/dcsoft/file/controller/test.java | 28 + .../com/dcsoft/file/controller/zctest.java | 55 + .../dcsoft/file/service/AlgoServiceImpl.java | 59 + .../dcsoft/file/service/FaceServiceImpl.java | 123 ++ .../service/FastDfsSysFileServiceImpl.java | 42 + .../com/dcsoft/file/service/IAlgoService.java | 14 + .../com/dcsoft/file/service/IFaceService.java | 23 + .../dcsoft/file/service/ISysFileService.java | 22 + .../file/service/LocalSysFileServiceImpl.java | 56 + .../file/service/MinioSysFileServiceImpl.java | 45 + .../utils/BASE64DecodedMultipartFile.java | 57 + .../dcsoft/file/utils/FileUploadUtils.java | 236 +++ .../java/com/dcsoft/file/utils/HttpUtil.java | 264 +++ .../dcsoft/file/utils/ImageToBase64Utils.java | 155 ++ .../java/com/dcsoft/file/utils/MinioUtil.java | 75 + .../com/dcsoft/file/utils/PictureUtils.java | 150 ++ .../dcsoft/file/utils/PngColoringUtil.java | 97 + .../java/com/uniubi/Register/FaceBox.java | 10 + .../com/uniubi/Register/UfaceRegister.java | 122 ++ .../com/uniubi/Register/UfaceRegisterJNI.java | 32 + .../dcsoft-file/src/main/resources/banner.txt | 7 + .../src/main/resources/bootstrap.yml | 29 + .../src/main/resources/logback.xml | 74 + dcsoft-modules/dcsoft-gen/pom.xml | 94 + .../com/dcsoft/gen/DCSGenApplication.java | 34 + .../java/com/dcsoft/gen/config/GenConfig.java | 66 + .../dcsoft/gen/controller/GenController.java | 211 +++ .../java/com/dcsoft/gen/domain/GenTable.java | 370 ++++ .../com/dcsoft/gen/domain/GenTableColumn.java | 374 ++++ .../gen/mapper/GenTableColumnMapper.java | 60 + .../com/dcsoft/gen/mapper/GenTableMapper.java | 83 + .../service/GenTableColumnServiceImpl.java | 68 + .../gen/service/GenTableServiceImpl.java | 521 ++++++ .../gen/service/IGenTableColumnService.java | 44 + .../dcsoft/gen/service/IGenTableService.java | 121 ++ .../java/com/dcsoft/gen/util/GenUtils.java | 257 +++ .../dcsoft/gen/util/VelocityInitializer.java | 34 + .../com/dcsoft/gen/util/VelocityUtils.java | 402 ++++ .../dcsoft-gen/src/main/resources/banner.txt | 10 + .../src/main/resources/bootstrap.yml | 25 + .../dcsoft-gen/src/main/resources/logback.xml | 74 + .../mapper/generator/GenTableColumnMapper.xml | 127 ++ .../mapper/generator/GenTableMapper.xml | 202 ++ .../main/resources/vm/java/controller.java.vm | 115 ++ .../src/main/resources/vm/java/domain.java.vm | 101 + .../src/main/resources/vm/java/mapper.java.vm | 91 + .../main/resources/vm/java/service.java.vm | 61 + .../resources/vm/java/serviceImpl.java.vm | 169 ++ .../main/resources/vm/java/sub-domain.java.vm | 73 + .../src/main/resources/vm/js/api.js.vm | 44 + .../src/main/resources/vm/sql/sql.vm | 22 + .../main/resources/vm/vue/index-tree.vue.vm | 505 +++++ .../src/main/resources/vm/vue/index.vue.vm | 602 ++++++ .../resources/vm/vue/v3/index-tree.vue.vm | 474 +++++ .../src/main/resources/vm/vue/v3/index.vue.vm | 590 ++++++ .../src/main/resources/vm/vue/v3/readme.txt | 1 + .../src/main/resources/vm/xml/mapper.xml.vm | 135 ++ dcsoft-modules/dcsoft-job/pom.xml | 106 ++ .../com/dcsoft/job/DCSJobApplication.java | 34 + .../com/dcsoft/job/config/ScheduleConfig.java | 57 + .../job/controller/SysJobController.java | 186 ++ .../job/controller/SysJobLogController.java | 91 + .../java/com/dcsoft/job/domain/DeviceVo.java | 11 + .../java/com/dcsoft/job/domain/HolidayVo.java | 33 + .../java/com/dcsoft/job/domain/KqHoliday.java | 130 ++ .../java/com/dcsoft/job/domain/SysJob.java | 171 ++ .../java/com/dcsoft/job/domain/SysJobLog.java | 155 ++ .../java/com/dcsoft/job/domain/VisitorVo.java | 10 + .../dcsoft/job/mapper/KqHolidayMapper.java | 68 + .../dcsoft/job/mapper/SysJobLogMapper.java | 94 + .../com/dcsoft/job/mapper/SysJobMapper.java | 67 + .../dcsoft/job/service/IKqHolidayService.java | 69 + .../dcsoft/job/service/ISysJobLogService.java | 81 + .../dcsoft/job/service/ISysJobService.java | 102 + .../job/service/KqHolidayServiceImpl.java | 118 ++ .../job/service/SysJobLogServiceImpl.java | 249 +++ .../dcsoft/job/service/SysJobServiceImpl.java | 260 +++ .../main/java/com/dcsoft/job/task/RyTask.java | 190 ++ .../dcsoft/job/util/AbstractQuartzJob.java | 106 ++ .../java/com/dcsoft/job/util/CronUtils.java | 63 + .../java/com/dcsoft/job/util/HolidayUtil.java | 117 ++ .../java/com/dcsoft/job/util/HttpUtils.java | 337 ++++ .../com/dcsoft/job/util/JobInvokeUtil.java | 182 ++ .../QuartzDisallowConcurrentExecution.java | 22 + .../dcsoft/job/util/QuartzJobExecution.java | 20 + .../com/dcsoft/job/util/ScheduleUtils.java | 139 ++ .../dcsoft-job/src/main/resources/banner.txt | 10 + .../src/main/resources/bootstrap.yml | 25 + .../dcsoft-job/src/main/resources/logback.xml | 74 + .../resources/mapper/job/KqHolidayMapper.xml | 99 + .../resources/mapper/job/SysJobLogMapper.xml | 147 ++ .../resources/mapper/job/SysJobMapper.xml | 111 ++ dcsoft-modules/dcsoft-system/pom.xml | 144 ++ .../dcsoft/system/DCSSystemApplication.java | 29 + .../car/controller/TbCarController.java | 142 ++ .../car/controller/TbCarRecordController.java | 98 + .../com/dcsoft/system/car/domain/TbCar.java | 230 +++ .../dcsoft/system/car/domain/TbCarRecord.java | 327 ++++ .../dcsoft/system/car/mapper/TbCarMapper.java | 62 + .../system/car/mapper/TbCarRecordMapper.java | 62 + .../system/car/service/ISysPmsService.java | 16 + .../car/service/ITbCarRecordService.java | 62 + .../system/car/service/ITbCarService.java | 70 + .../car/service/impl/SysPmsServiceImpl.java | 64 + .../service/impl/TbCarRecordServiceImpl.java | 94 + .../car/service/impl/TbCarServiceImpl.java | 135 ++ .../dcsoft/system/config/AlipayConfig.java | 0 .../dcsoft/system/config/WeixinPayConfig.java | 0 .../controller/SysBackGroupController.java | 99 + .../controller/SysBlackListController.java | 137 ++ .../controller/SysBranchController.java | 222 +++ .../controller/SysConfigController.java | 173 ++ .../system/controller/SysDeptController.java | 159 ++ .../controller/SysDictDataController.java | 122 ++ .../controller/SysDictTypeController.java | 132 ++ .../SysEmpowerRecordController.java | 245 +++ .../controller/SysEquipmentController.java | 350 ++++ .../controller/SysLogininforController.java | 92 + .../controller/SysManageRecordController.java | 202 ++ .../system/controller/SysMenuController.java | 159 ++ .../controller/SysNoticeController.java | 92 + .../controller/SysOperlogController.java | 78 + .../controller/SysPeopleController.java | 1260 +++++++++++++ .../controller/SysPeopleLeaveController.java | 330 ++++ .../controller/SysPeopleOtherController.java | 328 ++++ .../controller/SysPeopleRecordController.java | 122 ++ .../system/controller/SysPointController.java | 104 ++ .../system/controller/SysPostController.java | 130 ++ .../controller/SysProductController.java | 104 ++ .../controller/SysProfileController.java | 158 ++ .../system/controller/SysRoleController.java | 239 +++ .../system/controller/SysRuleController.java | 175 ++ .../system/controller/SysSpaceController.java | 124 ++ .../controller/SysSyncRuleController.java | 148 ++ .../system/controller/SysUserController.java | 434 +++++ .../controller/SysUserOnlineController.java | 87 + .../dcsoft/system/controller/ThreadTest1.java | 21 + .../dcsoft/system/domain/SysBackGroup.java | 76 + .../dcsoft/system/domain/SysBlackList.java | 112 ++ .../com/dcsoft/system/domain/SysBranch.java | 79 + .../com/dcsoft/system/domain/SysConfig.java | 111 ++ .../system/domain/SysEmpowerRecord.java | 67 + .../dcsoft/system/domain/SysEquipment.java | 1140 +++++++++++ .../dcsoft/system/domain/SysManageRecord.java | 148 ++ .../com/dcsoft/system/domain/SysMenu.java | 259 +++ .../com/dcsoft/system/domain/SysNotice.java | 102 + .../com/dcsoft/system/domain/SysPeople.java | 433 +++++ .../system/domain/SysPeopleEquipment.java | 116 ++ .../dcsoft/system/domain/SysPeopleLeave.java | 187 ++ .../dcsoft/system/domain/SysPeopleOther.java | 400 ++++ .../dcsoft/system/domain/SysPeopleRecord.java | 481 +++++ .../dcsoft/system/domain/SysPeopleRule.java | 97 + .../com/dcsoft/system/domain/SysPoint.java | 90 + .../com/dcsoft/system/domain/SysPost.java | 124 ++ .../com/dcsoft/system/domain/SysProduct.java | 195 ++ .../com/dcsoft/system/domain/SysRoleDept.java | 46 + .../com/dcsoft/system/domain/SysRoleMenu.java | 46 + .../com/dcsoft/system/domain/SysRule.java | 204 ++ .../com/dcsoft/system/domain/SysSpace.java | 128 ++ .../com/dcsoft/system/domain/SysSyncItem.java | 65 + .../com/dcsoft/system/domain/SysSyncRule.java | 148 ++ .../dcsoft/system/domain/SysUserOnline.java | 100 + .../com/dcsoft/system/domain/SysUserPost.java | 46 + .../com/dcsoft/system/domain/SysUserRole.java | 46 + .../dcsoft/system/domain/vo/AppletInfoVo.java | 26 + .../system/domain/vo/BranchSelectVo.java | 0 .../dcsoft/system/domain/vo/JjDivisionVo.java | 97 + .../dcsoft/system/domain/vo/JjStationVo.java | 39 + .../dcsoft/system/domain/vo/JjserInfoVo.java | 90 + .../com/dcsoft/system/domain/vo/MetaVo.java | 106 ++ .../system/domain/vo/OfficialAccountVo.java | 21 + .../com/dcsoft/system/domain/vo/RouterVo.java | 148 ++ .../dcsoft/system/domain/vo/SysAuthTree.java | 130 ++ .../dcsoft/system/domain/vo/SysFileVo.java | 40 + .../dcsoft/system/domain/vo/TreeSelect.java | 119 ++ .../dcsoft/system/domain/vo/TreeSelectVo.java | 36 + .../system/mapper/SysBackGroupMapper.java | 63 + .../system/mapper/SysBlackListMapper.java | 103 + .../dcsoft/system/mapper/SysBranchMapper.java | 100 + .../dcsoft/system/mapper/SysConfigMapper.java | 76 + .../dcsoft/system/mapper/SysDeptMapper.java | 120 ++ .../system/mapper/SysDictDataMapper.java | 95 + .../system/mapper/SysDictTypeMapper.java | 83 + .../system/mapper/SysEmpowerRecordMapper.java | 63 + .../system/mapper/SysEquipmentMapper.java | 124 ++ .../system/mapper/SysLogininforMapper.java | 42 + .../system/mapper/SysManageRecordMapper.java | 61 + .../dcsoft/system/mapper/SysMenuMapper.java | 125 ++ .../dcsoft/system/mapper/SysNoticeMapper.java | 60 + .../system/mapper/SysOperLogMapper.java | 48 + .../mapper/SysPeopleEquipmentMapper.java | 70 + .../system/mapper/SysPeopleLeaveMapper.java | 67 + .../dcsoft/system/mapper/SysPeopleMapper.java | 111 ++ .../system/mapper/SysPeopleOtherMapper.java | 101 + .../system/mapper/SysPeopleRecordMapper.java | 81 + .../system/mapper/SysPeopleRuleMapper.java | 61 + .../dcsoft/system/mapper/SysPointMapper.java | 62 + .../dcsoft/system/mapper/SysPostMapper.java | 99 + .../system/mapper/SysProductMapper.java | 61 + .../system/mapper/SysRoleDeptMapper.java | 44 + .../dcsoft/system/mapper/SysRoleMapper.java | 107 ++ .../system/mapper/SysRoleMenuMapper.java | 44 + .../dcsoft/system/mapper/SysRuleMapper.java | 61 + .../dcsoft/system/mapper/SysSpaceMapper.java | 64 + .../system/mapper/SysSyncRuleMapper.java | 80 + .../dcsoft/system/mapper/SysUserMapper.java | 160 ++ .../system/mapper/SysUserPostMapper.java | 44 + .../system/mapper/SysUserRoleMapper.java | 62 + .../system/service/ISysBackGroupService.java | 63 + .../system/service/ISysBlackListService.java | 64 + .../system/service/ISysBranchService.java | 128 ++ .../system/service/ISysConfigService.java | 93 + .../system/service/ISysDeptService.java | 126 ++ .../system/service/ISysDictDataService.java | 64 + .../system/service/ISysDictTypeService.java | 98 + .../service/ISysEmpowerRecordService.java | 63 + .../system/service/ISysEquipmentService.java | 126 ++ .../system/service/ISysLogininforService.java | 40 + .../service/ISysManageRecordService.java | 61 + .../system/service/ISysMenuService.java | 144 ++ .../system/service/ISysNoticeService.java | 60 + .../system/service/ISysOperLogService.java | 49 + .../service/ISysPeopleEquipmentService.java | 81 + .../service/ISysPeopleLeaveService.java | 70 + .../service/ISysPeopleOtherService.java | 107 ++ .../service/ISysPeopleRecordService.java | 82 + .../system/service/ISysPeopleRuleService.java | 61 + .../system/service/ISysPeopleService.java | 116 ++ .../system/service/ISysPermissionService.java | 29 + .../system/service/ISysPointService.java | 61 + .../system/service/ISysPostService.java | 99 + .../system/service/ISysProductService.java | 61 + .../system/service/ISysRoleService.java | 173 ++ .../system/service/ISysRuleService.java | 67 + .../system/service/ISysSpaceService.java | 81 + .../system/service/ISysSyncRuleService.java | 82 + .../system/service/ISysUserOnlineService.java | 48 + .../system/service/ISysUserService.java | 230 +++ .../service/impl/SysBackGroupServiceImpl.java | 100 + .../service/impl/SysBlackListServiceImpl.java | 102 + .../service/impl/SysBranchServiceImpl.java | 343 ++++ .../service/impl/SysConfigServiceImpl.java | 332 ++++ .../service/impl/SysDeptServiceImpl.java | 345 ++++ .../service/impl/SysDictDataServiceImpl.java | 122 ++ .../service/impl/SysDictTypeServiceImpl.java | 223 +++ .../impl/SysEmpowerRecordServiceImpl.java | 101 + .../service/impl/SysEquipmentServiceImpl.java | 251 +++ .../impl/SysLogininforServiceImpl.java | 65 + .../impl/SysManageRecordServiceImpl.java | 96 + .../service/impl/SysMenuServiceImpl.java | 531 ++++++ .../service/impl/SysNoticeServiceImpl.java | 92 + .../service/impl/SysOperLogServiceImpl.java | 79 + .../impl/SysPeopleEquipmentServiceImpl.java | 135 ++ .../impl/SysPeopleLeaveServiceImpl.java | 230 +++ .../impl/SysPeopleOtherServiceImpl.java | 348 ++++ .../impl/SysPeopleRecordServiceImpl.java | 134 ++ .../impl/SysPeopleRuleServiceImpl.java | 96 + .../service/impl/SysPeopleServiceImpl.java | 401 ++++ .../impl/SysPermissionServiceImpl.java | 85 + .../service/impl/SysPointServiceImpl.java | 96 + .../service/impl/SysPostServiceImpl.java | 178 ++ .../service/impl/SysProductServiceImpl.java | 96 + .../service/impl/SysRoleServiceImpl.java | 424 +++++ .../service/impl/SysRuleServiceImpl.java | 212 +++ .../service/impl/SysSpaceServiceImpl.java | 201 ++ .../service/impl/SysSyncRuleServiceImpl.java | 159 ++ .../impl/SysUserOnlineServiceImpl.java | 89 + .../service/impl/SysUserServiceImpl.java | 659 +++++++ .../uniubi/controller/SysApiController.java | 648 +++++++ .../uniubi/controller/SysSdkController.java | 767 ++++++++ .../dcsoft/system/uniubi/controller/test.java | 83 + .../dcsoft/system/uniubi/domain/BackInfo.java | 100 + .../system/uniubi/domain/BackResult.java | 52 + .../system/uniubi/domain/DingtalkCode.java | 22 + .../system/uniubi/domain/DingtalkMsgVo.java | 27 + .../system/uniubi/domain/EventResult.java | 24 + .../dcsoft/system/uniubi/domain/EwmInfo.java | 41 + .../system/uniubi/domain/HeartInfo.java | 54 + .../system/uniubi/domain/LadderControlVo.java | 44 + .../dcsoft/system/uniubi/domain/Person.java | 172 ++ .../dcsoft/system/uniubi/domain/QrCodeVo.java | 37 + .../system/uniubi/service/ISysApiService.java | 93 + .../system/uniubi/service/ISysSdkService.java | 122 ++ .../uniubi/service/ISysVehicleService.java | 15 + .../service/impl/SysApiServiceImpl.java | 674 +++++++ .../service/impl/SysSdkServiceImpl.java | 718 +++++++ .../service/impl/SysVehicleServiceImpl.java | 169 ++ .../com/dcsoft/system/utils/BackupConfig.java | 122 ++ .../utils/Base64DecodeMultipartFile.java | 57 + .../java/com/dcsoft/system/utils/FTPUtil.java | 162 ++ .../com/dcsoft/system/utils/FileUtils.java | 164 ++ .../com/dcsoft/system/utils/FloorUtil.java | 56 + .../com/dcsoft/system/utils/HttpClient.java | 0 .../com/dcsoft/system/utils/HttpUtil.java | 408 ++++ .../com/dcsoft/system/utils/IWXPayDomain.java | 0 .../system/utils/ImageToBase64Utils.java | 155 ++ .../com/dcsoft/system/utils/PictureUtils.java | 164 ++ .../com/dcsoft/system/utils/TreeUtil.java | 30 + .../com/dcsoft/system/utils/WXPayConfig.java | 0 .../dcsoft/system/utils/WXPayConstants.java | 0 .../com/dcsoft/system/utils/WXPayReport.java | 0 .../com/dcsoft/system/utils/WXPayUtil.java | 0 .../com/dcsoft/system/utils/WXPayXmlUtil.java | 0 .../com/dcsoft/system/utils/WeChatUtil.java | 182 ++ .../java/com/dcsoft/system/utils/ZipUtil.java | 127 ++ .../controller/CarChargeController.java | 123 ++ .../vehicle/controller/CarInfoController.java | 215 +++ .../vehicle/controller/CarParkController.java | 125 ++ .../controller/CarParkRecordController.java | 116 ++ .../controller/CarPassGatherController.java | 106 ++ .../controller/CarPassRecordController.java | 98 + .../system/vehicle/domain/CarCharge.java | 149 ++ .../system/vehicle/domain/CarChargeItem.java | 95 + .../dcsoft/system/vehicle/domain/CarInfo.java | 297 +++ .../dcsoft/system/vehicle/domain/CarPark.java | 121 ++ .../system/vehicle/domain/CarParkItem.java | 89 + .../system/vehicle/domain/CarParkRecord.java | 128 ++ .../system/vehicle/domain/CarPassGather.java | 151 ++ .../system/vehicle/domain/CarPassRecord.java | 245 +++ .../vehicle/mapper/CarChargeItemMapper.java | 64 + .../vehicle/mapper/CarChargeMapper.java | 62 + .../system/vehicle/mapper/CarInfoMapper.java | 64 + .../vehicle/mapper/CarParkItemMapper.java | 64 + .../system/vehicle/mapper/CarParkMapper.java | 76 + .../vehicle/mapper/CarParkRecordMapper.java | 70 + .../vehicle/mapper/CarPassGatherMapper.java | 65 + .../vehicle/mapper/CarPassRecordMapper.java | 62 + .../service/ICarChargeItemService.java | 64 + .../vehicle/service/ICarChargeService.java | 62 + .../vehicle/service/ICarInfoService.java | 77 + .../vehicle/service/ICarParkItemService.java | 64 + .../service/ICarParkRecordService.java | 69 + .../vehicle/service/ICarParkService.java | 62 + .../service/ICarPassGatherService.java | 65 + .../service/ICarPassRecordService.java | 62 + .../impl/CarChargeItemServiceImpl.java | 102 + .../service/impl/CarChargeServiceImpl.java | 97 + .../service/impl/CarInfoServiceImpl.java | 340 ++++ .../service/impl/CarParkItemServiceImpl.java | 100 + .../impl/CarParkRecordServiceImpl.java | 113 ++ .../service/impl/CarParkServiceImpl.java | 97 + .../impl/CarPassGatherServiceImpl.java | 100 + .../impl/CarPassRecordServiceImpl.java | 95 + .../VisVisitorExamineController.java | 100 + .../VisVisitorRegisterController.java | 98 + .../visitor/controller/VisitorController.java | 1227 ++++++++++++ .../controller/VisitorMachineController.java | 605 ++++++ .../system/visitor/domain/CheckCodeVo.java | 20 + .../system/visitor/domain/EwmInfoVo.java | 19 + .../visitor/domain/PersonnelInfoVo.java | 64 + .../visitor/domain/VisVisitorExamine.java | 203 ++ .../visitor/domain/VisVisitorLogisticsVo.java | 46 + .../visitor/domain/VisVisitorRegister.java | 176 ++ .../dcsoft/system/visitor/domain/Visitor.java | 245 +++ .../system/visitor/domain/VisitorCountVo.java | 24 + .../system/visitor/domain/VisitorInfoVo.java | 37 + .../system/visitor/domain/VisitorParamVo.java | 32 + .../visitor/domain/VisitorRecordVo.java | 91 + .../domain/VisitorReviewProcessVo.java | 31 + .../system/visitor/domain/VisitorVo.java | 33 + .../mapper/VisVisitorExamineMapper.java | 64 + .../mapper/VisVisitorRegisterMapper.java | 68 + .../system/visitor/mapper/VisitorMapper.java | 235 +++ .../service/IVisVisitorExamineService.java | 71 + .../service/IVisVisitorRegisterService.java | 69 + .../visitor/service/IVisitorService.java | 250 +++ .../impl/VisVisitorExamineServiceImpl.java | 105 ++ .../impl/VisVisitorRegisterServiceImpl.java | 103 + .../service/impl/VisitorServiceImpl.java | 671 +++++++ .../src/main/resources/banner.txt | 7 + .../src/main/resources/bootstrap.yml | 59 + .../src/main/resources/logback.xml | 74 + .../main/resources/mapper/car/TbCarMapper.xml | 118 ++ .../mapper/car/TbCarRecordMapper.xml | 141 ++ .../mapper/system/SysBackGroupMapper.xml | 72 + .../mapper/system/SysBlackListMapper.xml | 243 +++ .../mapper/system/SysBranchMapper.xml | 240 +++ .../mapper/system/SysConfigMapper.xml | 117 ++ .../resources/mapper/system/SysDeptMapper.xml | 166 ++ .../mapper/system/SysDictDataMapper.xml | 124 ++ .../mapper/system/SysDictTypeMapper.xml | 105 ++ .../mapper/system/SysEmpowerRecordMapper.xml | 131 ++ .../mapper/system/SysEquipmentMapper.xml | 522 ++++++ .../mapper/system/SysLogininforMapper.xml | 54 + .../mapper/system/SysManageRecordMapper.xml | 115 ++ .../resources/mapper/system/SysMenuMapper.xml | 202 ++ .../mapper/system/SysNoticeMapper.xml | 89 + .../mapper/system/SysOperLogMapper.xml | 83 + .../system/SysPeopleEquipmentMapper.xml | 102 + .../mapper/system/SysPeopleLeaveMapper.xml | 206 ++ .../mapper/system/SysPeopleMapper.xml | 322 ++++ .../mapper/system/SysPeopleOtherMapper.xml | 291 +++ .../mapper/system/SysPeopleRecordMapper.xml | 307 +++ .../mapper/system/SysPeopleRuleMapper.xml | 91 + .../mapper/system/SysPointMapper.xml | 98 + .../resources/mapper/system/SysPostMapper.xml | 122 ++ .../mapper/system/SysProductMapper.xml | 122 ++ .../mapper/system/SysRoleDeptMapper.xml | 34 + .../resources/mapper/system/SysRoleMapper.xml | 152 ++ .../mapper/system/SysRoleMenuMapper.xml | 34 + .../resources/mapper/system/SysRuleMapper.xml | 120 ++ .../mapper/system/SysSpaceMapper.xml | 114 ++ .../mapper/system/SysSyncRuleMapper.xml | 147 ++ .../resources/mapper/system/SysUserMapper.xml | 256 +++ .../mapper/system/SysUserPostMapper.xml | 34 + .../mapper/system/SysUserRoleMapper.xml | 44 + .../visitor/VisVisitorExamineMapper.xml | 132 ++ .../visitor/VisVisitorRegisterMapper.xml | 111 ++ .../mapper/system/visitor/VisitorMapper.xml | 811 ++++++++ .../mapper/vehicle/CarChargeItemMapper.xml | 75 + .../mapper/vehicle/CarChargeMapper.xml | 102 + .../mapper/vehicle/CarInfoMapper.xml | 166 ++ .../mapper/vehicle/CarParkItemMapper.xml | 76 + .../mapper/vehicle/CarParkMapper.xml | 125 ++ .../mapper/vehicle/CarParkRecordMapper.xml | 97 + .../mapper/vehicle/CarPassGatherMapper.xml | 90 + .../mapper/vehicle/CarPassRecordMapper.xml | 115 ++ dcsoft-modules/pom.xml | 25 + dcsoft-visual/dcsoft-monitor/pom.xml | 75 + .../monitor/DCSMonitorApplication.java | 30 + .../monitor/config/WebSecurityConfigurer.java | 51 + .../src/main/resources/banner.txt | 10 + .../src/main/resources/bootstrap.yml | 25 + .../src/main/resources/logback.xml | 74 + dcsoft-visual/pom.xml | 22 + license.xml | 8 + logs/dcsoft-auth/error.log | 0 logs/dcsoft-auth/info.2025-03-21.log | 106 ++ logs/dcsoft-auth/info.2025-03-22.log | 60 + logs/dcsoft-auth/info.log | 56 + logs/dcsoft-file/error.log | 0 logs/dcsoft-file/info.log | 0 logs/dcsoft-gateway/error.2025-03-21.log | 0 logs/dcsoft-gateway/error.log | 22 + logs/dcsoft-gateway/info.2025-03-21.log | 134 ++ logs/dcsoft-gateway/info.2025-03-22.log | 68 + logs/dcsoft-gateway/info.log | 115 ++ logs/dcsoft-system/error.2025-03-21.log | 85 + logs/dcsoft-system/error.log | 1663 +++++++++++++++++ logs/dcsoft-system/info.2025-03-21.log | 153 ++ logs/dcsoft-system/info.2025-03-22.log | 149 ++ logs/dcsoft-system/info.log | 61 + pom.xml | 316 ++++ 680 files changed, 83364 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/ApifoxUploaderProjectSetting.xml create mode 100644 .idea/compiler.xml create mode 100644 .idea/encodings.xml create mode 100644 .idea/jarRepositories.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/workspace.xml create mode 100644 .idea/xa-master-prod.iml create mode 100644 dcsoft-api/dcsoft-api-system/pom.xml create mode 100644 dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/RemoteAuthApplication.java create mode 100644 dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/RemoteAuthService.java create mode 100644 dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/RemoteFileService.java create mode 100644 dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/RemoteLogService.java create mode 100644 dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/RemoteStudentService.java create mode 100644 dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/RemoteUserService.java create mode 100644 dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/FaceStudentBody.java create mode 100644 dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/LoginBody.java create mode 100644 dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysAuth.java create mode 100644 dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysDept.java create mode 100644 dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysDictData.java create mode 100644 dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysDictType.java create mode 100644 dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysFile.java create mode 100644 dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysLogininfor.java create mode 100644 dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysOperLog.java create mode 100644 dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysRole.java create mode 100644 dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysUser.java create mode 100644 dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/factory/RemoteAuthFallbackFactory.java create mode 100644 dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/factory/RemoteAuthServiceFallbackFactory.java create mode 100644 dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/factory/RemoteFileFallbackFactory.java create mode 100644 dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/factory/RemoteLogFallbackFactory.java create mode 100644 dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/factory/RemoteStudentFallbackFactory.java create mode 100644 dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/factory/RemoteUserFallbackFactory.java create mode 100644 dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/model/LoginUser.java create mode 100644 dcsoft-api/dcsoft-api-system/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 dcsoft-api/pom.xml create mode 100644 dcsoft-auth/pom.xml create mode 100644 dcsoft-auth/src/main/java/com/dcsoft/auth/DCSAuthApplication.java create mode 100644 dcsoft-auth/src/main/java/com/dcsoft/auth/bean/CheckParams.java create mode 100644 dcsoft-auth/src/main/java/com/dcsoft/auth/bean/ValidateCodeEnum.java create mode 100644 dcsoft-auth/src/main/java/com/dcsoft/auth/bean/ValidateResult.java create mode 100644 dcsoft-auth/src/main/java/com/dcsoft/auth/controller/ApiController.java create mode 100644 dcsoft-auth/src/main/java/com/dcsoft/auth/controller/TokenController.java create mode 100644 dcsoft-auth/src/main/java/com/dcsoft/auth/form/AuthBody.java create mode 100644 dcsoft-auth/src/main/java/com/dcsoft/auth/form/IDaasBody.java create mode 100644 dcsoft-auth/src/main/java/com/dcsoft/auth/form/LoginBody.java create mode 100644 dcsoft-auth/src/main/java/com/dcsoft/auth/form/RegisterBody.java create mode 100644 dcsoft-auth/src/main/java/com/dcsoft/auth/service/SysAuthService.java create mode 100644 dcsoft-auth/src/main/java/com/dcsoft/auth/service/SysLoginService.java create mode 100644 dcsoft-auth/src/main/java/com/dcsoft/auth/service/SysPasswordService.java create mode 100644 dcsoft-auth/src/main/java/com/dcsoft/auth/service/SysRecordLogService.java create mode 100644 dcsoft-auth/src/main/java/com/dcsoft/auth/test/CreateSign.java create mode 100644 dcsoft-auth/src/main/java/com/dcsoft/auth/utils/AESUtils.java create mode 100644 dcsoft-auth/src/main/java/com/dcsoft/auth/utils/DateUtils.java create mode 100644 dcsoft-auth/src/main/java/com/dcsoft/auth/utils/KeyGenerator.java create mode 100644 dcsoft-auth/src/main/java/com/dcsoft/auth/utils/LicenseManager.java create mode 100644 dcsoft-auth/src/main/java/com/dcsoft/auth/utils/LicenseThread.java create mode 100644 dcsoft-auth/src/main/java/com/dcsoft/auth/utils/RSAUtils.java create mode 100644 dcsoft-auth/src/main/java/com/dcsoft/auth/utils/Systemutils.java create mode 100644 dcsoft-auth/src/main/resources/banner.txt create mode 100644 dcsoft-auth/src/main/resources/bootstrap.yml create mode 100644 dcsoft-auth/src/main/resources/lib/JWT-SDK-1.1.1_1.8.jar create mode 100644 dcsoft-auth/src/main/resources/lib/jose4j-0.4.3.jar create mode 100644 dcsoft-auth/src/main/resources/logback.xml create mode 100644 dcsoft-common/dcsoft-common-core/pom.xml create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/annotation/Excel.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/annotation/Excels.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/CacheConstants.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/Constants.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/GenConstants.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/HttpStatus.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/ScheduleConstants.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/SecurityConstants.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/ServiceNameConstants.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/TokenConstants.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/UserConstants.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/context/SecurityContextHolder.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/domain/R.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/enums/CompanyType.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/enums/UserStatus.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/enums/exception/CommonExceptionEnum.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/CaptchaException.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/CheckedException.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/DemoModeException.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/GlobalException.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/InnerAuthException.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/PreAuthorizeException.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/ServiceException.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/UtilException.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/auth/NotLoginException.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/auth/NotPermissionException.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/auth/NotRoleException.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/base/BaseException.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/file/FileException.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/file/FileNameLengthLimitExceededException.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/file/FileSizeLimitExceededException.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/file/FileUploadException.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/file/InvalidExtensionException.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/job/TaskException.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/user/CaptchaExpireException.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/user/UserException.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/user/UserPasswordNotMatchException.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/text/CharsetKit.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/text/Convert.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/text/StrFormatter.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/CollUtil.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/DateUtils.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/ExceptionUtil.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/JsonUtils.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/JwtUtils.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/PageUtils.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/ServletUtils.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/SpringUtils.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/StringUtils.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/bean/BeanUtils.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/bean/BeanValidators.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/file/FileTypeUtils.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/file/FileUtils.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/file/ImageUtils.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/file/MimeTypeUtils.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/html/EscapeUtil.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/html/HTMLFilter.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/ip/IpUtils.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/poi/ExcelHandlerAdapter.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/poi/ExcelUtil.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/reflect/ReflectUtils.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/sign/Base64.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/sql/SqlUtil.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/uuid/IdUtils.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/uuid/Seq.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/uuid/UUID.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/controller/BaseController.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/domain/AjaxResult.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/domain/BaseEntity.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/domain/HkResult.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/domain/TreeEntity.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/page/PageDomain.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/page/TableDataInfo.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/page/TableDataInfoPage.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/page/TableDatasInfo.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/page/TableSupport.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/xss/Xss.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/xss/XssValidator.java create mode 100644 dcsoft-common/dcsoft-common-core/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 dcsoft-common/dcsoft-common-datascope/pom.xml create mode 100644 dcsoft-common/dcsoft-common-datascope/src/main/java/com/dcsoft/common/datascope/annotation/DataScope.java create mode 100644 dcsoft-common/dcsoft-common-datascope/src/main/java/com/dcsoft/common/datascope/aspect/DataScopeAspect.java create mode 100644 dcsoft-common/dcsoft-common-datascope/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 dcsoft-common/dcsoft-common-datasource/pom.xml create mode 100644 dcsoft-common/dcsoft-common-datasource/src/main/java/com/dcsoft/common/datasource/annotation/Master.java create mode 100644 dcsoft-common/dcsoft-common-datasource/src/main/java/com/dcsoft/common/datasource/annotation/Slave.java create mode 100644 dcsoft-common/dcsoft-common-log/pom.xml create mode 100644 dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/annotation/Log.java create mode 100644 dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/aspect/LogAspect.java create mode 100644 dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/enums/BusinessStatus.java create mode 100644 dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/enums/BusinessType.java create mode 100644 dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/enums/OperatorType.java create mode 100644 dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/filter/PropertyPreExcludeFilter.java create mode 100644 dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/service/AsyncLogService.java create mode 100644 dcsoft-common/dcsoft-common-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 dcsoft-common/dcsoft-common-redis/pom.xml create mode 100644 dcsoft-common/dcsoft-common-redis/src/main/java/com/dcsoft/common/redis/configure/FastJson2JsonRedisSerializer.java create mode 100644 dcsoft-common/dcsoft-common-redis/src/main/java/com/dcsoft/common/redis/configure/RedisConfig.java create mode 100644 dcsoft-common/dcsoft-common-redis/src/main/java/com/dcsoft/common/redis/service/RedisService.java create mode 100644 dcsoft-common/dcsoft-common-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 dcsoft-common/dcsoft-common-seata/pom.xml create mode 100644 dcsoft-common/dcsoft-common-security/pom.xml create mode 100644 dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/EnableCustomConfig.java create mode 100644 dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/EnableRyFeignClients.java create mode 100644 dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/InnerAuth.java create mode 100644 dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/Logical.java create mode 100644 dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/RequiresLogin.java create mode 100644 dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/RequiresPermissions.java create mode 100644 dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/RequiresRoles.java create mode 100644 dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/aspect/InnerAuthAspect.java create mode 100644 dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/aspect/PreAuthorizeAspect.java create mode 100644 dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/auth/AuthLogic.java create mode 100644 dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/auth/AuthUtil.java create mode 100644 dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/config/ApplicationConfig.java create mode 100644 dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/config/WebMvcConfig.java create mode 100644 dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/feign/FeignAutoConfiguration.java create mode 100644 dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/feign/FeignRequestInterceptor.java create mode 100644 dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/handler/GlobalExceptionHandler.java create mode 100644 dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/interceptor/HeaderInterceptor.java create mode 100644 dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/service/TokenService.java create mode 100644 dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/utils/DictUtils.java create mode 100644 dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/utils/SecurityUtils.java create mode 100644 dcsoft-common/dcsoft-common-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 dcsoft-common/dcsoft-common-sms/pom.xml create mode 100644 dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/config/SmsAutoConfiguration.java create mode 100644 dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/config/properties/SmsProperties.java create mode 100644 dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/entity/SmsResult.java create mode 100644 dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/exception/SmsException.java create mode 100644 dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/service/SmsTemplate.java create mode 100644 dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/service/impl/AliyunSmsTemplate.java create mode 100644 dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/service/impl/TencentSmsTemplate.java create mode 100644 dcsoft-common/dcsoft-common-sms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 dcsoft-common/dcsoft-common-swagger/pom.xml create mode 100644 dcsoft-common/dcsoft-common-swagger/src/main/java/com/dcsoft/common/swagger/annotation/EnableCustomSwagger2.java create mode 100644 dcsoft-common/dcsoft-common-swagger/src/main/java/com/dcsoft/common/swagger/config/SwaggerAutoConfiguration.java create mode 100644 dcsoft-common/dcsoft-common-swagger/src/main/java/com/dcsoft/common/swagger/config/SwaggerBeanPostProcessor.java create mode 100644 dcsoft-common/dcsoft-common-swagger/src/main/java/com/dcsoft/common/swagger/config/SwaggerProperties.java create mode 100644 dcsoft-common/dcsoft-common-swagger/src/main/java/com/dcsoft/common/swagger/config/SwaggerWebConfiguration.java create mode 100644 dcsoft-common/dcsoft-common-swagger/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 dcsoft-common/pom.xml create mode 100644 dcsoft-gateway/pom.xml create mode 100644 dcsoft-gateway/src/main/java/com/dcsoft/gateway/DCSGatewayApplication.java create mode 100644 dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/CaptchaConfig.java create mode 100644 dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/CorsConfig.java create mode 100644 dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/GatewayConfig.java create mode 100644 dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/KaptchaTextCreator.java create mode 100644 dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/RouterFunctionConfiguration.java create mode 100644 dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/SwaggerProvider.java create mode 100644 dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/properties/CaptchaProperties.java create mode 100644 dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/properties/IgnoreWhiteProperties.java create mode 100644 dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/properties/XssProperties.java create mode 100644 dcsoft-gateway/src/main/java/com/dcsoft/gateway/filter/AuthFilter.java create mode 100644 dcsoft-gateway/src/main/java/com/dcsoft/gateway/filter/BlackListUrlFilter.java create mode 100644 dcsoft-gateway/src/main/java/com/dcsoft/gateway/filter/CacheRequestFilter.java create mode 100644 dcsoft-gateway/src/main/java/com/dcsoft/gateway/filter/ValidateCodeFilter.java create mode 100644 dcsoft-gateway/src/main/java/com/dcsoft/gateway/filter/XssFilter.java create mode 100644 dcsoft-gateway/src/main/java/com/dcsoft/gateway/handler/GatewayExceptionHandler.java create mode 100644 dcsoft-gateway/src/main/java/com/dcsoft/gateway/handler/SentinelFallbackHandler.java create mode 100644 dcsoft-gateway/src/main/java/com/dcsoft/gateway/handler/SwaggerHandler.java create mode 100644 dcsoft-gateway/src/main/java/com/dcsoft/gateway/handler/ValidateCodeHandler.java create mode 100644 dcsoft-gateway/src/main/java/com/dcsoft/gateway/service/ValidateCodeService.java create mode 100644 dcsoft-gateway/src/main/java/com/dcsoft/gateway/service/impl/ValidateCodeServiceImpl.java create mode 100644 dcsoft-gateway/src/main/resources/banner.txt create mode 100644 dcsoft-gateway/src/main/resources/bootstrap.yml create mode 100644 dcsoft-gateway/src/main/resources/logback.xml create mode 100644 dcsoft-modules/dcsoft-file/pom.xml create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/Main.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/DCSFileApplication.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/config/FileListener.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/config/MinioConfig.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/config/ResourcesConfig.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/controller/MinIO.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/controller/SysFileController.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/controller/test.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/controller/zctest.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/AlgoServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/FaceServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/FastDfsSysFileServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/IAlgoService.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/IFaceService.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/ISysFileService.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/LocalSysFileServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/MinioSysFileServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/utils/BASE64DecodedMultipartFile.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/utils/FileUploadUtils.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/utils/HttpUtil.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/utils/ImageToBase64Utils.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/utils/MinioUtil.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/utils/PictureUtils.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/utils/PngColoringUtil.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/uniubi/Register/FaceBox.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/uniubi/Register/UfaceRegister.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/java/com/uniubi/Register/UfaceRegisterJNI.java create mode 100644 dcsoft-modules/dcsoft-file/src/main/resources/banner.txt create mode 100644 dcsoft-modules/dcsoft-file/src/main/resources/bootstrap.yml create mode 100644 dcsoft-modules/dcsoft-file/src/main/resources/logback.xml create mode 100644 dcsoft-modules/dcsoft-gen/pom.xml create mode 100644 dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/DCSGenApplication.java create mode 100644 dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/config/GenConfig.java create mode 100644 dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/controller/GenController.java create mode 100644 dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/domain/GenTable.java create mode 100644 dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/domain/GenTableColumn.java create mode 100644 dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/mapper/GenTableColumnMapper.java create mode 100644 dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/mapper/GenTableMapper.java create mode 100644 dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/service/GenTableColumnServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/service/GenTableServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/service/IGenTableColumnService.java create mode 100644 dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/service/IGenTableService.java create mode 100644 dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/util/GenUtils.java create mode 100644 dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/util/VelocityInitializer.java create mode 100644 dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/util/VelocityUtils.java create mode 100644 dcsoft-modules/dcsoft-gen/src/main/resources/banner.txt create mode 100644 dcsoft-modules/dcsoft-gen/src/main/resources/bootstrap.yml create mode 100644 dcsoft-modules/dcsoft-gen/src/main/resources/logback.xml create mode 100644 dcsoft-modules/dcsoft-gen/src/main/resources/mapper/generator/GenTableColumnMapper.xml create mode 100644 dcsoft-modules/dcsoft-gen/src/main/resources/mapper/generator/GenTableMapper.xml create mode 100644 dcsoft-modules/dcsoft-gen/src/main/resources/vm/java/controller.java.vm create mode 100644 dcsoft-modules/dcsoft-gen/src/main/resources/vm/java/domain.java.vm create mode 100644 dcsoft-modules/dcsoft-gen/src/main/resources/vm/java/mapper.java.vm create mode 100644 dcsoft-modules/dcsoft-gen/src/main/resources/vm/java/service.java.vm create mode 100644 dcsoft-modules/dcsoft-gen/src/main/resources/vm/java/serviceImpl.java.vm create mode 100644 dcsoft-modules/dcsoft-gen/src/main/resources/vm/java/sub-domain.java.vm create mode 100644 dcsoft-modules/dcsoft-gen/src/main/resources/vm/js/api.js.vm create mode 100644 dcsoft-modules/dcsoft-gen/src/main/resources/vm/sql/sql.vm create mode 100644 dcsoft-modules/dcsoft-gen/src/main/resources/vm/vue/index-tree.vue.vm create mode 100644 dcsoft-modules/dcsoft-gen/src/main/resources/vm/vue/index.vue.vm create mode 100644 dcsoft-modules/dcsoft-gen/src/main/resources/vm/vue/v3/index-tree.vue.vm create mode 100644 dcsoft-modules/dcsoft-gen/src/main/resources/vm/vue/v3/index.vue.vm create mode 100644 dcsoft-modules/dcsoft-gen/src/main/resources/vm/vue/v3/readme.txt create mode 100644 dcsoft-modules/dcsoft-gen/src/main/resources/vm/xml/mapper.xml.vm create mode 100644 dcsoft-modules/dcsoft-job/pom.xml create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/DCSJobApplication.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/config/ScheduleConfig.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/controller/SysJobController.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/controller/SysJobLogController.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/domain/DeviceVo.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/domain/HolidayVo.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/domain/KqHoliday.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/domain/SysJob.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/domain/SysJobLog.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/domain/VisitorVo.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/mapper/KqHolidayMapper.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/mapper/SysJobLogMapper.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/mapper/SysJobMapper.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/service/IKqHolidayService.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/service/ISysJobLogService.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/service/ISysJobService.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/service/KqHolidayServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/service/SysJobLogServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/service/SysJobServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/task/RyTask.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/AbstractQuartzJob.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/CronUtils.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/HolidayUtil.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/HttpUtils.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/JobInvokeUtil.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/QuartzDisallowConcurrentExecution.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/QuartzJobExecution.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/ScheduleUtils.java create mode 100644 dcsoft-modules/dcsoft-job/src/main/resources/banner.txt create mode 100644 dcsoft-modules/dcsoft-job/src/main/resources/bootstrap.yml create mode 100644 dcsoft-modules/dcsoft-job/src/main/resources/logback.xml create mode 100644 dcsoft-modules/dcsoft-job/src/main/resources/mapper/job/KqHolidayMapper.xml create mode 100644 dcsoft-modules/dcsoft-job/src/main/resources/mapper/job/SysJobLogMapper.xml create mode 100644 dcsoft-modules/dcsoft-job/src/main/resources/mapper/job/SysJobMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/pom.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/DCSSystemApplication.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/controller/TbCarController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/controller/TbCarRecordController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/domain/TbCar.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/domain/TbCarRecord.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/mapper/TbCarMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/mapper/TbCarRecordMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/service/ISysPmsService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/service/ITbCarRecordService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/service/ITbCarService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/service/impl/SysPmsServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/service/impl/TbCarRecordServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/service/impl/TbCarServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/config/AlipayConfig.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/config/WeixinPayConfig.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysBackGroupController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysBlackListController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysBranchController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysConfigController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysDeptController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysDictDataController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysDictTypeController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysEmpowerRecordController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysEquipmentController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysLogininforController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysManageRecordController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysMenuController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysNoticeController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysOperlogController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysPeopleController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysPeopleLeaveController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysPeopleOtherController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysPeopleRecordController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysPointController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysPostController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysProductController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysProfileController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysRoleController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysRuleController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysSpaceController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysSyncRuleController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysUserController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysUserOnlineController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/ThreadTest1.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysBackGroup.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysBlackList.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysBranch.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysConfig.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysEmpowerRecord.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysEquipment.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysManageRecord.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysMenu.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysNotice.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPeople.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPeopleEquipment.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPeopleLeave.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPeopleOther.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPeopleRecord.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPeopleRule.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPoint.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPost.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysProduct.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysRoleDept.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysRoleMenu.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysRule.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysSpace.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysSyncItem.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysSyncRule.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysUserOnline.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysUserPost.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysUserRole.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/AppletInfoVo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/BranchSelectVo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/JjDivisionVo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/JjStationVo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/JjserInfoVo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/MetaVo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/OfficialAccountVo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/RouterVo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/SysAuthTree.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/SysFileVo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/TreeSelect.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/TreeSelectVo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysBackGroupMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysBlackListMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysBranchMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysConfigMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysDeptMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysDictDataMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysDictTypeMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysEmpowerRecordMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysEquipmentMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysLogininforMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysManageRecordMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysMenuMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysNoticeMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysOperLogMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPeopleEquipmentMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPeopleLeaveMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPeopleMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPeopleOtherMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPeopleRecordMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPeopleRuleMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPointMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPostMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysProductMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysRoleDeptMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysRoleMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysRoleMenuMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysRuleMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysSpaceMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysSyncRuleMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysUserMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysUserPostMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysUserRoleMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysBackGroupService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysBlackListService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysBranchService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysConfigService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysDeptService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysDictDataService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysDictTypeService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysEmpowerRecordService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysEquipmentService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysLogininforService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysManageRecordService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysMenuService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysNoticeService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysOperLogService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPeopleEquipmentService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPeopleLeaveService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPeopleOtherService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPeopleRecordService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPeopleRuleService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPeopleService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPermissionService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPointService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPostService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysProductService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysRoleService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysRuleService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysSpaceService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysSyncRuleService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysUserOnlineService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysUserService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysBackGroupServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysBlackListServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysBranchServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysConfigServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysDeptServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysDictDataServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysDictTypeServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysEmpowerRecordServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysEquipmentServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysLogininforServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysManageRecordServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysMenuServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysNoticeServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysOperLogServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPeopleEquipmentServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPeopleLeaveServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPeopleOtherServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPeopleRecordServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPeopleRuleServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPeopleServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPermissionServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPointServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPostServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysProductServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysRoleServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysRuleServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysSpaceServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysSyncRuleServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysUserOnlineServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysUserServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/controller/SysApiController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/controller/SysSdkController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/controller/test.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/BackInfo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/BackResult.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/DingtalkCode.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/DingtalkMsgVo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/EventResult.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/EwmInfo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/HeartInfo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/LadderControlVo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/Person.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/QrCodeVo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/service/ISysApiService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/service/ISysSdkService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/service/ISysVehicleService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/service/impl/SysApiServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/service/impl/SysSdkServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/service/impl/SysVehicleServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/BackupConfig.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/Base64DecodeMultipartFile.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/FTPUtil.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/FileUtils.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/FloorUtil.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/HttpClient.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/HttpUtil.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/IWXPayDomain.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/ImageToBase64Utils.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/PictureUtils.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/TreeUtil.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/WXPayConfig.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/WXPayConstants.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/WXPayReport.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/WXPayUtil.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/WXPayXmlUtil.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/WeChatUtil.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/ZipUtil.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/controller/CarChargeController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/controller/CarInfoController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/controller/CarParkController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/controller/CarParkRecordController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/controller/CarPassGatherController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/controller/CarPassRecordController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarCharge.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarChargeItem.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarInfo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarPark.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarParkItem.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarParkRecord.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarPassGather.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarPassRecord.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarChargeItemMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarChargeMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarInfoMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarParkItemMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarParkMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarParkRecordMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarPassGatherMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarPassRecordMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarChargeItemService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarChargeService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarInfoService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarParkItemService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarParkRecordService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarParkService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarPassGatherService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarPassRecordService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarChargeItemServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarChargeServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarInfoServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarParkItemServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarParkRecordServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarParkServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarPassGatherServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarPassRecordServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/controller/VisVisitorExamineController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/controller/VisVisitorRegisterController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/controller/VisitorController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/controller/VisitorMachineController.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/CheckCodeVo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/EwmInfoVo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/PersonnelInfoVo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisVisitorExamine.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisVisitorLogisticsVo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisVisitorRegister.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/Visitor.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisitorCountVo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisitorInfoVo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisitorParamVo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisitorRecordVo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisitorReviewProcessVo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisitorVo.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/mapper/VisVisitorExamineMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/mapper/VisVisitorRegisterMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/mapper/VisitorMapper.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/service/IVisVisitorExamineService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/service/IVisVisitorRegisterService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/service/IVisitorService.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/service/impl/VisVisitorExamineServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/service/impl/VisVisitorRegisterServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/service/impl/VisitorServiceImpl.java create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/banner.txt create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/bootstrap.yml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/logback.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/car/TbCarMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/car/TbCarRecordMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysBackGroupMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysBlackListMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysBranchMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysConfigMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysDeptMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysDictDataMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysDictTypeMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysEmpowerRecordMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysEquipmentMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysLogininforMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysManageRecordMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysMenuMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysNoticeMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysOperLogMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPeopleEquipmentMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPeopleLeaveMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPeopleMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPeopleOtherMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPeopleRecordMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPeopleRuleMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPointMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPostMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysProductMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysRoleMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysRuleMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysSpaceMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysSyncRuleMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysUserMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysUserPostMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysUserRoleMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/visitor/VisVisitorExamineMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/visitor/VisVisitorRegisterMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/visitor/VisitorMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarChargeItemMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarChargeMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarInfoMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarParkItemMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarParkMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarParkRecordMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarPassGatherMapper.xml create mode 100644 dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarPassRecordMapper.xml create mode 100644 dcsoft-modules/pom.xml create mode 100644 dcsoft-visual/dcsoft-monitor/pom.xml create mode 100644 dcsoft-visual/dcsoft-monitor/src/main/java/com/dcsoft/modules/monitor/DCSMonitorApplication.java create mode 100644 dcsoft-visual/dcsoft-monitor/src/main/java/com/dcsoft/modules/monitor/config/WebSecurityConfigurer.java create mode 100644 dcsoft-visual/dcsoft-monitor/src/main/resources/banner.txt create mode 100644 dcsoft-visual/dcsoft-monitor/src/main/resources/bootstrap.yml create mode 100644 dcsoft-visual/dcsoft-monitor/src/main/resources/logback.xml create mode 100644 dcsoft-visual/pom.xml create mode 100644 license.xml create mode 100644 logs/dcsoft-auth/error.log create mode 100644 logs/dcsoft-auth/info.2025-03-21.log create mode 100644 logs/dcsoft-auth/info.2025-03-22.log create mode 100644 logs/dcsoft-auth/info.log create mode 100644 logs/dcsoft-file/error.log create mode 100644 logs/dcsoft-file/info.log create mode 100644 logs/dcsoft-gateway/error.2025-03-21.log create mode 100644 logs/dcsoft-gateway/error.log create mode 100644 logs/dcsoft-gateway/info.2025-03-21.log create mode 100644 logs/dcsoft-gateway/info.2025-03-22.log create mode 100644 logs/dcsoft-gateway/info.log create mode 100644 logs/dcsoft-system/error.2025-03-21.log create mode 100644 logs/dcsoft-system/error.log create mode 100644 logs/dcsoft-system/info.2025-03-21.log create mode 100644 logs/dcsoft-system/info.2025-03-22.log create mode 100644 logs/dcsoft-system/info.log create mode 100644 pom.xml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/.idea/ApifoxUploaderProjectSetting.xml b/.idea/ApifoxUploaderProjectSetting.xml new file mode 100644 index 0000000..dcbef36 --- /dev/null +++ b/.idea/ApifoxUploaderProjectSetting.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..d2a236a --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..2ca34df --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..746e744 --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..bf8b8b6 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,20 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..cbe7e59 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + { + "associatedIndex": 1 +} + + + + { + "keyToString": { + "Application.zctest.executor": "Run", + "Maven.dcsoft [clean,install].executor": "Run", + "RequestMappingsPanelOrder0": "0", + "RequestMappingsPanelOrder1": "1", + "RequestMappingsPanelWidth0": "75", + "RequestMappingsPanelWidth1": "75", + "RunOnceActivity.ShowReadmeOnStart": "true", + "Spring Boot.DCSAuthApplication.executor": "Run", + "Spring Boot.DCSGatewayApplication.executor": "Run", + "Spring Boot.DCSSystemApplication.executor": "Debug", + "kotlin-language-version-configured": "true", + "last_opened_file_path": "D:/xa-prod/xa-master-prod/dcsoft-modules/dcsoft-system/src/main/resources/mapper", + "node.js.detected.package.eslint": "true", + "node.js.detected.package.tslint": "true", + "node.js.selected.package.eslint": "(autodetect)", + "node.js.selected.package.tslint": "(autodetect)", + "nodejs_package_manager_path": "npm", + "project.structure.last.edited": "Project", + "project.structure.proportion": "0.15", + "project.structure.side.proportion": "0.0", + "run.configurations.included.in.services": "true", + "settings.editor.selected.configurable": "MavenSettings", + "vue.rearranger.settings.migration": "true" + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1742564838346 + + + + + + \ No newline at end of file diff --git a/.idea/xa-master-prod.iml b/.idea/xa-master-prod.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/xa-master-prod.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/dcsoft-api/dcsoft-api-system/pom.xml b/dcsoft-api/dcsoft-api-system/pom.xml new file mode 100644 index 0000000..8e9da95 --- /dev/null +++ b/dcsoft-api/dcsoft-api-system/pom.xml @@ -0,0 +1,28 @@ + + + + com.dcsoft + dcsoft-api + 3.6.2 + + 4.0.0 + + dcsoft-api-system + + + dcsoft-api-system系统接口模块 + + + + + + + com.dcsoft + dcsoft-common-core + + + + + diff --git a/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/RemoteAuthApplication.java b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/RemoteAuthApplication.java new file mode 100644 index 0000000..9d16a5a --- /dev/null +++ b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/RemoteAuthApplication.java @@ -0,0 +1,23 @@ +package com.dcsoft.system.api; + +import com.dcsoft.common.core.constant.SecurityConstants; +import com.dcsoft.common.core.constant.ServiceNameConstants; +import com.dcsoft.common.core.domain.R; +import com.dcsoft.common.core.web.page.TableDatasInfo; +import com.dcsoft.system.api.domain.FaceStudentBody; +import com.dcsoft.system.api.domain.LoginBody; +import com.dcsoft.system.api.domain.SysAuth; +import com.dcsoft.system.api.factory.RemoteLogFallbackFactory; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; + +import java.util.Map; + +@FeignClient(contextId = "remoteAuthApplication", value = ServiceNameConstants.AUTH_SERVICE, fallbackFactory = RemoteLogFallbackFactory.class) +public interface RemoteAuthApplication { + + @PostMapping(value = "/login") + public R> login(@RequestBody LoginBody form); +} diff --git a/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/RemoteAuthService.java b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/RemoteAuthService.java new file mode 100644 index 0000000..ab8ed14 --- /dev/null +++ b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/RemoteAuthService.java @@ -0,0 +1,31 @@ +package com.dcsoft.system.api; + +import com.dcsoft.common.core.constant.SecurityConstants; +import com.dcsoft.common.core.constant.ServiceNameConstants; +import com.dcsoft.common.core.domain.R; +import com.dcsoft.system.api.domain.SysAuth; +import com.dcsoft.system.api.domain.SysLogininfor; +import com.dcsoft.system.api.domain.SysOperLog; +import com.dcsoft.system.api.factory.RemoteLogFallbackFactory; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.*; + +/** + * 日志服务 + * + * @author dcsoft + */ +@FeignClient(contextId = "remoteAuthService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteLogFallbackFactory.class) +public interface RemoteAuthService +{ + /** + * 保存系统日志 + * + * @param id appkey + * @param source 请求来源 + * @return 结果 + */ + @GetMapping("/auth/{id}") + public R getAuth(@PathVariable("id") String id, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); + +} diff --git a/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/RemoteFileService.java b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/RemoteFileService.java new file mode 100644 index 0000000..237f7ee --- /dev/null +++ b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/RemoteFileService.java @@ -0,0 +1,63 @@ +package com.dcsoft.system.api; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.http.MediaType; +import org.springframework.util.MultiValueMap; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.multipart.MultipartFile; +import com.dcsoft.common.core.constant.ServiceNameConstants; +import com.dcsoft.common.core.domain.R; +import com.dcsoft.system.api.domain.SysFile; +import com.dcsoft.system.api.factory.RemoteFileFallbackFactory; + +/** + * 文件服务 + * + * @author dcsoft + */ +@FeignClient(contextId = "remoteFileService", value = ServiceNameConstants.FILE_SERVICE, fallbackFactory = RemoteFileFallbackFactory.class) +public interface RemoteFileService +{ + /** + * 上传文件 + * + * @param file 文件信息 + * @return 结果 + */ + @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + public R upload(@RequestPart(value = "file") MultipartFile file); + + /** + * 上传文件 + * + * @param file 文件信息 + * @return 结果 + */ + @PostMapping(value = "/uploadMinio", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + public R uploadMinio(@RequestPart(value = "file") MultipartFile file,@RequestPart(value = "fileName") String fileName); + + /** + * 上传文件 + * + * @param file 文件信息 + * @return 结果 + */ + @PostMapping(value = "/uploadMinio1", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + public R uploadMinio1(@RequestPart(value = "file") MultipartFile file,@RequestPart(value = "fileName") String fileName); + + /** + * 上传文件 + * + * @param file 文件信息 + * @return 结果 + */ + @PostMapping(value = "/uploadMinios", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + public R uploadMinios(@RequestPart(value = "file") MultipartFile file,@RequestPart(value = "fileName") String fileName); + + + @PostMapping(value = "/uploadMinioCar", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + public R uploadMinioCar(@RequestPart(value = "file") MultipartFile file); + +} diff --git a/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/RemoteLogService.java b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/RemoteLogService.java new file mode 100644 index 0000000..b8248e9 --- /dev/null +++ b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/RemoteLogService.java @@ -0,0 +1,41 @@ +package com.dcsoft.system.api; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import com.dcsoft.common.core.constant.SecurityConstants; +import com.dcsoft.common.core.constant.ServiceNameConstants; +import com.dcsoft.common.core.domain.R; +import com.dcsoft.system.api.domain.SysLogininfor; +import com.dcsoft.system.api.domain.SysOperLog; +import com.dcsoft.system.api.factory.RemoteLogFallbackFactory; + +/** + * 日志服务 + * + * @author dcsoft + */ +@FeignClient(contextId = "remoteLogService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteLogFallbackFactory.class) +public interface RemoteLogService +{ + /** + * 保存系统日志 + * + * @param sysOperLog 日志实体 + * @param source 请求来源 + * @return 结果 + */ + @PostMapping("/operlog") + public R saveLog(@RequestBody SysOperLog sysOperLog, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); + + /** + * 保存访问记录 + * + * @param sysLogininfor 访问实体 + * @param source 请求来源 + * @return 结果 + */ + @PostMapping("/logininfor") + public R saveLogininfor(@RequestBody SysLogininfor sysLogininfor, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); +} diff --git a/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/RemoteStudentService.java b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/RemoteStudentService.java new file mode 100644 index 0000000..ca45fa2 --- /dev/null +++ b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/RemoteStudentService.java @@ -0,0 +1,73 @@ +package com.dcsoft.system.api; + +import com.dcsoft.common.core.constant.SecurityConstants; +import com.dcsoft.common.core.constant.ServiceNameConstants; +import com.dcsoft.common.core.web.page.TableDatasInfo; +import com.dcsoft.system.api.domain.FaceStudentBody; +import com.dcsoft.system.api.factory.RemoteLogFallbackFactory; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.*; + +/** + * 日志服务 + * + * @author dcsoft + */ +@FeignClient(contextId = "remoteStudentService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteLogFallbackFactory.class) +public interface RemoteStudentService +{ + /** + * 保存系统日志 + * + * @param source 请求来源 + * @return 结果 + */ + @PostMapping(value = "/student/studentList") + public TableDatasInfo studentList(@RequestBody FaceStudentBody faceStudent, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); + + @PostMapping(value = "/student/gatherMonth") + public void gatherMonth(@RequestHeader(SecurityConstants.FROM_SOURCE) String source); + + @PostMapping(value = "/config/backSql") + public void backUp(@RequestHeader(SecurityConstants.FROM_SOURCE) String source); + + @PostMapping(value = "/student/gather") + public void gather(@RequestHeader(SecurityConstants.FROM_SOURCE) String source); + + @PostMapping(value = "/peopleLeave/peopleLeave") + public void peopleLeave(@RequestHeader(SecurityConstants.FROM_SOURCE) String source); + + /** + * 新增请假人员信息 + * @param source + */ + @PostMapping(value = "/gather/saveAskForLeave") + void saveAskForLeave(@RequestHeader(SecurityConstants.FROM_SOURCE) String source); + + /** + * 新增补卡信息 + * @param inner + */ + @PostMapping(value = "/gather/saveCardReplacement") + void saveCardReplacement(String inner); + + /** + * 定时批量下发 + */ + @PostMapping(value = "/sysPeople/batchDistribute") + void batchDistribute(String inner); + + @PostMapping(value = "/sysBranch/saveBranchTree") + void saveBranchTree(String inner); + + @PostMapping(value = "/sysPeople/saveUserInfo") + void saveUserInfo(String inner); + + @PostMapping(value = "/sysBranch/saveStation") + void saveStation(String inner); + + @PostMapping(value = "/sysPeople/batchDown") + void batchDown(String inner); + + +} diff --git a/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/RemoteUserService.java b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/RemoteUserService.java new file mode 100644 index 0000000..bf2c621 --- /dev/null +++ b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/RemoteUserService.java @@ -0,0 +1,62 @@ +package com.dcsoft.system.api; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import com.dcsoft.common.core.constant.SecurityConstants; +import com.dcsoft.common.core.constant.ServiceNameConstants; +import com.dcsoft.common.core.domain.R; +import com.dcsoft.system.api.domain.SysUser; +import com.dcsoft.system.api.factory.RemoteUserFallbackFactory; +import com.dcsoft.system.api.model.LoginUser; + +/** + * 用户服务 + * + * @author dcsoft + */ +@FeignClient(contextId = "remoteUserService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteUserFallbackFactory.class) +public interface RemoteUserService +{ + /** + * 通过用户名查询用户信息 + * + * @param username 用户名 + * @param source 请求来源 + * @return 结果 + */ + @GetMapping("/user/info/{username}") + public R getUserInfo(@PathVariable("username") String username, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); + + /** + * 注册用户信息 + * + * @param sysUser 用户信息 + * @param source 请求来源 + * @return 结果 + */ + @PostMapping("/user/register") + public R registerUserInfo(@RequestBody SysUser sysUser, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); + + /** + * 通过用户名查询用户信息 + * + * @param openid 绑定的openid + * @param source 请求来源 + * @return 结果 + */ + @GetMapping("/user/wxinfo/{openid}") + public R getWxUserInfo(@PathVariable("openid") String openid, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); + + /** + * 更新openid + * + * @param sysUser 用户信息 + * @return 结果 + */ + @PostMapping("/user/updateOpenId") + public R updateOpenId(@RequestBody SysUser sysUser, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); +} diff --git a/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/FaceStudentBody.java b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/FaceStudentBody.java new file mode 100644 index 0000000..4b57588 --- /dev/null +++ b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/FaceStudentBody.java @@ -0,0 +1,180 @@ +package com.dcsoft.system.api.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.File; +import java.util.Date; + +/** + * 学生信息对象 face_student + * + * @author nichun + * @date 2023-03-30 + */ +public class FaceStudentBody extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 学生Id */ + private Long id; + + /** 学工号 */ + @Excel(name = "学工号") + private String stuId; + + /** 姓名 */ + @Excel(name = "姓名") + private String name; + + /** 手机号 */ + @Excel(name = "手机号") + private String phone; + + /** 证件号 */ + @Excel(name = "证件号") + private String idCard; + + /** 图片 */ + @Excel(name = "图片") + private String imgs; + + private File file; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date startTime; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date endTime; + + private String pageNum; + + private String pageSize; + + private String label; + + + + public Date getStartTime() { + return startTime; + } + + public void setStartTime(Date startTime) { + this.startTime = startTime; + } + + public Date getEndTime() { + return endTime; + } + + public void setEndTime(Date endTime) { + this.endTime = endTime; + } + + public String getPageNum() { + return pageNum; + } + + public void setPageNum(String pageNum) { + this.pageNum = pageNum; + } + + public String getPageSize() { + return pageSize; + } + + public void setPageSize(String pageSize) { + this.pageSize = pageSize; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setStuId(String stuId) + { + this.stuId = stuId; + } + + public String getStuId() + { + return stuId; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setPhone(String phone) + { + this.phone = phone; + } + + public String getPhone() + { + return phone; + } + public void setIdCard(String idCard) + { + this.idCard = idCard; + } + + public String getIdCard() + { + return idCard; + } + public void setImgs(String imgs) + { + this.imgs = imgs; + } + + public String getImgs() + { + return imgs; + } + + public File getFile() { + return file; + } + + public void setFile(File file) { + this.file = file; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("stuId", getStuId()) + .append("name", getName()) + .append("phone", getPhone()) + .append("idCard", getIdCard()) + .append("imgs", getImgs()) + .append("remark", getRemark()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/LoginBody.java b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/LoginBody.java new file mode 100644 index 0000000..27838d9 --- /dev/null +++ b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/LoginBody.java @@ -0,0 +1,74 @@ +package com.dcsoft.system.api.domain; + +/** + * 用户登录对象 + * + * @author dcsoft + */ +public class LoginBody +{ + /** + * 用户名 + */ + private String username; + + /** + * 用户密码 + */ + private String password; + /** + * 登录方式 + * **/ + private String flag; + /** + * 微信openid + * **/ + private String openid; + + + 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 getFlag() { + return flag; + } + + public void setFlag(String flag) { + this.flag = flag; + } + + public String getOpenid() { + return openid; + } + + public void setOpenid(String openid) { + this.openid = openid; + } + + @Override + public String toString() { + return "LoginBody{" + + "username='" + username + '\'' + + ", password='" + password + '\'' + + ", flag='" + flag + '\'' + + ", openid='" + openid + '\'' + + '}'; + } +} diff --git a/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysAuth.java b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysAuth.java new file mode 100644 index 0000000..6323b35 --- /dev/null +++ b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysAuth.java @@ -0,0 +1,70 @@ +package com.dcsoft.system.api.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 认证数据对象 sys_auth + * + * @author nichun + * @date 2023-03-29 + */ +public class SysAuth extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 访客Id */ + private Long id; + + /** appKey */ + @Excel(name = "appKey") + private String appKey; + + /** appSecret */ + @Excel(name = "appSecret") + private String appSecret; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setAppKey(String appKey) + { + this.appKey = appKey; + } + + public String getAppKey() + { + return appKey; + } + public void setAppSecret(String appSecret) + { + this.appSecret = appSecret; + } + + public String getAppSecret() + { + return appSecret; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("appKey", getAppKey()) + .append("appSecret", getAppSecret()) + .append("remark", getRemark()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysDept.java b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysDept.java new file mode 100644 index 0000000..c945935 --- /dev/null +++ b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysDept.java @@ -0,0 +1,215 @@ +package com.dcsoft.system.api.domain; + +import java.util.ArrayList; +import java.util.List; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.dcsoft.common.core.web.domain.BaseEntity; + +/** + * 部门表 sys_dept + * + * @author dcsoft + */ +public class SysDept extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 部门ID */ + private Long deptId; + + /** 父部门ID */ + private Long parentId; + + /** 祖级列表 */ + private String ancestors; + + /** 部门名称 */ + private String deptName; + + /** 显示顺序 */ + private Integer orderNum; + + /** 负责人 */ + private String leader; + + /** 联系电话 */ + private String phone; + + /** 邮箱 */ + private String email; + + /** 部门状态:0正常,1停用 */ + private String status; + + /** 删除标志(0代表存在 2代表删除) */ + private String delFlag; + + /** 父部门名称 */ + private String parentName; + + + /** 同步IDaas externalId */ + private String externalId; + + /** 子部门 */ + private List children = new ArrayList(); + + public Long getDeptId() + { + return deptId; + } + + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + public Long getParentId() + { + return parentId; + } + + public void setParentId(Long parentId) + { + this.parentId = parentId; + } + + public String getAncestors() + { + return ancestors; + } + + public void setAncestors(String ancestors) + { + this.ancestors = ancestors; + } + + @NotBlank(message = "部门名称不能为空") + @Size(min = 0, max = 30, message = "部门名称长度不能超过30个字符") + public String getDeptName() + { + return deptName; + } + + public void setDeptName(String deptName) + { + this.deptName = deptName; + } + + @NotNull(message = "显示顺序不能为空") + public Integer getOrderNum() + { + return orderNum; + } + + public void setOrderNum(Integer orderNum) + { + this.orderNum = orderNum; + } + + public String getLeader() + { + return leader; + } + + public void setLeader(String leader) + { + this.leader = leader; + } + + @Size(min = 0, max = 11, message = "联系电话长度不能超过11个字符") + public String getPhone() + { + return phone; + } + + public void setPhone(String phone) + { + this.phone = phone; + } + + @Email(message = "邮箱格式不正确") + @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符") + public String getEmail() + { + return email; + } + + public void setEmail(String email) + { + this.email = email; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getDelFlag() + { + return delFlag; + } + + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getParentName() + { + return parentName; + } + + public void setParentName(String parentName) + { + this.parentName = parentName; + } + + public List getChildren() + { + return children; + } + + public void setChildren(List children) + { + this.children = children; + } + + public String getExternalId() { + return externalId; + } + + public void setExternalId(String externalId) { + this.externalId = externalId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("deptId", getDeptId()) + .append("parentId", getParentId()) + .append("ancestors", getAncestors()) + .append("deptName", getDeptName()) + .append("orderNum", getOrderNum()) + .append("leader", getLeader()) + .append("phone", getPhone()) + .append("email", getEmail()) + .append("status", getStatus()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysDictData.java b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysDictData.java new file mode 100644 index 0000000..244529d --- /dev/null +++ b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysDictData.java @@ -0,0 +1,176 @@ +package com.dcsoft.system.api.domain; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.annotation.Excel.ColumnType; +import com.dcsoft.common.core.constant.UserConstants; +import com.dcsoft.common.core.web.domain.BaseEntity; + +/** + * 字典数据表 sys_dict_data + * + * @author dcsoft + */ +public class SysDictData extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 字典编码 */ + @Excel(name = "字典编码", cellType = ColumnType.NUMERIC) + private Long dictCode; + + /** 字典排序 */ + @Excel(name = "字典排序", cellType = ColumnType.NUMERIC) + private Long dictSort; + + /** 字典标签 */ + @Excel(name = "字典标签") + private String dictLabel; + + /** 字典键值 */ + @Excel(name = "字典键值") + private String dictValue; + + /** 字典类型 */ + @Excel(name = "字典类型") + private String dictType; + + /** 样式属性(其他样式扩展) */ + private String cssClass; + + /** 表格字典样式 */ + private String listClass; + + /** 是否默认(Y是 N否) */ + @Excel(name = "是否默认", readConverterExp = "Y=是,N=否") + private String isDefault; + + /** 状态(0正常 1停用) */ + @Excel(name = "状态", readConverterExp = "0=正常,1=停用") + private String status; + + public Long getDictCode() + { + return dictCode; + } + + public void setDictCode(Long dictCode) + { + this.dictCode = dictCode; + } + + public Long getDictSort() + { + return dictSort; + } + + public void setDictSort(Long dictSort) + { + this.dictSort = dictSort; + } + + @NotBlank(message = "字典标签不能为空") + @Size(min = 0, max = 100, message = "字典标签长度不能超过100个字符") + public String getDictLabel() + { + return dictLabel; + } + + public void setDictLabel(String dictLabel) + { + this.dictLabel = dictLabel; + } + + @NotBlank(message = "字典键值不能为空") + @Size(min = 0, max = 100, message = "字典键值长度不能超过100个字符") + public String getDictValue() + { + return dictValue; + } + + public void setDictValue(String dictValue) + { + this.dictValue = dictValue; + } + + @NotBlank(message = "字典类型不能为空") + @Size(min = 0, max = 100, message = "字典类型长度不能超过100个字符") + public String getDictType() + { + return dictType; + } + + public void setDictType(String dictType) + { + this.dictType = dictType; + } + + @Size(min = 0, max = 100, message = "样式属性长度不能超过100个字符") + public String getCssClass() + { + return cssClass; + } + + public void setCssClass(String cssClass) + { + this.cssClass = cssClass; + } + + public String getListClass() + { + return listClass; + } + + public void setListClass(String listClass) + { + this.listClass = listClass; + } + + public boolean getDefault() + { + return UserConstants.YES.equals(this.isDefault); + } + + public String getIsDefault() + { + return isDefault; + } + + public void setIsDefault(String isDefault) + { + this.isDefault = isDefault; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("dictCode", getDictCode()) + .append("dictSort", getDictSort()) + .append("dictLabel", getDictLabel()) + .append("dictValue", getDictValue()) + .append("dictType", getDictType()) + .append("cssClass", getCssClass()) + .append("listClass", getListClass()) + .append("isDefault", getIsDefault()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysDictType.java b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysDictType.java new file mode 100644 index 0000000..cfc10a9 --- /dev/null +++ b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysDictType.java @@ -0,0 +1,96 @@ +package com.dcsoft.system.api.domain; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.annotation.Excel.ColumnType; +import com.dcsoft.common.core.web.domain.BaseEntity; + +/** + * 字典类型表 sys_dict_type + * + * @author dcsoft + */ +public class SysDictType extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 字典主键 */ + @Excel(name = "字典主键", cellType = ColumnType.NUMERIC) + private Long dictId; + + /** 字典名称 */ + @Excel(name = "字典名称") + private String dictName; + + /** 字典类型 */ + @Excel(name = "字典类型") + private String dictType; + + /** 状态(0正常 1停用) */ + @Excel(name = "状态", readConverterExp = "0=正常,1=停用") + private String status; + + public Long getDictId() + { + return dictId; + } + + public void setDictId(Long dictId) + { + this.dictId = dictId; + } + + @NotBlank(message = "字典名称不能为空") + @Size(min = 0, max = 100, message = "字典类型名称长度不能超过100个字符") + public String getDictName() + { + return dictName; + } + + public void setDictName(String dictName) + { + this.dictName = dictName; + } + + @NotBlank(message = "字典类型不能为空") + @Size(min = 0, max = 100, message = "字典类型类型长度不能超过100个字符") + @Pattern(regexp = "^[a-z][a-z0-9_]*$", message = "字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)") + public String getDictType() + { + return dictType; + } + + public void setDictType(String dictType) + { + this.dictType = dictType; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("dictId", getDictId()) + .append("dictName", getDictName()) + .append("dictType", getDictType()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysFile.java b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysFile.java new file mode 100644 index 0000000..571b55e --- /dev/null +++ b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysFile.java @@ -0,0 +1,64 @@ +package com.dcsoft.system.api.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 文件信息 + * + * @author dcsoft + */ +public class SysFile +{ + /** + * 文件名称 + */ + private String name; + + /** + * 文件地址 + */ + private String url; + + /** + * 文件特征值 + */ + private String feature; + + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getUrl() + { + return url; + } + + public void setUrl(String url) + { + this.url = url; + } + + public String getFeature() { + return feature; + } + + public void setFeature(String feature) { + this.feature = feature; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("name", getName()) + .append("url", getUrl()) + .toString(); + } +} diff --git a/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysLogininfor.java b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysLogininfor.java new file mode 100644 index 0000000..7b99ea1 --- /dev/null +++ b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysLogininfor.java @@ -0,0 +1,102 @@ +package com.dcsoft.system.api.domain; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.annotation.Excel.ColumnType; +import com.dcsoft.common.core.web.domain.BaseEntity; + +/** + * 系统访问记录表 sys_logininfor + * + * @author dcsoft + */ +public class SysLogininfor extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** ID */ + @Excel(name = "序号", cellType = ColumnType.NUMERIC) + private Long infoId; + + /** 用户账号 */ + @Excel(name = "用户账号") + private String userName; + + /** 状态 0成功 1失败 */ + @Excel(name = "状态", readConverterExp = "0=成功,1=失败") + private String status; + + /** 地址 */ + @Excel(name = "地址") + private String ipaddr; + + /** 描述 */ + @Excel(name = "描述") + private String msg; + + /** 访问时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "访问时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date accessTime; + + public Long getInfoId() + { + return infoId; + } + + public void setInfoId(Long infoId) + { + this.infoId = infoId; + } + + public String getUserName() + { + return userName; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getIpaddr() + { + return ipaddr; + } + + public void setIpaddr(String ipaddr) + { + this.ipaddr = ipaddr; + } + + public String getMsg() + { + return msg; + } + + public void setMsg(String msg) + { + this.msg = msg; + } + + public Date getAccessTime() + { + return accessTime; + } + + public void setAccessTime(Date accessTime) + { + this.accessTime = accessTime; + } +} diff --git a/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysOperLog.java b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysOperLog.java new file mode 100644 index 0000000..d33f13d --- /dev/null +++ b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysOperLog.java @@ -0,0 +1,255 @@ +package com.dcsoft.system.api.domain; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.annotation.Excel.ColumnType; +import com.dcsoft.common.core.web.domain.BaseEntity; + +/** + * 操作日志记录表 oper_log + * + * @author dcsoft + */ +public class SysOperLog extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 日志主键 */ + @Excel(name = "操作序号", cellType = ColumnType.NUMERIC) + private Long operId; + + /** 操作模块 */ + @Excel(name = "操作模块") + private String title; + + /** 业务类型(0其它 1新增 2修改 3删除) */ + @Excel(name = "业务类型", readConverterExp = "0=其它,1=新增,2=修改,3=删除,4=授权,5=导出,6=导入,7=强退,8=生成代码,9=清空数据") + private Integer businessType; + + /** 业务类型数组 */ + private Integer[] businessTypes; + + /** 请求方法 */ + @Excel(name = "请求方法") + private String method; + + /** 请求方式 */ + @Excel(name = "请求方式") + private String requestMethod; + + /** 操作类别(0其它 1后台用户 2手机端用户) */ + @Excel(name = "操作类别", readConverterExp = "0=其它,1=后台用户,2=手机端用户") + private Integer operatorType; + + /** 操作人员 */ + @Excel(name = "操作人员") + private String operName; + + /** 部门名称 */ + @Excel(name = "部门名称") + private String deptName; + + /** 请求url */ + @Excel(name = "请求地址") + private String operUrl; + + /** 操作地址 */ + @Excel(name = "操作地址") + private String operIp; + + /** 请求参数 */ + @Excel(name = "请求参数") + private String operParam; + + /** 返回参数 */ + @Excel(name = "返回参数") + private String jsonResult; + + /** 操作状态(0正常 1异常) */ + @Excel(name = "状态", readConverterExp = "0=正常,1=异常") + private Integer status; + + /** 错误消息 */ + @Excel(name = "错误消息") + private String errorMsg; + + /** 操作时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "操作时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date operTime; + + /** 消耗时间 */ + @Excel(name = "消耗时间", suffix = "毫秒") + private Long costTime; + + public Long getOperId() + { + return operId; + } + + public void setOperId(Long operId) + { + this.operId = operId; + } + + public String getTitle() + { + return title; + } + + public void setTitle(String title) + { + this.title = title; + } + + public Integer getBusinessType() + { + return businessType; + } + + public void setBusinessType(Integer businessType) + { + this.businessType = businessType; + } + + public Integer[] getBusinessTypes() + { + return businessTypes; + } + + public void setBusinessTypes(Integer[] businessTypes) + { + this.businessTypes = businessTypes; + } + + public String getMethod() + { + return method; + } + + public void setMethod(String method) + { + this.method = method; + } + + public String getRequestMethod() + { + return requestMethod; + } + + public void setRequestMethod(String requestMethod) + { + this.requestMethod = requestMethod; + } + + public Integer getOperatorType() + { + return operatorType; + } + + public void setOperatorType(Integer operatorType) + { + this.operatorType = operatorType; + } + + public String getOperName() + { + return operName; + } + + public void setOperName(String operName) + { + this.operName = operName; + } + + public String getDeptName() + { + return deptName; + } + + public void setDeptName(String deptName) + { + this.deptName = deptName; + } + + public String getOperUrl() + { + return operUrl; + } + + public void setOperUrl(String operUrl) + { + this.operUrl = operUrl; + } + + public String getOperIp() + { + return operIp; + } + + public void setOperIp(String operIp) + { + this.operIp = operIp; + } + + public String getOperParam() + { + return operParam; + } + + public void setOperParam(String operParam) + { + this.operParam = operParam; + } + + public String getJsonResult() + { + return jsonResult; + } + + public void setJsonResult(String jsonResult) + { + this.jsonResult = jsonResult; + } + + public Integer getStatus() + { + return status; + } + + public void setStatus(Integer status) + { + this.status = status; + } + + public String getErrorMsg() + { + return errorMsg; + } + + public void setErrorMsg(String errorMsg) + { + this.errorMsg = errorMsg; + } + + public Date getOperTime() + { + return operTime; + } + + public void setOperTime(Date operTime) + { + this.operTime = operTime; + } + + public Long getCostTime() + { + return costTime; + } + + public void setCostTime(Long costTime) + { + this.costTime = costTime; + } +} diff --git a/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysRole.java b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysRole.java new file mode 100644 index 0000000..c13aacf --- /dev/null +++ b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysRole.java @@ -0,0 +1,241 @@ +package com.dcsoft.system.api.domain; + +import java.util.Set; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.annotation.Excel.ColumnType; +import com.dcsoft.common.core.web.domain.BaseEntity; + +/** + * 角色表 sys_role + * + * @author dcsoft + */ +public class SysRole extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 角色ID */ + @Excel(name = "角色序号", cellType = ColumnType.NUMERIC) + private Long roleId; + + /** 角色名称 */ + @Excel(name = "角色名称") + private String roleName; + + /** 角色权限 */ + @Excel(name = "角色权限") + private String roleKey; + + /** 角色排序 */ + @Excel(name = "角色排序") + private Integer roleSort; + + /** 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限) */ + @Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限") + private String dataScope; + + /** 菜单树选择项是否关联显示( 0:父子不互相关联显示 1:父子互相关联显示) */ + private boolean menuCheckStrictly; + + /** 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示 ) */ + private boolean deptCheckStrictly; + + /** 角色状态(0正常 1停用) */ + @Excel(name = "角色状态", readConverterExp = "0=正常,1=停用") + private String status; + + /** 删除标志(0代表存在 2代表删除) */ + private String delFlag; + + /** 用户是否存在此角色标识 默认不存在 */ + private boolean flag = false; + + /** 菜单组 */ + private Long[] menuIds; + + /** 部门组(数据权限) */ + private Long[] deptIds; + + /** 角色菜单权限 */ + private Set permissions; + + public SysRole() + { + + } + + public SysRole(Long roleId) + { + this.roleId = roleId; + } + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + public boolean isAdmin() + { + return isAdmin(this.roleId); + } + + public static boolean isAdmin(Long roleId) + { + return roleId != null && 1L == roleId; + } + + @NotBlank(message = "角色名称不能为空") + @Size(min = 0, max = 30, message = "角色名称长度不能超过30个字符") + public String getRoleName() + { + return roleName; + } + + public void setRoleName(String roleName) + { + this.roleName = roleName; + } + + @NotBlank(message = "权限字符不能为空") + @Size(min = 0, max = 100, message = "权限字符长度不能超过100个字符") + public String getRoleKey() + { + return roleKey; + } + + public void setRoleKey(String roleKey) + { + this.roleKey = roleKey; + } + + @NotNull(message = "显示顺序不能为空") + public Integer getRoleSort() + { + return roleSort; + } + + public void setRoleSort(Integer roleSort) + { + this.roleSort = roleSort; + } + + public String getDataScope() + { + return dataScope; + } + + public void setDataScope(String dataScope) + { + this.dataScope = dataScope; + } + + public boolean isMenuCheckStrictly() + { + return menuCheckStrictly; + } + + public void setMenuCheckStrictly(boolean menuCheckStrictly) + { + this.menuCheckStrictly = menuCheckStrictly; + } + + public boolean isDeptCheckStrictly() + { + return deptCheckStrictly; + } + + public void setDeptCheckStrictly(boolean deptCheckStrictly) + { + this.deptCheckStrictly = deptCheckStrictly; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getDelFlag() + { + return delFlag; + } + + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public boolean isFlag() + { + return flag; + } + + public void setFlag(boolean flag) + { + this.flag = flag; + } + + public Long[] getMenuIds() + { + return menuIds; + } + + public void setMenuIds(Long[] menuIds) + { + this.menuIds = menuIds; + } + + public Long[] getDeptIds() + { + return deptIds; + } + + public void setDeptIds(Long[] deptIds) + { + this.deptIds = deptIds; + } + + public Set getPermissions() + { + return permissions; + } + + public void setPermissions(Set permissions) + { + this.permissions = permissions; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("roleId", getRoleId()) + .append("roleName", getRoleName()) + .append("roleKey", getRoleKey()) + .append("roleSort", getRoleSort()) + .append("dataScope", getDataScope()) + .append("menuCheckStrictly", isMenuCheckStrictly()) + .append("deptCheckStrictly", isDeptCheckStrictly()) + .append("status", getStatus()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysUser.java b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysUser.java new file mode 100644 index 0000000..74aa9ed --- /dev/null +++ b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/domain/SysUser.java @@ -0,0 +1,355 @@ +package com.dcsoft.system.api.domain; + +import java.util.Date; +import java.util.List; +import javax.validation.constraints.*; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.annotation.Excel.ColumnType; +import com.dcsoft.common.core.annotation.Excel.Type; +import com.dcsoft.common.core.annotation.Excels; +import com.dcsoft.common.core.web.domain.BaseEntity; +import com.dcsoft.common.core.xss.Xss; + +/** + * 用户对象 sys_user + * + * @author dcsoft + */ +public class SysUser extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 用户ID */ + @Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号") + private Long userId; + + /** 部门ID */ + @Excel(name = "部门编号", type = Type.IMPORT) + private Long deptId; + + /** 用户账号 */ + @Excel(name = "登录名称") + private String userName; + + /** 用户昵称 */ + @Excel(name = "用户名称") + private String nickName; + + /** 用户邮箱 */ + @Excel(name = "用户邮箱") + private String email; + + /** 手机号码 */ + @Excel(name = "手机号码") + private String phonenumber; + + /** 用户性别 */ + @Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知") + private String sex; + + /** 用户头像 */ + private String avatar; + + /** 密码 */ + private String password; + + /** 帐号状态(0正常 1停用) */ + @Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用") + private String status; + + /** 删除标志(0代表存在 2代表删除) */ + private String delFlag; + + /** 最后登录IP */ + @Excel(name = "最后登录IP", type = Type.EXPORT) + private String loginIp; + + /** 最后登录时间 */ + @Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT) + private Date loginDate; + + /** 部门对象 */ + @Excels({ + @Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT), + @Excel(name = "部门负责人", targetAttr = "leader", type = Type.EXPORT) + }) + private SysDept dept; + + /** 角色对象 */ + private List roles; + + /** 角色组 */ + private Long[] roleIds; + + /** 岗位组 */ + private Long[] postIds; + + /** 角色ID */ + private Long roleId; + + private String openid; + + /** 同步IDaas externalId */ + private String externalId; + + private Long equipmentId; + + public SysUser() + { + + } + + public SysUser(Long userId) + { + this.userId = userId; + } + + public Long getUserId() + { + return userId; + } + + public void setUserId(Long userId) + { + this.userId = userId; + } + + public boolean isAdmin() + { + return isAdmin(this.userId); + } + + public static boolean isAdmin(Long userId) + { + return userId != null && 1L == userId; + } + + public Long getDeptId() + { + return deptId; + } + + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + @Xss(message = "用户昵称不能包含脚本字符") + @Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符") + public String getNickName() + { + return nickName; + } + + public void setNickName(String nickName) + { + this.nickName = nickName; + } + + @Xss(message = "用户账号不能包含脚本字符") + @NotBlank(message = "用户账号不能为空") + @Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符") + public String getUserName() + { + return userName; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + @Email(message = "邮箱格式不正确") + @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符") + public String getEmail() + { + return email; + } + + public void setEmail(String email) + { + this.email = email; + } + + @Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符") + public String getPhonenumber() + { + return phonenumber; + } + + public void setPhonenumber(String phonenumber) + { + this.phonenumber = phonenumber; + } + + public String getSex() + { + return sex; + } + + public void setSex(String sex) + { + this.sex = sex; + } + + public String getAvatar() + { + return avatar; + } + + public void setAvatar(String avatar) + { + this.avatar = avatar; + } + + public String getPassword() + { + return password; + } + + public void setPassword(String password) + { + this.password = password; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getDelFlag() + { + return delFlag; + } + + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getLoginIp() + { + return loginIp; + } + + public void setLoginIp(String loginIp) + { + this.loginIp = loginIp; + } + + public Date getLoginDate() + { + return loginDate; + } + + public void setLoginDate(Date loginDate) + { + this.loginDate = loginDate; + } + + public SysDept getDept() + { + return dept; + } + + public void setDept(SysDept dept) + { + this.dept = dept; + } + + public List getRoles() + { + return roles; + } + + public void setRoles(List roles) + { + this.roles = roles; + } + + public Long[] getRoleIds() + { + return roleIds; + } + + public void setRoleIds(Long[] roleIds) + { + this.roleIds = roleIds; + } + + public Long[] getPostIds() + { + return postIds; + } + + public void setPostIds(Long[] postIds) + { + this.postIds = postIds; + } + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + public String getOpenid() { + return openid; + } + + public void setOpenid(String openid) { + this.openid = openid; + } + + public String getExternalId() { + return externalId; + } + + public void setExternalId(String externalId) { + this.externalId = externalId; + } + + public Long getEquipmentId() { + return equipmentId; + } + + public void setEquipmentId(Long equipmentId) { + this.equipmentId = equipmentId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("userId", getUserId()) + .append("deptId", getDeptId()) + .append("userName", getUserName()) + .append("nickName", getNickName()) + .append("email", getEmail()) + .append("phonenumber", getPhonenumber()) + .append("sex", getSex()) + .append("avatar", getAvatar()) + .append("password", getPassword()) + .append("status", getStatus()) + .append("delFlag", getDelFlag()) + .append("loginIp", getLoginIp()) + .append("loginDate", getLoginDate()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .append("dept", getDept()) + .toString(); + } +} diff --git a/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/factory/RemoteAuthFallbackFactory.java b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/factory/RemoteAuthFallbackFactory.java new file mode 100644 index 0000000..247f4bf --- /dev/null +++ b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/factory/RemoteAuthFallbackFactory.java @@ -0,0 +1,37 @@ +package com.dcsoft.system.api.factory; + +import com.dcsoft.common.core.domain.R; +import com.dcsoft.system.api.RemoteAuthService; +import com.dcsoft.system.api.domain.SysAuth; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.openfeign.FallbackFactory; +import org.springframework.stereotype.Component; + +/** + * 日志服务降级处理 + * + * @author dcsoft + */ +@Component +public class RemoteAuthFallbackFactory implements FallbackFactory +{ + private static final Logger log = LoggerFactory.getLogger(RemoteAuthFallbackFactory.class); + + @Override + public RemoteAuthService create(Throwable throwable) + { + log.error("认证服务调用失败:{}", throwable.getMessage()); + return new RemoteAuthService() + { + @Override + public R getAuth(String id, String source) + { + return null; + } + + + }; + + } +} diff --git a/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/factory/RemoteAuthServiceFallbackFactory.java b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/factory/RemoteAuthServiceFallbackFactory.java new file mode 100644 index 0000000..ee5709a --- /dev/null +++ b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/factory/RemoteAuthServiceFallbackFactory.java @@ -0,0 +1,27 @@ +package com.dcsoft.system.api.factory; + +import com.dcsoft.common.core.domain.R; +import com.dcsoft.system.api.RemoteAuthApplication; +import com.dcsoft.system.api.RemoteFileService; +import com.dcsoft.system.api.domain.LoginBody; +import org.springframework.cloud.openfeign.FallbackFactory; +import org.springframework.stereotype.Component; + +import java.util.Map; + +/** + * @author wu_gu + */ +@Component +public class RemoteAuthServiceFallbackFactory implements FallbackFactory { + @Override + public RemoteAuthApplication create(Throwable cause) { + return new RemoteAuthApplication() { + + @Override + public R> login(LoginBody form) { + return null; + } + }; + } +} diff --git a/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/factory/RemoteFileFallbackFactory.java b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/factory/RemoteFileFallbackFactory.java new file mode 100644 index 0000000..343bf51 --- /dev/null +++ b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/factory/RemoteFileFallbackFactory.java @@ -0,0 +1,59 @@ +package com.dcsoft.system.api.factory; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.openfeign.FallbackFactory; +import org.springframework.stereotype.Component; +import org.springframework.util.MultiValueMap; +import org.springframework.web.multipart.MultipartFile; +import com.dcsoft.common.core.domain.R; +import com.dcsoft.system.api.RemoteFileService; +import com.dcsoft.system.api.domain.SysFile; + +/** + * 文件服务降级处理 + * + * @author dcsoft + */ +@Component +public class RemoteFileFallbackFactory implements FallbackFactory +{ + private static final Logger log = LoggerFactory.getLogger(RemoteFileFallbackFactory.class); + + @Override + public RemoteFileService create(Throwable throwable) + { + log.error("文件服务调用失败:{}", throwable.getMessage()); + return new RemoteFileService() + { + @Override + public R upload(MultipartFile file) + { + return R.fail("上传文件失败:" + throwable.getMessage()); + } + @Override + public R uploadMinio(MultipartFile file,String fileName) + { + return R.fail("上传文件失败:" + throwable.getMessage()); + } + + @Override + public R uploadMinio1(MultipartFile file, String fileName) { + return null; + } + + @Override + public R uploadMinios(MultipartFile file,String fileName) + { + return R.fail("上传文件失败:" + throwable.getMessage()); + } + + @Override + public R uploadMinioCar(MultipartFile file) { + return R.fail("上传文件失败:" + throwable.getMessage()); + } + + + }; + } +} diff --git a/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/factory/RemoteLogFallbackFactory.java b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/factory/RemoteLogFallbackFactory.java new file mode 100644 index 0000000..a6eed6d --- /dev/null +++ b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/factory/RemoteLogFallbackFactory.java @@ -0,0 +1,42 @@ +package com.dcsoft.system.api.factory; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.openfeign.FallbackFactory; +import org.springframework.stereotype.Component; +import com.dcsoft.common.core.domain.R; +import com.dcsoft.system.api.RemoteLogService; +import com.dcsoft.system.api.domain.SysLogininfor; +import com.dcsoft.system.api.domain.SysOperLog; + +/** + * 日志服务降级处理 + * + * @author dcsoft + */ +@Component +public class RemoteLogFallbackFactory implements FallbackFactory +{ + private static final Logger log = LoggerFactory.getLogger(RemoteLogFallbackFactory.class); + + @Override + public RemoteLogService create(Throwable throwable) + { + log.error("日志服务调用失败:{}", throwable.getMessage()); + return new RemoteLogService() + { + @Override + public R saveLog(SysOperLog sysOperLog, String source) + { + return null; + } + + @Override + public R saveLogininfor(SysLogininfor sysLogininfor, String source) + { + return null; + } + }; + + } +} diff --git a/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/factory/RemoteStudentFallbackFactory.java b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/factory/RemoteStudentFallbackFactory.java new file mode 100644 index 0000000..9ec7174 --- /dev/null +++ b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/factory/RemoteStudentFallbackFactory.java @@ -0,0 +1,94 @@ +package com.dcsoft.system.api.factory; + +import com.dcsoft.common.core.domain.R; +import com.dcsoft.common.core.web.page.TableDatasInfo; +import com.dcsoft.system.api.RemoteStudentService; +import com.dcsoft.system.api.domain.FaceStudentBody; +import com.dcsoft.system.api.domain.SysFile; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.openfeign.FallbackFactory; +import org.springframework.stereotype.Component; + +/** + * 日志服务降级处理 + * + * @author dcsoft + */ +@Component +public class RemoteStudentFallbackFactory implements FallbackFactory +{ + private static final Logger log = LoggerFactory.getLogger(RemoteStudentFallbackFactory.class); + + @Override + public RemoteStudentService create(Throwable throwable) + { + log.error("学生信息调用失败:{}", throwable.getMessage()); + return new RemoteStudentService() + { + @Override + public TableDatasInfo studentList(FaceStudentBody faceStudent, String source) + { + return null; + } + @Override + public void gatherMonth(String source) + { + return ; + } + @Override + public void backUp(String source) + { + return ; + } + + @Override + public void gather(String source) + { + return ; + } + + @Override + public void peopleLeave(String source) { + return ; + } + + @Override + public void saveAskForLeave(String source) { + + } + + @Override + public void saveCardReplacement(String inner) { + + } + + @Override + public void batchDistribute(String inner) { + + } + + @Override + public void saveBranchTree(String inner) { + + } + + @Override + public void saveUserInfo(String inner) { + + } + + @Override + public void saveStation(String inner) { + + } + + @Override + public void batchDown(String inner) { + + } + + }; + + } +} diff --git a/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/factory/RemoteUserFallbackFactory.java b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/factory/RemoteUserFallbackFactory.java new file mode 100644 index 0000000..cb87930 --- /dev/null +++ b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/factory/RemoteUserFallbackFactory.java @@ -0,0 +1,53 @@ +package com.dcsoft.system.api.factory; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.openfeign.FallbackFactory; +import org.springframework.stereotype.Component; +import com.dcsoft.common.core.domain.R; +import com.dcsoft.system.api.RemoteUserService; +import com.dcsoft.system.api.domain.SysUser; +import com.dcsoft.system.api.model.LoginUser; + +/** + * 用户服务降级处理 + * + * @author dcsoft + */ +@Component +public class RemoteUserFallbackFactory implements FallbackFactory +{ + private static final Logger log = LoggerFactory.getLogger(RemoteUserFallbackFactory.class); + + @Override + public RemoteUserService create(Throwable throwable) + { + log.error("用户服务调用失败:{}", throwable.getMessage()); + return new RemoteUserService() + { + @Override + public R getUserInfo(String username, String source) + { + return R.fail("获取用户失败:" + throwable.getMessage()); + } + + @Override + public R registerUserInfo(SysUser sysUser, String source) + { + return R.fail("注册用户失败:" + throwable.getMessage()); + } + + @Override + public R getWxUserInfo(String openid, String source) + { + return R.fail("获取用户失败:" + throwable.getMessage()); + } + @Override + public R updateOpenId(SysUser sysUser, String source) + { + return R.fail("绑定用户openid失败:" + throwable.getMessage()); + } + + }; + } +} diff --git a/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/model/LoginUser.java b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/model/LoginUser.java new file mode 100644 index 0000000..0145cf2 --- /dev/null +++ b/dcsoft-api/dcsoft-api-system/src/main/java/com/dcsoft/system/api/model/LoginUser.java @@ -0,0 +1,150 @@ +package com.dcsoft.system.api.model; + +import java.io.Serializable; +import java.util.Set; +import com.dcsoft.system.api.domain.SysUser; + +/** + * 用户信息 + * + * @author dcsoft + */ +public class LoginUser implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** + * 用户唯一标识 + */ + private String token; + + /** + * 用户名id + */ + private Long userid; + + /** + * 用户名 + */ + private String username; + + /** + * 登录时间 + */ + private Long loginTime; + + /** + * 过期时间 + */ + private Long expireTime; + + /** + * 登录IP地址 + */ + private String ipaddr; + + /** + * 权限列表 + */ + private Set permissions; + + /** + * 角色列表 + */ + private Set roles; + + /** + * 用户信息 + */ + private SysUser sysUser; + + public String getToken() + { + return token; + } + + public void setToken(String token) + { + this.token = token; + } + + public Long getUserid() + { + return userid; + } + + public void setUserid(Long userid) + { + this.userid = userid; + } + + public String getUsername() + { + return username; + } + + public void setUsername(String username) + { + this.username = username; + } + + public Long getLoginTime() + { + return loginTime; + } + + public void setLoginTime(Long loginTime) + { + this.loginTime = loginTime; + } + + public Long getExpireTime() + { + return expireTime; + } + + public void setExpireTime(Long expireTime) + { + this.expireTime = expireTime; + } + + public String getIpaddr() + { + return ipaddr; + } + + public void setIpaddr(String ipaddr) + { + this.ipaddr = ipaddr; + } + + public Set getPermissions() + { + return permissions; + } + + public void setPermissions(Set permissions) + { + this.permissions = permissions; + } + + public Set getRoles() + { + return roles; + } + + public void setRoles(Set roles) + { + this.roles = roles; + } + + public SysUser getSysUser() + { + return sysUser; + } + + public void setSysUser(SysUser sysUser) + { + this.sysUser = sysUser; + } +} diff --git a/dcsoft-api/dcsoft-api-system/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/dcsoft-api/dcsoft-api-system/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..2036ca2 --- /dev/null +++ b/dcsoft-api/dcsoft-api-system/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,3 @@ +com.dcsoft.system.api.factory.RemoteUserFallbackFactory +com.dcsoft.system.api.factory.RemoteLogFallbackFactory +com.dcsoft.system.api.factory.RemoteFileFallbackFactory diff --git a/dcsoft-api/pom.xml b/dcsoft-api/pom.xml new file mode 100644 index 0000000..127420c --- /dev/null +++ b/dcsoft-api/pom.xml @@ -0,0 +1,22 @@ + + + + com.dcsoft + dcsoft + 3.6.2 + + 4.0.0 + + + dcsoft-api-system + + + dcsoft-api + pom + + + dcsoft-api系统接口 + + + diff --git a/dcsoft-auth/pom.xml b/dcsoft-auth/pom.xml new file mode 100644 index 0000000..5d4a9c2 --- /dev/null +++ b/dcsoft-auth/pom.xml @@ -0,0 +1,100 @@ + + + com.dcsoft + dcsoft + 3.6.2 + + 4.0.0 + + dcsoft-auth + + + dcsoft-auth认证授权中心 + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + com.dcsoft + dcsoft-common-security + + + + org.dom4j + dom4j + 2.1.1 + compile + + + + com.idsmanager.dingdang + jwt-sdk + 1.1.1 + system + ${project.basedir}/src/main/resources/lib/JWT-SDK-1.1.1_1.8.jar + + + + rg.jose4j.jwt + jose4j-sdk + 0.4.3 + system + ${project.basedir}/src/main/resources/lib/jose4j-0.4.3.jar + + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + true + + + + + + diff --git a/dcsoft-auth/src/main/java/com/dcsoft/auth/DCSAuthApplication.java b/dcsoft-auth/src/main/java/com/dcsoft/auth/DCSAuthApplication.java new file mode 100644 index 0000000..5e618e2 --- /dev/null +++ b/dcsoft-auth/src/main/java/com/dcsoft/auth/DCSAuthApplication.java @@ -0,0 +1,26 @@ +package com.dcsoft.auth; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import com.dcsoft.common.security.annotation.EnableRyFeignClients; + +/** + * 认证授权中心 + * + * @author dcsoft + */ +@EnableRyFeignClients +@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class }) +public class DCSAuthApplication +{ + public static void main(String[] args) + { + SpringApplication.run(com.dcsoft.auth.DCSAuthApplication.class, args); + System.out.println("(♥◠‿◠)ノ゙ 认证授权中心启动成功 ლ(´ڡ`ლ)゙ \n" + + " ___ ___ ___ \n" + + " | \\ / __| / __| \n" + + " | |) | | (__ \\__ \\ \n" + + " |___/ \\___| |___/ "); + } +} diff --git a/dcsoft-auth/src/main/java/com/dcsoft/auth/bean/CheckParams.java b/dcsoft-auth/src/main/java/com/dcsoft/auth/bean/CheckParams.java new file mode 100644 index 0000000..a17952e --- /dev/null +++ b/dcsoft-auth/src/main/java/com/dcsoft/auth/bean/CheckParams.java @@ -0,0 +1,27 @@ +package com.dcsoft.auth.bean; + +import lombok.Builder; +import lombok.Data; + +/** + * @author penghao + * @createDate 2022/05/10 + * @createTime 10:05 + */ +@Data +@Builder +public class CheckParams { + + private long lastValidateTime; + + private String macAddress; + + private String cpuSerial; + + private Long generatedTime; + + private Long expiredTime; + + private String version; + +} diff --git a/dcsoft-auth/src/main/java/com/dcsoft/auth/bean/ValidateCodeEnum.java b/dcsoft-auth/src/main/java/com/dcsoft/auth/bean/ValidateCodeEnum.java new file mode 100644 index 0000000..b291ce0 --- /dev/null +++ b/dcsoft-auth/src/main/java/com/dcsoft/auth/bean/ValidateCodeEnum.java @@ -0,0 +1,22 @@ +package com.dcsoft.auth.bean; + +import lombok.Getter; + +@Getter +public enum ValidateCodeEnum { + + SUCCESS(200, "验证通过"), + EXPIRED(1101, "授权已过期"), + ILLEGAL(1102, "授权码不正确"), + EXCEPTION(1103, "解析签名异常"), + FILE_NOT_EXIST(1104, "license文件不存在"), + UNAUTHORIZED(1105, "产品未授权"); + + private Integer code; + private String message; + + ValidateCodeEnum(Integer code, String message) { + this.code = code; + this.message = message; + } +} diff --git a/dcsoft-auth/src/main/java/com/dcsoft/auth/bean/ValidateResult.java b/dcsoft-auth/src/main/java/com/dcsoft/auth/bean/ValidateResult.java new file mode 100644 index 0000000..e2a5013 --- /dev/null +++ b/dcsoft-auth/src/main/java/com/dcsoft/auth/bean/ValidateResult.java @@ -0,0 +1,38 @@ +package com.dcsoft.auth.bean; + +import lombok.Data; + +@Data +public class ValidateResult { + + /** + * 是否验证通过 + */ + private Boolean isValidate; + + /** + * 验证结果状态码 + */ + private Integer code; + + /** + * 验证结果信息 + */ + private String message; + + public static ValidateResult ok() { + ValidateResult result = new ValidateResult(); + result.setIsValidate(true); + result.setCode(ValidateCodeEnum.SUCCESS.getCode()); + result.setMessage(ValidateCodeEnum.SUCCESS.getMessage()); + return result; + } + + public static ValidateResult error(ValidateCodeEnum codeEnum) { + ValidateResult result = new ValidateResult(); + result.setIsValidate(false); + result.setCode(codeEnum.getCode()); + result.setMessage(codeEnum.getMessage()); + return result; + } +} diff --git a/dcsoft-auth/src/main/java/com/dcsoft/auth/controller/ApiController.java b/dcsoft-auth/src/main/java/com/dcsoft/auth/controller/ApiController.java new file mode 100644 index 0000000..352edbc --- /dev/null +++ b/dcsoft-auth/src/main/java/com/dcsoft/auth/controller/ApiController.java @@ -0,0 +1,187 @@ +package com.dcsoft.auth.controller; + +import com.dcsoft.auth.service.SysAuthService; +import com.dcsoft.common.core.constant.CacheConstants; +import com.dcsoft.common.core.utils.JwtUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDatasInfo; +import com.dcsoft.common.redis.service.RedisService; +import com.dcsoft.system.api.domain.FaceStudentBody; +import com.dcsoft.system.api.domain.SysAuth; +import io.jsonwebtoken.Claims; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import java.math.BigInteger; +import java.security.MessageDigest; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * token 控制 + * + * @author dcsoft + */ +@RestController +@RequestMapping("/face-api") +public class ApiController +{ + @Autowired + private RedisService redisService; + + @Autowired + private SysAuthService sysAuthService; + + + /** + * 鉴权接口 + */ + @GetMapping("/auth") + public AjaxResult auth(HttpServletRequest request) + { + String timestamp=request.getHeader("timestamp"); + String appKey=request.getHeader("appKey"); + String sign=request.getHeader("sign"); + if(StringUtils.isEmpty(timestamp)){ + return AjaxResult.error("timestamp is empty"); + } + Long timeLong=new Date().getTime()/1000-Long.parseLong(timestamp); + if(timeLong>5*60){ + return AjaxResult.error("timestamp is timeOut"); + } + if(StringUtils.isEmpty(appKey)){ + return AjaxResult.error("appKey is empty"); + } + if(StringUtils.isEmpty(sign)){ + return AjaxResult.error("sign is empty"); + } + //appSecret通过后台获取 + SysAuth auth=sysAuthService.getAuth(appKey); + if(auth == null){ + return AjaxResult.error("appKey is error"); + } + String appSecret=auth.getAppSecret(); + String sign1= EncodeByMD5(appKey+timestamp+appSecret).toLowerCase(); + //比较两次秘钥的sign的值是否一致 + if(sign.equals(sign1)){ + //根据appKey生成token + // Jwt存储信息 + Map claimsMap = new HashMap(); + String verifyKey = CacheConstants.AUTH_KEY + appKey; + claimsMap.put(CacheConstants.AUTH_KEY, appKey); + String token =JwtUtils.createToken(claimsMap); + redisService.setCacheObject(verifyKey,token); + redisService.expire(verifyKey,24*60*60); + return AjaxResult.success("token get success",token); + }else{ + return AjaxResult.error("sign create error"); + } + } + + /** + * 人脸信息接口 + */ + @PostMapping("/faceInfo") + public TableDatasInfo faceInfo(HttpServletRequest request) + { + TableDatasInfo msg=new TableDatasInfo(); + + String token=request.getHeader("token"); + Boolean flag=validate(token); + if(flag){ + String phone=request.getParameter("phone"); + String idCard=request.getParameter("id_card"); + String label=request.getParameter("label"); + String pageNum=request.getParameter("pageNum"); + String pageSize=request.getParameter("pageSize"); + if(StringUtils.isEmpty(pageNum)){ + pageNum="1"; + } + if(StringUtils.isEmpty(pageSize)){ + pageSize="10"; + } + String endTime=request.getParameter("endTime"); + String startTime=request.getParameter("startTime"); + FaceStudentBody faceStudent=new FaceStudentBody(); + faceStudent.setPhone(phone); + faceStudent.setIdCard(idCard); + faceStudent.setPageNum(pageNum); + faceStudent.setPageSize(pageSize); + faceStudent.setLabel(label); + SimpleDateFormat sdf=new SimpleDateFormat("yyyy-HH-mm"); + try { + if(StringUtils.isNotEmpty(startTime)){ + faceStudent.setStartTime(sdf.parse(startTime)); + } + if(StringUtils.isNotEmpty(endTime)){ + faceStudent.setEndTime(sdf.parse(endTime)); + } + } catch (ParseException e) { + throw new RuntimeException(e); + } + msg=sysAuthService.studentList(faceStudent); + }else{ + msg.setCode(500); + msg.setMsg("token is timeOut or is error"); + } + + return msg; + } + + + public Boolean validate(String token){ + if (StringUtils.isEmpty(token)){ + return false; + } + Claims claims = JwtUtils.parseToken(token); + if (claims == null) + { + return false; + } + String appKey=JwtUtils.getValue(claims,CacheConstants.AUTH_KEY); + //所有请求 token 及其他参数都写在 header 中 + String verifyKey = CacheConstants.AUTH_KEY + appKey; + String tokens = redisService.getCacheObject(verifyKey); + if(StringUtils.isEmpty(tokens)) {//重新获取token + return false; + } + if(token.equals(tokens)){ + return true; + }else{ + return false; + } + } + + + + /** + * 对字符串进行32位MD5加密 + * @param str + * @return + */ + public static String EncodeByMD5(String str) { + try { + // 生成一个MD5加密计算摘要 + MessageDigest md = MessageDigest.getInstance("MD5"); + // 计算md5函数 + md.update(str.getBytes("UTF-8")); + // digest()最后确定返回md5 hash值,返回值为8为字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符 + // BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值 + String md5=new BigInteger(1, md.digest()).toString(16); + //BigInteger会把0省略掉,需补全至32位 + return fillMD5(md5); + } catch (Exception e) { + throw new RuntimeException("MD5加密错误:"+e.getMessage(),e); + } + } + + private static String fillMD5(String md5) { + //如果不够32位则回调自身补零,最后返回32位长度的签名 + return md5.length() == 32 ? md5 : fillMD5("0" + md5); + } + + +} diff --git a/dcsoft-auth/src/main/java/com/dcsoft/auth/controller/TokenController.java b/dcsoft-auth/src/main/java/com/dcsoft/auth/controller/TokenController.java new file mode 100644 index 0000000..876fe34 --- /dev/null +++ b/dcsoft-auth/src/main/java/com/dcsoft/auth/controller/TokenController.java @@ -0,0 +1,205 @@ +package com.dcsoft.auth.controller; + +import javax.servlet.http.HttpServletRequest; + +import com.dcsoft.auth.bean.ValidateResult; +import com.dcsoft.auth.form.IDaasBody; +import com.dcsoft.auth.utils.LicenseManager; +import com.dcsoft.auth.utils.LicenseThread; +import com.idsmanager.dingdang.jwt.DingdangUserRetriever; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.*; +import com.dcsoft.auth.form.LoginBody; +import com.dcsoft.auth.form.RegisterBody; +import com.dcsoft.auth.service.SysLoginService; +import com.dcsoft.common.core.domain.R; +import com.dcsoft.common.core.utils.JwtUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.security.auth.AuthUtil; +import com.dcsoft.common.security.service.TokenService; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.api.model.LoginUser; + +import java.io.UnsupportedEncodingException; +import java.util.HashMap; +import java.util.Map; + +/** + * token 控制 + * + * @author dcsoft + */ +@RestController +public class TokenController +{ + @Autowired + private TokenService tokenService; + + @Autowired + private SysLoginService sysLoginService; + + @Value("${license.enabled}") + private Boolean enabled; + + @PostMapping("login") + public R login(@RequestBody LoginBody form) + { + /* if(enabled){ + ValidateResult validateResult = LicenseThread.validateResult.get("Authorize"); + if (!validateResult.getIsValidate()){ + return R.fail(validateResult.getMessage()); + } + }*/ + + LoginUser userInfo=new LoginUser(); + // 用户登录 + if("weixin".equals(form.getFlag())){ + R userInfos=sysLoginService.getWxUserInfo(form); + userInfo = userInfos.getData(); + if(userInfo==null){ + return R.fail(userInfos.getCode(), userInfos.getMsg()); + } + }else if("app".equals(form.getFlag())){ + userInfo = sysLoginService.login(form.getUsername(), form.getPassword()); + //保存用户openid + if(StringUtils.isNotEmpty(form.getOpenid())){ + sysLoginService.updateOpenId(userInfo,form); + } + }else{ + userInfo = sysLoginService.login(form.getUsername(), form.getPassword()); + } + // 获取登录token + return R.ok(tokenService.createToken(userInfo)); + } + + @PostMapping("app") + public R app(@RequestBody LoginBody form) + { + /* if(enabled){ + ValidateResult validateResult = LicenseThread.validateResult.get("Authorize"); + if (!validateResult.getIsValidate()){ + return R.fail(validateResult.getMessage()); + } + }*/ + + LoginUser userInfo=new LoginUser(); + // 用户登录 + if("weixin".equals(form.getFlag())){ + R userInfos=sysLoginService.getWxUserInfo(form); + userInfo = userInfos.getData(); + if(userInfo==null){ + R.fail(); + } + }else if("app".equals(form.getFlag())){ + userInfo = sysLoginService.login(form.getUsername(), form.getPassword()); + //保存用户openid + if(!"".equals(form.getOpenid())){ + sysLoginService.updateOpenId(userInfo,form); + } + }else{ + userInfo = sysLoginService.login(form.getUsername(), form.getPassword()); + } + // 获取登录token + return R.ok(tokenService.createToken(userInfo)); + } + + + @DeleteMapping("logout") + public R logout(HttpServletRequest request) + { + String token = SecurityUtils.getToken(request); + if (StringUtils.isNotEmpty(token)) + { + String username = JwtUtils.getUserName(token); + // 删除用户缓存记录 + AuthUtil.logoutByToken(token); + // 记录用户退出日志 + sysLoginService.logout(username); + } + return R.ok(); + } + + @PostMapping("refresh") + public R refresh(HttpServletRequest request) + { + LoginUser loginUser = tokenService.getLoginUser(request); + if (StringUtils.isNotNull(loginUser)) + { + // 刷新令牌有效期 + tokenService.refreshToken(loginUser); + return R.ok(); + } + return R.ok(); + } + + @PostMapping("register") + public R register(@RequestBody RegisterBody registerBody) + { + // 用户注册 + sysLoginService.register(registerBody.getUsername(), registerBody.getPassword()); + return R.ok(); + } + + /* @PostMapping("validate") + public R validate(@RequestBody IDaasBody iDaasBody) + { + String name= null; + try { + name = checkUsername(iDaasBody.getIdToken()); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + LoginUser userInfo=new LoginUser(); + // 用户登录 + userInfo = sysLoginService.login(name); + // 获取登录token + return R.ok(tokenService.createToken(userInfo)); + }*/ + + /* private String checkUsername(String id_token) throws + UnsupportedEncodingException { + //1.使⽤公钥解析id_token,使⽤publicKey解密上⼀步获取的id_token令牌 + DingdangUserRetriever retriever = new DingdangUserRetriever(id_token,publickey); + DingdangUserRetriever.User user = null; + try { + //2.获取⽤户信息 + user = retriever.retrieve(); + } catch (Exception e) { + return "error"; + } + //3.如果publicKey不正确或者id_token过期,获取到的⽤户信息可能为null + if (null == user) { + + return "error"; + } + //4.获取到⽤户信息,检测⽤户名是否存在⾃⼰的业务系统中,isExistedUsername⽅法为示例实现 + if (StringUtils.isNotEmpty(user.getUsername())) { + return user.getUsername(); + } else { + //8.如果不存在,返回登录失败⻚⾯,提示⽤户不存在 + return "error"; + } + }*/ + + //获取服务器标识接口 + @GetMapping("/getServerID") + public Map getServerID(){ + Map retMap=new HashMap<>(2); + retMap.put("code","200"); + retMap.put("serverID", LicenseManager.getSystemSign()); + return retMap; + } + + //授权码更新接口 + @PostMapping("/updateSign") + public Map updateSign(String sign){ + Map retMap=new HashMap<>(2); + LicenseManager.updateSign(sign); + LicenseThread.validateAfterUpdateSign(); + retMap.put("code","200"); + retMap.put("msg","激活成功!"); + return retMap; + } + +} diff --git a/dcsoft-auth/src/main/java/com/dcsoft/auth/form/AuthBody.java b/dcsoft-auth/src/main/java/com/dcsoft/auth/form/AuthBody.java new file mode 100644 index 0000000..02f700a --- /dev/null +++ b/dcsoft-auth/src/main/java/com/dcsoft/auth/form/AuthBody.java @@ -0,0 +1,35 @@ +package com.dcsoft.auth.form; + +/** + * 用户登录对象 + * + * @author dcsoft + */ +public class AuthBody +{ + /** + * appKey + */ + private String appKey; + + /** + * appSecret + */ + private String appSecret; + + public String getAppKey() { + return appKey; + } + + public void setAppKey(String appKey) { + this.appKey = appKey; + } + + public String getAppSecret() { + return appSecret; + } + + public void setAppSecret(String appSecret) { + this.appSecret = appSecret; + } +} diff --git a/dcsoft-auth/src/main/java/com/dcsoft/auth/form/IDaasBody.java b/dcsoft-auth/src/main/java/com/dcsoft/auth/form/IDaasBody.java new file mode 100644 index 0000000..a6d78b0 --- /dev/null +++ b/dcsoft-auth/src/main/java/com/dcsoft/auth/form/IDaasBody.java @@ -0,0 +1,35 @@ +package com.dcsoft.auth.form; + +/** + * 用户登录对象 + * + * @author dcsoft + */ +public class IDaasBody +{ + /** + * idToken + */ + private String idToken; + + /** + * targetUrl + */ + private String targetUrl; + + public String getIdToken() { + return idToken; + } + + public void setIdToken(String idToken) { + this.idToken = idToken; + } + + public String getTargetUrl() { + return targetUrl; + } + + public void setTargetUrl(String targetUrl) { + this.targetUrl = targetUrl; + } +} diff --git a/dcsoft-auth/src/main/java/com/dcsoft/auth/form/LoginBody.java b/dcsoft-auth/src/main/java/com/dcsoft/auth/form/LoginBody.java new file mode 100644 index 0000000..4a5ebce --- /dev/null +++ b/dcsoft-auth/src/main/java/com/dcsoft/auth/form/LoginBody.java @@ -0,0 +1,74 @@ +package com.dcsoft.auth.form; + +/** + * 用户登录对象 + * + * @author dcsoft + */ +public class LoginBody +{ + /** + * 用户名 + */ + private String username; + + /** + * 用户密码 + */ + private String password; + /** + * 登录方式 + * **/ + private String flag; + /** + * 微信openid + * **/ + private String openid; + + + 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 getFlag() { + return flag; + } + + public void setFlag(String flag) { + this.flag = flag; + } + + public String getOpenid() { + return openid; + } + + public void setOpenid(String openid) { + this.openid = openid; + } + + @Override + public String toString() { + return "LoginBody{" + + "username='" + username + '\'' + + ", password='" + password + '\'' + + ", flag='" + flag + '\'' + + ", openid='" + openid + '\'' + + '}'; + } +} diff --git a/dcsoft-auth/src/main/java/com/dcsoft/auth/form/RegisterBody.java b/dcsoft-auth/src/main/java/com/dcsoft/auth/form/RegisterBody.java new file mode 100644 index 0000000..682a1b2 --- /dev/null +++ b/dcsoft-auth/src/main/java/com/dcsoft/auth/form/RegisterBody.java @@ -0,0 +1,11 @@ +package com.dcsoft.auth.form; + +/** + * 用户注册对象 + * + * @author dcsoft + */ +public class RegisterBody extends LoginBody +{ + +} diff --git a/dcsoft-auth/src/main/java/com/dcsoft/auth/service/SysAuthService.java b/dcsoft-auth/src/main/java/com/dcsoft/auth/service/SysAuthService.java new file mode 100644 index 0000000..f961f63 --- /dev/null +++ b/dcsoft-auth/src/main/java/com/dcsoft/auth/service/SysAuthService.java @@ -0,0 +1,45 @@ +package com.dcsoft.auth.service; + +import com.dcsoft.common.core.constant.SecurityConstants; +import com.dcsoft.common.core.domain.R; +import com.dcsoft.common.core.web.page.TableDatasInfo; +import com.dcsoft.system.api.RemoteAuthService; +import com.dcsoft.system.api.RemoteStudentService; +import com.dcsoft.system.api.domain.FaceStudentBody; +import com.dcsoft.system.api.domain.SysAuth; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * 登录校验方法 + * + * @author dcsoft + */ +@Component +public class SysAuthService +{ + @Autowired + private RemoteAuthService remoteAuthService; + + + @Autowired + private RemoteStudentService remoteStudentService; + + + public SysAuth getAuth(String appKey) + { + // 查询用户信息 + R userResult = remoteAuthService.getAuth(appKey, SecurityConstants.INNER); + return userResult.getData(); + } + + + public TableDatasInfo studentList(FaceStudentBody faceStudent) + { + // 查询用户信息 + TableDatasInfo userResult = remoteStudentService.studentList(faceStudent, SecurityConstants.INNER); + return userResult; + } + + +} diff --git a/dcsoft-auth/src/main/java/com/dcsoft/auth/service/SysLoginService.java b/dcsoft-auth/src/main/java/com/dcsoft/auth/service/SysLoginService.java new file mode 100644 index 0000000..b053b5a --- /dev/null +++ b/dcsoft-auth/src/main/java/com/dcsoft/auth/service/SysLoginService.java @@ -0,0 +1,212 @@ +package com.dcsoft.auth.service; + +import com.dcsoft.auth.form.LoginBody; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import com.dcsoft.common.core.constant.CacheConstants; +import com.dcsoft.common.core.constant.Constants; +import com.dcsoft.common.core.constant.SecurityConstants; +import com.dcsoft.common.core.constant.UserConstants; +import com.dcsoft.common.core.domain.R; +import com.dcsoft.common.core.enums.UserStatus; +import com.dcsoft.common.core.exception.ServiceException; +import com.dcsoft.common.core.text.Convert; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.utils.ip.IpUtils; +import com.dcsoft.common.redis.service.RedisService; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.api.RemoteUserService; +import com.dcsoft.system.api.domain.SysUser; +import com.dcsoft.system.api.model.LoginUser; + +/** + * 登录校验方法 + * + * @author dcsoft + */ +@Component +public class SysLoginService +{ + @Autowired + private RemoteUserService remoteUserService; + + @Autowired + private SysPasswordService passwordService; + + @Autowired + private SysRecordLogService recordLogService; + + @Autowired + private RedisService redisService; + + /** + * 登录 + */ + public LoginUser login(String username, String password) + { + // 用户名或密码为空 错误 + if (StringUtils.isAnyBlank(username, password)) + { + recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户/密码必须填写"); + throw new ServiceException("用户/密码必须填写"); + } + // 密码如果不在指定范围内 错误 + if (password.length() < UserConstants.PASSWORD_MIN_LENGTH + || password.length() > UserConstants.PASSWORD_MAX_LENGTH) + { + recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户密码不在指定范围"); + throw new ServiceException("用户密码不在指定范围"); + } + // 用户名不在指定范围内 错误 + if (username.length() < UserConstants.USERNAME_MIN_LENGTH + || username.length() > UserConstants.USERNAME_MAX_LENGTH) + { + recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户名不在指定范围"); + throw new ServiceException("用户名不在指定范围"); + } + // IP黑名单校验 + String blackStr = Convert.toStr(redisService.getCacheObject(CacheConstants.SYS_LOGIN_BLACKIPLIST)); + if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) + { + recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "很遗憾,访问IP已被列入系统黑名单"); + throw new ServiceException("很遗憾,访问IP已被列入系统黑名单"); + } + // 查询用户信息 + R userResult = remoteUserService.getUserInfo(username, SecurityConstants.INNER); + + if (StringUtils.isNull(userResult) || StringUtils.isNull(userResult.getData())) + { + recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "登录用户不存在"); + throw new ServiceException("登录用户:" + username + " 不存在"); + } + + if (R.FAIL == userResult.getCode()) + { + throw new ServiceException(userResult.getMsg()); + } + + LoginUser userInfo = userResult.getData(); + SysUser user = userResult.getData().getSysUser(); + if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) + { + recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "对不起,您的账号已被删除"); + throw new ServiceException("对不起,您的账号:" + username + " 已被删除"); + } + if (UserStatus.DISABLE.getCode().equals(user.getStatus())) + { + recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户已停用,请联系管理员"); + throw new ServiceException("对不起,您的账号:" + username + " 已停用"); + } + passwordService.validate(user, password); + recordLogService.recordLogininfor(username, Constants.LOGIN_SUCCESS, "登录成功"); + return userInfo; + } + + public void logout(String loginName) + { + recordLogService.recordLogininfor(loginName, Constants.LOGOUT, "退出成功"); + } + + /** + * 注册 + */ + public void register(String username, String password) + { + // 用户名或密码为空 错误 + if (StringUtils.isAnyBlank(username, password)) + { + throw new ServiceException("用户/密码必须填写"); + } + if (username.length() < UserConstants.USERNAME_MIN_LENGTH + || username.length() > UserConstants.USERNAME_MAX_LENGTH) + { + throw new ServiceException("账户长度必须在2到20个字符之间"); + } + if (password.length() < UserConstants.PASSWORD_MIN_LENGTH + || password.length() > UserConstants.PASSWORD_MAX_LENGTH) + { + throw new ServiceException("密码长度必须在5到20个字符之间"); + } + + // 注册用户信息 + SysUser sysUser = new SysUser(); + sysUser.setUserName(username); + sysUser.setNickName(username); + sysUser.setPassword(SecurityUtils.encryptPassword(password)); + R registerResult = remoteUserService.registerUserInfo(sysUser, SecurityConstants.INNER); + + if (R.FAIL == registerResult.getCode()) + { + throw new ServiceException(registerResult.getMsg()); + } + recordLogService.recordLogininfor(username, Constants.REGISTER, "注册成功"); + } + + /** + * 登录 + */ + public LoginUser login(String username) + { + + // 用户名不在指定范围内 错误 + if (username.length() < UserConstants.USERNAME_MIN_LENGTH + || username.length() > UserConstants.USERNAME_MAX_LENGTH) + { + recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户名不在指定范围"); + throw new ServiceException("用户名不在指定范围"); + } + // IP黑名单校验 + String blackStr = Convert.toStr(redisService.getCacheObject(CacheConstants.SYS_LOGIN_BLACKIPLIST)); + if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) + { + recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "很遗憾,访问IP已被列入系统黑名单"); + throw new ServiceException("很遗憾,访问IP已被列入系统黑名单"); + } + // 查询用户信息 + R userResult = remoteUserService.getUserInfo(username, SecurityConstants.INNER); + + if (StringUtils.isNull(userResult) || StringUtils.isNull(userResult.getData())) + { + recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "登录用户不存在"); + throw new ServiceException("登录用户:" + username + " 不存在"); + } + + if (R.FAIL == userResult.getCode()) + { + throw new ServiceException(userResult.getMsg()); + } + + LoginUser userInfo = userResult.getData(); + SysUser user = userResult.getData().getSysUser(); + if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) + { + recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "对不起,您的账号已被删除"); + throw new ServiceException("对不起,您的账号:" + username + " 已被删除"); + } + if (UserStatus.DISABLE.getCode().equals(user.getStatus())) + { + recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户已停用,请联系管理员"); + throw new ServiceException("对不起,您的账号:" + username + " 已停用"); + } + recordLogService.recordLogininfor(username, Constants.LOGIN_SUCCESS, "登录成功"); + return userInfo; + } + + public void updateOpenId(LoginUser userInfo, LoginBody form) { + // 注册用户信息 + SysUser sysUser = new SysUser(); + sysUser=userInfo.getSysUser(); + sysUser.setUserName(form.getUsername()); + sysUser.setOpenid(form.getOpenid()); + R registerResult = remoteUserService.updateOpenId(sysUser, SecurityConstants.INNER); + if (R.FAIL == registerResult.getCode()) + { + throw new ServiceException(registerResult.getMsg()); + } + } + + public R getWxUserInfo(LoginBody form) { + R registerResult = remoteUserService.getWxUserInfo(form.getOpenid(), SecurityConstants.INNER); + return registerResult; + } +} diff --git a/dcsoft-auth/src/main/java/com/dcsoft/auth/service/SysPasswordService.java b/dcsoft-auth/src/main/java/com/dcsoft/auth/service/SysPasswordService.java new file mode 100644 index 0000000..2cc3df9 --- /dev/null +++ b/dcsoft-auth/src/main/java/com/dcsoft/auth/service/SysPasswordService.java @@ -0,0 +1,85 @@ +package com.dcsoft.auth.service; + +import java.util.concurrent.TimeUnit; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import com.dcsoft.common.core.constant.CacheConstants; +import com.dcsoft.common.core.constant.Constants; +import com.dcsoft.common.core.exception.ServiceException; +import com.dcsoft.common.redis.service.RedisService; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.api.domain.SysUser; + +/** + * 登录密码方法 + * + * @author dcsoft + */ +@Component +public class SysPasswordService +{ + @Autowired + private RedisService redisService; + + private int maxRetryCount = CacheConstants.PASSWORD_MAX_RETRY_COUNT; + + private Long lockTime = CacheConstants.PASSWORD_LOCK_TIME; + + @Autowired + private SysRecordLogService recordLogService; + + /** + * 登录账户密码错误次数缓存键名 + * + * @param username 用户名 + * @return 缓存键key + */ + private String getCacheKey(String username) + { + return CacheConstants.PWD_ERR_CNT_KEY + username; + } + + public void validate(SysUser user, String password) + { + String username = user.getUserName(); + + Integer retryCount = redisService.getCacheObject(getCacheKey(username)); + + if (retryCount == null) + { + retryCount = 0; + } + + if (retryCount >= Integer.valueOf(maxRetryCount).intValue()) + { + String errMsg = String.format("密码输入错误%s次,帐户锁定%s分钟", maxRetryCount, lockTime); + recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL,errMsg); + throw new ServiceException(errMsg); + } + + if (!matches(user, password)) + { + retryCount = retryCount + 1; + recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, String.format("密码输入错误%s次", retryCount)); + redisService.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES); + throw new ServiceException("用户不存在/密码错误"); + } + else + { + clearLoginRecordCache(username); + } + } + + public boolean matches(SysUser user, String rawPassword) + { + return SecurityUtils.matchesPassword(rawPassword, user.getPassword()); + } + + public void clearLoginRecordCache(String loginName) + { + if (redisService.hasKey(getCacheKey(loginName))) + { + redisService.deleteObject(getCacheKey(loginName)); + } + } +} diff --git a/dcsoft-auth/src/main/java/com/dcsoft/auth/service/SysRecordLogService.java b/dcsoft-auth/src/main/java/com/dcsoft/auth/service/SysRecordLogService.java new file mode 100644 index 0000000..e4dd770 --- /dev/null +++ b/dcsoft-auth/src/main/java/com/dcsoft/auth/service/SysRecordLogService.java @@ -0,0 +1,48 @@ +package com.dcsoft.auth.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import com.dcsoft.common.core.constant.Constants; +import com.dcsoft.common.core.constant.SecurityConstants; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.utils.ip.IpUtils; +import com.dcsoft.system.api.RemoteLogService; +import com.dcsoft.system.api.domain.SysLogininfor; + +/** + * 记录日志方法 + * + * @author dcsoft + */ +@Component +public class SysRecordLogService +{ + @Autowired + private RemoteLogService remoteLogService; + + /** + * 记录登录信息 + * + * @param username 用户名 + * @param status 状态 + * @param message 消息内容 + * @return + */ + public void recordLogininfor(String username, String status, String message) + { + SysLogininfor logininfor = new SysLogininfor(); + logininfor.setUserName(username); + logininfor.setIpaddr(IpUtils.getIpAddr()); + logininfor.setMsg(message); + // 日志状态 + if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)) + { + logininfor.setStatus(Constants.LOGIN_SUCCESS_STATUS); + } + else if (Constants.LOGIN_FAIL.equals(status)) + { + logininfor.setStatus(Constants.LOGIN_FAIL_STATUS); + } + remoteLogService.saveLogininfor(logininfor, SecurityConstants.INNER); + } +} diff --git a/dcsoft-auth/src/main/java/com/dcsoft/auth/test/CreateSign.java b/dcsoft-auth/src/main/java/com/dcsoft/auth/test/CreateSign.java new file mode 100644 index 0000000..8228a53 --- /dev/null +++ b/dcsoft-auth/src/main/java/com/dcsoft/auth/test/CreateSign.java @@ -0,0 +1,108 @@ +package com.dcsoft.auth.test; + +import com.dcsoft.auth.utils.AESUtils; +import com.dcsoft.auth.utils.DateUtils; +import org.dom4j.Document; +import org.dom4j.DocumentHelper; +import org.dom4j.Element; +import org.dom4j.io.OutputFormat; +import org.dom4j.io.XMLWriter; + +import java.io.File; +import java.io.FileWriter; +import java.util.Scanner; + +/** + * @author penghao + * @Description 生成签名 + * @createDate 2022/05/05 + * @createTime 17:41 + */ +public class CreateSign { + + public static void main(String[] args) { + //系统标识---由mac地址+cpu序列号 使用AES加密而来 +// String systemSign = "1jfNqzhz66e8egvhsONUXJMDNalNPTLWDO1lLBetwck="; + //生效起始时间 +// String generatedTimeStr = "2022-05-09 00:00:00"; + //生效截止时间 +// String expiredTimeStr = "2022-05-11 00:00:00"; + //上一次校验时间(初始值) +// String lastValidateTimeStr = "2022-05-09 00:00:01"; + //项目部署序列号(版本标识) +// String version = "dmoiji3xkoa4p33"; + //license生成路径 +// String path = "C:\\Users\\Administrator\\Desktop\\license.xml"; + + System.out.println(" mac地址+cpu序列号:"); + Scanner sc1 = new Scanner(System.in); + String signBuilder = sc1.nextLine(); + String sign = AESUtils.encrypt(signBuilder); + System.out.println("mac地址+cpu序列号 AES加密生成签名:"+sign); + + Scanner sc = new Scanner(System.in); + System.out.println("请输入系统标识串(部署的服务获取):"); + String systemSign = sc.nextLine(); + System.out.println("请输入生效起始时间(格式如:2022-05-05 00:00:00):"); + String generatedTimeStr = sc.nextLine(); + System.out.println("请输入生效截止时间(格式如:2022-05-05 00:00:00):"); + String expiredTimeStr = sc.nextLine(); + System.out.println("请输入上一次校验时间初始值(格式如:2022-05-05 00:00:00):"); + String lastValidateTimeStr = sc.nextLine(); + System.out.println("请输入项目部署唯一版本号(不能带“-”):"); + String version = sc.nextLine(); + System.out.println("请输入license文件生成路径:"); + String path = sc.nextLine(); + createLicense(systemSign, generatedTimeStr, expiredTimeStr, lastValidateTimeStr, version, path); + System.out.println("license文件生成成功,文件路径:" + path); + } + + private static void createLicense(String systemSign, String generatedTimeStr, String expiredTimeStr, String lastValidateTimeStr, String version, String path) { + try { + //解密系统标识得到mac地址+cpu序列号 + String macAndCpu = AESUtils.decrypt(systemSign); + System.out.println("客户服务器mac地址和cpu序列号:" + macAndCpu); + + //MAC复制-CPU序列号-生效起始时间-生效结束结束时间-软件产品序列号(项目版本唯一标识) +// String content = "A8:A1:59:41:89:36-BFEBFBFF000906EA-20220506-20220507-dmoiji3xkoa4p33"; + StringBuilder signBuilder = new StringBuilder(macAndCpu); + //生效起始时间 + long generatedTime = DateUtils.getTimeInMillis(generatedTimeStr); + //生效截止时间 + long expiredTime = DateUtils.getTimeInMillis(expiredTimeStr); + //项目唯一标识 + signBuilder.append("-").append(generatedTime).append("-").append(expiredTime).append("-").append(version); + + String sign = AESUtils.encrypt(signBuilder.toString()); + System.out.println("AES加密生成签名:"); + System.out.println("-----------------------------------------------------------------------------------------------"); + System.out.println(sign); + System.out.println("-----------------------------------------------------------------------------------------------"); + + //生成licence文件 + Document document = DocumentHelper.createDocument(); + //根节点 + Element rootEle = document.addElement("license"); + //功能数据节点,扩展参数时可在此节点下扩展 + Element dataEle = rootEle.addElement("features"); + Element featureEle = dataEle.addElement("feature"); + featureEle.addAttribute("name", "lastValidateTi"); + featureEle.addAttribute("ti", AESUtils.encrypt(String.valueOf(DateUtils.getTimeInMillis(lastValidateTimeStr)))); + //签名节点 + Element signEle = rootEle.addElement("signature"); + signEle.setText(sign); + System.out.println(document.asXML()); + OutputFormat format = OutputFormat.createPrettyPrint(); + // 设置编码格式 + format.setEncoding("UTF-8"); + FileWriter fileWriter = new FileWriter(new File(path)); + XMLWriter xmlWriter = new XMLWriter(fileWriter, format); + // 设置是否转义,默认使用转义字符 + xmlWriter.setEscapeText(false); + xmlWriter.write(document); + xmlWriter.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/dcsoft-auth/src/main/java/com/dcsoft/auth/utils/AESUtils.java b/dcsoft-auth/src/main/java/com/dcsoft/auth/utils/AESUtils.java new file mode 100644 index 0000000..32175ca --- /dev/null +++ b/dcsoft-auth/src/main/java/com/dcsoft/auth/utils/AESUtils.java @@ -0,0 +1,97 @@ +package com.dcsoft.auth.utils; + +import org.springframework.util.Base64Utils; + +import javax.crypto.KeyGenerator; +import javax.crypto.*; +import javax.crypto.spec.SecretKeySpec; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; + +/** + * @version V1.0 + * @desc AES 加密工具类 + */ +public class AESUtils { + + /** + * RSA加密后的AES秘钥 + */ + private static String aesEncyptPwd="ZIkun+KvXFWLZLYUwXqFWazQeRe119AkcGcl+p8Erzi4EEaHBFYcQuGuKthIE+1IWSQxoUpUJkT0T1+xtoRi3txDnBikdrFhccGZdRpqwRv58q5nqxJX4wVrq0Ms02KBKgQRTqqlzfYLzQcYPyhv8KPE8JDVkttic+W+j5pFles="; + + private static final String KEY_ALGORITHM = "AES"; + + private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding"; + + /** + * AES 加密操作 + * + * @param content 待加密内容 + * @return 返回Base64转码后的加密数据 + */ + public static String encrypt(String content) { + try { + Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM); + byte[] byteContent = content.getBytes("utf-8"); + cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(RSAUtils.decrypt(aesEncyptPwd))); + byte[] result = cipher.doFinal(byteContent); + return Base64Utils.encodeToString(result); + } catch (Exception ex) { + ex.printStackTrace(); + System.out.println("AES加密失败"); + } + + return null; + } + + /** + * AES 解密操作 + * + * @param content 已加密内容 + * @return + */ + public static String decrypt(String content) { + try { + //实例化 + Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM); + //使用密钥初始化,设置为解密模式 + cipher.init(Cipher.DECRYPT_MODE, getSecretKey(RSAUtils.decrypt(aesEncyptPwd))); + //执行操作 + byte[] result = cipher.doFinal(Base64Utils.decodeFromString(content)); + return new String(result, "utf-8"); + } catch (Exception ex) { + ex.printStackTrace(); + System.out.println("AES解密失败"); + } + return null; + } + + /** + * 生成加密秘钥 + * + * @return + */ + private static SecretKeySpec getSecretKey(String aesKey) { + //返回生成指定算法密钥生成器的 KeyGenerator 对象 + KeyGenerator kg = null; + try { + kg = KeyGenerator.getInstance(KEY_ALGORITHM); + //AES 要求密钥长度为 128 + SecureRandom random=SecureRandom.getInstance("SHA1PRNG","SUN"); + random.setSeed(aesKey.getBytes()); + kg.init(128, random); + //生成一个密钥 + SecretKey secretKey = kg.generateKey(); + return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM); + } catch (NoSuchAlgorithmException ex) { + ex.printStackTrace(); + System.out.println("生成加密秘钥失败"); + } catch (NoSuchProviderException e) { + e.printStackTrace(); + System.out.println("生成加密秘钥失败"); + } + return null; + } +} + diff --git a/dcsoft-auth/src/main/java/com/dcsoft/auth/utils/DateUtils.java b/dcsoft-auth/src/main/java/com/dcsoft/auth/utils/DateUtils.java new file mode 100644 index 0000000..a18cba6 --- /dev/null +++ b/dcsoft-auth/src/main/java/com/dcsoft/auth/utils/DateUtils.java @@ -0,0 +1,28 @@ +package com.dcsoft.auth.utils; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * @author penghao + * @Description TODO + * @createDate 2022/05/09 + * @createTime 13:27 + */ +public class DateUtils { + + public static Long getTimeInMillis(String formatTime){ + try { + SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date date=format.parse(formatTime); + Calendar calendar=Calendar.getInstance(); + calendar.setTime(date); + return calendar.getTimeInMillis(); + }catch (Exception e){ + e.printStackTrace(); + System.out.println("日期转换失败"); + } + return 0L; + } +} diff --git a/dcsoft-auth/src/main/java/com/dcsoft/auth/utils/KeyGenerator.java b/dcsoft-auth/src/main/java/com/dcsoft/auth/utils/KeyGenerator.java new file mode 100644 index 0000000..45b4491 --- /dev/null +++ b/dcsoft-auth/src/main/java/com/dcsoft/auth/utils/KeyGenerator.java @@ -0,0 +1,54 @@ +package com.dcsoft.auth.utils; + +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.util.Base64; + +/** + * @Description 生成公钥私钥对 + * @createDate 2022/05/05 + * @createTime 14:25 + */ +public class KeyGenerator { + + /** + * 私钥 + */ + private static byte[] privateKey; + + /** + * 公钥 + */ + private static byte[] publicKey; + + /** + * 加密算法 + */ + private static final String KEY_ALGORITHM = "RSA"; + + public void generater() { + try { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM); + keyPairGenerator.initialize(1024); + KeyPair keyPair = keyPairGenerator.genKeyPair(); + RSAPublicKey pubKey = (RSAPublicKey) keyPair.getPublic(); + RSAPrivateKey priKey = (RSAPrivateKey) keyPair.getPrivate(); + privateKey = Base64.getEncoder().encode(priKey.getEncoded()); + publicKey = Base64.getEncoder().encode(pubKey.getEncoded()); + System.out.println("公钥:" + new String(publicKey)); + System.out.println("私钥:" + new String(privateKey)); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + System.out.println("生成密钥对失败!"); + } + } + + public static void main(String[] args) { + KeyGenerator keyGenerator = new KeyGenerator(); + keyGenerator.generater(); + } + +} diff --git a/dcsoft-auth/src/main/java/com/dcsoft/auth/utils/LicenseManager.java b/dcsoft-auth/src/main/java/com/dcsoft/auth/utils/LicenseManager.java new file mode 100644 index 0000000..2e0cd6e --- /dev/null +++ b/dcsoft-auth/src/main/java/com/dcsoft/auth/utils/LicenseManager.java @@ -0,0 +1,167 @@ +package com.dcsoft.auth.utils; + + +import com.dcsoft.auth.bean.CheckParams; +import com.dcsoft.auth.bean.ValidateCodeEnum; +import com.dcsoft.auth.bean.ValidateResult; +import lombok.extern.slf4j.Slf4j; +import org.dom4j.Document; +import org.dom4j.Element; +import org.dom4j.io.OutputFormat; +import org.dom4j.io.SAXReader; +import org.dom4j.io.XMLWriter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.io.File; +import java.io.FileWriter; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author PH + */ +@Slf4j +@Component +public class LicenseManager { + + public static Map validate() { + Map result = new HashMap<>(); + CheckParams checkParams = null; + try { + checkParams = getCheckParams(result); + if (checkParams == null) { + return result; + } + } catch (Exception e) { + e.printStackTrace(); + result.put("Authorize", ValidateResult.error(ValidateCodeEnum.EXCEPTION)); + return result; + } + + //校验mac地址 + if (!checkParams.getMacAddress().equals(Systemutils.getMacAddress())) { + result.put("Authorize", ValidateResult.error(ValidateCodeEnum.UNAUTHORIZED)); + return result; + } + //校验cpu序列号 + if (!checkParams.getCpuSerial().equals(Systemutils.getCpuNum())) { + result.put("Authorize", ValidateResult.error(ValidateCodeEnum.UNAUTHORIZED)); + return result; + } + long currentTi = System.currentTimeMillis(); + //校验时间 + if (notAfterLastValidateTime(checkParams.getLastValidateTime(), currentTi) || notAfter(checkParams.getGeneratedTime(), currentTi) + || notBefore(checkParams.getExpiredTime(), currentTi)) { + result.put("Authorize", ValidateResult.error(ValidateCodeEnum.EXPIRED)); + return result; + } + + result.put("Authorize", ValidateResult.ok()); + return result; + } + + public static String getSystemSign() { + String MacAddress = Systemutils.getMacAddress(); + String cpuNum = Systemutils.getCpuNum(); + return AESUtils.encrypt(MacAddress + "-" + cpuNum); + } + + + public static void updateSign(String sign) { + try { + Document document = readLicense(); + Element rootElement = document.getRootElement(); + Element signatureEle = rootElement.element("signature"); + signatureEle.setText(sign); + OutputFormat format = OutputFormat.createPrettyPrint(); + // 设置编码格式 + format.setEncoding("UTF-8"); + String path = System.getProperty("user.dir"); + FileWriter fileWriter = new FileWriter(new File(path + File.separator + "license.xml")); + XMLWriter xmlWriter = new XMLWriter(fileWriter, format); + // 设置是否转义,默认使用转义字符 + xmlWriter.setEscapeText(false); + xmlWriter.write(document); + xmlWriter.close(); + log.info("更新授权码成功"); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("更新授权码失败!"); + } + + } + + private static boolean notAfterLastValidateTime(long lastValidateTime, long currentTi) { + return lastValidateTime >= currentTi; + } + + private static boolean notBefore(Long expiredTime, long currentTi) { + return expiredTime <= currentTi; + } + + private static boolean notAfter(long generatedTime, long currentTi) { + return generatedTime >= currentTi; + } + + + private static CheckParams getCheckParams(Map result) { + //读取license文件 + Document document = readLicense(); + if (document == null) { + log.error("license 读取失败!"); + result.put("Authorize", ValidateResult.error(ValidateCodeEnum.FILE_NOT_EXIST)); + return null; + } + Element rootElement = document.getRootElement(); + Element dataEle = rootElement.element("features"); + List featuresEles = dataEle.elements(); + Element lastValidateTimeEle = featuresEles.get(0); + //提取上一次验证时间 + String lastValidateTimeStr = lastValidateTimeEle.attributeValue("ti"); + long lastValidateTime = Long.parseLong(AESUtils.decrypt(lastValidateTimeStr)); + log.debug("上一次校验时间:{}", lastValidateTime); + //提取签名内容 + Element signEle = rootElement.element("signature"); + String signStr = signEle.getText(); + String sign = AESUtils.decrypt(signStr); + if (sign == null) { + log.error("授权码不正确"); + result.put("Authorize", ValidateResult.error(ValidateCodeEnum.ILLEGAL)); + return null; + } + log.debug("签名内容:{}", sign); + String[] signArr = sign.split("-"); + if (signArr.length != 5) { + log.error("授权码不正确"); + result.put("Authorize", ValidateResult.error(ValidateCodeEnum.ILLEGAL)); + return null; + } + + CheckParams params = CheckParams.builder().lastValidateTime(lastValidateTime).macAddress(signArr[0]) + .cpuSerial(signArr[1]).generatedTime(Long.parseLong(signArr[2])).expiredTime(Long.parseLong(signArr[3])) + .version(signArr[4]).build(); + return params; + } + + private static Document readLicense() { + Document document = null; + try { + SAXReader saxReader = new SAXReader(); + String path = System.getProperty("user.dir"); + document = saxReader.read(new File(path + File.separator + "license.xml")); + return document; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + public static void main(String[] args) { +// String sign = AESUtils.decrypt("VorZodH/B6eeNLPA09TNJ8fpjlvrsckBk3VW3Pvr2qzhQVdeL38xS8unNFFxzQrjZ70f4wIoi1Tg1wlZq9DFKuVyp2zD20A//lDswyaD8NsmwMR72R2Ua+Gb0dp+PpM3b9gx2iIFIAtKOyaJlMMV8H4az/EKc/d733lyHfY3wbhsmo4vUvsqPYiriaj+psPu7DgO0DsQqw0xjAblpcrfL1xc42E3STEi9NTNbbBTsLU="); + + String s="PXVnqRD54Gd4f0cEECwqpL0KYlN40lDtUTQRhpSURSqYg+QzDF4/9mYLcu0JNMxsy1O5ZrsAhSLjNzf0TGO05w=="; + System.out.println(AESUtils.decrypt(s)); + } +} diff --git a/dcsoft-auth/src/main/java/com/dcsoft/auth/utils/LicenseThread.java b/dcsoft-auth/src/main/java/com/dcsoft/auth/utils/LicenseThread.java new file mode 100644 index 0000000..cdd53ec --- /dev/null +++ b/dcsoft-auth/src/main/java/com/dcsoft/auth/utils/LicenseThread.java @@ -0,0 +1,59 @@ +package com.dcsoft.auth.utils; + +import com.dcsoft.auth.bean.ValidateResult; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.stereotype.Component; + +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * @author penghao + * @createDate 2022/05/11 + * @createTime 16:42 + */ +@Component +@Slf4j +public class LicenseThread implements Runnable { + + public static Map validateResult = null; + + @Value("${license.checkTime}") + private Long checkTime; + + @Bean + public void startThread() { + Thread thread = new Thread(this); + thread.setDaemon(true); + thread.start(); + log.debug("license校验结果:"); + + } + + @Override + public void run() { + while (true) { + validateResult = LicenseManager.validate(); + if (validateResult != null) { + ValidateResult result = validateResult.get("Authorize"); + log.debug("license校验结果:" + result.getMessage()); + } + try { + //正式改为12个小时校验一次,保持与登录同步即可 +// TimeUnit.HOURS.sleep(12); + //测试1分钟校验一次 + TimeUnit.SECONDS.sleep(checkTime); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + public static boolean validateAfterUpdateSign() { + validateResult = LicenseManager.validate(); + ValidateResult result = validateResult.get("Authorize"); + return result != null && result.getIsValidate(); + } +} diff --git a/dcsoft-auth/src/main/java/com/dcsoft/auth/utils/RSAUtils.java b/dcsoft-auth/src/main/java/com/dcsoft/auth/utils/RSAUtils.java new file mode 100644 index 0000000..d8fb3c2 --- /dev/null +++ b/dcsoft-auth/src/main/java/com/dcsoft/auth/utils/RSAUtils.java @@ -0,0 +1,67 @@ +package com.dcsoft.auth.utils; +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import java.security.*; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; + +/** + * @Description 对AES密码加密 + * @createDate 2022/05/05 + * @createTime 14:28 + */ +public class RSAUtils { + + /** + * 公钥base64 + */ + private static String puk = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCdfujgTmG4aOa4oK2VysmKvAI+hurN/wuKQjzgJTo3ct6TH5NHFHncb9KXijC1xk2Po+pJ8UjU4XGjU4gq5yhTdeSYPYR6hj5jqLy8fkWpFzeC6RvM4bLDe1lDNKphpcUoo5ZO7T77w9fX2lgJSyy/8LxdBThc4Megga3KW1/W4wIDAQAB"; + + /** + * 加密 + * + * @return + * @throws Exception + */ + protected static String encrypt(String content) throws Exception { + + byte[] publicKeyBytes = puk.getBytes(); + X509EncodedKeySpec x = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyBytes)); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PublicKey pubKey = keyFactory.generatePublic(x); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, pubKey); + + byte[] result = cipher.doFinal(content.getBytes("UTF-8")); + return Base64.getEncoder().encodeToString(result); + } + + /** + * 私钥base64 + */ + private static String prk = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJ1+6OBOYbho5rigrZXKyYq8Aj6G6s3/C4pCPOAlOjdy3pMfk0cUedxv0peKMLXGTY+j6knxSNThcaNTiCrnKFN15Jg9hHqGPmOovLx+RakXN4LpG8zhssN7WUM0qmGlxSijlk7tPvvD19faWAlLLL/wvF0FOFzgx6CBrcpbX9bjAgMBAAECgYA8uRWohg//PdLXFHxY6JrUNrDW0sXtLoyQfgFimnfbsRpHt0DdgvOJHkQf0VP+gbqdyyEl6TWfflyGEErL39wX1rrosy+LpiN0HeISERJuwJtuiGeR+0qw+Xz2M7VE+e5oD94dRtlzERft2mcDbQAQYUCFNgUBtd1dCJgMJPZJYQJBANHxKKHqMbsH91JsGP8eCu+yeMah0X8cT79nwD71SJRc03W5P1MPKhRyGWJj0M+Wax32pAPCMTfbj19scLplJpUCQQDADD5OuSLYRVqx68/CYbFVK3ye/YD4Cgc+0kT9SoI9bLB10JumHT0seDGeXQqwUPAF3bBZGI8pW2bdtzDj8YGXAkABQXgEv+ncPIf2Lj9YB035cQ/X4E/oerrfYjd8KOtuN7/sDFecn5KY3LXaKM6u7y9k1nzUqOyycNXCtFtYQhKhAkBvgyxyvaFz/uFoyko6zksP705Pa1eFrx0B50pT4P26+O+FmXmnfPbWaXw2PkREmNqmLVGGinImS4JxXzuuP79FAkAFQejjE+5Twi8oSCcNwse7FFP86U6jgcc+S+XCUUkLXQ5SPlkyb037hwoV1lEEJpcyI2tSFRxBKT89KZN0Nfat"; + + protected static String decrypt(String signEncrypt) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { + byte[] privateKeyBytes = prk.getBytes(); + PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyBytes)); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PrivateKey priKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); + + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.DECRYPT_MODE, priKey); + + byte[] result = cipher.doFinal(Base64.getDecoder().decode(signEncrypt)); + return new String(result); + } + + public static void main(String[] args) throws Exception { + String password = "123456"; + String a = encrypt(password); + System.out.println("AES加密秘钥:" + a); + } +} + diff --git a/dcsoft-auth/src/main/java/com/dcsoft/auth/utils/Systemutils.java b/dcsoft-auth/src/main/java/com/dcsoft/auth/utils/Systemutils.java new file mode 100644 index 0000000..83df502 --- /dev/null +++ b/dcsoft-auth/src/main/java/com/dcsoft/auth/utils/Systemutils.java @@ -0,0 +1,102 @@ +package com.dcsoft.auth.utils; +import lombok.extern.slf4j.Slf4j; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.InetAddress; +import java.net.InterfaceAddress; +import java.net.NetworkInterface; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; +import java.util.stream.Collectors; + +/** + * @author penghao + */ +@Slf4j +public class Systemutils { + + protected static String getMacAddress() { + try { + java.util.Enumeration en = NetworkInterface.getNetworkInterfaces(); + StringBuilder sb = new StringBuilder(); + while (en.hasMoreElements()) { + NetworkInterface iface = en.nextElement(); + List addrs = iface.getInterfaceAddresses(); + for (InterfaceAddress addr : addrs) { + InetAddress ip = addr.getAddress(); + NetworkInterface network = NetworkInterface.getByInetAddress(ip); + if (network == null) { + continue; + } + if (network.getName().toLowerCase().startsWith("ens")) { + byte[] mac = network.getHardwareAddress(); + if (mac == null) { + continue; + } + for (int i = 0; i < mac.length; i++) { + sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : "")); + } + String xxy = sb.toString().replaceAll("-", "").toUpperCase(); + log.info("xxy地址:{}", xxy); + return xxy; + } + } + } + } catch (Exception e) { + e.printStackTrace(); + log.error("读取本机系统信息失败!"); + } + return null; + } + + protected static String getCpuNum() { + BufferedReader reader = null; + InputStreamReader ir = null; + try { + String[] linux = {"/bin/bash", "-c", "dmidecode -t processor | grep 'ID' | awk -F ':' '{print $2}' | head -n 1"}; + String[] windows = {"wmic", "cpu", "get", "ProcessorId"}; + + // 获取系统信息 + String property = System.getProperty("os.name"); + Process process = Runtime.getRuntime().exec(property.contains("Window") ? windows : linux); + process.getOutputStream().close(); + ir = new InputStreamReader(process.getInputStream()); + reader = new BufferedReader(ir); + String xxw = reader.readLine(); + if (xxw != null) { + xxw = xxw.replaceAll(" ", ""); + } + log.info("xxw识别码:{}", xxw); + return xxw; + } catch (Exception e) { + e.printStackTrace(); + log.error("获取系统信息失败!"); + } finally { + if (reader != null) { + try { + reader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (ir != null) { + try { + ir.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return null; + } + + public static void main(String[] args) throws Exception { +// List macs = getMacAddress(); +// System.out.println("本机的mac网卡的地址列表" + macs); + System.out.println(getCpuNum()); + } +} + diff --git a/dcsoft-auth/src/main/resources/banner.txt b/dcsoft-auth/src/main/resources/banner.txt new file mode 100644 index 0000000..c3813f6 --- /dev/null +++ b/dcsoft-auth/src/main/resources/banner.txt @@ -0,0 +1,7 @@ +Spring Boot Version: ${spring-boot.version} +Spring Application Name: ${spring.application.name} + + ___ ___ ___ ___ _ _ _____ _ _ + | \ / __| / __| ___ / \ | | | | |_ _| | || | + | |) | | (__ \__ \ |___| | - | | |_| | | | | __ | + |___/ \___| |___/ _____ |_|_| \___/ _|_|_ |_||_| diff --git a/dcsoft-auth/src/main/resources/bootstrap.yml b/dcsoft-auth/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..5d27380 --- /dev/null +++ b/dcsoft-auth/src/main/resources/bootstrap.yml @@ -0,0 +1,25 @@ +# Tomcat +server: + port: 9200 + +# Spring +spring: + application: + # 应用名称 + name: dcsoft-auth + profiles: + # 环境配置 + active: dev + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: 127.0.0.1:8848 + config: + # 配置中心地址 + server-addr: 127.0.0.1:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} diff --git a/dcsoft-auth/src/main/resources/lib/JWT-SDK-1.1.1_1.8.jar b/dcsoft-auth/src/main/resources/lib/JWT-SDK-1.1.1_1.8.jar new file mode 100644 index 0000000000000000000000000000000000000000..e7592fc2e42b068deff82fd35b974a3d3bb5b0d5 GIT binary patch literal 4711 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 z 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 p&$!{~85c->lVmzmJ+j-#cuM|3?G* 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 + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/info.log + + + + ${log.path}/info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/error.log + + + + ${log.path}/error.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + + + + + + + + + + + + + diff --git a/dcsoft-common/dcsoft-common-core/pom.xml b/dcsoft-common/dcsoft-common-core/pom.xml new file mode 100644 index 0000000..dfd0951 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/pom.xml @@ -0,0 +1,128 @@ + + + + com.dcsoft + dcsoft-common + 3.6.2 + + 4.0.0 + + dcsoft-common-core + + + dcsoft-common-core核心模块 + + + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + + + + + org.springframework + spring-context-support + + + + + org.springframework + spring-web + + + + + com.alibaba + transmittable-thread-local + + + + + com.github.pagehelper + pagehelper-spring-boot-starter + + + + + org.springframework.boot + spring-boot-starter-validation + + + + + com.fasterxml.jackson.core + jackson-databind + + + + + com.alibaba.fastjson2 + fastjson2 + + + + + io.jsonwebtoken + jjwt + + + + + javax.xml.bind + jaxb-api + + + + + org.apache.commons + commons-lang3 + + + + + commons-io + commons-io + + + + + org.apache.poi + poi-ooxml + + + + + javax.servlet + javax.servlet-api + + + + + io.swagger + swagger-annotations + + + + + cn.hutool + hutool-core + + + org.projectlombok + lombok + + + + + diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/annotation/Excel.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/annotation/Excel.java new file mode 100644 index 0000000..10f19f7 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/annotation/Excel.java @@ -0,0 +1,187 @@ +package com.dcsoft.common.core.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.math.BigDecimal; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.IndexedColors; +import com.dcsoft.common.core.utils.poi.ExcelHandlerAdapter; + +/** + * 自定义导出Excel数据注解 + * + * @author dcsoft + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface Excel +{ + /** + * 导出时在excel中排序 + */ + public int sort() default Integer.MAX_VALUE; + + /** + * 导出到Excel中的名字. + */ + public String name() default ""; + + /** + * 日期格式, 如: yyyy-MM-dd + */ + public String dateFormat() default ""; + + /** + * 读取内容转表达式 (如: 0=男,1=女,2=未知) + */ + public String readConverterExp() default ""; + + /** + * 如果是字典类型,请设置字典的type值 (如: sys_user_sex) + */ + public String dictType() default ""; + + /** + * 分隔符,读取字符串组内容 + */ + public String separator() default ","; + + /** + * BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化) + */ + public int scale() default -1; + + /** + * BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN + */ + public int roundingMode() default BigDecimal.ROUND_HALF_EVEN; + + /** + * 导出时在excel中每个列的高度 单位为字符 + */ + public double height() default 14; + + /** + * 导出时在excel中每个列的宽 单位为字符 + */ + public double width() default 16; + + /** + * 文字后缀,如% 90 变成90% + */ + public String suffix() default ""; + + /** + * 当值为空时,字段的默认值 + */ + public String defaultValue() default ""; + + /** + * 提示信息 + */ + public String prompt() default ""; + + /** + * 设置只能选择不能输入的列内容. + */ + public String[] combo() default {}; + + /** + * 是否需要纵向合并单元格,应对需求:含有list集合单元格) + */ + public boolean needMerge() default false; + + /** + * 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写. + */ + public boolean isExport() default true; + + /** + * 另一个类中的属性名称,支持多级获取,以小数点隔开 + */ + public String targetAttr() default ""; + + /** + * 是否自动统计数据,在最后追加一行统计数据总和 + */ + public boolean isStatistics() default false; + + /** + * 导出类型(0数字 1字符串) + */ + public ColumnType cellType() default ColumnType.STRING; + + /** + * 导出列头背景色 + */ + public IndexedColors headerBackgroundColor() default IndexedColors.GREY_50_PERCENT; + + /** + * 导出列头字体颜色 + */ + public IndexedColors headerColor() default IndexedColors.WHITE; + + /** + * 导出单元格背景色 + */ + public IndexedColors backgroundColor() default IndexedColors.WHITE; + + /** + * 导出单元格字体颜色 + */ + public IndexedColors color() default IndexedColors.BLACK; + + /** + * 导出字段对齐方式 + */ + public HorizontalAlignment align() default HorizontalAlignment.CENTER; + + /** + * 自定义数据处理器 + */ + public Class handler() default ExcelHandlerAdapter.class; + + /** + * 自定义数据处理器参数 + */ + public String[] args() default {}; + + /** + * 字段类型(0:导出导入;1:仅导出;2:仅导入) + */ + Type type() default Type.ALL; + + public enum Type + { + ALL(0), EXPORT(1), IMPORT(2); + private final int value; + + Type(int value) + { + this.value = value; + } + + public int value() + { + return this.value; + } + } + + public enum ColumnType + { + NUMERIC(0), STRING(1), IMAGE(2); + private final int value; + + ColumnType(int value) + { + this.value = value; + } + + public int value() + { + return this.value; + } + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/annotation/Excels.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/annotation/Excels.java new file mode 100644 index 0000000..f3d9ed0 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/annotation/Excels.java @@ -0,0 +1,18 @@ +package com.dcsoft.common.core.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Excel注解集 + * + * @author dcsoft + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Excels +{ + Excel[] value(); +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/CacheConstants.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/CacheConstants.java new file mode 100644 index 0000000..1540ab7 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/CacheConstants.java @@ -0,0 +1,75 @@ +package com.dcsoft.common.core.constant; + +/** + * 缓存常量信息 + * + * @author dcsoft + */ +public class CacheConstants +{ + /** + * 缓存有效期,默认720(分钟) + */ + public final static long EXPIRATION = 720; + + /** + * 缓存刷新时间,默认120(分钟) + */ + public final static long REFRESH_TIME = 120; + + /** + * 密码最大错误次数 + */ + public final static int PASSWORD_MAX_RETRY_COUNT = 5; + + /** + * 密码锁定时间,默认10(分钟) + */ + public final static long PASSWORD_LOCK_TIME = 10; + + /** + * 权限缓存前缀 + */ + public final static String LOGIN_TOKEN_KEY = "login_tokens:"; + + /** + * 验证码 redis key + */ + public static final String CAPTCHA_CODE_KEY = "captcha_codes:"; + + /** + * 参数管理 cache key + */ + public static final String SYS_CONFIG_KEY = "sys_config:"; + + /** + * 字典管理 cache key + */ + public static final String SYS_DICT_KEY = "sys_dict:"; + + /** + * 登录账户密码错误次数 redis key + */ + public static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:"; + + /** + * 登录IP黑名单 cache key + */ + public static final String SYS_LOGIN_BLACKIPLIST = SYS_CONFIG_KEY + "sys.login.blackIPList"; + + /** UNIUNBI redis key */ + public static final String AUTH_KEY = "auth_codes:"; + + /** 微信 redis key */ + public static final String WX_KEY = "weixin_code:"; + + public static final String LOGIN_TOKEN = "redis_login_token:"; + + public static final String WEIXIN_TOKEN = "weixin_token:"; + + public static final String WEIXIN_APPLET_TOKEN = "weixin_applet_token:"; + + public static final String WEIXIN_URL_LINK = "weixin_url_link"; + + public static final String WE_COM_TOKEN = "we_com_token:"; +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/Constants.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/Constants.java new file mode 100644 index 0000000..84e6324 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/Constants.java @@ -0,0 +1,220 @@ +package com.dcsoft.common.core.constant; + +/** + * 通用常量信息 + * + * @author dcsoft + */ +public class Constants +{ + /** + * UTF-8 字符集 + */ + public static final String UTF8 = "UTF-8"; + + /** + * GBK 字符集 + */ + public static final String GBK = "GBK"; + + /** + * www主域 + */ + public static final String WWW = "www."; + + /** + * RMI 远程方法调用 + */ + public static final String LOOKUP_RMI = "rmi:"; + + /** + * LDAP 远程方法调用 + */ + public static final String LOOKUP_LDAP = "ldap:"; + + /** + * LDAPS 远程方法调用 + */ + public static final String LOOKUP_LDAPS = "ldaps:"; + + /** + * http请求 + */ + public static final String HTTP = "http://"; + + /** + * https请求 + */ + public static final String HTTPS = "https://"; + + /** + * 成功标记 + */ + public static final Integer SUCCESS = 200; + + /** + * 失败标记 + */ + public static final Integer FAIL = 500; + + /** + * 登录成功状态 + */ + public static final String LOGIN_SUCCESS_STATUS = "0"; + + /** + * 登录失败状态 + */ + public static final String LOGIN_FAIL_STATUS = "1"; + + /** + * 登录成功 + */ + public static final String LOGIN_SUCCESS = "Success"; + + /** + * 注销 + */ + public static final String LOGOUT = "Logout"; + + /** + * 注册 + */ + public static final String REGISTER = "Register"; + + /** + * 登录失败 + */ + public static final String LOGIN_FAIL = "Error"; + + /** + * 当前记录起始索引 + */ + public static final String PAGE_NUM = "pageNum"; + + /** + * 每页显示记录数 + */ + public static final String PAGE_SIZE = "pageSize"; + + /** + * 排序列 + */ + public static final String ORDER_BY_COLUMN = "orderByColumn"; + + /** + * 排序的方向 "desc" 或者 "asc". + */ + public static final String IS_ASC = "isAsc"; + + /** + * 验证码有效期(分钟) + */ + public static final long CAPTCHA_EXPIRATION = 2; + + /** + * 资源映射路径 前缀 + */ + public static final String RESOURCE_PREFIX = "/profile"; + + /** + * 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加) + */ + public static final String[] JOB_WHITELIST_STR = { "com.dcsoft" }; + + /** + * 定时任务违规的字符 + */ + public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml", + "org.springframework", "org.apache", "com.dcsoft.common.core.utils.file" }; + + + /** + * 0 + */ + public static final String ZERO = "0"; + + /** + * 1 + */ + public static final String ONE = "1"; + + /** + * 2 + */ + public static final String TWO = "2"; + + /** + * 5 + */ + public static final String FIVE = "5"; + + /** + * 200 + */ + public static final String CODE = "200"; + + /** + * OK + */ + public static final String OK = "ok"; + + /** + * 宇泛门禁设备开关门状态1开门 + */ + public static final Integer ACCESS_CONTROL_ONE = 1; + + /** + * 宇泛门禁设备开关门状态2关门 + */ + public static final Integer ACCESS_CONTROL_TWO = 2; + + /** + * + */ + public static final String TTS_MOD_CONTENT = "未授权,请联系管理员"; + + /** + * + */ + public static final String DISPLAY_MOD_CONTENT = "未授权,请联系管理员"; + + /** + * 梯控结束时间 + */ + public static final String END_TIME = "2099-12-31 23:59:59"; + + /** + * 梯控起始可用时间 + */ + public static final String START_DAY_TIME = "00:00:00"; + + /** + * 梯控结束可用时间 + */ + public static final String END_DAY_TIME = "23:59:59"; + + /** + * 梯控星期 + */ + public static final String WEEK = "1 1 1 1 1 1 1"; + + public static final String CONTENT = "{\n" + + " \"touser\": \"%\", \n" + + " \"template_id\": \"wODO_BDj8n1grelUSGTNvpZbSnFdhzC3odWHek0brSM\",\n" + + " \"url\": \"#\",\n" + + " \"data\": {\n" + + " \"first\": {\n" + + " \"value\": \"广州腾讯科技有限公司\"\n" + + " },\n" + + " \"keyword1\": {\n" + + " \"value\": \"广州腾讯科技有限公司\"\n" + + " },\n" + + " \"keyword2\": {\n" + + " \"value\": \"2019年8月8日\"\n" + + " }\n" + + " }\n" + + "}"; + + +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/GenConstants.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/GenConstants.java new file mode 100644 index 0000000..6feea53 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/GenConstants.java @@ -0,0 +1,117 @@ +package com.dcsoft.common.core.constant; + +/** + * 代码生成通用常量 + * + * @author dcsoft + */ +public class GenConstants +{ + /** 单表(增删改查) */ + public static final String TPL_CRUD = "crud"; + + /** 树表(增删改查) */ + public static final String TPL_TREE = "tree"; + + /** 主子表(增删改查) */ + public static final String TPL_SUB = "sub"; + + /** 树编码字段 */ + public static final String TREE_CODE = "treeCode"; + + /** 树父编码字段 */ + public static final String TREE_PARENT_CODE = "treeParentCode"; + + /** 树名称字段 */ + public static final String TREE_NAME = "treeName"; + + /** 上级菜单ID字段 */ + public static final String PARENT_MENU_ID = "parentMenuId"; + + /** 上级菜单名称字段 */ + public static final String PARENT_MENU_NAME = "parentMenuName"; + + /** 数据库字符串类型 */ + public static final String[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", "varchar2" }; + + /** 数据库文本类型 */ + public static final String[] COLUMNTYPE_TEXT = { "tinytext", "text", "mediumtext", "longtext" }; + + /** 数据库时间类型 */ + public static final String[] COLUMNTYPE_TIME = { "datetime", "time", "date", "timestamp" }; + + /** 数据库数字类型 */ + public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer", + "bigint", "float", "double", "decimal" }; + + /** 页面不需要编辑字段 */ + public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" }; + + /** 页面不需要显示的列表字段 */ + public static final String[] COLUMNNAME_NOT_LIST = { "id", "create_by", "create_time", "del_flag", "update_by", + "update_time" }; + + /** 页面不需要查询字段 */ + public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", "del_flag", "update_by", + "update_time", "remark" }; + + /** Entity基类字段 */ + public static final String[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime", "remark" }; + + /** Tree基类字段 */ + public static final String[] TREE_ENTITY = { "parentName", "parentId", "orderNum", "ancestors" }; + + /** 文本框 */ + public static final String HTML_INPUT = "input"; + + /** 文本域 */ + public static final String HTML_TEXTAREA = "textarea"; + + /** 下拉框 */ + public static final String HTML_SELECT = "select"; + + /** 单选框 */ + public static final String HTML_RADIO = "radio"; + + /** 复选框 */ + public static final String HTML_CHECKBOX = "checkbox"; + + /** 日期控件 */ + public static final String HTML_DATETIME = "datetime"; + + /** 图片上传控件 */ + public static final String HTML_IMAGE_UPLOAD = "imageUpload"; + + /** 文件上传控件 */ + public static final String HTML_FILE_UPLOAD = "fileUpload"; + + /** 富文本控件 */ + public static final String HTML_EDITOR = "editor"; + + /** 字符串类型 */ + public static final String TYPE_STRING = "String"; + + /** 整型 */ + public static final String TYPE_INTEGER = "Integer"; + + /** 长整型 */ + public static final String TYPE_LONG = "Long"; + + /** 浮点型 */ + public static final String TYPE_DOUBLE = "Double"; + + /** 高精度计算类型 */ + public static final String TYPE_BIGDECIMAL = "BigDecimal"; + + /** 时间类型 */ + public static final String TYPE_DATE = "Date"; + + /** 模糊查询 */ + public static final String QUERY_LIKE = "LIKE"; + + /** 相等查询 */ + public static final String QUERY_EQ = "EQ"; + + /** 需要 */ + public static final String REQUIRE = "1"; +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/HttpStatus.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/HttpStatus.java new file mode 100644 index 0000000..fdebee9 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/HttpStatus.java @@ -0,0 +1,94 @@ +package com.dcsoft.common.core.constant; + +/** + * 返回状态码 + * + * @author dcsoft + */ +public class HttpStatus +{ + /** + * 操作成功 + */ + public static final int SUCCESS = 200; + + /** + * 对象创建成功 + */ + public static final int CREATED = 201; + + /** + * 请求已经被接受 + */ + public static final int ACCEPTED = 202; + + /** + * 操作已经执行成功,但是没有返回数据 + */ + public static final int NO_CONTENT = 204; + + /** + * 资源已被移除 + */ + public static final int MOVED_PERM = 301; + + /** + * 重定向 + */ + public static final int SEE_OTHER = 303; + + /** + * 资源没有被修改 + */ + public static final int NOT_MODIFIED = 304; + + /** + * 参数列表错误(缺少,格式不匹配) + */ + public static final int BAD_REQUEST = 400; + + /** + * 未授权 + */ + public static final int UNAUTHORIZED = 401; + + /** + * 访问受限,授权过期 + */ + public static final int FORBIDDEN = 403; + + /** + * 资源,服务未找到 + */ + public static final int NOT_FOUND = 404; + + /** + * 不允许的http方法 + */ + public static final int BAD_METHOD = 405; + + /** + * 资源冲突,或者资源被锁 + */ + public static final int CONFLICT = 409; + + /** + * 不支持的数据,媒体类型 + */ + public static final int UNSUPPORTED_TYPE = 415; + + /** + * 系统内部错误 + */ + public static final int ERROR = 500; + + /** + * 接口未实现 + */ + public static final int NOT_IMPLEMENTED = 501; + + /** + * 系统警告消息 + */ + public static final int WARN = 601; +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/ScheduleConstants.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/ScheduleConstants.java new file mode 100644 index 0000000..cd90780 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/ScheduleConstants.java @@ -0,0 +1,50 @@ +package com.dcsoft.common.core.constant; + +/** + * 任务调度通用常量 + * + * @author dcsoft + */ +public class ScheduleConstants +{ + public static final String TASK_CLASS_NAME = "TASK_CLASS_NAME"; + + /** 执行目标key */ + public static final String TASK_PROPERTIES = "TASK_PROPERTIES"; + + /** 默认 */ + public static final String MISFIRE_DEFAULT = "0"; + + /** 立即触发执行 */ + public static final String MISFIRE_IGNORE_MISFIRES = "1"; + + /** 触发一次执行 */ + public static final String MISFIRE_FIRE_AND_PROCEED = "2"; + + /** 不触发立即执行 */ + public static final String MISFIRE_DO_NOTHING = "3"; + + public enum Status + { + /** + * 正常 + */ + NORMAL("0"), + /** + * 暂停 + */ + PAUSE("1"); + + private String value; + + private Status(String value) + { + this.value = value; + } + + public String getValue() + { + return value; + } + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/SecurityConstants.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/SecurityConstants.java new file mode 100644 index 0000000..0f439ca --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/SecurityConstants.java @@ -0,0 +1,49 @@ +package com.dcsoft.common.core.constant; + +/** + * 权限相关通用常量 + * + * @author dcsoft + */ +public class SecurityConstants +{ + /** + * 用户ID字段 + */ + public static final String DETAILS_USER_ID = "user_id"; + + /** + * 用户名字段 + */ + public static final String DETAILS_USERNAME = "username"; + + /** + * 授权信息字段 + */ + public static final String AUTHORIZATION_HEADER = "authorization"; + + /** + * 请求来源 + */ + public static final String FROM_SOURCE = "from-source"; + + /** + * 内部请求 + */ + public static final String INNER = "inner"; + + /** + * 用户标识 + */ + public static final String USER_KEY = "user_key"; + + /** + * 登录用户 + */ + public static final String LOGIN_USER = "login_user"; + + /** + * 角色权限 + */ + public static final String ROLE_PERMISSION = "role_permission"; +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/ServiceNameConstants.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/ServiceNameConstants.java new file mode 100644 index 0000000..10d4b6b --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/ServiceNameConstants.java @@ -0,0 +1,24 @@ +package com.dcsoft.common.core.constant; + +/** + * 服务名称 + * + * @author dcsoft + */ +public class ServiceNameConstants +{ + /** + * 认证服务的serviceid + */ + public static final String AUTH_SERVICE = "dcsoft-auth"; + + /** + * 系统模块的serviceid + */ + public static final String SYSTEM_SERVICE = "dcsoft-system"; + + /** + * 文件服务的serviceid + */ + public static final String FILE_SERVICE = "dcsoft-file"; +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/TokenConstants.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/TokenConstants.java new file mode 100644 index 0000000..eae02ca --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/TokenConstants.java @@ -0,0 +1,25 @@ +package com.dcsoft.common.core.constant; + +/** + * Token的Key常量 + * + * @author dcsoft + */ +public class TokenConstants +{ + /** + * 令牌自定义标识 + */ + public static final String AUTHENTICATION = "Authorization"; + + /** + * 令牌前缀 + */ + public static final String PREFIX = "Bearer "; + + /** + * 令牌秘钥 + */ + public final static String SECRET = "abcdefghijklmnopqrstuvwxyz"; + +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/UserConstants.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/UserConstants.java new file mode 100644 index 0000000..0175e99 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/constant/UserConstants.java @@ -0,0 +1,80 @@ +package com.dcsoft.common.core.constant; + +/** + * 用户常量信息 + * + * @author dcsoft + */ +public class UserConstants +{ + /** + * 平台内系统用户的唯一标志 + */ + public static final String SYS_USER = "SYS_USER"; + + /** 正常状态 */ + public static final String NORMAL = "0"; + + /** 异常状态 */ + public static final String EXCEPTION = "1"; + + /** 用户封禁状态 */ + public static final String USER_DISABLE = "1"; + + /** 角色封禁状态 */ + public static final String ROLE_DISABLE = "1"; + + /** 部门正常状态 */ + public static final String DEPT_NORMAL = "0"; + + /** 部门停用状态 */ + public static final String DEPT_DISABLE = "1"; + + /** 字典正常状态 */ + public static final String DICT_NORMAL = "0"; + + /** 是否为系统默认(是) */ + public static final String YES = "Y"; + + /** 是否菜单外链(是) */ + public static final String YES_FRAME = "0"; + + /** 是否菜单外链(否) */ + public static final String NO_FRAME = "1"; + + /** 菜单类型(目录) */ + public static final String TYPE_DIR = "M"; + + /** 菜单类型(菜单) */ + public static final String TYPE_MENU = "C"; + + /** 菜单类型(按钮) */ + public static final String TYPE_BUTTON = "F"; + + /** Layout组件标识 */ + public final static String LAYOUT = "Layout"; + + /** ParentView组件标识 */ + public final static String PARENT_VIEW = "ParentView"; + + /** InnerLink组件标识 */ + public final static String INNER_LINK = "InnerLink"; + + /** 校验是否唯一的返回标识 */ + public final static boolean UNIQUE = true; + public final static boolean NOT_UNIQUE = false; + + /** + * 用户名长度限制 + */ + public static final int USERNAME_MIN_LENGTH = 2; + + public static final int USERNAME_MAX_LENGTH = 20; + + /** + * 密码长度限制 + */ + public static final int PASSWORD_MIN_LENGTH = 5; + + public static final int PASSWORD_MAX_LENGTH = 20; +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/context/SecurityContextHolder.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/context/SecurityContextHolder.java new file mode 100644 index 0000000..f0b50a0 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/context/SecurityContextHolder.java @@ -0,0 +1,98 @@ +package com.dcsoft.common.core.context; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import com.alibaba.ttl.TransmittableThreadLocal; +import com.dcsoft.common.core.constant.SecurityConstants; +import com.dcsoft.common.core.text.Convert; +import com.dcsoft.common.core.utils.StringUtils; + +/** + * 获取当前线程变量中的 用户id、用户名称、Token等信息 + * 注意: 必须在网关通过请求头的方法传入,同时在HeaderInterceptor拦截器设置值。 否则这里无法获取 + * + * @author dcsoft + */ +public class SecurityContextHolder +{ + private static final TransmittableThreadLocal> THREAD_LOCAL = new TransmittableThreadLocal<>(); + + public static void set(String key, Object value) + { + Map map = getLocalMap(); + map.put(key, value == null ? StringUtils.EMPTY : value); + } + + public static String get(String key) + { + Map map = getLocalMap(); + return Convert.toStr(map.getOrDefault(key, StringUtils.EMPTY)); + } + + public static T get(String key, Class clazz) + { + Map map = getLocalMap(); + return StringUtils.cast(map.getOrDefault(key, null)); + } + + public static Map getLocalMap() + { + Map map = THREAD_LOCAL.get(); + if (map == null) + { + map = new ConcurrentHashMap(); + THREAD_LOCAL.set(map); + } + return map; + } + + public static void setLocalMap(Map threadLocalMap) + { + THREAD_LOCAL.set(threadLocalMap); + } + + public static Long getUserId() + { + return Convert.toLong(get(SecurityConstants.DETAILS_USER_ID), 0L); + } + + public static void setUserId(String account) + { + set(SecurityConstants.DETAILS_USER_ID, account); + } + + public static String getUserName() + { + return get(SecurityConstants.DETAILS_USERNAME); + } + + public static void setUserName(String username) + { + set(SecurityConstants.DETAILS_USERNAME, username); + } + + public static String getUserKey() + { + return get(SecurityConstants.USER_KEY); + } + + public static void setUserKey(String userKey) + { + set(SecurityConstants.USER_KEY, userKey); + } + + public static String getPermission() + { + return get(SecurityConstants.ROLE_PERMISSION); + } + + public static void setPermission(String permissions) + { + set(SecurityConstants.ROLE_PERMISSION, permissions); + } + + public static void remove() + { + THREAD_LOCAL.remove(); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/domain/R.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/domain/R.java new file mode 100644 index 0000000..8335484 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/domain/R.java @@ -0,0 +1,115 @@ +package com.dcsoft.common.core.domain; + +import java.io.Serializable; +import com.dcsoft.common.core.constant.Constants; + +/** + * 响应信息主体 + * + * @author dcsoft + */ +public class R implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 成功 */ + public static final int SUCCESS = Constants.SUCCESS; + + /** 失败 */ + public static final int FAIL = Constants.FAIL; + + private int code; + + private String msg; + + private T data; + + public static R ok() + { + return restResult(null, SUCCESS, null); + } + + public static R ok(T data) + { + return restResult(data, SUCCESS, null); + } + + public static R ok(T data, String msg) + { + return restResult(data, SUCCESS, msg); + } + + public static R fail() + { + return restResult(null, FAIL, null); + } + + public static R fail(String msg) + { + return restResult(null, FAIL, msg); + } + + public static R fail(T data) + { + return restResult(data, FAIL, null); + } + + public static R fail(T data, String msg) + { + return restResult(data, FAIL, msg); + } + + public static R fail(int code, String msg) + { + return restResult(null, code, msg); + } + + private static R restResult(T data, int code, String msg) + { + R apiResult = new R<>(); + apiResult.setCode(code); + apiResult.setData(data); + apiResult.setMsg(msg); + return apiResult; + } + + public int getCode() + { + return code; + } + + public void setCode(int code) + { + this.code = code; + } + + public String getMsg() + { + return msg; + } + + public void setMsg(String msg) + { + this.msg = msg; + } + + public T getData() + { + return data; + } + + public void setData(T data) + { + this.data = data; + } + + public static Boolean isError(R ret) + { + return !isSuccess(ret); + } + + public static Boolean isSuccess(R ret) + { + return R.SUCCESS == ret.getCode(); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/enums/CompanyType.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/enums/CompanyType.java new file mode 100644 index 0000000..cac4835 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/enums/CompanyType.java @@ -0,0 +1,29 @@ +package com.dcsoft.common.core.enums; + +/** + * 园区/公司类型 + * + * @author dcsoft + */ +public enum CompanyType { + HEADQUARTERS("1", "总部"), + TD_PARK("2", "田东园区"), + XA_PARK("3", "兴安化工厂") + ; + + CompanyType(String code, String name) { + this.code = code; + this.name = name; + } + + private String code; + private String name; + + public String getCode() { + return code; + } + + public String getValue() { + return name; + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/enums/UserStatus.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/enums/UserStatus.java new file mode 100644 index 0000000..d0c650a --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/enums/UserStatus.java @@ -0,0 +1,30 @@ +package com.dcsoft.common.core.enums; + +/** + * 用户状态 + * + * @author dcsoft + */ +public enum UserStatus +{ + OK("0", "正常"), DISABLE("1", "停用"), DELETED("2", "删除"); + + private final String code; + private final String info; + + UserStatus(String code, String info) + { + this.code = code; + this.info = info; + } + + public String getCode() + { + return code; + } + + public String getInfo() + { + return info; + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/enums/exception/CommonExceptionEnum.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/enums/exception/CommonExceptionEnum.java new file mode 100644 index 0000000..586b63b --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/enums/exception/CommonExceptionEnum.java @@ -0,0 +1,27 @@ +package com.dcsoft.common.core.enums.exception; + +public enum CommonExceptionEnum { + RULE_ERROR(1000, "您所所在得部门所属规则未绑定设备"), + REQUEST_ERROR(1001, "请求异常"), + PEOPLE_ERROR(1002, "您的信息未录入"), + QR_CODE_ERROR(1003, "二维码过期"), + DEVICE_INITIALIZE_ERROR(1004, "设备序列号不能为空"), + ; + + private Integer errCode; + private String errMsg; + + CommonExceptionEnum(Integer errCode, String errMsg) { + this.errCode = errCode; + this.errMsg = errMsg; + } + + + public Integer getCode() { + return errCode; + } + + public String getMessage() { + return errMsg; + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/CaptchaException.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/CaptchaException.java new file mode 100644 index 0000000..4899522 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/CaptchaException.java @@ -0,0 +1,16 @@ +package com.dcsoft.common.core.exception; + +/** + * 验证码错误异常类 + * + * @author dcsoft + */ +public class CaptchaException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public CaptchaException(String msg) + { + super(msg); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/CheckedException.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/CheckedException.java new file mode 100644 index 0000000..c5bdf9f --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/CheckedException.java @@ -0,0 +1,31 @@ +package com.dcsoft.common.core.exception; + +/** + * 检查异常 + * + * @author dcsoft + */ +public class CheckedException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public CheckedException(String message) + { + super(message); + } + + public CheckedException(Throwable cause) + { + super(cause); + } + + public CheckedException(String message, Throwable cause) + { + super(message, cause); + } + + public CheckedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) + { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/DemoModeException.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/DemoModeException.java new file mode 100644 index 0000000..4b6f13a --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/DemoModeException.java @@ -0,0 +1,15 @@ +package com.dcsoft.common.core.exception; + +/** + * 演示模式异常 + * + * @author dcsoft + */ +public class DemoModeException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public DemoModeException() + { + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/GlobalException.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/GlobalException.java new file mode 100644 index 0000000..81740f4 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/GlobalException.java @@ -0,0 +1,58 @@ +package com.dcsoft.common.core.exception; + +/** + * 全局异常 + * + * @author dcsoft + */ +public class GlobalException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + /** + * 错误提示 + */ + private String message; + + /** + * 错误明细,内部调试错误 + * + * 和 {@link CommonResult#getDetailMessage()} 一致的设计 + */ + private String detailMessage; + + /** + * 空构造方法,避免反序列化问题 + */ + public GlobalException() + { + } + + public GlobalException(String message) + { + this.message = message; + } + + public String getDetailMessage() + { + return detailMessage; + } + + public GlobalException setDetailMessage(String detailMessage) + { + this.detailMessage = detailMessage; + return this; + } + + @Override + public String getMessage() + { + return message; + } + + public GlobalException setMessage(String message) + { + this.message = message; + return this; + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/InnerAuthException.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/InnerAuthException.java new file mode 100644 index 0000000..4fa99ef --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/InnerAuthException.java @@ -0,0 +1,16 @@ +package com.dcsoft.common.core.exception; + +/** + * 内部认证异常 + * + * @author dcsoft + */ +public class InnerAuthException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public InnerAuthException(String message) + { + super(message); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/PreAuthorizeException.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/PreAuthorizeException.java new file mode 100644 index 0000000..e6003fa --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/PreAuthorizeException.java @@ -0,0 +1,15 @@ +package com.dcsoft.common.core.exception; + +/** + * 权限异常 + * + * @author dcsoft + */ +public class PreAuthorizeException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public PreAuthorizeException() + { + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/ServiceException.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/ServiceException.java new file mode 100644 index 0000000..221b531 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/ServiceException.java @@ -0,0 +1,74 @@ +package com.dcsoft.common.core.exception; + +/** + * 业务异常 + * + * @author dcsoft + */ +public final class ServiceException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + /** + * 错误码 + */ + private Integer code; + + /** + * 错误提示 + */ + private String message; + + /** + * 错误明细,内部调试错误 + * + * 和 {@link CommonResult#getDetailMessage()} 一致的设计 + */ + private String detailMessage; + + /** + * 空构造方法,避免反序列化问题 + */ + public ServiceException() + { + } + + public ServiceException(String message) + { + this.message = message; + } + + public ServiceException(Integer code, String message) + { + this.message = message; + this.code = code; + } + + public String getDetailMessage() + { + return detailMessage; + } + + @Override + public String getMessage() + { + return message; + } + + public Integer getCode() + { + return code; + } + + public ServiceException setMessage(String message) + { + this.message = message; + return this; + } + + public ServiceException setDetailMessage(String detailMessage) + { + this.detailMessage = detailMessage; + return this; + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/UtilException.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/UtilException.java new file mode 100644 index 0000000..29c8f2d --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/UtilException.java @@ -0,0 +1,26 @@ +package com.dcsoft.common.core.exception; + +/** + * 工具类异常 + * + * @author dcsoft + */ +public class UtilException extends RuntimeException +{ + private static final long serialVersionUID = 8247610319171014183L; + + public UtilException(Throwable e) + { + super(e.getMessage(), e); + } + + public UtilException(String message) + { + super(message); + } + + public UtilException(String message, Throwable throwable) + { + super(message, throwable); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/auth/NotLoginException.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/auth/NotLoginException.java new file mode 100644 index 0000000..d30bac4 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/auth/NotLoginException.java @@ -0,0 +1,16 @@ +package com.dcsoft.common.core.exception.auth; + +/** + * 未能通过的登录认证异常 + * + * @author dcsoft + */ +public class NotLoginException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public NotLoginException(String message) + { + super(message); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/auth/NotPermissionException.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/auth/NotPermissionException.java new file mode 100644 index 0000000..e804244 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/auth/NotPermissionException.java @@ -0,0 +1,23 @@ +package com.dcsoft.common.core.exception.auth; + +import org.apache.commons.lang3.StringUtils; + +/** + * 未能通过的权限认证异常 + * + * @author dcsoft + */ +public class NotPermissionException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public NotPermissionException(String permission) + { + super(permission); + } + + public NotPermissionException(String[] permissions) + { + super(StringUtils.join(permissions, ",")); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/auth/NotRoleException.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/auth/NotRoleException.java new file mode 100644 index 0000000..665b0d0 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/auth/NotRoleException.java @@ -0,0 +1,23 @@ +package com.dcsoft.common.core.exception.auth; + +import org.apache.commons.lang3.StringUtils; + +/** + * 未能通过的角色认证异常 + * + * @author dcsoft + */ +public class NotRoleException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public NotRoleException(String role) + { + super(role); + } + + public NotRoleException(String[] roles) + { + super(StringUtils.join(roles, ",")); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/base/BaseException.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/base/BaseException.java new file mode 100644 index 0000000..eab6234 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/base/BaseException.java @@ -0,0 +1,79 @@ +package com.dcsoft.common.core.exception.base; + +/** + * 基础异常 + * + * @author dcsoft + */ +public class BaseException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + /** + * 所属模块 + */ + private String module; + + /** + * 错误码 + */ + private String code; + + /** + * 错误码对应的参数 + */ + private Object[] args; + + /** + * 错误消息 + */ + private String defaultMessage; + + public BaseException(String module, String code, Object[] args, String defaultMessage) + { + this.module = module; + this.code = code; + this.args = args; + this.defaultMessage = defaultMessage; + } + + public BaseException(String module, String code, Object[] args) + { + this(module, code, args, null); + } + + public BaseException(String module, String defaultMessage) + { + this(module, null, null, defaultMessage); + } + + public BaseException(String code, Object[] args) + { + this(null, code, args, null); + } + + public BaseException(String defaultMessage) + { + this(null, null, null, defaultMessage); + } + + public String getModule() + { + return module; + } + + public String getCode() + { + return code; + } + + public Object[] getArgs() + { + return args; + } + + public String getDefaultMessage() + { + return defaultMessage; + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/file/FileException.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/file/FileException.java new file mode 100644 index 0000000..a009ba4 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/file/FileException.java @@ -0,0 +1,19 @@ +package com.dcsoft.common.core.exception.file; + +import com.dcsoft.common.core.exception.base.BaseException; + +/** + * 文件信息异常类 + * + * @author dcsoft + */ +public class FileException extends BaseException +{ + private static final long serialVersionUID = 1L; + + public FileException(String code, Object[] args) + { + super("file", code, args, null); + } + +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/file/FileNameLengthLimitExceededException.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/file/FileNameLengthLimitExceededException.java new file mode 100644 index 0000000..28d8d64 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/file/FileNameLengthLimitExceededException.java @@ -0,0 +1,16 @@ +package com.dcsoft.common.core.exception.file; + +/** + * 文件名称超长限制异常类 + * + * @author dcsoft + */ +public class FileNameLengthLimitExceededException extends FileException +{ + private static final long serialVersionUID = 1L; + + public FileNameLengthLimitExceededException(int defaultFileNameLength) + { + super("upload.filename.exceed.length", new Object[] { defaultFileNameLength }); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/file/FileSizeLimitExceededException.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/file/FileSizeLimitExceededException.java new file mode 100644 index 0000000..cac3442 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/file/FileSizeLimitExceededException.java @@ -0,0 +1,16 @@ +package com.dcsoft.common.core.exception.file; + +/** + * 文件名大小限制异常类 + * + * @author dcsoft + */ +public class FileSizeLimitExceededException extends FileException +{ + private static final long serialVersionUID = 1L; + + public FileSizeLimitExceededException(long defaultMaxSize) + { + super("upload.exceed.maxSize", new Object[] { defaultMaxSize }); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/file/FileUploadException.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/file/FileUploadException.java new file mode 100644 index 0000000..115c172 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/file/FileUploadException.java @@ -0,0 +1,61 @@ +package com.dcsoft.common.core.exception.file; + +import java.io.PrintStream; +import java.io.PrintWriter; + +/** + * 文件上传异常类 + * + * @author dcsoft + */ +public class FileUploadException extends Exception +{ + + private static final long serialVersionUID = 1L; + + private final Throwable cause; + + public FileUploadException() + { + this(null, null); + } + + public FileUploadException(final String msg) + { + this(msg, null); + } + + public FileUploadException(String msg, Throwable cause) + { + super(msg); + this.cause = cause; + } + + @Override + public void printStackTrace(PrintStream stream) + { + super.printStackTrace(stream); + if (cause != null) + { + stream.println("Caused by:"); + cause.printStackTrace(stream); + } + } + + @Override + public void printStackTrace(PrintWriter writer) + { + super.printStackTrace(writer); + if (cause != null) + { + writer.println("Caused by:"); + cause.printStackTrace(writer); + } + } + + @Override + public Throwable getCause() + { + return cause; + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/file/InvalidExtensionException.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/file/InvalidExtensionException.java new file mode 100644 index 0000000..c5d7825 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/file/InvalidExtensionException.java @@ -0,0 +1,80 @@ +package com.dcsoft.common.core.exception.file; + +import java.util.Arrays; + +/** + * 文件上传 误异常类 + * + * @author dcsoft + */ +public class InvalidExtensionException extends FileUploadException +{ + private static final long serialVersionUID = 1L; + + private String[] allowedExtension; + private String extension; + private String filename; + + public InvalidExtensionException(String[] allowedExtension, String extension, String filename) + { + super("filename : [" + filename + "], extension : [" + extension + "], allowed extension : [" + Arrays.toString(allowedExtension) + "]"); + this.allowedExtension = allowedExtension; + this.extension = extension; + this.filename = filename; + } + + public String[] getAllowedExtension() + { + return allowedExtension; + } + + public String getExtension() + { + return extension; + } + + public String getFilename() + { + return filename; + } + + public static class InvalidImageExtensionException extends InvalidExtensionException + { + private static final long serialVersionUID = 1L; + + public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename) + { + super(allowedExtension, extension, filename); + } + } + + public static class InvalidFlashExtensionException extends InvalidExtensionException + { + private static final long serialVersionUID = 1L; + + public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename) + { + super(allowedExtension, extension, filename); + } + } + + public static class InvalidMediaExtensionException extends InvalidExtensionException + { + private static final long serialVersionUID = 1L; + + public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename) + { + super(allowedExtension, extension, filename); + } + } + + public static class InvalidVideoExtensionException extends InvalidExtensionException + { + private static final long serialVersionUID = 1L; + + public InvalidVideoExtensionException(String[] allowedExtension, String extension, String filename) + { + super(allowedExtension, extension, filename); + } + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/job/TaskException.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/job/TaskException.java new file mode 100644 index 0000000..8a8f391 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/job/TaskException.java @@ -0,0 +1,34 @@ +package com.dcsoft.common.core.exception.job; + +/** + * 计划策略异常 + * + * @author dcsoft + */ +public class TaskException extends Exception +{ + private static final long serialVersionUID = 1L; + + private Code code; + + public TaskException(String msg, Code code) + { + this(msg, code, null); + } + + public TaskException(String msg, Code code, Exception nestedEx) + { + super(msg, nestedEx); + this.code = code; + } + + public Code getCode() + { + return code; + } + + public enum Code + { + TASK_EXISTS, NO_TASK_EXISTS, TASK_ALREADY_STARTED, UNKNOWN, CONFIG_ERROR, TASK_NODE_NOT_AVAILABLE + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/user/CaptchaExpireException.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/user/CaptchaExpireException.java new file mode 100644 index 0000000..593ea80 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/user/CaptchaExpireException.java @@ -0,0 +1,16 @@ +package com.dcsoft.common.core.exception.user; + +/** + * 验证码失效异常类 + * + * @author dcsoft + */ +public class CaptchaExpireException extends UserException +{ + private static final long serialVersionUID = 1L; + + public CaptchaExpireException() + { + super("user.jcaptcha.expire", null); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/user/UserException.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/user/UserException.java new file mode 100644 index 0000000..f98509a --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/user/UserException.java @@ -0,0 +1,18 @@ +package com.dcsoft.common.core.exception.user; + +import com.dcsoft.common.core.exception.base.BaseException; + +/** + * 用户信息异常类 + * + * @author dcsoft + */ +public class UserException extends BaseException +{ + private static final long serialVersionUID = 1L; + + public UserException(String code, Object[] args) + { + super("user", code, args, null); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/user/UserPasswordNotMatchException.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/user/UserPasswordNotMatchException.java new file mode 100644 index 0000000..d75fbe9 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/exception/user/UserPasswordNotMatchException.java @@ -0,0 +1,16 @@ +package com.dcsoft.common.core.exception.user; + +/** + * 用户密码不正确或不符合规范异常类 + * + * @author dcsoft + */ +public class UserPasswordNotMatchException extends UserException +{ + private static final long serialVersionUID = 1L; + + public UserPasswordNotMatchException() + { + super("user.password.not.match", null); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/text/CharsetKit.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/text/CharsetKit.java new file mode 100644 index 0000000..50256a8 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/text/CharsetKit.java @@ -0,0 +1,86 @@ +package com.dcsoft.common.core.text; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import com.dcsoft.common.core.utils.StringUtils; + +/** + * 字符集工具类 + * + * @author dcsoft + */ +public class CharsetKit +{ + /** ISO-8859-1 */ + public static final String ISO_8859_1 = "ISO-8859-1"; + /** UTF-8 */ + public static final String UTF_8 = "UTF-8"; + /** GBK */ + public static final String GBK = "GBK"; + + /** ISO-8859-1 */ + public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1); + /** UTF-8 */ + public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8); + /** GBK */ + public static final Charset CHARSET_GBK = Charset.forName(GBK); + + /** + * 转换为Charset对象 + * + * @param charset 字符集,为空则返回默认字符集 + * @return Charset + */ + public static Charset charset(String charset) + { + return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset); + } + + /** + * 转换字符串的字符集编码 + * + * @param source 字符串 + * @param srcCharset 源字符集,默认ISO-8859-1 + * @param destCharset 目标字符集,默认UTF-8 + * @return 转换后的字符集 + */ + public static String convert(String source, String srcCharset, String destCharset) + { + return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset)); + } + + /** + * 转换字符串的字符集编码 + * + * @param source 字符串 + * @param srcCharset 源字符集,默认ISO-8859-1 + * @param destCharset 目标字符集,默认UTF-8 + * @return 转换后的字符集 + */ + public static String convert(String source, Charset srcCharset, Charset destCharset) + { + if (null == srcCharset) + { + srcCharset = StandardCharsets.ISO_8859_1; + } + + if (null == destCharset) + { + destCharset = StandardCharsets.UTF_8; + } + + if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset)) + { + return source; + } + return new String(source.getBytes(srcCharset), destCharset); + } + + /** + * @return 系统字符集编码 + */ + public static String systemCharset() + { + return Charset.defaultCharset().name(); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/text/Convert.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/text/Convert.java new file mode 100644 index 0000000..8aed8de --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/text/Convert.java @@ -0,0 +1,1006 @@ +package com.dcsoft.common.core.text; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.text.NumberFormat; +import java.util.Set; +import com.dcsoft.common.core.utils.StringUtils; + +/** + * 类型转换器 + * + * @author dcsoft + */ +public class Convert +{ + /** + * 转换为字符串
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static String toStr(Object value, String defaultValue) + { + if (null == value) + { + return defaultValue; + } + if (value instanceof String) + { + return (String) value; + } + return value.toString(); + } + + /** + * 转换为字符串
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static String toStr(Object value) + { + return toStr(value, null); + } + + /** + * 转换为字符
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Character toChar(Object value, Character defaultValue) + { + if (null == value) + { + return defaultValue; + } + if (value instanceof Character) + { + return (Character) value; + } + + final String valueStr = toStr(value, null); + return StringUtils.isEmpty(valueStr) ? defaultValue : valueStr.charAt(0); + } + + /** + * 转换为字符
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Character toChar(Object value) + { + return toChar(value, null); + } + + /** + * 转换为byte
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Byte toByte(Object value, Byte defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Byte) + { + return (Byte) value; + } + if (value instanceof Number) + { + return ((Number) value).byteValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Byte.parseByte(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为byte
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Byte toByte(Object value) + { + return toByte(value, null); + } + + /** + * 转换为Short
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Short toShort(Object value, Short defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Short) + { + return (Short) value; + } + if (value instanceof Number) + { + return ((Number) value).shortValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Short.parseShort(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Short
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Short toShort(Object value) + { + return toShort(value, null); + } + + /** + * 转换为Number
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Number toNumber(Object value, Number defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Number) + { + return (Number) value; + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return NumberFormat.getInstance().parse(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Number
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Number toNumber(Object value) + { + return toNumber(value, null); + } + + /** + * 转换为int
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Integer toInt(Object value, Integer defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Integer) + { + return (Integer) value; + } + if (value instanceof Number) + { + return ((Number) value).intValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Integer.parseInt(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为int
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Integer toInt(Object value) + { + return toInt(value, null); + } + + /** + * 转换为Integer数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static Integer[] toIntArray(String str) + { + return toIntArray(",", str); + } + + /** + * 转换为Long数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static Long[] toLongArray(String str) + { + return toLongArray(",", str); + } + + /** + * 转换为Integer数组
+ * + * @param split 分隔符 + * @param str 被转换的值 + * @return 结果 + */ + public static Integer[] toIntArray(String split, String str) + { + if (StringUtils.isEmpty(str)) + { + return new Integer[] {}; + } + String[] arr = str.split(split); + final Integer[] ints = new Integer[arr.length]; + for (int i = 0; i < arr.length; i++) + { + final Integer v = toInt(arr[i], 0); + ints[i] = v; + } + return ints; + } + + /** + * 转换为Long数组
+ * + * @param split 分隔符 + * @param str 被转换的值 + * @return 结果 + */ + public static Long[] toLongArray(String split, String str) + { + if (StringUtils.isEmpty(str)) + { + return new Long[] {}; + } + String[] arr = str.split(split); + final Long[] longs = new Long[arr.length]; + for (int i = 0; i < arr.length; i++) + { + final Long v = toLong(arr[i], null); + longs[i] = v; + } + return longs; + } + + /** + * 转换为String数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static String[] toStrArray(String str) + { + return toStrArray(",", str); + } + + /** + * 转换为String数组
+ * + * @param split 分隔符 + * @param str 被转换的值 + * @return 结果 + */ + public static String[] toStrArray(String split, String str) + { + return str.split(split); + } + + /** + * 转换为long
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Long toLong(Object value, Long defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Long) + { + return (Long) value; + } + if (value instanceof Number) + { + return ((Number) value).longValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + // 支持科学计数法 + return new BigDecimal(valueStr.trim()).longValue(); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为long
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Long toLong(Object value) + { + return toLong(value, null); + } + + /** + * 转换为double
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Double toDouble(Object value, Double defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Double) + { + return (Double) value; + } + if (value instanceof Number) + { + return ((Number) value).doubleValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + // 支持科学计数法 + return new BigDecimal(valueStr.trim()).doubleValue(); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为double
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Double toDouble(Object value) + { + return toDouble(value, null); + } + + /** + * 转换为Float
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Float toFloat(Object value, Float defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Float) + { + return (Float) value; + } + if (value instanceof Number) + { + return ((Number) value).floatValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Float.parseFloat(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Float
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Float toFloat(Object value) + { + return toFloat(value, null); + } + + /** + * 转换为boolean
+ * String支持的值为:true、false、yes、ok、no,1,0 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Boolean toBool(Object value, Boolean defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Boolean) + { + return (Boolean) value; + } + String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + valueStr = valueStr.trim().toLowerCase(); + switch (valueStr) + { + case "true": + case "yes": + case "ok": + case "1": + return true; + case "false": + case "no": + case "0": + return false; + default: + return defaultValue; + } + } + + /** + * 转换为boolean
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Boolean toBool(Object value) + { + return toBool(value, null); + } + + /** + * 转换为Enum对象
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * + * @param clazz Enum的Class + * @param value 值 + * @param defaultValue 默认值 + * @return Enum + */ + public static > E toEnum(Class clazz, Object value, E defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (clazz.isAssignableFrom(value.getClass())) + { + @SuppressWarnings("unchecked") + E myE = (E) value; + return myE; + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Enum.valueOf(clazz, valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Enum对象
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * + * @param clazz Enum的Class + * @param value 值 + * @return Enum + */ + public static > E toEnum(Class clazz, Object value) + { + return toEnum(clazz, value, null); + } + + /** + * 转换为BigInteger
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static BigInteger toBigInteger(Object value, BigInteger defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof BigInteger) + { + return (BigInteger) value; + } + if (value instanceof Long) + { + return BigInteger.valueOf((Long) value); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return new BigInteger(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为BigInteger
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static BigInteger toBigInteger(Object value) + { + return toBigInteger(value, null); + } + + /** + * 转换为BigDecimal
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static BigDecimal toBigDecimal(Object value, BigDecimal defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof BigDecimal) + { + return (BigDecimal) value; + } + if (value instanceof Long) + { + return new BigDecimal((Long) value); + } + if (value instanceof Double) + { + return BigDecimal.valueOf((Double) value); + } + if (value instanceof Integer) + { + return new BigDecimal((Integer) value); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return new BigDecimal(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为BigDecimal
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static BigDecimal toBigDecimal(Object value) + { + return toBigDecimal(value, null); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 + * + * @param obj 对象 + * @return 字符串 + */ + public static String utf8Str(Object obj) + { + return str(obj, CharsetKit.CHARSET_UTF_8); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 + * + * @param obj 对象 + * @param charsetName 字符集 + * @return 字符串 + */ + public static String str(Object obj, String charsetName) + { + return str(obj, Charset.forName(charsetName)); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 + * + * @param obj 对象 + * @param charset 字符集 + * @return 字符串 + */ + public static String str(Object obj, Charset charset) + { + if (null == obj) + { + return null; + } + + if (obj instanceof String) + { + return (String) obj; + } + else if (obj instanceof byte[] || obj instanceof Byte[]) + { + if (obj instanceof byte[]) + { + return str((byte[]) obj, charset); + } + else + { + Byte[] bytes = (Byte[]) obj; + int length = bytes.length; + byte[] dest = new byte[length]; + for (int i = 0; i < length; i++) + { + dest[i] = bytes[i]; + } + return str(dest, charset); + } + } + else if (obj instanceof ByteBuffer) + { + return str((ByteBuffer) obj, charset); + } + return obj.toString(); + } + + /** + * 将byte数组转为字符串 + * + * @param bytes byte数组 + * @param charset 字符集 + * @return 字符串 + */ + public static String str(byte[] bytes, String charset) + { + return str(bytes, StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset)); + } + + /** + * 解码字节码 + * + * @param data 字符串 + * @param charset 字符集,如果此字段为空,则解码的结果取决于平台 + * @return 解码后的字符串 + */ + public static String str(byte[] data, Charset charset) + { + if (data == null) + { + return null; + } + + if (null == charset) + { + return new String(data); + } + return new String(data, charset); + } + + /** + * 将编码的byteBuffer数据转换为字符串 + * + * @param data 数据 + * @param charset 字符集,如果为空使用当前系统字符集 + * @return 字符串 + */ + public static String str(ByteBuffer data, String charset) + { + if (data == null) + { + return null; + } + + return str(data, Charset.forName(charset)); + } + + /** + * 将编码的byteBuffer数据转换为字符串 + * + * @param data 数据 + * @param charset 字符集,如果为空使用当前系统字符集 + * @return 字符串 + */ + public static String str(ByteBuffer data, Charset charset) + { + if (null == charset) + { + charset = Charset.defaultCharset(); + } + return charset.decode(data).toString(); + } + + // ----------------------------------------------------------------------- 全角半角转换 + /** + * 半角转全角 + * + * @param input String. + * @return 全角字符串. + */ + public static String toSBC(String input) + { + return toSBC(input, null); + } + + /** + * 半角转全角 + * + * @param input String + * @param notConvertSet 不替换的字符集合 + * @return 全角字符串. + */ + public static String toSBC(String input, Set notConvertSet) + { + char[] c = input.toCharArray(); + for (int i = 0; i < c.length; i++) + { + if (null != notConvertSet && notConvertSet.contains(c[i])) + { + // 跳过不替换的字符 + continue; + } + + if (c[i] == ' ') + { + c[i] = '\u3000'; + } + else if (c[i] < '\177') + { + c[i] = (char) (c[i] + 65248); + + } + } + return new String(c); + } + + /** + * 全角转半角 + * + * @param input String. + * @return 半角字符串 + */ + public static String toDBC(String input) + { + return toDBC(input, null); + } + + /** + * 替换全角为半角 + * + * @param text 文本 + * @param notConvertSet 不替换的字符集合 + * @return 替换后的字符 + */ + public static String toDBC(String text, Set notConvertSet) + { + char[] c = text.toCharArray(); + for (int i = 0; i < c.length; i++) + { + if (null != notConvertSet && notConvertSet.contains(c[i])) + { + // 跳过不替换的字符 + continue; + } + + if (c[i] == '\u3000') + { + c[i] = ' '; + } + else if (c[i] > '\uFF00' && c[i] < '\uFF5F') + { + c[i] = (char) (c[i] - 65248); + } + } + return new String(c); + } + + /** + * 数字金额大写转换 先写个完整的然后将如零拾替换成零 + * + * @param n 数字 + * @return 中文大写数字 + */ + public static String digitUppercase(double n) + { + String[] fraction = { "角", "分" }; + String[] digit = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" }; + String[][] unit = { { "元", "万", "亿" }, { "", "拾", "佰", "仟" } }; + + String head = n < 0 ? "负" : ""; + n = Math.abs(n); + + String s = ""; + for (int i = 0; i < fraction.length; i++) + { + s += (digit[(int) (Math.floor(n * 10 * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", ""); + } + if (s.length() < 1) + { + s = "整"; + } + int integerPart = (int) Math.floor(n); + + for (int i = 0; i < unit[0].length && integerPart > 0; i++) + { + String p = ""; + for (int j = 0; j < unit[1].length && n > 0; j++) + { + p = digit[integerPart % 10] + unit[1][j] + p; + integerPart = integerPart / 10; + } + s = p.replaceAll("(零.)*零$", "").replaceAll("^$", "零") + unit[0][i] + s; + } + return head + s.replaceAll("(零.)*零元", "元").replaceFirst("(零.)+", "").replaceAll("(零.)+", "零").replaceAll("^整$", "零元整"); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/text/StrFormatter.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/text/StrFormatter.java new file mode 100644 index 0000000..5137e16 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/text/StrFormatter.java @@ -0,0 +1,92 @@ +package com.dcsoft.common.core.text; + +import com.dcsoft.common.core.utils.StringUtils; + +/** + * 字符串格式化 + * + * @author dcsoft + */ +public class StrFormatter +{ + public static final String EMPTY_JSON = "{}"; + public static final char C_BACKSLASH = '\\'; + public static final char C_DELIM_START = '{'; + public static final char C_DELIM_END = '}'; + + /** + * 格式化字符串
+ * 此方法只是简单将占位符 {} 按照顺序替换为参数
+ * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可
+ * 例:
+ * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b
+ * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a
+ * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b
+ * + * @param strPattern 字符串模板 + * @param argArray 参数列表 + * @return 结果 + */ + public static String format(final String strPattern, final Object... argArray) + { + if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray)) + { + return strPattern; + } + final int strPatternLength = strPattern.length(); + + // 初始化定义好的长度以获得更好的性能 + StringBuilder sbuf = new StringBuilder(strPatternLength + 50); + + int handledPosition = 0; + int delimIndex;// 占位符所在位置 + for (int argIndex = 0; argIndex < argArray.length; argIndex++) + { + delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition); + if (delimIndex == -1) + { + if (handledPosition == 0) + { + return strPattern; + } + else + { // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果 + sbuf.append(strPattern, handledPosition, strPatternLength); + return sbuf.toString(); + } + } + else + { + if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH) + { + if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH) + { + // 转义符之前还有一个转义符,占位符依旧有效 + sbuf.append(strPattern, handledPosition, delimIndex - 1); + sbuf.append(Convert.utf8Str(argArray[argIndex])); + handledPosition = delimIndex + 2; + } + else + { + // 占位符被转义 + argIndex--; + sbuf.append(strPattern, handledPosition, delimIndex - 1); + sbuf.append(C_DELIM_START); + handledPosition = delimIndex + 1; + } + } + else + { + // 正常占位符 + sbuf.append(strPattern, handledPosition, delimIndex); + sbuf.append(Convert.utf8Str(argArray[argIndex])); + handledPosition = delimIndex + 2; + } + } + } + // 加入最后一个占位符后所有的字符 + sbuf.append(strPattern, handledPosition, strPattern.length()); + + return sbuf.toString(); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/CollUtil.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/CollUtil.java new file mode 100644 index 0000000..d23f02e --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/CollUtil.java @@ -0,0 +1,19 @@ +package com.dcsoft.common.core.utils; + +import java.util.Collection; + +/** + * 集合工具类 + * + * @author xueyi + */ +public class CollUtil extends cn.hutool.core.collection.CollUtil { + + public static boolean isNotNull(Collection collection) { + return !isNull(collection); + } + + public static boolean isNull(Collection collection) { + return collection == null; + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/DateUtils.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/DateUtils.java new file mode 100644 index 0000000..89188ec --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/DateUtils.java @@ -0,0 +1,209 @@ +package com.dcsoft.common.core.utils; + +import java.lang.management.ManagementFactory; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.Date; +import org.apache.commons.lang3.time.DateFormatUtils; + +/** + * 时间工具类 + * + * @author dcsoft + */ +public class DateUtils extends org.apache.commons.lang3.time.DateUtils +{ + public static String YYYY = "yyyy"; + + public static String YYYY_MM = "yyyy-MM"; + + public static String YYYY_MM_DD = "yyyy-MM-dd"; + + public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss"; + + public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; + + private static String[] parsePatterns = { + "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", + "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", + "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"}; + + /** + * 获取当前Date型日期 + * + * @return Date() 当前日期 + */ + public static Date getNowDate() + { + return new Date(); + } + + /** + * 获取当前日期, 默认格式为yyyy-MM-dd + * + * @return String + */ + public static String getDate() + { + return dateTimeNow(YYYY_MM_DD); + } + + public static final String getTime() + { + return dateTimeNow(YYYY_MM_DD_HH_MM_SS); + } + + public static final String dateTimeNow() + { + return dateTimeNow(YYYYMMDDHHMMSS); + } + + public static final String dateTimeNow(final String format) + { + return parseDateToStr(format, new Date()); + } + + public static final String dateTime(final Date date) + { + return parseDateToStr(YYYY_MM_DD, date); + } + + public static final String parseDateToStr(final String format, final Date date) + { + return new SimpleDateFormat(format).format(date); + } + + public static final Date dateTime(final String format, final String ts) + { + try + { + return new SimpleDateFormat(format).parse(ts); + } + catch (ParseException e) + { + throw new RuntimeException(e); + } + } + + /** + * 日期路径 即年/月/日 如2018/08/08 + */ + public static final String datePath() + { + Date now = new Date(); + return DateFormatUtils.format(now, "yyyy/MM/dd"); + } + + /** + * 日期路径 即年/月/日 如20180808 + */ + public static final String dateTime() + { + Date now = new Date(); + return DateFormatUtils.format(now, "yyyyMMdd"); + } + + /** + * 日期型字符串转化为日期 格式 + */ + public static Date parseDate(Object str) + { + if (str == null) + { + return null; + } + try + { + return parseDate(str.toString(), parsePatterns); + } + catch (ParseException e) + { + return null; + } + } + + /** + * 获取服务器启动时间 + */ + public static Date getServerStartDate() + { + long time = ManagementFactory.getRuntimeMXBean().getStartTime(); + return new Date(time); + } + + /** + * 计算时间差 + * + * @param endTime 最后时间 + * @param startTime 开始时间 + * @return 时间差(天/小时/分钟) + */ + public static String timeDistance(Date endDate, Date startTime) + { + long nd = 1000 * 24 * 60 * 60; + long nh = 1000 * 60 * 60; + long nm = 1000 * 60; + // long ns = 1000; + // 获得两个时间的毫秒时间差异 + long diff = endDate.getTime() - startTime.getTime(); + // 计算差多少天 + long day = diff / nd; + // 计算差多少小时 + long hour = diff % nd / nh; + // 计算差多少分钟 + long min = diff % nd % nh / nm; + // 计算差多少秒//输出结果 + // long sec = diff % nd % nh % nm / ns; + return day + "天" + hour + "小时" + min + "分钟"; + } + + /** + * 计算时间差 + * + * @param endTime 最后时间 + * @param startTime 开始时间 + * @return 时间差(天/小时/分钟) + */ + public static Long timeTwo(Date endDate, Date startTime) + { + long nd = 1000 * 24 * 60 * 60; + long nh = 1000 * 60 * 60; + long nm = 1000 * 60; + // long ns = 1000; + // 获得两个时间的毫秒时间差异 + long diff = endDate.getTime() - startTime.getTime(); + // 计算差多少天 + long day = diff / nd; + // 计算差多少小时 + long hour = diff % nd / nh; + // 计算差多少分钟 + long min = diff % nd % nh / nm; + // 计算差多少秒//输出结果 + // long sec = diff % nd % nh % nm / ns; + return day; + } + + /** + * 增加 LocalDateTime ==> Date + */ + public static Date toDate(LocalDateTime temporalAccessor) + { + ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault()); + return Date.from(zdt.toInstant()); + } + + /** + * 增加 LocalDate ==> Date + */ + public static Date toDate(LocalDate temporalAccessor) + { + LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0)); + ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault()); + return Date.from(zdt.toInstant()); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/ExceptionUtil.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/ExceptionUtil.java new file mode 100644 index 0000000..8f3b772 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/ExceptionUtil.java @@ -0,0 +1,39 @@ +package com.dcsoft.common.core.utils; + +import java.io.PrintWriter; +import java.io.StringWriter; +import org.apache.commons.lang3.exception.ExceptionUtils; + +/** + * 错误信息处理类。 + * + * @author dcsoft + */ +public class ExceptionUtil +{ + /** + * 获取exception的详细错误信息。 + */ + public static String getExceptionMessage(Throwable e) + { + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw, true)); + return sw.toString(); + } + + public static String getRootErrorMessage(Exception e) + { + Throwable root = ExceptionUtils.getRootCause(e); + root = (root == null ? e : root); + if (root == null) + { + return ""; + } + String msg = root.getMessage(); + if (msg == null) + { + return "null"; + } + return StringUtils.defaultString(msg); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/JsonUtils.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/JsonUtils.java new file mode 100644 index 0000000..7bf9482 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/JsonUtils.java @@ -0,0 +1,111 @@ +package com.dcsoft.common.core.utils; + +import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.ObjectUtil; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.exc.MismatchedInputException; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * JSON 工具类 + * + * @author 芋道源码 + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class JsonUtils { + + private static ObjectMapper OBJECT_MAPPER = SpringUtils.getBean(ObjectMapper.class); + + public static ObjectMapper getObjectMapper() { + return OBJECT_MAPPER; + } + + public static String toJsonString(Object object) { + if (ObjectUtil.isNull(object)) { + return null; + } + try { + return OBJECT_MAPPER.writeValueAsString(object); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + + public static T parseObject(String text, Class clazz) { + if (StringUtils.isEmpty(text)) { + return null; + } + try { + return OBJECT_MAPPER.readValue(text, clazz); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static T parseObject(byte[] bytes, Class clazz) { + if (ArrayUtil.isEmpty(bytes)) { + return null; + } + try { + return OBJECT_MAPPER.readValue(bytes, clazz); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static T parseObject(String text, TypeReference typeReference) { + if (StringUtils.isBlank(text)) { + return null; + } + try { + return OBJECT_MAPPER.readValue(text, typeReference); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static Dict parseMap(String text) { + if (StringUtils.isBlank(text)) { + return null; + } + try { + return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructType(Dict.class)); + } catch (MismatchedInputException e) { + // 类型不匹配说明不是json + return null; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static List parseArrayMap(String text) { + if (StringUtils.isBlank(text)) { + return null; + } + try { + return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, Dict.class)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static List parseArray(String text, Class clazz) { + if (StringUtils.isEmpty(text)) { + return new ArrayList<>(); + } + try { + return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, clazz)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/JwtUtils.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/JwtUtils.java new file mode 100644 index 0000000..1aa24d3 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/JwtUtils.java @@ -0,0 +1,130 @@ +package com.dcsoft.common.core.utils; + +import java.util.Map; + +import com.dcsoft.common.core.constant.CacheConstants; +import com.dcsoft.common.core.constant.SecurityConstants; +import com.dcsoft.common.core.constant.TokenConstants; +import com.dcsoft.common.core.text.Convert; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; + +/** + * Jwt工具类 + * + * @author dcsoft + */ +public class JwtUtils +{ + public static String secret = TokenConstants.SECRET; + + /** + * 从数据声明生成令牌 + * + * @param claims 数据声明 + * @return 令牌 + */ + public static String createToken(Map claims) + { + String token = Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS512, secret).compact(); + return token; + } + + /** + * 从令牌中获取数据声明 + * + * @param token 令牌 + * @return 数据声明 + */ + public static Claims parseToken(String token) + { + return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody(); + } + + /** + * 根据令牌获取用户标识 + * + * @param token 令牌 + * @return 用户ID + */ + public static String getUserKey(String token) + { + Claims claims = parseToken(token); + return getValue(claims, SecurityConstants.USER_KEY); + } + + /** + * 根据令牌获取用户标识 + * + * @param claims 身份信息 + * @return 用户ID + */ + public static String getUserKey(Claims claims) + { + return getValue(claims, SecurityConstants.USER_KEY); + } + + public static String getAppKey(Claims claims) + { + return getValue(claims, CacheConstants.AUTH_KEY); + } + + /** + * 根据令牌获取用户ID + * + * @param token 令牌 + * @return 用户ID + */ + public static String getUserId(String token) + { + Claims claims = parseToken(token); + return getValue(claims, SecurityConstants.DETAILS_USER_ID); + } + + /** + * 根据身份信息获取用户ID + * + * @param claims 身份信息 + * @return 用户ID + */ + public static String getUserId(Claims claims) + { + return getValue(claims, SecurityConstants.DETAILS_USER_ID); + } + + /** + * 根据令牌获取用户名 + * + * @param token 令牌 + * @return 用户名 + */ + public static String getUserName(String token) + { + Claims claims = parseToken(token); + return getValue(claims, SecurityConstants.DETAILS_USERNAME); + } + + /** + * 根据身份信息获取用户名 + * + * @param claims 身份信息 + * @return 用户名 + */ + public static String getUserName(Claims claims) + { + return getValue(claims, SecurityConstants.DETAILS_USERNAME); + } + + /** + * 根据身份信息获取键值 + * + * @param claims 身份信息 + * @param key 键 + * @return 值 + */ + public static String getValue(Claims claims, String key) + { + return Convert.toStr(claims.get(key), ""); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/PageUtils.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/PageUtils.java new file mode 100644 index 0000000..834e131 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/PageUtils.java @@ -0,0 +1,35 @@ +package com.dcsoft.common.core.utils; + +import com.github.pagehelper.PageHelper; +import com.dcsoft.common.core.utils.sql.SqlUtil; +import com.dcsoft.common.core.web.page.PageDomain; +import com.dcsoft.common.core.web.page.TableSupport; + +/** + * 分页工具类 + * + * @author dcsoft + */ +public class PageUtils extends PageHelper +{ + /** + * 设置请求分页数据 + */ + public static void startPage() + { + PageDomain pageDomain = TableSupport.buildPageRequest(); + Integer pageNum = pageDomain.getPageNum(); + Integer pageSize = pageDomain.getPageSize(); + String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy()); + Boolean reasonable = pageDomain.getReasonable(); + PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable); + } + + /** + * 清理分页的线程变量 + */ + public static void clearPage() + { + PageHelper.clearPage(); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/ServletUtils.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/ServletUtils.java new file mode 100644 index 0000000..2b65e76 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/ServletUtils.java @@ -0,0 +1,333 @@ +package com.dcsoft.common.core.utils; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.util.LinkedCaseInsensitiveMap; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import com.alibaba.fastjson2.JSON; +import com.dcsoft.common.core.constant.Constants; +import com.dcsoft.common.core.domain.R; +import com.dcsoft.common.core.text.Convert; +import reactor.core.publisher.Mono; + +/** + * 客户端工具类 + * + * @author dcsoft + */ +public class ServletUtils +{ + /** + * 获取String参数 + */ + public static String getParameter(String name) + { + return getRequest().getParameter(name); + } + + /** + * 获取String参数 + */ + public static String getParameter(String name, String defaultValue) + { + return Convert.toStr(getRequest().getParameter(name), defaultValue); + } + + /** + * 获取Integer参数 + */ + public static Integer getParameterToInt(String name) + { + return Convert.toInt(getRequest().getParameter(name)); + } + + /** + * 获取Integer参数 + */ + public static Integer getParameterToInt(String name, Integer defaultValue) + { + return Convert.toInt(getRequest().getParameter(name), defaultValue); + } + + /** + * 获取Boolean参数 + */ + public static Boolean getParameterToBool(String name) + { + return Convert.toBool(getRequest().getParameter(name)); + } + + /** + * 获取Boolean参数 + */ + public static Boolean getParameterToBool(String name, Boolean defaultValue) + { + return Convert.toBool(getRequest().getParameter(name), defaultValue); + } + + /** + * 获得所有请求参数 + * + * @param request 请求对象{@link ServletRequest} + * @return Map + */ + public static Map getParams(ServletRequest request) + { + final Map map = request.getParameterMap(); + return Collections.unmodifiableMap(map); + } + + /** + * 获得所有请求参数 + * + * @param request 请求对象{@link ServletRequest} + * @return Map + */ + public static Map getParamMap(ServletRequest request) + { + Map params = new HashMap<>(); + for (Map.Entry entry : getParams(request).entrySet()) + { + params.put(entry.getKey(), StringUtils.join(entry.getValue(), ",")); + } + return params; + } + + /** + * 获取request + */ + public static HttpServletRequest getRequest() + { + try + { + return getRequestAttributes().getRequest(); + } + catch (Exception e) + { + return null; + } + } + + /** + * 获取response + */ + public static HttpServletResponse getResponse() + { + try + { + return getRequestAttributes().getResponse(); + } + catch (Exception e) + { + return null; + } + } + + /** + * 获取session + */ + public static HttpSession getSession() + { + return getRequest().getSession(); + } + + public static ServletRequestAttributes getRequestAttributes() + { + try + { + RequestAttributes attributes = RequestContextHolder.getRequestAttributes(); + return (ServletRequestAttributes) attributes; + } + catch (Exception e) + { + return null; + } + } + + public static String getHeader(HttpServletRequest request, String name) + { + String value = request.getHeader(name); + if (StringUtils.isEmpty(value)) + { + return StringUtils.EMPTY; + } + return urlDecode(value); + } + + public static Map getHeaders(HttpServletRequest request) + { + Map map = new LinkedCaseInsensitiveMap<>(); + Enumeration enumeration = request.getHeaderNames(); + if (enumeration != null) + { + while (enumeration.hasMoreElements()) + { + String key = enumeration.nextElement(); + String value = request.getHeader(key); + map.put(key, value); + } + } + return map; + } + + /** + * 将字符串渲染到客户端 + * + * @param response 渲染对象 + * @param string 待渲染的字符串 + */ + public static void renderString(HttpServletResponse response, String string) + { + try + { + response.setStatus(200); + response.setContentType("application/json"); + response.setCharacterEncoding("utf-8"); + response.getWriter().print(string); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + + /** + * 是否是Ajax异步请求 + * + * @param request + */ + public static boolean isAjaxRequest(HttpServletRequest request) + { + String accept = request.getHeader("accept"); + if (accept != null && accept.contains("application/json")) + { + return true; + } + + String xRequestedWith = request.getHeader("X-Requested-With"); + if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest")) + { + return true; + } + + String uri = request.getRequestURI(); + if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml")) + { + return true; + } + + String ajax = request.getParameter("__ajax"); + return StringUtils.inStringIgnoreCase(ajax, "json", "xml"); + } + + /** + * 内容编码 + * + * @param str 内容 + * @return 编码后的内容 + */ + public static String urlEncode(String str) + { + try + { + return URLEncoder.encode(str, Constants.UTF8); + } + catch (UnsupportedEncodingException e) + { + return StringUtils.EMPTY; + } + } + + /** + * 内容解码 + * + * @param str 内容 + * @return 解码后的内容 + */ + public static String urlDecode(String str) + { + try + { + return URLDecoder.decode(str, Constants.UTF8); + } + catch (UnsupportedEncodingException e) + { + return StringUtils.EMPTY; + } + } + + /** + * 设置webflux模型响应 + * + * @param response ServerHttpResponse + * @param value 响应内容 + * @return Mono + */ + public static Mono webFluxResponseWriter(ServerHttpResponse response, Object value) + { + return webFluxResponseWriter(response, HttpStatus.OK, value, R.FAIL); + } + + /** + * 设置webflux模型响应 + * + * @param response ServerHttpResponse + * @param code 响应状态码 + * @param value 响应内容 + * @return Mono + */ + public static Mono webFluxResponseWriter(ServerHttpResponse response, Object value, int code) + { + return webFluxResponseWriter(response, HttpStatus.OK, value, code); + } + + /** + * 设置webflux模型响应 + * + * @param response ServerHttpResponse + * @param status http状态码 + * @param code 响应状态码 + * @param value 响应内容 + * @return Mono + */ + public static Mono webFluxResponseWriter(ServerHttpResponse response, HttpStatus status, Object value, int code) + { + return webFluxResponseWriter(response, MediaType.APPLICATION_JSON_VALUE, status, value, code); + } + + /** + * 设置webflux模型响应 + * + * @param response ServerHttpResponse + * @param contentType content-type + * @param status http状态码 + * @param code 响应状态码 + * @param value 响应内容 + * @return Mono + */ + public static Mono webFluxResponseWriter(ServerHttpResponse response, String contentType, HttpStatus status, Object value, int code) + { + response.setStatusCode(status); + response.getHeaders().add(HttpHeaders.CONTENT_TYPE, contentType); + R result = R.fail(code, value.toString()); + DataBuffer dataBuffer = response.bufferFactory().wrap(JSON.toJSONString(result).getBytes()); + return response.writeWith(Mono.just(dataBuffer)); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/SpringUtils.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/SpringUtils.java new file mode 100644 index 0000000..4ba3993 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/SpringUtils.java @@ -0,0 +1,114 @@ +package com.dcsoft.common.core.utils; + +import org.springframework.aop.framework.AopContext; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.stereotype.Component; + +/** + * spring工具类 方便在非spring管理环境中获取bean + * + * @author dcsoft + */ +@Component +public final class SpringUtils implements BeanFactoryPostProcessor +{ + /** Spring应用上下文环境 */ + private static ConfigurableListableBeanFactory beanFactory; + + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException + { + SpringUtils.beanFactory = beanFactory; + } + + /** + * 获取对象 + * + * @param name + * @return Object 一个以所给名字注册的bean的实例 + * @throws org.springframework.beans.BeansException + * + */ + @SuppressWarnings("unchecked") + public static T getBean(String name) throws BeansException + { + return (T) beanFactory.getBean(name); + } + + /** + * 获取类型为requiredType的对象 + * + * @param clz + * @return + * @throws org.springframework.beans.BeansException + * + */ + public static T getBean(Class clz) throws BeansException + { + T result = (T) beanFactory.getBean(clz); + return result; + } + + /** + * 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true + * + * @param name + * @return boolean + */ + public static boolean containsBean(String name) + { + return beanFactory.containsBean(name); + } + + /** + * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException) + * + * @param name + * @return boolean + * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException + * + */ + public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException + { + return beanFactory.isSingleton(name); + } + + /** + * @param name + * @return Class 注册对象的类型 + * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException + * + */ + public static Class getType(String name) throws NoSuchBeanDefinitionException + { + return beanFactory.getType(name); + } + + /** + * 如果给定的bean名字在bean定义中有别名,则返回这些别名 + * + * @param name + * @return + * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException + * + */ + public static String[] getAliases(String name) throws NoSuchBeanDefinitionException + { + return beanFactory.getAliases(name); + } + + /** + * 获取aop代理对象 + * + * @param invoker + * @return + */ + @SuppressWarnings("unchecked") + public static T getAopProxy(T invoker) + { + return (T) AopContext.currentProxy(); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/StringUtils.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/StringUtils.java new file mode 100644 index 0000000..d3c7624 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/StringUtils.java @@ -0,0 +1,561 @@ +package com.dcsoft.common.core.utils; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import org.springframework.util.AntPathMatcher; +import com.dcsoft.common.core.constant.Constants; +import com.dcsoft.common.core.text.StrFormatter; + +/** + * 字符串工具类 + * + * @author dcsoft + */ +public class StringUtils extends org.apache.commons.lang3.StringUtils +{ + /** 空字符串 */ + private static final String NULLSTR = ""; + + /** 下划线 */ + private static final char SEPARATOR = '_'; + + /** + * 获取参数不为空值 + * + * @param value defaultValue 要判断的value + * @return value 返回值 + */ + public static T nvl(T value, T defaultValue) + { + return value != null ? value : defaultValue; + } + + /** + * * 判断一个Collection是否为空, 包含List,Set,Queue + * + * @param coll 要判断的Collection + * @return true:为空 false:非空 + */ + public static boolean isEmpty(Collection coll) + { + return isNull(coll) || coll.isEmpty(); + } + + /** + * * 判断一个Collection是否非空,包含List,Set,Queue + * + * @param coll 要判断的Collection + * @return true:非空 false:空 + */ + public static boolean isNotEmpty(Collection coll) + { + return !isEmpty(coll); + } + + /** + * * 判断一个对象数组是否为空 + * + * @param objects 要判断的对象数组 + ** @return true:为空 false:非空 + */ + public static boolean isEmpty(Object[] objects) + { + return isNull(objects) || (objects.length == 0); + } + + /** + * * 判断一个对象数组是否非空 + * + * @param objects 要判断的对象数组 + * @return true:非空 false:空 + */ + public static boolean isNotEmpty(Object[] objects) + { + return !isEmpty(objects); + } + + /** + * * 判断一个Map是否为空 + * + * @param map 要判断的Map + * @return true:为空 false:非空 + */ + public static boolean isEmpty(Map map) + { + return isNull(map) || map.isEmpty(); + } + + /** + * * 判断一个Map是否为空 + * + * @param map 要判断的Map + * @return true:非空 false:空 + */ + public static boolean isNotEmpty(Map map) + { + return !isEmpty(map); + } + + /** + * * 判断一个字符串是否为空串 + * + * @param str String + * @return true:为空 false:非空 + */ + public static boolean isEmpty(String str) + { + return isNull(str) || NULLSTR.equals(str.trim()); + } + + /** + * * 判断一个字符串是否为非空串 + * + * @param str String + * @return true:非空串 false:空串 + */ + public static boolean isNotEmpty(String str) + { + return !isEmpty(str); + } + + /** + * * 判断一个对象是否为空 + * + * @param object Object + * @return true:为空 false:非空 + */ + public static boolean isNull(Object object) + { + return object == null; + } + + /** + * * 判断一个对象是否非空 + * + * @param object Object + * @return true:非空 false:空 + */ + public static boolean isNotNull(Object object) + { + return !isNull(object); + } + + /** + * * 判断一个对象是否是数组类型(Java基本型别的数组) + * + * @param object 对象 + * @return true:是数组 false:不是数组 + */ + public static boolean isArray(Object object) + { + return isNotNull(object) && object.getClass().isArray(); + } + + /** + * 去空格 + */ + public static String trim(String str) + { + return (str == null ? "" : str.trim()); + } + + /** + * 截取字符串 + * + * @param str 字符串 + * @param start 开始 + * @return 结果 + */ + public static String substring(final String str, int start) + { + if (str == null) + { + return NULLSTR; + } + + if (start < 0) + { + start = str.length() + start; + } + + if (start < 0) + { + start = 0; + } + if (start > str.length()) + { + return NULLSTR; + } + + return str.substring(start); + } + + /** + * 截取字符串 + * + * @param str 字符串 + * @param start 开始 + * @param end 结束 + * @return 结果 + */ + public static String substring(final String str, int start, int end) + { + if (str == null) + { + return NULLSTR; + } + + if (end < 0) + { + end = str.length() + end; + } + if (start < 0) + { + start = str.length() + start; + } + + if (end > str.length()) + { + end = str.length(); + } + + if (start > end) + { + return NULLSTR; + } + + if (start < 0) + { + start = 0; + } + if (end < 0) + { + end = 0; + } + + return str.substring(start, end); + } + + /** + * 判断是否为空,并且不是空白字符 + * + * @param str 要判断的value + * @return 结果 + */ + public static boolean hasText(String str) + { + return (str != null && !str.isEmpty() && containsText(str)); + } + + private static boolean containsText(CharSequence str) + { + int strLen = str.length(); + for (int i = 0; i < strLen; i++) + { + if (!Character.isWhitespace(str.charAt(i))) + { + return true; + } + } + return false; + } + + /** + * 格式化文本, {} 表示占位符
+ * 此方法只是简单将占位符 {} 按照顺序替换为参数
+ * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可
+ * 例:
+ * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b
+ * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a
+ * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b
+ * + * @param template 文本模板,被替换的部分用 {} 表示 + * @param params 参数值 + * @return 格式化后的文本 + */ + public static String format(String template, Object... params) + { + if (isEmpty(params) || isEmpty(template)) + { + return template; + } + return StrFormatter.format(template, params); + } + + /** + * 是否为http(s)://开头 + * + * @param link 链接 + * @return 结果 + */ + public static boolean ishttp(String link) + { + return StringUtils.startsWithAny(link, Constants.HTTP, Constants.HTTPS); + } + + /** + * 判断给定的set列表中是否包含数组array 判断给定的数组array中是否包含给定的元素value + * + * @param set 给定的集合 + * @param array 给定的数组 + * @return boolean 结果 + */ + public static boolean containsAny(Collection collection, String... array) + { + if (isEmpty(collection) || isEmpty(array)) + { + return false; + } + else + { + for (String str : array) + { + if (collection.contains(str)) + { + return true; + } + } + return false; + } + } + + /** + * 驼峰转下划线命名 + */ + public static String toUnderScoreCase(String str) + { + if (str == null) + { + return null; + } + StringBuilder sb = new StringBuilder(); + // 前置字符是否大写 + boolean preCharIsUpperCase = true; + // 当前字符是否大写 + boolean curreCharIsUpperCase = true; + // 下一字符是否大写 + boolean nexteCharIsUpperCase = true; + for (int i = 0; i < str.length(); i++) + { + char c = str.charAt(i); + if (i > 0) + { + preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1)); + } + else + { + preCharIsUpperCase = false; + } + + curreCharIsUpperCase = Character.isUpperCase(c); + + if (i < (str.length() - 1)) + { + nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1)); + } + + if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase) + { + sb.append(SEPARATOR); + } + else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase) + { + sb.append(SEPARATOR); + } + sb.append(Character.toLowerCase(c)); + } + + return sb.toString(); + } + + /** + * 是否包含字符串 + * + * @param str 验证字符串 + * @param strs 字符串组 + * @return 包含返回true + */ + public static boolean inStringIgnoreCase(String str, String... strs) + { + if (str != null && strs != null) + { + for (String s : strs) + { + if (str.equalsIgnoreCase(trim(s))) + { + return true; + } + } + } + return false; + } + + /** + * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld + * + * @param name 转换前的下划线大写方式命名的字符串 + * @return 转换后的驼峰式命名的字符串 + */ + public static String convertToCamelCase(String name) + { + StringBuilder result = new StringBuilder(); + // 快速检查 + if (name == null || name.isEmpty()) + { + // 没必要转换 + return ""; + } + else if (!name.contains("_")) + { + // 不含下划线,仅将首字母大写 + return name.substring(0, 1).toUpperCase() + name.substring(1); + } + // 用下划线将原始字符串分割 + String[] camels = name.split("_"); + for (String camel : camels) + { + // 跳过原始字符串中开头、结尾的下换线或双重下划线 + if (camel.isEmpty()) + { + continue; + } + // 首字母大写 + result.append(camel.substring(0, 1).toUpperCase()); + result.append(camel.substring(1).toLowerCase()); + } + return result.toString(); + } + + /** + * 驼峰式命名法 + * 例如:user_name->userName + */ + public static String toCamelCase(String s) + { + if (s == null) + { + return null; + } + if (s.indexOf(SEPARATOR) == -1) + { + return s; + } + s = s.toLowerCase(); + StringBuilder sb = new StringBuilder(s.length()); + boolean upperCase = false; + for (int i = 0; i < s.length(); i++) + { + char c = s.charAt(i); + + if (c == SEPARATOR) + { + upperCase = true; + } + else if (upperCase) + { + sb.append(Character.toUpperCase(c)); + upperCase = false; + } + else + { + sb.append(c); + } + } + return sb.toString(); + } + + /** + * 查找指定字符串是否匹配指定字符串列表中的任意一个字符串 + * + * @param str 指定字符串 + * @param strs 需要检查的字符串数组 + * @return 是否匹配 + */ + public static boolean matches(String str, List strs) + { + if (isEmpty(str) || isEmpty(strs)) + { + return false; + } + for (String pattern : strs) + { + if (isMatch(pattern, str)) + { + return true; + } + } + return false; + } + + /** + * 判断url是否与规则配置: + * ? 表示单个字符; + * * 表示一层路径内的任意字符串,不可跨层级; + * ** 表示任意层路径; + * + * @param pattern 匹配规则 + * @param url 需要匹配的url + * @return + */ + public static boolean isMatch(String pattern, String url) + { + AntPathMatcher matcher = new AntPathMatcher(); + return matcher.match(pattern, url); + } + + @SuppressWarnings("unchecked") + public static T cast(Object obj) + { + return (T) obj; + } + + /** + * 数字左边补齐0,使之达到指定长度。注意,如果数字转换为字符串后,长度大于size,则只保留 最后size个字符。 + * + * @param num 数字对象 + * @param size 字符串指定长度 + * @return 返回数字的字符串格式,该字符串为指定长度。 + */ + public static final String padl(final Number num, final int size) + { + return padl(num.toString(), size, '0'); + } + + /** + * 字符串左补齐。如果原始字符串s长度大于size,则只保留最后size个字符。 + * + * @param s 原始字符串 + * @param size 字符串指定长度 + * @param c 用于补齐的字符 + * @return 返回指定长度的字符串,由原字符串左补齐或截取得到。 + */ + public static final String padl(final String s, final int size, final char c) + { + final StringBuilder sb = new StringBuilder(size); + if (s != null) + { + final int len = s.length(); + if (s.length() <= size) + { + for (int i = size - len; i > 0; i--) + { + sb.append(c); + } + sb.append(s); + } + else + { + return s.substring(len - size, len); + } + } + else + { + for (int i = size; i > 0; i--) + { + sb.append(c); + } + } + return sb.toString(); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/bean/BeanUtils.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/bean/BeanUtils.java new file mode 100644 index 0000000..1742827 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/bean/BeanUtils.java @@ -0,0 +1,110 @@ +package com.dcsoft.common.core.utils.bean; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Bean 工具类 + * + * @author dcsoft + */ +public class BeanUtils extends org.springframework.beans.BeanUtils +{ + /** Bean方法名中属性名开始的下标 */ + private static final int BEAN_METHOD_PROP_INDEX = 3; + + /** * 匹配getter方法的正则表达式 */ + private static final Pattern GET_PATTERN = Pattern.compile("get(\\p{javaUpperCase}\\w*)"); + + /** * 匹配setter方法的正则表达式 */ + private static final Pattern SET_PATTERN = Pattern.compile("set(\\p{javaUpperCase}\\w*)"); + + /** + * Bean属性复制工具方法。 + * + * @param dest 目标对象 + * @param src 源对象 + */ + public static void copyBeanProp(Object dest, Object src) + { + try + { + copyProperties(src, dest); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + /** + * 获取对象的setter方法。 + * + * @param obj 对象 + * @return 对象的setter方法列表 + */ + public static List getSetterMethods(Object obj) + { + // setter方法列表 + List setterMethods = new ArrayList(); + + // 获取所有方法 + Method[] methods = obj.getClass().getMethods(); + + // 查找setter方法 + + for (Method method : methods) + { + Matcher m = SET_PATTERN.matcher(method.getName()); + if (m.matches() && (method.getParameterTypes().length == 1)) + { + setterMethods.add(method); + } + } + // 返回setter方法列表 + return setterMethods; + } + + /** + * 获取对象的getter方法。 + * + * @param obj 对象 + * @return 对象的getter方法列表 + */ + + public static List getGetterMethods(Object obj) + { + // getter方法列表 + List getterMethods = new ArrayList(); + // 获取所有方法 + Method[] methods = obj.getClass().getMethods(); + // 查找getter方法 + for (Method method : methods) + { + Matcher m = GET_PATTERN.matcher(method.getName()); + if (m.matches() && (method.getParameterTypes().length == 0)) + { + getterMethods.add(method); + } + } + // 返回getter方法列表 + return getterMethods; + } + + /** + * 检查Bean方法名中的属性名是否相等。
+ * 如getName()和setName()属性名一样,getName()和setAge()属性名不一样。 + * + * @param m1 方法名1 + * @param m2 方法名2 + * @return 属性名一样返回true,否则返回false + */ + + public static boolean isMethodPropEquals(String m1, String m2) + { + return m1.substring(BEAN_METHOD_PROP_INDEX).equals(m2.substring(BEAN_METHOD_PROP_INDEX)); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/bean/BeanValidators.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/bean/BeanValidators.java new file mode 100644 index 0000000..9161927 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/bean/BeanValidators.java @@ -0,0 +1,24 @@ +package com.dcsoft.common.core.utils.bean; + +import java.util.Set; +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import javax.validation.Validator; + +/** + * bean对象属性验证 + * + * @author dcsoft + */ +public class BeanValidators +{ + public static void validateWithException(Validator validator, Object object, Class... groups) + throws ConstraintViolationException + { + Set> constraintViolations = validator.validate(object, groups); + if (!constraintViolations.isEmpty()) + { + throw new ConstraintViolationException(constraintViolations); + } + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/file/FileTypeUtils.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/file/FileTypeUtils.java new file mode 100644 index 0000000..508a12f --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/file/FileTypeUtils.java @@ -0,0 +1,95 @@ +package com.dcsoft.common.core.utils.file; + +import java.io.File; +import java.util.Objects; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.multipart.MultipartFile; + +/** + * 文件类型工具类 + * + * @author dcsoft + */ +public class FileTypeUtils +{ + /** + * 获取文件类型 + *

+ * 例如: dcsoft.txt, 返回: txt + * + * @param file 文件名 + * @return 后缀(不含".") + */ + public static String getFileType(File file) + { + if (null == file) + { + return StringUtils.EMPTY; + } + return getFileType(file.getName()); + } + + /** + * 获取文件类型 + *

+ * 例如: dcsoft.txt, 返回: txt + * + * @param fileName 文件名 + * @return 后缀(不含".") + */ + public static String getFileType(String fileName) + { + int separatorIndex = fileName.lastIndexOf("."); + if (separatorIndex < 0) + { + return ""; + } + return fileName.substring(separatorIndex + 1).toLowerCase(); + } + + /** + * 获取文件名的后缀 + * + * @param file 表单文件 + * @return 后缀名 + */ + public static final String getExtension(MultipartFile file) + { + String extension = FilenameUtils.getExtension(file.getOriginalFilename()); + if (StringUtils.isEmpty(extension)) + { + extension = MimeTypeUtils.getExtension(Objects.requireNonNull(file.getContentType())); + } + return extension; + } + + /** + * 获取文件类型 + * + * @param photoByte 文件字节码 + * @return 后缀(不含".") + */ + public static String getFileExtendName(byte[] photoByte) + { + String strFileExtendName = "JPG"; + if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56) + && ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97)) + { + strFileExtendName = "GIF"; + } + else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70)) + { + strFileExtendName = "JPG"; + } + else if ((photoByte[0] == 66) && (photoByte[1] == 77)) + { + strFileExtendName = "BMP"; + } + else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71)) + { + strFileExtendName = "PNG"; + } + return strFileExtendName; + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/file/FileUtils.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/file/FileUtils.java new file mode 100644 index 0000000..05541d9 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/file/FileUtils.java @@ -0,0 +1,293 @@ +package com.dcsoft.common.core.utils.file; + +import java.io.*; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.ArrayUtils; +import com.dcsoft.common.core.utils.StringUtils; + +/** + * 文件处理工具类 + * + * @author dcsoft + */ +public class FileUtils +{ + /** 字符常量:斜杠 {@code '/'} */ + public static final char SLASH = '/'; + + /** 字符常量:反斜杠 {@code '\\'} */ + public static final char BACKSLASH = '\\'; + + public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+"; + + /** + * 输出指定文件的byte数组 + * + * @param filePath 文件路径 + * @param os 输出流 + * @return + */ + public static void writeBytes(String filePath, OutputStream os) throws IOException + { + FileInputStream fis = null; + try + { + File file = new File(filePath); + if (!file.exists()) + { + throw new FileNotFoundException(filePath); + } + fis = new FileInputStream(file); + byte[] b = new byte[1024]; + int length; + while ((length = fis.read(b)) > 0) + { + os.write(b, 0, length); + } + } + catch (IOException e) + { + throw e; + } + finally + { + if (os != null) + { + try + { + os.close(); + } + catch (IOException e1) + { + e1.printStackTrace(); + } + } + if (fis != null) + { + try + { + fis.close(); + } + catch (IOException e1) + { + e1.printStackTrace(); + } + } + } + } + + /** + * 删除文件 + * + * @param filePath 文件 + * @return + */ + public static boolean deleteFile(String filePath) + { + boolean flag = false; + File file = new File(filePath); + // 路径为文件且不为空则进行删除 + if (file.isFile() && file.exists()) + { + flag = file.delete(); + } + return flag; + } + + /** + * 文件名称验证 + * + * @param filename 文件名称 + * @return true 正常 false 非法 + */ + public static boolean isValidFilename(String filename) + { + return filename.matches(FILENAME_PATTERN); + } + + /** + * 检查文件是否可下载 + * + * @param resource 需要下载的文件 + * @return true 正常 false 非法 + */ + public static boolean checkAllowDownload(String resource) + { + // 禁止目录上跳级别 + if (StringUtils.contains(resource, "..")) + { + return false; + } + + // 检查允许下载的文件规则 + if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource))) + { + return true; + } + + // 不在允许下载的文件规则 + return false; + } + + /** + * 下载文件名重新编码 + * + * @param request 请求对象 + * @param fileName 文件名 + * @return 编码后的文件名 + */ + public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException + { + final String agent = request.getHeader("USER-AGENT"); + String filename = fileName; + if (agent.contains("MSIE")) + { + // IE浏览器 + filename = URLEncoder.encode(filename, "utf-8"); + filename = filename.replace("+", " "); + } + else if (agent.contains("Firefox")) + { + // 火狐浏览器 + filename = new String(fileName.getBytes(), "ISO8859-1"); + } + else if (agent.contains("Chrome")) + { + // google浏览器 + filename = URLEncoder.encode(filename, "utf-8"); + } + else + { + // 其它浏览器 + filename = URLEncoder.encode(filename, "utf-8"); + } + return filename; + } + + /** + * 返回文件名 + * + * @param filePath 文件 + * @return 文件名 + */ + public static String getName(String filePath) + { + if (null == filePath) + { + return null; + } + int len = filePath.length(); + if (0 == len) + { + return filePath; + } + if (isFileSeparator(filePath.charAt(len - 1))) + { + // 以分隔符结尾的去掉结尾分隔符 + len--; + } + + int begin = 0; + char c; + for (int i = len - 1; i > -1; i--) + { + c = filePath.charAt(i); + if (isFileSeparator(c)) + { + // 查找最后一个路径分隔符(/或者\) + begin = i + 1; + break; + } + } + + return filePath.substring(begin, len); + } + + /** + * 是否为Windows或者Linux(Unix)文件分隔符
+ * Windows平台下分隔符为\,Linux(Unix)为/ + * + * @param c 字符 + * @return 是否为Windows或者Linux(Unix)文件分隔符 + */ + public static boolean isFileSeparator(char c) + { + return SLASH == c || BACKSLASH == c; + } + + /** + * 下载文件名重新编码 + * + * @param response 响应对象 + * @param realFileName 真实文件名 + * @return + */ + public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException + { + String percentEncodedFileName = percentEncode(realFileName); + + StringBuilder contentDispositionValue = new StringBuilder(); + contentDispositionValue.append("attachment; filename=") + .append(percentEncodedFileName) + .append(";") + .append("filename*=") + .append("utf-8''") + .append(percentEncodedFileName); + + response.setHeader("Content-disposition", contentDispositionValue.toString()); + response.setHeader("download-filename", percentEncodedFileName); + } + + /** + * 百分号编码工具方法 + * + * @param s 需要百分号编码的字符串 + * @return 百分号编码后的字符串 + */ + public static String percentEncode(String s) throws UnsupportedEncodingException + { + String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString()); + return encode.replaceAll("\\+", "%20"); + } + + /** + * byte 转file + */ + public static File byte2File(byte[] buf, String filePath, String fileName){ + BufferedOutputStream bos = null; + FileOutputStream fos = null; + File file = null; + try{ + File dir = new File(filePath); + if (!dir.exists() && dir.isDirectory()){ + dir.mkdirs(); + } + file = new File(filePath + File.separator + fileName); + fos = new FileOutputStream(file); + bos = new BufferedOutputStream(fos); + bos.write(buf); + }catch (Exception e){ + e.printStackTrace(); + } + finally{ + if (bos != null){ + try{ + bos.close(); + }catch (IOException e){ + e.printStackTrace(); + } + } + if (fos != null){ + try{ + fos.close(); + }catch (IOException e){ + e.printStackTrace(); + } + } + } + return file; + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/file/ImageUtils.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/file/ImageUtils.java new file mode 100644 index 0000000..bbce34c --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/file/ImageUtils.java @@ -0,0 +1,84 @@ +package com.dcsoft.common.core.utils.file; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.util.Arrays; +import org.apache.poi.util.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 图片处理工具类 + * + * @author dcsoft + */ +public class ImageUtils +{ + private static final Logger log = LoggerFactory.getLogger(ImageUtils.class); + + public static byte[] getImage(String imagePath) + { + InputStream is = getFile(imagePath); + try + { + return IOUtils.toByteArray(is); + } + catch (Exception e) + { + log.error("图片加载异常 {}", e); + return null; + } + finally + { + IOUtils.closeQuietly(is); + } + } + + public static InputStream getFile(String imagePath) + { + try + { + byte[] result = readFile(imagePath); + result = Arrays.copyOf(result, result.length); + return new ByteArrayInputStream(result); + } + catch (Exception e) + { + log.error("获取图片异常 {}", e); + } + return null; + } + + /** + * 读取文件为字节数据 + * + * @param url 地址 + * @return 字节数据 + */ + public static byte[] readFile(String url) + { + InputStream in = null; + try + { + // 网络地址 + URL urlObj = new URL(url); + URLConnection urlConnection = urlObj.openConnection(); + urlConnection.setConnectTimeout(30 * 1000); + urlConnection.setReadTimeout(60 * 1000); + urlConnection.setDoInput(true); + in = urlConnection.getInputStream(); + return IOUtils.toByteArray(in); + } + catch (Exception e) + { + log.error("访问文件异常 {}", e); + return null; + } + finally + { + IOUtils.closeQuietly(in); + } + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/file/MimeTypeUtils.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/file/MimeTypeUtils.java new file mode 100644 index 0000000..915afd5 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/file/MimeTypeUtils.java @@ -0,0 +1,59 @@ +package com.dcsoft.common.core.utils.file; + +/** + * 媒体类型工具类 + * + * @author dcsoft + */ +public class MimeTypeUtils +{ + public static final String IMAGE_PNG = "image/png"; + + public static final String IMAGE_JPG = "image/jpg"; + + public static final String IMAGE_JPEG = "image/jpeg"; + + public static final String IMAGE_BMP = "image/bmp"; + + public static final String IMAGE_GIF = "image/gif"; + + public static final String[] IMAGE_EXTENSION = { "bmp", "gif", "jpg", "jpeg", "png" }; + + public static final String[] FLASH_EXTENSION = { "swf", "flv" }; + + public static final String[] MEDIA_EXTENSION = { "swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg", + "asf", "rm", "rmvb" }; + + public static final String[] VIDEO_EXTENSION = { "mp4", "avi", "rmvb" }; + + public static final String[] DEFAULT_ALLOWED_EXTENSION = { + // 图片 + "bmp", "gif", "jpg", "jpeg", "png", + // word excel powerpoint + "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt", + // 压缩文件 + "rar", "zip", "gz", "bz2", + // 视频格式 + "mp4", "avi", "rmvb", + // pdf + "pdf" }; + + public static String getExtension(String prefix) + { + switch (prefix) + { + case IMAGE_PNG: + return "png"; + case IMAGE_JPG: + return "jpg"; + case IMAGE_JPEG: + return "jpeg"; + case IMAGE_BMP: + return "bmp"; + case IMAGE_GIF: + return "gif"; + default: + return ""; + } + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/html/EscapeUtil.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/html/EscapeUtil.java new file mode 100644 index 0000000..c7a2c55 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/html/EscapeUtil.java @@ -0,0 +1,167 @@ +package com.dcsoft.common.core.utils.html; + +import com.dcsoft.common.core.utils.StringUtils; + +/** + * 转义和反转义工具类 + * + * @author dcsoft + */ +public class EscapeUtil +{ + public static final String RE_HTML_MARK = "(<[^<]*?>)|(<[\\s]*?/[^<]*?>)|(<[^<]*?/[\\s]*?>)"; + + private static final char[][] TEXT = new char[64][]; + + static + { + for (int i = 0; i < 64; i++) + { + TEXT[i] = new char[] { (char) i }; + } + + // special HTML characters + TEXT['\''] = "'".toCharArray(); // 单引号 + TEXT['"'] = """.toCharArray(); // 双引号 + TEXT['&'] = "&".toCharArray(); // &符 + TEXT['<'] = "<".toCharArray(); // 小于号 + TEXT['>'] = ">".toCharArray(); // 大于号 + } + + /** + * 转义文本中的HTML字符为安全的字符 + * + * @param text 被转义的文本 + * @return 转义后的文本 + */ + public static String escape(String text) + { + return encode(text); + } + + /** + * 还原被转义的HTML特殊字符 + * + * @param content 包含转义符的HTML内容 + * @return 转换后的字符串 + */ + public static String unescape(String content) + { + return decode(content); + } + + /** + * 清除所有HTML标签,但是不删除标签内的内容 + * + * @param content 文本 + * @return 清除标签后的文本 + */ + public static String clean(String content) + { + return new HTMLFilter().filter(content); + } + + /** + * Escape编码 + * + * @param text 被编码的文本 + * @return 编码后的字符 + */ + private static String encode(String text) + { + if (StringUtils.isEmpty(text)) + { + return StringUtils.EMPTY; + } + + final StringBuilder tmp = new StringBuilder(text.length() * 6); + char c; + for (int i = 0; i < text.length(); i++) + { + c = text.charAt(i); + if (c < 256) + { + tmp.append("%"); + if (c < 16) + { + tmp.append("0"); + } + tmp.append(Integer.toString(c, 16)); + } + else + { + tmp.append("%u"); + if (c <= 0xfff) + { + // issue#I49JU8@Gitee + tmp.append("0"); + } + tmp.append(Integer.toString(c, 16)); + } + } + return tmp.toString(); + } + + /** + * Escape解码 + * + * @param content 被转义的内容 + * @return 解码后的字符串 + */ + public static String decode(String content) + { + if (StringUtils.isEmpty(content)) + { + return content; + } + + StringBuilder tmp = new StringBuilder(content.length()); + int lastPos = 0, pos = 0; + char ch; + while (lastPos < content.length()) + { + pos = content.indexOf("%", lastPos); + if (pos == lastPos) + { + if (content.charAt(pos + 1) == 'u') + { + ch = (char) Integer.parseInt(content.substring(pos + 2, pos + 6), 16); + tmp.append(ch); + lastPos = pos + 6; + } + else + { + ch = (char) Integer.parseInt(content.substring(pos + 1, pos + 3), 16); + tmp.append(ch); + lastPos = pos + 3; + } + } + else + { + if (pos == -1) + { + tmp.append(content.substring(lastPos)); + lastPos = content.length(); + } + else + { + tmp.append(content.substring(lastPos, pos)); + lastPos = pos; + } + } + } + return tmp.toString(); + } + + public static void main(String[] args) + { + String html = ""; + String escape = EscapeUtil.escape(html); + // String html = "ipt>alert(\"XSS\")ipt>"; + // String html = "<123"; + // String html = "123>"; + System.out.println("clean: " + EscapeUtil.clean(html)); + System.out.println("escape: " + escape); + System.out.println("unescape: " + EscapeUtil.unescape(escape)); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/html/HTMLFilter.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/html/HTMLFilter.java new file mode 100644 index 0000000..96a872f --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/html/HTMLFilter.java @@ -0,0 +1,570 @@ +package com.dcsoft.common.core.utils.html; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * HTML过滤器,用于去除XSS漏洞隐患。 + * + * @author dcsoft + */ +public final class HTMLFilter +{ + /** + * regex flag union representing /si modifiers in php + **/ + private static final int REGEX_FLAGS_SI = Pattern.CASE_INSENSITIVE | Pattern.DOTALL; + private static final Pattern P_COMMENTS = Pattern.compile("", Pattern.DOTALL); + private static final Pattern P_COMMENT = Pattern.compile("^!--(.*)--$", REGEX_FLAGS_SI); + private static final Pattern P_TAGS = Pattern.compile("<(.*?)>", Pattern.DOTALL); + private static final Pattern P_END_TAG = Pattern.compile("^/([a-z0-9]+)", REGEX_FLAGS_SI); + private static final Pattern P_START_TAG = Pattern.compile("^([a-z0-9]+)(.*?)(/?)$", REGEX_FLAGS_SI); + private static final Pattern P_QUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)=([\"'])(.*?)\\2", REGEX_FLAGS_SI); + private static final Pattern P_UNQUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)(=)([^\"\\s']+)", REGEX_FLAGS_SI); + private static final Pattern P_PROTOCOL = Pattern.compile("^([^:]+):", REGEX_FLAGS_SI); + private static final Pattern P_ENTITY = Pattern.compile("&#(\\d+);?"); + private static final Pattern P_ENTITY_UNICODE = Pattern.compile("&#x([0-9a-f]+);?"); + private static final Pattern P_ENCODE = Pattern.compile("%([0-9a-f]{2});?"); + private static final Pattern P_VALID_ENTITIES = Pattern.compile("&([^&;]*)(?=(;|&|$))"); + private static final Pattern P_VALID_QUOTES = Pattern.compile("(>|^)([^<]+?)(<|$)", Pattern.DOTALL); + private static final Pattern P_END_ARROW = Pattern.compile("^>"); + private static final Pattern P_BODY_TO_END = Pattern.compile("<([^>]*?)(?=<|$)"); + private static final Pattern P_XML_CONTENT = Pattern.compile("(^|>)([^<]*?)(?=>)"); + private static final Pattern P_STRAY_LEFT_ARROW = Pattern.compile("<([^>]*?)(?=<|$)"); + private static final Pattern P_STRAY_RIGHT_ARROW = Pattern.compile("(^|>)([^<]*?)(?=>)"); + private static final Pattern P_AMP = Pattern.compile("&"); + private static final Pattern P_QUOTE = Pattern.compile("\""); + private static final Pattern P_LEFT_ARROW = Pattern.compile("<"); + private static final Pattern P_RIGHT_ARROW = Pattern.compile(">"); + private static final Pattern P_BOTH_ARROWS = Pattern.compile("<>"); + + // @xxx could grow large... maybe use sesat's ReferenceMap + private static final ConcurrentMap P_REMOVE_PAIR_BLANKS = new ConcurrentHashMap<>(); + private static final ConcurrentMap P_REMOVE_SELF_BLANKS = new ConcurrentHashMap<>(); + + /** + * set of allowed html elements, along with allowed attributes for each element + **/ + private final Map> vAllowed; + /** + * counts of open tags for each (allowable) html element + **/ + private final Map vTagCounts = new HashMap<>(); + + /** + * html elements which must always be self-closing (e.g. "") + **/ + private final String[] vSelfClosingTags; + /** + * html elements which must always have separate opening and closing tags (e.g. "") + **/ + private final String[] vNeedClosingTags; + /** + * set of disallowed html elements + **/ + private final String[] vDisallowed; + /** + * attributes which should be checked for valid protocols + **/ + private final String[] vProtocolAtts; + /** + * allowed protocols + **/ + private final String[] vAllowedProtocols; + /** + * tags which should be removed if they contain no content (e.g. "" or "") + **/ + private final String[] vRemoveBlanks; + /** + * entities allowed within html markup + **/ + private final String[] vAllowedEntities; + /** + * flag determining whether comments are allowed in input String. + */ + private final boolean stripComment; + private final boolean encodeQuotes; + /** + * flag determining whether to try to make tags when presented with "unbalanced" angle brackets (e.g. "" + * becomes " text "). If set to false, unbalanced angle brackets will be html escaped. + */ + private final boolean alwaysMakeTags; + + /** + * Default constructor. + */ + public HTMLFilter() + { + vAllowed = new HashMap<>(); + + final ArrayList a_atts = new ArrayList<>(); + a_atts.add("href"); + a_atts.add("target"); + vAllowed.put("a", a_atts); + + final ArrayList img_atts = new ArrayList<>(); + img_atts.add("src"); + img_atts.add("width"); + img_atts.add("height"); + img_atts.add("alt"); + vAllowed.put("img", img_atts); + + final ArrayList no_atts = new ArrayList<>(); + vAllowed.put("b", no_atts); + vAllowed.put("strong", no_atts); + vAllowed.put("i", no_atts); + vAllowed.put("em", no_atts); + + vSelfClosingTags = new String[] { "img" }; + vNeedClosingTags = new String[] { "a", "b", "strong", "i", "em" }; + vDisallowed = new String[] {}; + vAllowedProtocols = new String[] { "http", "mailto", "https" }; // no ftp. + vProtocolAtts = new String[] { "src", "href" }; + vRemoveBlanks = new String[] { "a", "b", "strong", "i", "em" }; + vAllowedEntities = new String[] { "amp", "gt", "lt", "quot" }; + stripComment = true; + encodeQuotes = true; + alwaysMakeTags = false; + } + + /** + * Map-parameter configurable constructor. + * + * @param conf map containing configuration. keys match field names. + */ + @SuppressWarnings("unchecked") + public HTMLFilter(final Map conf) + { + + assert conf.containsKey("vAllowed") : "configuration requires vAllowed"; + assert conf.containsKey("vSelfClosingTags") : "configuration requires vSelfClosingTags"; + assert conf.containsKey("vNeedClosingTags") : "configuration requires vNeedClosingTags"; + assert conf.containsKey("vDisallowed") : "configuration requires vDisallowed"; + assert conf.containsKey("vAllowedProtocols") : "configuration requires vAllowedProtocols"; + assert conf.containsKey("vProtocolAtts") : "configuration requires vProtocolAtts"; + assert conf.containsKey("vRemoveBlanks") : "configuration requires vRemoveBlanks"; + assert conf.containsKey("vAllowedEntities") : "configuration requires vAllowedEntities"; + + vAllowed = Collections.unmodifiableMap((HashMap>) conf.get("vAllowed")); + vSelfClosingTags = (String[]) conf.get("vSelfClosingTags"); + vNeedClosingTags = (String[]) conf.get("vNeedClosingTags"); + vDisallowed = (String[]) conf.get("vDisallowed"); + vAllowedProtocols = (String[]) conf.get("vAllowedProtocols"); + vProtocolAtts = (String[]) conf.get("vProtocolAtts"); + vRemoveBlanks = (String[]) conf.get("vRemoveBlanks"); + vAllowedEntities = (String[]) conf.get("vAllowedEntities"); + stripComment = conf.containsKey("stripComment") ? (Boolean) conf.get("stripComment") : true; + encodeQuotes = conf.containsKey("encodeQuotes") ? (Boolean) conf.get("encodeQuotes") : true; + alwaysMakeTags = conf.containsKey("alwaysMakeTags") ? (Boolean) conf.get("alwaysMakeTags") : true; + } + + private void reset() + { + vTagCounts.clear(); + } + + // --------------------------------------------------------------- + // my versions of some PHP library functions + public static String chr(final int decimal) + { + return String.valueOf((char) decimal); + } + + public static String htmlSpecialChars(final String s) + { + String result = s; + result = regexReplace(P_AMP, "&", result); + result = regexReplace(P_QUOTE, """, result); + result = regexReplace(P_LEFT_ARROW, "<", result); + result = regexReplace(P_RIGHT_ARROW, ">", result); + return result; + } + + // --------------------------------------------------------------- + + /** + * given a user submitted input String, filter out any invalid or restricted html. + * + * @param input text (i.e. submitted by a user) than may contain html + * @return "clean" version of input, with only valid, whitelisted html elements allowed + */ + public String filter(final String input) + { + reset(); + String s = input; + + s = escapeComments(s); + + s = balanceHTML(s); + + s = checkTags(s); + + s = processRemoveBlanks(s); + + // s = validateEntities(s); + + return s; + } + + public boolean isAlwaysMakeTags() + { + return alwaysMakeTags; + } + + public boolean isStripComments() + { + return stripComment; + } + + private String escapeComments(final String s) + { + final Matcher m = P_COMMENTS.matcher(s); + final StringBuffer buf = new StringBuffer(); + if (m.find()) + { + final String match = m.group(1); // (.*?) + m.appendReplacement(buf, Matcher.quoteReplacement("")); + } + m.appendTail(buf); + + return buf.toString(); + } + + private String balanceHTML(String s) + { + if (alwaysMakeTags) + { + // + // try and form html + // + s = regexReplace(P_END_ARROW, "", s); + // 不追加结束标签 + s = regexReplace(P_BODY_TO_END, "<$1>", s); + s = regexReplace(P_XML_CONTENT, "$1<$2", s); + + } + else + { + // + // escape stray brackets + // + s = regexReplace(P_STRAY_LEFT_ARROW, "<$1", s); + s = regexReplace(P_STRAY_RIGHT_ARROW, "$1$2><", s); + + // + // the last regexp causes '<>' entities to appear + // (we need to do a lookahead assertion so that the last bracket can + // be used in the next pass of the regexp) + // + s = regexReplace(P_BOTH_ARROWS, "", s); + } + + return s; + } + + private String checkTags(String s) + { + Matcher m = P_TAGS.matcher(s); + + final StringBuffer buf = new StringBuffer(); + while (m.find()) + { + String replaceStr = m.group(1); + replaceStr = processTag(replaceStr); + m.appendReplacement(buf, Matcher.quoteReplacement(replaceStr)); + } + m.appendTail(buf); + + // these get tallied in processTag + // (remember to reset before subsequent calls to filter method) + final StringBuilder sBuilder = new StringBuilder(buf.toString()); + for (String key : vTagCounts.keySet()) + { + for (int ii = 0; ii < vTagCounts.get(key); ii++) + { + sBuilder.append(""); + } + } + s = sBuilder.toString(); + + return s; + } + + private String processRemoveBlanks(final String s) + { + String result = s; + for (String tag : vRemoveBlanks) + { + if (!P_REMOVE_PAIR_BLANKS.containsKey(tag)) + { + P_REMOVE_PAIR_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?>")); + } + result = regexReplace(P_REMOVE_PAIR_BLANKS.get(tag), "", result); + if (!P_REMOVE_SELF_BLANKS.containsKey(tag)) + { + P_REMOVE_SELF_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?/>")); + } + result = regexReplace(P_REMOVE_SELF_BLANKS.get(tag), "", result); + } + + return result; + } + + private static String regexReplace(final Pattern regex_pattern, final String replacement, final String s) + { + Matcher m = regex_pattern.matcher(s); + return m.replaceAll(replacement); + } + + private String processTag(final String s) + { + // ending tags + Matcher m = P_END_TAG.matcher(s); + if (m.find()) + { + final String name = m.group(1).toLowerCase(); + if (allowed(name)) + { + if (!inArray(name, vSelfClosingTags)) + { + if (vTagCounts.containsKey(name)) + { + vTagCounts.put(name, vTagCounts.get(name) - 1); + return ""; + } + } + } + } + + // starting tags + m = P_START_TAG.matcher(s); + if (m.find()) + { + final String name = m.group(1).toLowerCase(); + final String body = m.group(2); + String ending = m.group(3); + + // debug( "in a starting tag, name='" + name + "'; body='" + body + "'; ending='" + ending + "'" ); + if (allowed(name)) + { + final StringBuilder params = new StringBuilder(); + + final Matcher m2 = P_QUOTED_ATTRIBUTES.matcher(body); + final Matcher m3 = P_UNQUOTED_ATTRIBUTES.matcher(body); + final List paramNames = new ArrayList<>(); + final List paramValues = new ArrayList<>(); + while (m2.find()) + { + paramNames.add(m2.group(1)); // ([a-z0-9]+) + paramValues.add(m2.group(3)); // (.*?) + } + while (m3.find()) + { + paramNames.add(m3.group(1)); // ([a-z0-9]+) + paramValues.add(m3.group(3)); // ([^\"\\s']+) + } + + String paramName, paramValue; + for (int ii = 0; ii < paramNames.size(); ii++) + { + paramName = paramNames.get(ii).toLowerCase(); + paramValue = paramValues.get(ii); + + // debug( "paramName='" + paramName + "'" ); + // debug( "paramValue='" + paramValue + "'" ); + // debug( "allowed? " + vAllowed.get( name ).contains( paramName ) ); + + if (allowedAttribute(name, paramName)) + { + if (inArray(paramName, vProtocolAtts)) + { + paramValue = processParamProtocol(paramValue); + } + params.append(' ').append(paramName).append("=\\\"").append(paramValue).append("\\\""); + } + } + + if (inArray(name, vSelfClosingTags)) + { + ending = " /"; + } + + if (inArray(name, vNeedClosingTags)) + { + ending = ""; + } + + if (ending == null || ending.length() < 1) + { + if (vTagCounts.containsKey(name)) + { + vTagCounts.put(name, vTagCounts.get(name) + 1); + } + else + { + vTagCounts.put(name, 1); + } + } + else + { + ending = " /"; + } + return "<" + name + params + ending + ">"; + } + else + { + return ""; + } + } + + // comments + m = P_COMMENT.matcher(s); + if (!stripComment && m.find()) + { + return "<" + m.group() + ">"; + } + + return ""; + } + + private String processParamProtocol(String s) + { + s = decodeEntities(s); + final Matcher m = P_PROTOCOL.matcher(s); + if (m.find()) + { + final String protocol = m.group(1); + if (!inArray(protocol, vAllowedProtocols)) + { + // bad protocol, turn into local anchor link instead + s = "#" + s.substring(protocol.length() + 1); + if (s.startsWith("#//")) + { + s = "#" + s.substring(3); + } + } + } + + return s; + } + + private String decodeEntities(String s) + { + StringBuffer buf = new StringBuffer(); + + Matcher m = P_ENTITY.matcher(s); + while (m.find()) + { + final String match = m.group(1); + final int decimal = Integer.decode(match).intValue(); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + buf = new StringBuffer(); + m = P_ENTITY_UNICODE.matcher(s); + while (m.find()) + { + final String match = m.group(1); + final int decimal = Integer.valueOf(match, 16).intValue(); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + buf = new StringBuffer(); + m = P_ENCODE.matcher(s); + while (m.find()) + { + final String match = m.group(1); + final int decimal = Integer.valueOf(match, 16).intValue(); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + s = validateEntities(s); + return s; + } + + private String validateEntities(final String s) + { + StringBuffer buf = new StringBuffer(); + + // validate entities throughout the string + Matcher m = P_VALID_ENTITIES.matcher(s); + while (m.find()) + { + final String one = m.group(1); // ([^&;]*) + final String two = m.group(2); // (?=(;|&|$)) + m.appendReplacement(buf, Matcher.quoteReplacement(checkEntity(one, two))); + } + m.appendTail(buf); + + return encodeQuotes(buf.toString()); + } + + private String encodeQuotes(final String s) + { + if (encodeQuotes) + { + StringBuffer buf = new StringBuffer(); + Matcher m = P_VALID_QUOTES.matcher(s); + while (m.find()) + { + final String one = m.group(1); // (>|^) + final String two = m.group(2); // ([^<]+?) + final String three = m.group(3); // (<|$) + // 不替换双引号为",防止json格式无效 regexReplace(P_QUOTE, """, two) + m.appendReplacement(buf, Matcher.quoteReplacement(one + two + three)); + } + m.appendTail(buf); + return buf.toString(); + } + else + { + return s; + } + } + + private String checkEntity(final String preamble, final String term) + { + + return ";".equals(term) && isValidEntity(preamble) ? '&' + preamble : "&" + preamble; + } + + private boolean isValidEntity(final String entity) + { + return inArray(entity, vAllowedEntities); + } + + private static boolean inArray(final String s, final String[] array) + { + for (String item : array) + { + if (item != null && item.equals(s)) + { + return true; + } + } + return false; + } + + private boolean allowed(final String name) + { + return (vAllowed.isEmpty() || vAllowed.containsKey(name)) && !inArray(name, vDisallowed); + } + + private boolean allowedAttribute(final String name, final String paramName) + { + return allowed(name) && (vAllowed.isEmpty() || vAllowed.get(name).contains(paramName)); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/ip/IpUtils.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/ip/IpUtils.java new file mode 100644 index 0000000..f1e1140 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/ip/IpUtils.java @@ -0,0 +1,382 @@ +package com.dcsoft.common.core.utils.ip; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import javax.servlet.http.HttpServletRequest; +import com.dcsoft.common.core.utils.ServletUtils; +import com.dcsoft.common.core.utils.StringUtils; + +/** + * 获取IP方法 + * + * @author dcsoft + */ +public class IpUtils +{ + public final static String REGX_0_255 = "(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)"; + // 匹配 ip + public final static String REGX_IP = "((" + REGX_0_255 + "\\.){3}" + REGX_0_255 + ")"; + public final static String REGX_IP_WILDCARD = "(((\\*\\.){3}\\*)|(" + REGX_0_255 + "(\\.\\*){3})|(" + REGX_0_255 + "\\." + REGX_0_255 + ")(\\.\\*){2}" + "|((" + REGX_0_255 + "\\.){3}\\*))"; + // 匹配网段 + public final static String REGX_IP_SEG = "(" + REGX_IP + "\\-" + REGX_IP + ")"; + + /** + * 获取客户端IP + * + * @return IP地址 + */ + public static String getIpAddr() + { + return getIpAddr(ServletUtils.getRequest()); + } + + /** + * 获取客户端IP + * + * @param request 请求对象 + * @return IP地址 + */ + public static String getIpAddr(HttpServletRequest request) + { + if (request == null) + { + return "unknown"; + } + String ip = request.getHeader("x-forwarded-for"); + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getHeader("Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getHeader("X-Forwarded-For"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getHeader("X-Real-IP"); + } + + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getRemoteAddr(); + } + + return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip); + } + + /** + * 检查是否为内部IP地址 + * + * @param ip IP地址 + * @return 结果 + */ + public static boolean internalIp(String ip) + { + byte[] addr = textToNumericFormatV4(ip); + return internalIp(addr) || "127.0.0.1".equals(ip); + } + + /** + * 检查是否为内部IP地址 + * + * @param addr byte地址 + * @return 结果 + */ + private static boolean internalIp(byte[] addr) + { + if (StringUtils.isNull(addr) || addr.length < 2) + { + return true; + } + final byte b0 = addr[0]; + final byte b1 = addr[1]; + // 10.x.x.x/8 + final byte SECTION_1 = 0x0A; + // 172.16.x.x/12 + final byte SECTION_2 = (byte) 0xAC; + final byte SECTION_3 = (byte) 0x10; + final byte SECTION_4 = (byte) 0x1F; + // 192.168.x.x/16 + final byte SECTION_5 = (byte) 0xC0; + final byte SECTION_6 = (byte) 0xA8; + switch (b0) + { + case SECTION_1: + return true; + case SECTION_2: + if (b1 >= SECTION_3 && b1 <= SECTION_4) + { + return true; + } + case SECTION_5: + switch (b1) + { + case SECTION_6: + return true; + } + default: + return false; + } + } + + /** + * 将IPv4地址转换成字节 + * + * @param text IPv4地址 + * @return byte 字节 + */ + public static byte[] textToNumericFormatV4(String text) + { + if (text.length() == 0) + { + return null; + } + + byte[] bytes = new byte[4]; + String[] elements = text.split("\\.", -1); + try + { + long l; + int i; + switch (elements.length) + { + case 1: + l = Long.parseLong(elements[0]); + if ((l < 0L) || (l > 4294967295L)) + { + return null; + } + bytes[0] = (byte) (int) (l >> 24 & 0xFF); + bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF); + bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 2: + l = Integer.parseInt(elements[0]); + if ((l < 0L) || (l > 255L)) + { + return null; + } + bytes[0] = (byte) (int) (l & 0xFF); + l = Integer.parseInt(elements[1]); + if ((l < 0L) || (l > 16777215L)) + { + return null; + } + bytes[1] = (byte) (int) (l >> 16 & 0xFF); + bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 3: + for (i = 0; i < 2; ++i) + { + l = Integer.parseInt(elements[i]); + if ((l < 0L) || (l > 255L)) + { + return null; + } + bytes[i] = (byte) (int) (l & 0xFF); + } + l = Integer.parseInt(elements[2]); + if ((l < 0L) || (l > 65535L)) + { + return null; + } + bytes[2] = (byte) (int) (l >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 4: + for (i = 0; i < 4; ++i) + { + l = Integer.parseInt(elements[i]); + if ((l < 0L) || (l > 255L)) + { + return null; + } + bytes[i] = (byte) (int) (l & 0xFF); + } + break; + default: + return null; + } + } + catch (NumberFormatException e) + { + return null; + } + return bytes; + } + + /** + * 获取IP地址 + * + * @return 本地IP地址 + */ + public static String getHostIp() + { + try + { + return InetAddress.getLocalHost().getHostAddress(); + } + catch (UnknownHostException e) + { + } + return "127.0.0.1"; + } + + /** + * 获取主机名 + * + * @return 本地主机名 + */ + public static String getHostName() + { + try + { + return InetAddress.getLocalHost().getHostName(); + } + catch (UnknownHostException e) + { + } + return "未知"; + } + + /** + * 从多级反向代理中获得第一个非unknown IP地址 + * + * @param ip 获得的IP地址 + * @return 第一个非unknown IP地址 + */ + public static String getMultistageReverseProxyIp(String ip) + { + // 多级反向代理检测 + if (ip != null && ip.indexOf(",") > 0) + { + final String[] ips = ip.trim().split(","); + for (String subIp : ips) + { + if (false == isUnknown(subIp)) + { + ip = subIp; + break; + } + } + } + return StringUtils.substring(ip, 0, 255); + } + + /** + * 检测给定字符串是否为未知,多用于检测HTTP请求相关 + * + * @param checkString 被检测的字符串 + * @return 是否未知 + */ + public static boolean isUnknown(String checkString) + { + return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString); + } + + /** + * 是否为IP + */ + public static boolean isIP(String ip) + { + return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP); + } + + /** + * 是否为IP,或 *为间隔的通配符地址 + */ + public static boolean isIpWildCard(String ip) + { + return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP_WILDCARD); + } + + /** + * 检测参数是否在ip通配符里 + */ + public static boolean ipIsInWildCardNoCheck(String ipWildCard, String ip) + { + String[] s1 = ipWildCard.split("\\."); + String[] s2 = ip.split("\\."); + boolean isMatchedSeg = true; + for (int i = 0; i < s1.length && !s1[i].equals("*"); i++) + { + if (!s1[i].equals(s2[i])) + { + isMatchedSeg = false; + break; + } + } + return isMatchedSeg; + } + + /** + * 是否为特定格式如:“10.10.10.1-10.10.10.99”的ip段字符串 + */ + public static boolean isIPSegment(String ipSeg) + { + return StringUtils.isNotBlank(ipSeg) && ipSeg.matches(REGX_IP_SEG); + } + + /** + * 判断ip是否在指定网段中 + */ + public static boolean ipIsInNetNoCheck(String iparea, String ip) + { + int idx = iparea.indexOf('-'); + String[] sips = iparea.substring(0, idx).split("\\."); + String[] sipe = iparea.substring(idx + 1).split("\\."); + String[] sipt = ip.split("\\."); + long ips = 0L, ipe = 0L, ipt = 0L; + for (int i = 0; i < 4; ++i) + { + ips = ips << 8 | Integer.parseInt(sips[i]); + ipe = ipe << 8 | Integer.parseInt(sipe[i]); + ipt = ipt << 8 | Integer.parseInt(sipt[i]); + } + if (ips > ipe) + { + long t = ips; + ips = ipe; + ipe = t; + } + return ips <= ipt && ipt <= ipe; + } + + /** + * 校验ip是否符合过滤串规则 + * + * @param filter 过滤IP列表,支持后缀'*'通配,支持网段如:`10.10.10.1-10.10.10.99` + * @param ip 校验IP地址 + * @return boolean 结果 + */ + public static boolean isMatchedIp(String filter, String ip) + { + if (StringUtils.isEmpty(filter) || StringUtils.isEmpty(ip)) + { + return false; + } + String[] ips = filter.split(";"); + for (String iStr : ips) + { + if (isIP(iStr) && iStr.equals(ip)) + { + return true; + } + else if (isIpWildCard(iStr) && ipIsInWildCardNoCheck(iStr, ip)) + { + return true; + } + else if (isIPSegment(iStr) && ipIsInNetNoCheck(iStr, ip)) + { + return true; + } + } + return false; + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/poi/ExcelHandlerAdapter.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/poi/ExcelHandlerAdapter.java new file mode 100644 index 0000000..72f46a6 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/poi/ExcelHandlerAdapter.java @@ -0,0 +1,19 @@ +package com.dcsoft.common.core.utils.poi; + +/** + * Excel数据格式处理适配器 + * + * @author dcsoft + */ +public interface ExcelHandlerAdapter +{ + /** + * 格式化 + * + * @param value 单元格数据值 + * @param args excel注解args参数组 + * + * @return 处理后的值 + */ + Object format(Object value, String[] args); +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/poi/ExcelUtil.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/poi/ExcelUtil.java new file mode 100644 index 0000000..050e4f6 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/poi/ExcelUtil.java @@ -0,0 +1,1486 @@ +package com.dcsoft.common.core.utils.poi; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.RegExUtils; +import org.apache.commons.lang3.reflect.FieldUtils; +import org.apache.poi.ss.usermodel.BorderStyle; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.ClientAnchor; +import org.apache.poi.ss.usermodel.DataValidation; +import org.apache.poi.ss.usermodel.DataValidationConstraint; +import org.apache.poi.ss.usermodel.DataValidationHelper; +import org.apache.poi.ss.usermodel.DateUtil; +import org.apache.poi.ss.usermodel.Drawing; +import org.apache.poi.ss.usermodel.FillPatternType; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.usermodel.Name; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.VerticalAlignment; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.ss.usermodel.WorkbookFactory; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.util.CellRangeAddressList; +import org.apache.poi.util.IOUtils; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.XSSFClientAnchor; +import org.apache.poi.xssf.usermodel.XSSFDataValidation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.annotation.Excel.ColumnType; +import com.dcsoft.common.core.annotation.Excel.Type; +import com.dcsoft.common.core.annotation.Excels; +import com.dcsoft.common.core.text.Convert; +import com.dcsoft.common.core.utils.DateUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.utils.file.FileTypeUtils; +import com.dcsoft.common.core.utils.file.ImageUtils; +import com.dcsoft.common.core.utils.reflect.ReflectUtils; + +/** + * Excel相关处理 + * + * @author dcsoft + */ +public class ExcelUtil +{ + private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class); + + public static final String FORMULA_REGEX_STR = "=|-|\\+|@"; + + public static final String[] FORMULA_STR = { "=", "-", "+", "@" }; + + /** + * Excel sheet最大行数,默认65536 + */ + public static final int sheetSize = 65536; + + /** + * 工作表名称 + */ + private String sheetName; + + /** + * 导出类型(EXPORT:导出数据;IMPORT:导入模板) + */ + private Type type; + + /** + * 工作薄对象 + */ + private Workbook wb; + + /** + * 工作表对象 + */ + private Sheet sheet; + + /** + * 样式列表 + */ + private Map styles; + + /** + * 导入导出数据列表 + */ + private List list; + + /** + * 注解列表 + */ + private List fields; + + /** + * 当前行号 + */ + private int rownum; + + /** + * 标题 + */ + private String title; + + /** + * 最大高度 + */ + private short maxHeight; + + /** + * 合并后最后行数 + */ + private int subMergedLastRowNum = 0; + + /** + * 合并后开始行数 + */ + private int subMergedFirstRowNum = 1; + + /** + * 对象的子列表方法 + */ + private Method subMethod; + + /** + * 对象的子列表属性 + */ + private List subFields; + + /** + * 统计列表 + */ + private Map statistics = new HashMap(); + + /** + * 数字格式 + */ + private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00"); + + /** + * 实体对象 + */ + public Class clazz; + + /** + * 需要排除列属性 + */ + public String[] excludeFields; + + public ExcelUtil(Class clazz) + { + this.clazz = clazz; + } + + /** + * 隐藏Excel中列属性 + * + * @param fields 列属性名 示例[单个"name"/多个"id","name"] + * @throws Exception + */ + public void hideColumn(String... fields) + { + this.excludeFields = fields; + } + + public void init(List list, String sheetName, String title, Type type) + { + if (list == null) + { + list = new ArrayList(); + } + this.list = list; + this.sheetName = sheetName; + this.type = type; + this.title = title; + createExcelField(); + createWorkbook(); + createTitle(); + createSubHead(); + } + + /** + * 创建excel第一行标题 + */ + public void createTitle() + { + if (StringUtils.isNotEmpty(title)) + { + subMergedFirstRowNum++; + subMergedLastRowNum++; + int titleLastCol = this.fields.size() - 1; + if (isSubList()) + { + titleLastCol = titleLastCol + subFields.size() - 1; + } + Row titleRow = sheet.createRow(rownum == 0 ? rownum++ : 0); + titleRow.setHeightInPoints(30); + Cell titleCell = titleRow.createCell(0); + titleCell.setCellStyle(styles.get("title")); + titleCell.setCellValue(title); + sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), titleRow.getRowNum(), titleLastCol)); + } + } + + /** + * 创建对象的子列表名称 + */ + public void createSubHead() + { + if (isSubList()) + { + subMergedFirstRowNum++; + subMergedLastRowNum++; + Row subRow = sheet.createRow(rownum); + int excelNum = 0; + for (Object[] objects : fields) + { + Excel attr = (Excel) objects[1]; + Cell headCell1 = subRow.createCell(excelNum); + headCell1.setCellValue(attr.name()); + headCell1.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor()))); + excelNum++; + } + int headFirstRow = excelNum - 1; + int headLastRow = headFirstRow + subFields.size() - 1; + if (headLastRow > headFirstRow) + { + sheet.addMergedRegion(new CellRangeAddress(rownum, rownum, headFirstRow, headLastRow)); + } + rownum++; + } + } + + /** + * 对excel表单默认第一个索引名转换成list + * + * @param is 输入流 + * @return 转换后集合 + */ + public List importExcel(InputStream is) throws Exception + { + return importExcel(is, 0); + } + + /** + * 对excel表单默认第一个索引名转换成list + * + * @param is 输入流 + * @param titleNum 标题占用行数 + * @return 转换后集合 + */ + public List importExcel(InputStream is, int titleNum) throws Exception + { + return importExcel(StringUtils.EMPTY, is, titleNum); + } + + /** + * 对excel表单指定表格索引名转换成list + * + * @param sheetName 表格索引名 + * @param titleNum 标题占用行数 + * @param is 输入流 + * @return 转换后集合 + */ + public List importExcel(String sheetName, InputStream is, int titleNum) throws Exception + { + this.type = Type.IMPORT; + this.wb = WorkbookFactory.create(is); + List list = new ArrayList(); + // 如果指定sheet名,则取指定sheet中的内容 否则默认指向第1个sheet + Sheet sheet = StringUtils.isNotEmpty(sheetName) ? wb.getSheet(sheetName) : wb.getSheetAt(0); + if (sheet == null) + { + throw new IOException("文件sheet不存在"); + } + + // 获取最后一个非空行的行下标,比如总行数为n,则返回的为n-1 + int rows = sheet.getLastRowNum(); + + if (rows > 0) + { + // 定义一个map用于存放excel列的序号和field. + Map cellMap = new HashMap(); + // 获取表头 + Row heard = sheet.getRow(titleNum); + for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++) + { + Cell cell = heard.getCell(i); + if (StringUtils.isNotNull(cell)) + { + String value = this.getCellValue(heard, i).toString(); + cellMap.put(value, i); + } + else + { + cellMap.put(null, i); + } + } + // 有数据时才处理 得到类的所有field. + List fields = this.getFields(); + Map fieldsMap = new HashMap(); + for (Object[] objects : fields) + { + Excel attr = (Excel) objects[1]; + Integer column = cellMap.get(attr.name()); + if (column != null) + { + fieldsMap.put(column, objects); + } + } + for (int i = titleNum + 1; i <= rows; i++) + { + // 从第2行开始取数据,默认第一行是表头. + Row row = sheet.getRow(i); + // 判断当前行是否是空行 + if (isRowEmpty(row)) + { + continue; + } + T entity = null; + for (Map.Entry entry : fieldsMap.entrySet()) + { + Object val = this.getCellValue(row, entry.getKey()); + + // 如果不存在实例则新建. + entity = (entity == null ? clazz.newInstance() : entity); + // 从map中得到对应列的field. + Field field = (Field) entry.getValue()[0]; + Excel attr = (Excel) entry.getValue()[1]; + // 取得类型,并根据对象类型设置值. + Class fieldType = field.getType(); + if (String.class == fieldType) + { + String s = Convert.toStr(val); + if (StringUtils.endsWith(s, ".0")) + { + val = StringUtils.substringBefore(s, ".0"); + } + else + { + String dateFormat = field.getAnnotation(Excel.class).dateFormat(); + if (StringUtils.isNotEmpty(dateFormat)) + { + val = parseDateToStr(dateFormat, val); + } + else + { + val = Convert.toStr(val); + } + } + } + else if ((Integer.TYPE == fieldType || Integer.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val))) + { + val = Convert.toInt(val); + } + else if ((Long.TYPE == fieldType || Long.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val))) + { + val = Convert.toLong(val); + } + else if (Double.TYPE == fieldType || Double.class == fieldType) + { + val = Convert.toDouble(val); + } + else if (Float.TYPE == fieldType || Float.class == fieldType) + { + val = Convert.toFloat(val); + } + else if (BigDecimal.class == fieldType) + { + val = Convert.toBigDecimal(val); + } + else if (Date.class == fieldType) + { + if (val instanceof String) + { + val = DateUtils.parseDate(val); + } + else if (val instanceof Double) + { + val = DateUtil.getJavaDate((Double) val); + } + } + else if (Boolean.TYPE == fieldType || Boolean.class == fieldType) + { + val = Convert.toBool(val, false); + } + if (StringUtils.isNotNull(fieldType)) + { + String propertyName = field.getName(); + if (StringUtils.isNotEmpty(attr.targetAttr())) + { + propertyName = field.getName() + "." + attr.targetAttr(); + } + else if (StringUtils.isNotEmpty(attr.readConverterExp())) + { + val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator()); + } + else if (!attr.handler().equals(ExcelHandlerAdapter.class)) + { + val = dataFormatHandlerAdapter(val, attr); + } + ReflectUtils.invokeSetter(entity, propertyName, val); + } + } + list.add(entity); + } + } + return list; + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param response 返回数据 + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @return 结果 + */ + public void exportExcel(HttpServletResponse response, List list, String sheetName) + { + exportExcel(response, list, sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param response 返回数据 + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public void exportExcel(HttpServletResponse response, List list, String sheetName, String title) + { + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + this.init(list, sheetName, title, Type.EXPORT); + exportExcel(response); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @return 结果 + */ + public void importTemplateExcel(HttpServletResponse response, String sheetName) + { + importTemplateExcel(response, sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public void importTemplateExcel(HttpServletResponse response, String sheetName, String title) + { + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + this.init(null, sheetName, title, Type.IMPORT); + exportExcel(response); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @return 结果 + */ + public void exportExcel(HttpServletResponse response) + { + try + { + writeSheet(); + wb.write(response.getOutputStream()); + } + catch (Exception e) + { + log.error("导出Excel异常{}", e.getMessage()); + } + finally + { + IOUtils.closeQuietly(wb); + } + } + + /** + * 创建写入数据到Sheet + */ + public void writeSheet() + { + // 取出一共有多少个sheet. + int sheetNo = Math.max(1, (int) Math.ceil(list.size() * 1.0 / sheetSize)); + for (int index = 0; index < sheetNo; index++) + { + createSheet(sheetNo, index); + + // 产生一行 + Row row = sheet.createRow(rownum); + int column = 0; + // 写入各个字段的列头名称 + for (Object[] os : fields) + { + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + if (Collection.class.isAssignableFrom(field.getType())) + { + for (Field subField : subFields) + { + Excel subExcel = subField.getAnnotation(Excel.class); + this.createHeadCell(subExcel, row, column++); + } + } + else + { + this.createHeadCell(excel, row, column++); + } + } + if (Type.EXPORT.equals(type)) + { + fillExcelData(index, row); + addStatisticsRow(); + } + } + } + + /** + * 填充excel数据 + * + * @param index 序号 + * @param row 单元格行 + */ + @SuppressWarnings("unchecked") + public void fillExcelData(int index, Row row) + { + int startNo = index * sheetSize; + int endNo = Math.min(startNo + sheetSize, list.size()); + int rowNo = (1 + rownum) - startNo; + for (int i = startNo; i < endNo; i++) + { + rowNo = isSubList() ? (i > 1 ? rowNo + 1 : rowNo + i) : i + 1 + rownum - startNo; + row = sheet.createRow(rowNo); + // 得到导出对象. + T vo = (T) list.get(i); + Collection subList = null; + if (isSubList()) + { + if (isSubListValue(vo)) + { + subList = getListCellValue(vo); + subMergedLastRowNum = subMergedLastRowNum + subList.size(); + } + else + { + subMergedFirstRowNum++; + subMergedLastRowNum++; + } + } + int column = 0; + for (Object[] os : fields) + { + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + if (Collection.class.isAssignableFrom(field.getType()) && StringUtils.isNotNull(subList)) + { + boolean subFirst = false; + for (Object obj : subList) + { + if (subFirst) + { + rowNo++; + row = sheet.createRow(rowNo); + } + List subFields = FieldUtils.getFieldsListWithAnnotation(obj.getClass(), Excel.class); + int subIndex = 0; + for (Field subField : subFields) + { + if (subField.isAnnotationPresent(Excel.class)) + { + subField.setAccessible(true); + Excel attr = subField.getAnnotation(Excel.class); + this.addCell(attr, row, (T) obj, subField, column + subIndex); + } + subIndex++; + } + subFirst = true; + } + this.subMergedFirstRowNum = this.subMergedFirstRowNum + subList.size(); + } + else + { + this.addCell(excel, row, vo, field, column++); + } + } + } + } + + /** + * 创建表格样式 + * + * @param wb 工作薄对象 + * @return 样式列表 + */ + private Map createStyles(Workbook wb) + { + // 写入各条记录,每条记录对应excel表中的一行 + Map styles = new HashMap(); + CellStyle style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + Font titleFont = wb.createFont(); + titleFont.setFontName("Arial"); + titleFont.setFontHeightInPoints((short) 16); + titleFont.setBold(true); + style.setFont(titleFont); + styles.put("title", style); + + style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setBorderRight(BorderStyle.THIN); + style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderLeft(BorderStyle.THIN); + style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderTop(BorderStyle.THIN); + style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderBottom(BorderStyle.THIN); + style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + Font dataFont = wb.createFont(); + dataFont.setFontName("Arial"); + dataFont.setFontHeightInPoints((short) 10); + style.setFont(dataFont); + styles.put("data", style); + + style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + Font totalFont = wb.createFont(); + totalFont.setFontName("Arial"); + totalFont.setFontHeightInPoints((short) 10); + style.setFont(totalFont); + styles.put("total", style); + + styles.putAll(annotationHeaderStyles(wb, styles)); + + styles.putAll(annotationDataStyles(wb)); + + return styles; + } + + /** + * 根据Excel注解创建表格头样式 + * + * @param wb 工作薄对象 + * @return 自定义样式列表 + */ + private Map annotationHeaderStyles(Workbook wb, Map styles) + { + Map headerStyles = new HashMap(); + for (Object[] os : fields) + { + Excel excel = (Excel) os[1]; + String key = StringUtils.format("header_{}_{}", excel.headerColor(), excel.headerBackgroundColor()); + if (!headerStyles.containsKey(key)) + { + CellStyle style = wb.createCellStyle(); + style.cloneStyleFrom(styles.get("data")); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setFillForegroundColor(excel.headerBackgroundColor().index); + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + Font headerFont = wb.createFont(); + headerFont.setFontName("Arial"); + headerFont.setFontHeightInPoints((short) 10); + headerFont.setBold(true); + headerFont.setColor(excel.headerColor().index); + style.setFont(headerFont); + headerStyles.put(key, style); + } + } + return headerStyles; + } + + /** + * 根据Excel注解创建表格列样式 + * + * @param wb 工作薄对象 + * @return 自定义样式列表 + */ + private Map annotationDataStyles(Workbook wb) + { + Map styles = new HashMap(); + for (Object[] os : fields) + { + Excel excel = (Excel) os[1]; + String key = StringUtils.format("data_{}_{}_{}", excel.align(), excel.color(), excel.backgroundColor()); + if (!styles.containsKey(key)) + { + CellStyle style = wb.createCellStyle(); + style.setAlignment(excel.align()); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setBorderRight(BorderStyle.THIN); + style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderLeft(BorderStyle.THIN); + style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderTop(BorderStyle.THIN); + style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderBottom(BorderStyle.THIN); + style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + style.setFillForegroundColor(excel.backgroundColor().getIndex()); + Font dataFont = wb.createFont(); + dataFont.setFontName("Arial"); + dataFont.setFontHeightInPoints((short) 10); + dataFont.setColor(excel.color().index); + style.setFont(dataFont); + styles.put(key, style); + } + } + return styles; + } + + /** + * 创建单元格 + */ + public Cell createHeadCell(Excel attr, Row row, int column) + { + // 创建列 + Cell cell = row.createCell(column); + // 写入列信息 + cell.setCellValue(attr.name()); + setDataValidation(attr, row, column); + cell.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor()))); + if (isSubList()) + { + // 填充默认样式,防止合并单元格样式失效 + sheet.setDefaultColumnStyle(column, styles.get(StringUtils.format("data_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor()))); + if (attr.needMerge()) + { + sheet.addMergedRegion(new CellRangeAddress(rownum - 1, rownum, column, column)); + } + } + return cell; + } + + /** + * 设置单元格信息 + * + * @param value 单元格值 + * @param attr 注解相关 + * @param cell 单元格信息 + */ + public void setCellVo(Object value, Excel attr, Cell cell) + { + if (ColumnType.STRING == attr.cellType()) + { + String cellValue = Convert.toStr(value); + // 对于任何以表达式触发字符 =-+@开头的单元格,直接使用tab字符作为前缀,防止CSV注入。 + if (StringUtils.startsWithAny(cellValue, FORMULA_STR)) + { + cellValue = RegExUtils.replaceFirst(cellValue, FORMULA_REGEX_STR, "\t$0"); + } + if (value instanceof Collection && StringUtils.equals("[]", cellValue)) + { + cellValue = StringUtils.EMPTY; + } + cell.setCellValue(StringUtils.isNull(cellValue) ? attr.defaultValue() : cellValue + attr.suffix()); + } + else if (ColumnType.NUMERIC == attr.cellType()) + { + if (StringUtils.isNotNull(value)) + { + cell.setCellValue(StringUtils.contains(Convert.toStr(value), ".") ? Convert.toDouble(value) : Convert.toInt(value)); + } + } + else if (ColumnType.IMAGE == attr.cellType()) + { + ClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1), cell.getRow().getRowNum() + 1); + String imagePath = Convert.toStr(value); + if (StringUtils.isNotEmpty(imagePath)) + { + byte[] data = ImageUtils.getImage(imagePath); + getDrawingPatriarch(cell.getSheet()).createPicture(anchor, + cell.getSheet().getWorkbook().addPicture(data, getImageType(data))); + } + } + } + + /** + * 获取画布 + */ + public static Drawing getDrawingPatriarch(Sheet sheet) + { + if (sheet.getDrawingPatriarch() == null) + { + sheet.createDrawingPatriarch(); + } + return sheet.getDrawingPatriarch(); + } + + /** + * 获取图片类型,设置图片插入类型 + */ + public int getImageType(byte[] value) + { + String type = FileTypeUtils.getFileExtendName(value); + if ("JPG".equalsIgnoreCase(type)) + { + return Workbook.PICTURE_TYPE_JPEG; + } + else if ("PNG".equalsIgnoreCase(type)) + { + return Workbook.PICTURE_TYPE_PNG; + } + return Workbook.PICTURE_TYPE_JPEG; + } + + /** + * 创建表格样式 + */ + public void setDataValidation(Excel attr, Row row, int column) + { + if (attr.name().indexOf("注:") >= 0) + { + sheet.setColumnWidth(column, 6000); + } + else + { + // 设置列宽 + sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256)); + } + if (StringUtils.isNotEmpty(attr.prompt()) || attr.combo().length > 0) + { + if (attr.combo().length > 15 || StringUtils.join(attr.combo()).length() > 255) + { + // 如果下拉数大于15或字符串长度大于255,则使用一个新sheet存储,避免生成的模板下拉值获取不到 + setXSSFValidationWithHidden(sheet, attr.combo(), attr.prompt(), 1, 100, column, column); + } + else + { + // 提示信息或只能选择不能输入的列内容. + setPromptOrValidation(sheet, attr.combo(), attr.prompt(), 1, 100, column, column); + } + } + } + + /** + * 添加单元格 + */ + public Cell addCell(Excel attr, Row row, T vo, Field field, int column) + { + Cell cell = null; + try + { + // 设置行高 + row.setHeight(maxHeight); + // 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列. + if (attr.isExport()) + { + // 创建cell + cell = row.createCell(column); + if (isSubListValue(vo) && getListCellValue(vo).size() > 1 && attr.needMerge()) + { + CellRangeAddress cellAddress = new CellRangeAddress(subMergedFirstRowNum, subMergedLastRowNum, column, column); + sheet.addMergedRegion(cellAddress); + } + cell.setCellStyle(styles.get(StringUtils.format("data_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor()))); + + // 用于读取对象中的属性 + Object value = getTargetValue(vo, field, attr); + String dateFormat = attr.dateFormat(); + String readConverterExp = attr.readConverterExp(); + String separator = attr.separator(); + if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value)) + { + cell.setCellValue(parseDateToStr(dateFormat, value)); + } + else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value)) + { + cell.setCellValue(convertByExp(Convert.toStr(value), readConverterExp, separator)); + } + else if (value instanceof BigDecimal && -1 != attr.scale()) + { + cell.setCellValue((((BigDecimal) value).setScale(attr.scale(), attr.roundingMode())).doubleValue()); + } + else if (!attr.handler().equals(ExcelHandlerAdapter.class)) + { + cell.setCellValue(dataFormatHandlerAdapter(value, attr)); + } + else + { + // 设置列类型 + setCellVo(value, attr, cell); + } + addStatisticsData(column, Convert.toStr(value), attr); + } + } + catch (Exception e) + { + log.error("导出Excel失败{}", e); + } + return cell; + } + + /** + * 设置 POI XSSFSheet 单元格提示或选择框 + * + * @param sheet 表单 + * @param textlist 下拉框显示的内容 + * @param promptContent 提示内容 + * @param firstRow 开始行 + * @param endRow 结束行 + * @param firstCol 开始列 + * @param endCol 结束列 + */ + public void setPromptOrValidation(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow, + int firstCol, int endCol) + { + DataValidationHelper helper = sheet.getDataValidationHelper(); + DataValidationConstraint constraint = textlist.length > 0 ? helper.createExplicitListConstraint(textlist) : helper.createCustomConstraint("DD1"); + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + DataValidation dataValidation = helper.createValidation(constraint, regions); + if (StringUtils.isNotEmpty(promptContent)) + { + // 如果设置了提示信息则鼠标放上去提示 + dataValidation.createPromptBox("", promptContent); + dataValidation.setShowPromptBox(true); + } + // 处理Excel兼容性问题 + if (dataValidation instanceof XSSFDataValidation) + { + dataValidation.setSuppressDropDownArrow(true); + dataValidation.setShowErrorBox(true); + } + else + { + dataValidation.setSuppressDropDownArrow(false); + } + sheet.addValidationData(dataValidation); + } + + /** + * 设置某些列的值只能输入预制的数据,显示下拉框(兼容超出一定数量的下拉框). + * + * @param sheet 要设置的sheet. + * @param textlist 下拉框显示的内容 + * @param promptContent 提示内容 + * @param firstRow 开始行 + * @param endRow 结束行 + * @param firstCol 开始列 + * @param endCol 结束列 + */ + public void setXSSFValidationWithHidden(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow, int firstCol, int endCol) + { + String hideSheetName = "combo_" + firstCol + "_" + endCol; + Sheet hideSheet = wb.createSheet(hideSheetName); // 用于存储 下拉菜单数据 + for (int i = 0; i < textlist.length; i++) + { + hideSheet.createRow(i).createCell(0).setCellValue(textlist[i]); + } + // 创建名称,可被其他单元格引用 + Name name = wb.createName(); + name.setNameName(hideSheetName + "_data"); + name.setRefersToFormula(hideSheetName + "!$A$1:$A$" + textlist.length); + DataValidationHelper helper = sheet.getDataValidationHelper(); + // 加载下拉列表内容 + DataValidationConstraint constraint = helper.createFormulaListConstraint(hideSheetName + "_data"); + // 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列 + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + // 数据有效性对象 + DataValidation dataValidation = helper.createValidation(constraint, regions); + if (StringUtils.isNotEmpty(promptContent)) + { + // 如果设置了提示信息则鼠标放上去提示 + dataValidation.createPromptBox("", promptContent); + dataValidation.setShowPromptBox(true); + } + // 处理Excel兼容性问题 + if (dataValidation instanceof XSSFDataValidation) + { + dataValidation.setSuppressDropDownArrow(true); + dataValidation.setShowErrorBox(true); + } + else + { + dataValidation.setSuppressDropDownArrow(false); + } + + sheet.addValidationData(dataValidation); + // 设置hiddenSheet隐藏 + wb.setSheetHidden(wb.getSheetIndex(hideSheet), true); + } + + /** + * 解析导出值 0=男,1=女,2=未知 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @param separator 分隔符 + * @return 解析后值 + */ + public static String convertByExp(String propertyValue, String converterExp, String separator) + { + StringBuilder propertyString = new StringBuilder(); + String[] convertSource = converterExp.split(","); + for (String item : convertSource) + { + String[] itemArray = item.split("="); + if (StringUtils.containsAny(propertyValue, separator)) + { + for (String value : propertyValue.split(separator)) + { + if (itemArray[0].equals(value)) + { + propertyString.append(itemArray[1] + separator); + break; + } + } + } + else + { + if (itemArray[0].equals(propertyValue)) + { + return itemArray[1]; + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 反向解析值 男=0,女=1,未知=2 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @param separator 分隔符 + * @return 解析后值 + */ + public static String reverseByExp(String propertyValue, String converterExp, String separator) + { + StringBuilder propertyString = new StringBuilder(); + String[] convertSource = converterExp.split(","); + for (String item : convertSource) + { + String[] itemArray = item.split("="); + if (StringUtils.containsAny(propertyValue, separator)) + { + for (String value : propertyValue.split(separator)) + { + if (itemArray[1].equals(value)) + { + propertyString.append(itemArray[0] + separator); + break; + } + } + } + else + { + if (itemArray[1].equals(propertyValue)) + { + return itemArray[0]; + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 数据处理器 + * + * @param value 数据值 + * @param excel 数据注解 + * @return + */ + public String dataFormatHandlerAdapter(Object value, Excel excel) + { + try + { + Object instance = excel.handler().newInstance(); + Method formatMethod = excel.handler().getMethod("format", new Class[] { Object.class, String[].class }); + value = formatMethod.invoke(instance, value, excel.args()); + } + catch (Exception e) + { + log.error("不能格式化数据 " + excel.handler(), e.getMessage()); + } + return Convert.toStr(value); + } + + /** + * 合计统计信息 + */ + private void addStatisticsData(Integer index, String text, Excel entity) + { + if (entity != null && entity.isStatistics()) + { + Double temp = 0D; + if (!statistics.containsKey(index)) + { + statistics.put(index, temp); + } + try + { + temp = Double.valueOf(text); + } + catch (NumberFormatException e) + { + } + statistics.put(index, statistics.get(index) + temp); + } + } + + /** + * 创建统计行 + */ + public void addStatisticsRow() + { + if (statistics.size() > 0) + { + Row row = sheet.createRow(sheet.getLastRowNum() + 1); + Set keys = statistics.keySet(); + Cell cell = row.createCell(0); + cell.setCellStyle(styles.get("total")); + cell.setCellValue("合计"); + + for (Integer key : keys) + { + cell = row.createCell(key); + cell.setCellStyle(styles.get("total")); + cell.setCellValue(DOUBLE_FORMAT.format(statistics.get(key))); + } + statistics.clear(); + } + } + + /** + * 获取bean中的属性值 + * + * @param vo 实体对象 + * @param field 字段 + * @param excel 注解 + * @return 最终的属性值 + * @throws Exception + */ + private Object getTargetValue(T vo, Field field, Excel excel) throws Exception + { + Object o = field.get(vo); + if (StringUtils.isNotEmpty(excel.targetAttr())) + { + String target = excel.targetAttr(); + if (target.contains(".")) + { + String[] targets = target.split("[.]"); + for (String name : targets) + { + o = getValue(o, name); + } + } + else + { + o = getValue(o, target); + } + } + return o; + } + + /** + * 以类的属性的get方法方法形式获取值 + * + * @param o + * @param name + * @return value + * @throws Exception + */ + private Object getValue(Object o, String name) throws Exception + { + if (StringUtils.isNotNull(o) && StringUtils.isNotEmpty(name)) + { + Class clazz = o.getClass(); + Field field = clazz.getDeclaredField(name); + field.setAccessible(true); + o = field.get(o); + } + return o; + } + + /** + * 得到所有定义字段 + */ + private void createExcelField() + { + this.fields = getFields(); + this.fields = this.fields.stream().sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort())).collect(Collectors.toList()); + this.maxHeight = getRowHeight(); + } + + /** + * 获取字段注解信息 + */ + public List getFields() + { + List fields = new ArrayList(); + List tempFields = new ArrayList<>(); + tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields())); + tempFields.addAll(Arrays.asList(clazz.getDeclaredFields())); + for (Field field : tempFields) + { + if (!ArrayUtils.contains(this.excludeFields, field.getName())) + { + // 单注解 + if (field.isAnnotationPresent(Excel.class)) + { + Excel attr = field.getAnnotation(Excel.class); + if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) + { + field.setAccessible(true); + fields.add(new Object[] { field, attr }); + } + if (Collection.class.isAssignableFrom(field.getType())) + { + subMethod = getSubMethod(field.getName(), clazz); + ParameterizedType pt = (ParameterizedType) field.getGenericType(); + Class subClass = (Class) pt.getActualTypeArguments()[0]; + this.subFields = FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class); + } + } + + // 多注解 + if (field.isAnnotationPresent(Excels.class)) + { + Excels attrs = field.getAnnotation(Excels.class); + Excel[] excels = attrs.value(); + for (Excel attr : excels) + { + if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) + { + field.setAccessible(true); + fields.add(new Object[] { field, attr }); + } + } + } + } + } + return fields; + } + + /** + * 根据注解获取最大行高 + */ + public short getRowHeight() + { + double maxHeight = 0; + for (Object[] os : this.fields) + { + Excel excel = (Excel) os[1]; + maxHeight = Math.max(maxHeight, excel.height()); + } + return (short) (maxHeight * 20); + } + + /** + * 创建一个工作簿 + */ + public void createWorkbook() + { + this.wb = new SXSSFWorkbook(500); + this.sheet = wb.createSheet(); + wb.setSheetName(0, sheetName); + this.styles = createStyles(wb); + } + + /** + * 创建工作表 + * + * @param sheetNo sheet数量 + * @param index 序号 + */ + public void createSheet(int sheetNo, int index) + { + // 设置工作表的名称. + if (sheetNo > 1 && index > 0) + { + this.sheet = wb.createSheet(); + this.createTitle(); + wb.setSheetName(index, sheetName + index); + } + } + + /** + * 获取单元格值 + * + * @param row 获取的行 + * @param column 获取单元格列号 + * @return 单元格值 + */ + public Object getCellValue(Row row, int column) + { + if (row == null) + { + return row; + } + Object val = ""; + try + { + Cell cell = row.getCell(column); + if (StringUtils.isNotNull(cell)) + { + if (cell.getCellType() == CellType.NUMERIC || cell.getCellType() == CellType.FORMULA) + { + val = cell.getNumericCellValue(); + if (DateUtil.isCellDateFormatted(cell)) + { + val = DateUtil.getJavaDate((Double) val); // POI Excel 日期格式转换 + } + else + { + if ((Double) val % 1 != 0) + { + val = new BigDecimal(val.toString()); + } + else + { + val = new DecimalFormat("0").format(val); + } + } + } + else if (cell.getCellType() == CellType.STRING) + { + val = cell.getStringCellValue(); + } + else if (cell.getCellType() == CellType.BOOLEAN) + { + val = cell.getBooleanCellValue(); + } + else if (cell.getCellType() == CellType.ERROR) + { + val = cell.getErrorCellValue(); + } + + } + } + catch (Exception e) + { + return val; + } + return val; + } + + /** + * 判断是否是空行 + * + * @param row 判断的行 + * @return + */ + private boolean isRowEmpty(Row row) + { + if (row == null) + { + return true; + } + for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) + { + Cell cell = row.getCell(i); + if (cell != null && cell.getCellType() != CellType.BLANK) + { + return false; + } + } + return true; + } + + /** + * 格式化不同类型的日期对象 + * + * @param dateFormat 日期格式 + * @param val 被格式化的日期对象 + * @return 格式化后的日期字符 + */ + public String parseDateToStr(String dateFormat, Object val) + { + if (val == null) + { + return ""; + } + String str; + if (val instanceof Date) + { + str = DateUtils.parseDateToStr(dateFormat, (Date) val); + } + else if (val instanceof LocalDateTime) + { + str = DateUtils.parseDateToStr(dateFormat, DateUtils.toDate((LocalDateTime) val)); + } + else if (val instanceof LocalDate) + { + str = DateUtils.parseDateToStr(dateFormat, DateUtils.toDate((LocalDate) val)); + } + else + { + str = val.toString(); + } + return str; + } + + /** + * 是否有对象的子列表 + */ + public boolean isSubList() + { + return StringUtils.isNotNull(subFields) && subFields.size() > 0; + } + + /** + * 是否有对象的子列表,集合不为空 + */ + public boolean isSubListValue(T vo) + { + return StringUtils.isNotNull(subFields) && subFields.size() > 0 && StringUtils.isNotNull(getListCellValue(vo)) && getListCellValue(vo).size() > 0; + } + + /** + * 获取集合的值 + */ + public Collection getListCellValue(Object obj) + { + Object value; + try + { + value = subMethod.invoke(obj, new Object[] {}); + } + catch (Exception e) + { + return new ArrayList(); + } + return (Collection) value; + } + + /** + * 获取对象的子列表方法 + * + * @param name 名称 + * @param pojoClass 类对象 + * @return 子列表方法 + */ + public Method getSubMethod(String name, Class pojoClass) + { + StringBuffer getMethodName = new StringBuffer("get"); + getMethodName.append(name.substring(0, 1).toUpperCase()); + getMethodName.append(name.substring(1)); + Method method = null; + try + { + method = pojoClass.getMethod(getMethodName.toString(), new Class[] {}); + } + catch (Exception e) + { + log.error("获取对象异常{}", e.getMessage()); + } + return method; + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/reflect/ReflectUtils.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/reflect/ReflectUtils.java new file mode 100644 index 0000000..bee5abf --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/reflect/ReflectUtils.java @@ -0,0 +1,410 @@ +package com.dcsoft.common.core.utils.reflect; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Date; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.apache.poi.ss.usermodel.DateUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.dcsoft.common.core.text.Convert; +import com.dcsoft.common.core.utils.DateUtils; + +/** + * 反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数. + * + * @author dcsoft + */ +@SuppressWarnings("rawtypes") +public class ReflectUtils +{ + private static final String SETTER_PREFIX = "set"; + + private static final String GETTER_PREFIX = "get"; + + private static final String CGLIB_CLASS_SEPARATOR = "$$"; + + private static Logger logger = LoggerFactory.getLogger(ReflectUtils.class); + + /** + * 调用Getter方法. + * 支持多级,如:对象名.对象名.方法 + */ + @SuppressWarnings("unchecked") + public static E invokeGetter(Object obj, String propertyName) + { + Object object = obj; + for (String name : StringUtils.split(propertyName, ".")) + { + String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name); + object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {}); + } + return (E) object; + } + + /** + * 调用Setter方法, 仅匹配方法名。 + * 支持多级,如:对象名.对象名.方法 + */ + public static void invokeSetter(Object obj, String propertyName, E value) + { + Object object = obj; + String[] names = StringUtils.split(propertyName, "."); + for (int i = 0; i < names.length; i++) + { + if (i < names.length - 1) + { + String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]); + object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {}); + } + else + { + String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]); + invokeMethodByName(object, setterMethodName, new Object[] { value }); + } + } + } + + /** + * 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数. + */ + @SuppressWarnings("unchecked") + public static E getFieldValue(final Object obj, final String fieldName) + { + Field field = getAccessibleField(obj, fieldName); + if (field == null) + { + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 "); + return null; + } + E result = null; + try + { + result = (E) field.get(obj); + } + catch (IllegalAccessException e) + { + logger.error("不可能抛出的异常{}", e.getMessage()); + } + return result; + } + + /** + * 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数. + */ + public static void setFieldValue(final Object obj, final String fieldName, final E value) + { + Field field = getAccessibleField(obj, fieldName); + if (field == null) + { + // throw new IllegalArgumentException("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 "); + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 "); + return; + } + try + { + field.set(obj, value); + } + catch (IllegalAccessException e) + { + logger.error("不可能抛出的异常: {}", e.getMessage()); + } + } + + /** + * 直接调用对象方法, 无视private/protected修饰符. + * 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用. + * 同时匹配方法名+参数类型, + */ + @SuppressWarnings("unchecked") + public static E invokeMethod(final Object obj, final String methodName, final Class[] parameterTypes, + final Object[] args) + { + if (obj == null || methodName == null) + { + return null; + } + Method method = getAccessibleMethod(obj, methodName, parameterTypes); + if (method == null) + { + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 "); + return null; + } + try + { + return (E) method.invoke(obj, args); + } + catch (Exception e) + { + String msg = "method: " + method + ", obj: " + obj + ", args: " + args + ""; + throw convertReflectionExceptionToUnchecked(msg, e); + } + } + + /** + * 直接调用对象方法, 无视private/protected修饰符, + * 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用. + * 只匹配函数名,如果有多个同名函数调用第一个。 + */ + @SuppressWarnings("unchecked") + public static E invokeMethodByName(final Object obj, final String methodName, final Object[] args) + { + Method method = getAccessibleMethodByName(obj, methodName, args.length); + if (method == null) + { + // 如果为空不报错,直接返回空。 + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 "); + return null; + } + try + { + // 类型转换(将参数数据类型转换为目标方法参数类型) + Class[] cs = method.getParameterTypes(); + for (int i = 0; i < cs.length; i++) + { + if (args[i] != null && !args[i].getClass().equals(cs[i])) + { + if (cs[i] == String.class) + { + args[i] = Convert.toStr(args[i]); + if (StringUtils.endsWith((String) args[i], ".0")) + { + args[i] = StringUtils.substringBefore((String) args[i], ".0"); + } + } + else if (cs[i] == Integer.class) + { + args[i] = Convert.toInt(args[i]); + } + else if (cs[i] == Long.class) + { + args[i] = Convert.toLong(args[i]); + } + else if (cs[i] == Double.class) + { + args[i] = Convert.toDouble(args[i]); + } + else if (cs[i] == Float.class) + { + args[i] = Convert.toFloat(args[i]); + } + else if (cs[i] == Date.class) + { + if (args[i] instanceof String) + { + args[i] = DateUtils.parseDate(args[i]); + } + else + { + args[i] = DateUtil.getJavaDate((Double) args[i]); + } + } + else if (cs[i] == boolean.class || cs[i] == Boolean.class) + { + args[i] = Convert.toBool(args[i]); + } + } + } + return (E) method.invoke(obj, args); + } + catch (Exception e) + { + String msg = "method: " + method + ", obj: " + obj + ", args: " + args + ""; + throw convertReflectionExceptionToUnchecked(msg, e); + } + } + + /** + * 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + */ + public static Field getAccessibleField(final Object obj, final String fieldName) + { + // 为空不报错。直接返回 null + if (obj == null) + { + return null; + } + Validate.notBlank(fieldName, "fieldName can't be blank"); + for (Class superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) + { + try + { + Field field = superClass.getDeclaredField(fieldName); + makeAccessible(field); + return field; + } + catch (NoSuchFieldException e) + { + continue; + } + } + return null; + } + + /** + * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + * 匹配函数名+参数类型。 + * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args) + */ + public static Method getAccessibleMethod(final Object obj, final String methodName, + final Class... parameterTypes) + { + // 为空不报错。直接返回 null + if (obj == null) + { + return null; + } + Validate.notBlank(methodName, "methodName can't be blank"); + for (Class searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) + { + try + { + Method method = searchType.getDeclaredMethod(methodName, parameterTypes); + makeAccessible(method); + return method; + } + catch (NoSuchMethodException e) + { + continue; + } + } + return null; + } + + /** + * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + * 只匹配函数名。 + * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args) + */ + public static Method getAccessibleMethodByName(final Object obj, final String methodName, int argsNum) + { + // 为空不报错。直接返回 null + if (obj == null) + { + return null; + } + Validate.notBlank(methodName, "methodName can't be blank"); + for (Class searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) + { + Method[] methods = searchType.getDeclaredMethods(); + for (Method method : methods) + { + if (method.getName().equals(methodName) && method.getParameterTypes().length == argsNum) + { + makeAccessible(method); + return method; + } + } + } + return null; + } + + /** + * 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 + */ + public static void makeAccessible(Method method) + { + if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) + && !method.isAccessible()) + { + method.setAccessible(true); + } + } + + /** + * 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 + */ + public static void makeAccessible(Field field) + { + if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) + || Modifier.isFinal(field.getModifiers())) && !field.isAccessible()) + { + field.setAccessible(true); + } + } + + /** + * 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处 + * 如无法找到, 返回Object.class. + */ + @SuppressWarnings("unchecked") + public static Class getClassGenricType(final Class clazz) + { + return getClassGenricType(clazz, 0); + } + + /** + * 通过反射, 获得Class定义中声明的父类的泛型参数的类型. + * 如无法找到, 返回Object.class. + */ + public static Class getClassGenricType(final Class clazz, final int index) + { + Type genType = clazz.getGenericSuperclass(); + + if (!(genType instanceof ParameterizedType)) + { + logger.debug(clazz.getSimpleName() + "'s superclass not ParameterizedType"); + return Object.class; + } + + Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); + + if (index >= params.length || index < 0) + { + logger.debug("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: " + + params.length); + return Object.class; + } + if (!(params[index] instanceof Class)) + { + logger.debug(clazz.getSimpleName() + " not set the actual class on superclass generic parameter"); + return Object.class; + } + + return (Class) params[index]; + } + + public static Class getUserClass(Object instance) + { + if (instance == null) + { + throw new RuntimeException("Instance must not be null"); + } + Class clazz = instance.getClass(); + if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) + { + Class superClass = clazz.getSuperclass(); + if (superClass != null && !Object.class.equals(superClass)) + { + return superClass; + } + } + return clazz; + + } + + /** + * 将反射时的checked exception转换为unchecked exception. + */ + public static RuntimeException convertReflectionExceptionToUnchecked(String msg, Exception e) + { + if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException + || e instanceof NoSuchMethodException) + { + return new IllegalArgumentException(msg, e); + } + else if (e instanceof InvocationTargetException) + { + return new RuntimeException(msg, ((InvocationTargetException) e).getTargetException()); + } + return new RuntimeException(msg, e); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/sign/Base64.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/sign/Base64.java new file mode 100644 index 0000000..d882254 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/sign/Base64.java @@ -0,0 +1,291 @@ +package com.dcsoft.common.core.utils.sign; + +/** + * Base64工具类 + * + * @author dcsoft + */ +public final class Base64 +{ + static private final int BASELENGTH = 128; + static private final int LOOKUPLENGTH = 64; + static private final int TWENTYFOURBITGROUP = 24; + static private final int EIGHTBIT = 8; + static private final int SIXTEENBIT = 16; + static private final int FOURBYTE = 4; + static private final int SIGN = -128; + static private final char PAD = '='; + static final private byte[] base64Alphabet = new byte[BASELENGTH]; + static final private char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH]; + + static + { + for (int i = 0; i < BASELENGTH; ++i) + { + base64Alphabet[i] = -1; + } + for (int i = 'Z'; i >= 'A'; i--) + { + base64Alphabet[i] = (byte) (i - 'A'); + } + for (int i = 'z'; i >= 'a'; i--) + { + base64Alphabet[i] = (byte) (i - 'a' + 26); + } + + for (int i = '9'; i >= '0'; i--) + { + base64Alphabet[i] = (byte) (i - '0' + 52); + } + + base64Alphabet['+'] = 62; + base64Alphabet['/'] = 63; + + for (int i = 0; i <= 25; i++) + { + lookUpBase64Alphabet[i] = (char) ('A' + i); + } + + for (int i = 26, j = 0; i <= 51; i++, j++) + { + lookUpBase64Alphabet[i] = (char) ('a' + j); + } + + for (int i = 52, j = 0; i <= 61; i++, j++) + { + lookUpBase64Alphabet[i] = (char) ('0' + j); + } + lookUpBase64Alphabet[62] = (char) '+'; + lookUpBase64Alphabet[63] = (char) '/'; + } + + private static boolean isWhiteSpace(char octect) + { + return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9); + } + + private static boolean isPad(char octect) + { + return (octect == PAD); + } + + private static boolean isData(char octect) + { + return (octect < BASELENGTH && base64Alphabet[octect] != -1); + } + + /** + * Encodes hex octects into Base64 + * + * @param binaryData Array containing binaryData + * @return Encoded Base64 array + */ + public static String encode(byte[] binaryData) + { + if (binaryData == null) + { + return null; + } + + int lengthDataBits = binaryData.length * EIGHTBIT; + if (lengthDataBits == 0) + { + return ""; + } + + int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP; + int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP; + int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets; + char encodedData[] = null; + + encodedData = new char[numberQuartet * 4]; + + byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0; + + int encodedIndex = 0; + int dataIndex = 0; + + for (int i = 0; i < numberTriplets; i++) + { + b1 = binaryData[dataIndex++]; + b2 = binaryData[dataIndex++]; + b3 = binaryData[dataIndex++]; + + l = (byte) (b2 & 0x0f); + k = (byte) (b1 & 0x03); + + byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); + byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0); + byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc); + + encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f]; + } + + // form integral number of 6-bit groups + if (fewerThan24bits == EIGHTBIT) + { + b1 = binaryData[dataIndex]; + k = (byte) (b1 & 0x03); + byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); + encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4]; + encodedData[encodedIndex++] = PAD; + encodedData[encodedIndex++] = PAD; + } + else if (fewerThan24bits == SIXTEENBIT) + { + b1 = binaryData[dataIndex]; + b2 = binaryData[dataIndex + 1]; + l = (byte) (b2 & 0x0f); + k = (byte) (b1 & 0x03); + + byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); + byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0); + + encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2]; + encodedData[encodedIndex++] = PAD; + } + return new String(encodedData); + } + + /** + * Decodes Base64 data into octects + * + * @param encoded string containing Base64 data + * @return Array containind decoded data. + */ + public static byte[] decode(String encoded) + { + if (encoded == null) + { + return null; + } + + char[] base64Data = encoded.toCharArray(); + // remove white spaces + int len = removeWhiteSpace(base64Data); + + if (len % FOURBYTE != 0) + { + return null;// should be divisible by four + } + + int numberQuadruple = (len / FOURBYTE); + + if (numberQuadruple == 0) + { + return new byte[0]; + } + + byte decodedData[] = null; + byte b1 = 0, b2 = 0, b3 = 0, b4 = 0; + char d1 = 0, d2 = 0, d3 = 0, d4 = 0; + + int i = 0; + int encodedIndex = 0; + int dataIndex = 0; + decodedData = new byte[(numberQuadruple) * 3]; + + for (; i < numberQuadruple - 1; i++) + { + + if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++])) + || !isData((d3 = base64Data[dataIndex++])) || !isData((d4 = base64Data[dataIndex++]))) + { + return null; + } // if found "no data" just return null + + b1 = base64Alphabet[d1]; + b2 = base64Alphabet[d2]; + b3 = base64Alphabet[d3]; + b4 = base64Alphabet[d4]; + + decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); + decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); + decodedData[encodedIndex++] = (byte) (b3 << 6 | b4); + } + + if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))) + { + return null;// if found "no data" just return null + } + + b1 = base64Alphabet[d1]; + b2 = base64Alphabet[d2]; + + d3 = base64Data[dataIndex++]; + d4 = base64Data[dataIndex++]; + if (!isData((d3)) || !isData((d4))) + {// Check if they are PAD characters + if (isPad(d3) && isPad(d4)) + { + if ((b2 & 0xf) != 0)// last 4 bits should be zero + { + return null; + } + byte[] tmp = new byte[i * 3 + 1]; + System.arraycopy(decodedData, 0, tmp, 0, i * 3); + tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); + return tmp; + } + else if (!isPad(d3) && isPad(d4)) + { + b3 = base64Alphabet[d3]; + if ((b3 & 0x3) != 0)// last 2 bits should be zero + { + return null; + } + byte[] tmp = new byte[i * 3 + 2]; + System.arraycopy(decodedData, 0, tmp, 0, i * 3); + tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); + tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); + return tmp; + } + else + { + return null; + } + } + else + { // No PAD e.g 3cQl + b3 = base64Alphabet[d3]; + b4 = base64Alphabet[d4]; + decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); + decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); + decodedData[encodedIndex++] = (byte) (b3 << 6 | b4); + + } + return decodedData; + } + + /** + * remove WhiteSpace from MIME containing encoded Base64 data. + * + * @param data the byte array of base64 data (with WS) + * @return the new length + */ + private static int removeWhiteSpace(char[] data) + { + if (data == null) + { + return 0; + } + + // count characters that's not whitespace + int newSize = 0; + int len = data.length; + for (int i = 0; i < len; i++) + { + if (!isWhiteSpace(data[i])) + { + data[newSize++] = data[i]; + } + } + return newSize; + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/sql/SqlUtil.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/sql/SqlUtil.java new file mode 100644 index 0000000..08d83a4 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/sql/SqlUtil.java @@ -0,0 +1,61 @@ +package com.dcsoft.common.core.utils.sql; + +import com.dcsoft.common.core.exception.UtilException; +import com.dcsoft.common.core.utils.StringUtils; + +/** + * sql操作工具类 + * + * @author dcsoft + */ +public class SqlUtil +{ + /** + * 定义常用的 sql关键字 + */ + public static String SQL_REGEX = "and |extractvalue|updatexml|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |+|user()"; + + /** + * 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序) + */ + public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+"; + + /** + * 检查字符,防止注入绕过 + */ + public static String escapeOrderBySql(String value) + { + if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)) + { + throw new UtilException("参数不符合规范,不能进行查询"); + } + return value; + } + + /** + * 验证 order by 语法是否符合规范 + */ + public static boolean isValidOrderBySql(String value) + { + return value.matches(SQL_PATTERN); + } + + /** + * SQL关键字检查 + */ + public static void filterKeyword(String value) + { + if (StringUtils.isEmpty(value)) + { + return; + } + String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|"); + for (String sqlKeyword : sqlKeywords) + { + if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1) + { + throw new UtilException("参数存在SQL注入风险"); + } + } + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/uuid/IdUtils.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/uuid/IdUtils.java new file mode 100644 index 0000000..7f021ec --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/uuid/IdUtils.java @@ -0,0 +1,49 @@ +package com.dcsoft.common.core.utils.uuid; + +/** + * ID生成器工具类 + * + * @author dcsoft + */ +public class IdUtils +{ + /** + * 获取随机UUID + * + * @return 随机UUID + */ + public static String randomUUID() + { + return UUID.randomUUID().toString(); + } + + /** + * 简化的UUID,去掉了横线 + * + * @return 简化的UUID,去掉了横线 + */ + public static String simpleUUID() + { + return UUID.randomUUID().toString(true); + } + + /** + * 获取随机UUID,使用性能更好的ThreadLocalRandom生成UUID + * + * @return 随机UUID + */ + public static String fastUUID() + { + return UUID.fastUUID().toString(); + } + + /** + * 简化的UUID,去掉了横线,使用性能更好的ThreadLocalRandom生成UUID + * + * @return 简化的UUID,去掉了横线 + */ + public static String fastSimpleUUID() + { + return UUID.fastUUID().toString(true); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/uuid/Seq.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/uuid/Seq.java new file mode 100644 index 0000000..c69c812 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/uuid/Seq.java @@ -0,0 +1,86 @@ +package com.dcsoft.common.core.utils.uuid; + +import java.util.concurrent.atomic.AtomicInteger; +import com.dcsoft.common.core.utils.DateUtils; +import com.dcsoft.common.core.utils.StringUtils; + +/** + * @author dcsoft 序列生成类 + */ +public class Seq +{ + // 通用序列类型 + public static final String commSeqType = "COMMON"; + + // 上传序列类型 + public static final String uploadSeqType = "UPLOAD"; + + // 通用接口序列数 + private static AtomicInteger commSeq = new AtomicInteger(1); + + // 上传接口序列数 + private static AtomicInteger uploadSeq = new AtomicInteger(1); + + // 机器标识 + private static final String machineCode = "A"; + + /** + * 获取通用序列号 + * + * @return 序列值 + */ + public static String getId() + { + return getId(commSeqType); + } + + /** + * 默认16位序列号 yyMMddHHmmss + 一位机器标识 + 3长度循环递增字符串 + * + * @return 序列值 + */ + public static String getId(String type) + { + AtomicInteger atomicInt = commSeq; + if (uploadSeqType.equals(type)) + { + atomicInt = uploadSeq; + } + return getId(atomicInt, 3); + } + + /** + * 通用接口序列号 yyMMddHHmmss + 一位机器标识 + length长度循环递增字符串 + * + * @param atomicInt 序列数 + * @param length 数值长度 + * @return 序列值 + */ + public static String getId(AtomicInteger atomicInt, int length) + { + String result = DateUtils.dateTimeNow(); + result += machineCode; + result += getSeq(atomicInt, length); + return result; + } + + /** + * 序列循环递增字符串[1, 10 的 (length)幂次方), 用0左补齐length位数 + * + * @return 序列值 + */ + private synchronized static String getSeq(AtomicInteger atomicInt, int length) + { + // 先取值再+1 + int value = atomicInt.getAndIncrement(); + + // 如果更新后值>=10 的 (length)幂次方则重置为1 + int maxSeq = (int) Math.pow(10, length); + if (atomicInt.get() >= maxSeq) + { + atomicInt.set(1); + } + // 转字符串,用0左补齐 + return StringUtils.padl(value, length); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/uuid/UUID.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/uuid/UUID.java new file mode 100644 index 0000000..09bb1c2 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/utils/uuid/UUID.java @@ -0,0 +1,484 @@ +package com.dcsoft.common.core.utils.uuid; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; +import com.dcsoft.common.core.exception.UtilException; + +/** + * 提供通用唯一识别码(universally unique identifier)(UUID)实现 + * + * @author dcsoft + */ +public final class UUID implements java.io.Serializable, Comparable +{ + private static final long serialVersionUID = -1185015143654744140L; + + /** + * SecureRandom 的单例 + * + */ + private static class Holder + { + static final SecureRandom numberGenerator = getSecureRandom(); + } + + /** 此UUID的最高64有效位 */ + private final long mostSigBits; + + /** 此UUID的最低64有效位 */ + private final long leastSigBits; + + /** + * 私有构造 + * + * @param data 数据 + */ + private UUID(byte[] data) + { + long msb = 0; + long lsb = 0; + assert data.length == 16 : "data must be 16 bytes in length"; + for (int i = 0; i < 8; i++) + { + msb = (msb << 8) | (data[i] & 0xff); + } + for (int i = 8; i < 16; i++) + { + lsb = (lsb << 8) | (data[i] & 0xff); + } + this.mostSigBits = msb; + this.leastSigBits = lsb; + } + + /** + * 使用指定的数据构造新的 UUID。 + * + * @param mostSigBits 用于 {@code UUID} 的最高有效 64 位 + * @param leastSigBits 用于 {@code UUID} 的最低有效 64 位 + */ + public UUID(long mostSigBits, long leastSigBits) + { + this.mostSigBits = mostSigBits; + this.leastSigBits = leastSigBits; + } + + /** + * 获取类型 4(伪随机生成的)UUID 的静态工厂。 使用加密的本地线程伪随机数生成器生成该 UUID。 + * + * @return 随机生成的 {@code UUID} + */ + public static UUID fastUUID() + { + return randomUUID(false); + } + + /** + * 获取类型 4(伪随机生成的)UUID 的静态工厂。 使用加密的强伪随机数生成器生成该 UUID。 + * + * @return 随机生成的 {@code UUID} + */ + public static UUID randomUUID() + { + return randomUUID(true); + } + + /** + * 获取类型 4(伪随机生成的)UUID 的静态工厂。 使用加密的强伪随机数生成器生成该 UUID。 + * + * @param isSecure 是否使用{@link SecureRandom}如果是可以获得更安全的随机码,否则可以得到更好的性能 + * @return 随机生成的 {@code UUID} + */ + public static UUID randomUUID(boolean isSecure) + { + final Random ng = isSecure ? Holder.numberGenerator : getRandom(); + + byte[] randomBytes = new byte[16]; + ng.nextBytes(randomBytes); + randomBytes[6] &= 0x0f; /* clear version */ + randomBytes[6] |= 0x40; /* set to version 4 */ + randomBytes[8] &= 0x3f; /* clear variant */ + randomBytes[8] |= 0x80; /* set to IETF variant */ + return new UUID(randomBytes); + } + + /** + * 根据指定的字节数组获取类型 3(基于名称的)UUID 的静态工厂。 + * + * @param name 用于构造 UUID 的字节数组。 + * + * @return 根据指定数组生成的 {@code UUID} + */ + public static UUID nameUUIDFromBytes(byte[] name) + { + MessageDigest md; + try + { + md = MessageDigest.getInstance("MD5"); + } + catch (NoSuchAlgorithmException nsae) + { + throw new InternalError("MD5 not supported"); + } + byte[] md5Bytes = md.digest(name); + md5Bytes[6] &= 0x0f; /* clear version */ + md5Bytes[6] |= 0x30; /* set to version 3 */ + md5Bytes[8] &= 0x3f; /* clear variant */ + md5Bytes[8] |= 0x80; /* set to IETF variant */ + return new UUID(md5Bytes); + } + + /** + * 根据 {@link #toString()} 方法中描述的字符串标准表示形式创建{@code UUID}。 + * + * @param name 指定 {@code UUID} 字符串 + * @return 具有指定值的 {@code UUID} + * @throws IllegalArgumentException 如果 name 与 {@link #toString} 中描述的字符串表示形式不符抛出此异常 + * + */ + public static UUID fromString(String name) + { + String[] components = name.split("-"); + if (components.length != 5) + { + throw new IllegalArgumentException("Invalid UUID string: " + name); + } + for (int i = 0; i < 5; i++) + { + components[i] = "0x" + components[i]; + } + + long mostSigBits = Long.decode(components[0]).longValue(); + mostSigBits <<= 16; + mostSigBits |= Long.decode(components[1]).longValue(); + mostSigBits <<= 16; + mostSigBits |= Long.decode(components[2]).longValue(); + + long leastSigBits = Long.decode(components[3]).longValue(); + leastSigBits <<= 48; + leastSigBits |= Long.decode(components[4]).longValue(); + + return new UUID(mostSigBits, leastSigBits); + } + + /** + * 返回此 UUID 的 128 位值中的最低有效 64 位。 + * + * @return 此 UUID 的 128 位值中的最低有效 64 位。 + */ + public long getLeastSignificantBits() + { + return leastSigBits; + } + + /** + * 返回此 UUID 的 128 位值中的最高有效 64 位。 + * + * @return 此 UUID 的 128 位值中最高有效 64 位。 + */ + public long getMostSignificantBits() + { + return mostSigBits; + } + + /** + * 与此 {@code UUID} 相关联的版本号. 版本号描述此 {@code UUID} 是如何生成的。 + *

+ * 版本号具有以下含意: + *

    + *
  • 1 基于时间的 UUID + *
  • 2 DCE 安全 UUID + *
  • 3 基于名称的 UUID + *
  • 4 随机生成的 UUID + *
+ * + * @return 此 {@code UUID} 的版本号 + */ + public int version() + { + // Version is bits masked by 0x000000000000F000 in MS long + return (int) ((mostSigBits >> 12) & 0x0f); + } + + /** + * 与此 {@code UUID} 相关联的变体号。变体号描述 {@code UUID} 的布局。 + *

+ * 变体号具有以下含意: + *

    + *
  • 0 为 NCS 向后兼容保留 + *
  • 2 IETF RFC 4122(Leach-Salz), 用于此类 + *
  • 6 保留,微软向后兼容 + *
  • 7 保留供以后定义使用 + *
+ * + * @return 此 {@code UUID} 相关联的变体号 + */ + public int variant() + { + // This field is composed of a varying number of bits. + // 0 - - Reserved for NCS backward compatibility + // 1 0 - The IETF aka Leach-Salz variant (used by this class) + // 1 1 0 Reserved, Microsoft backward compatibility + // 1 1 1 Reserved for future definition. + return (int) ((leastSigBits >>> (64 - (leastSigBits >>> 62))) & (leastSigBits >> 63)); + } + + /** + * 与此 UUID 相关联的时间戳值。 + * + *

+ * 60 位的时间戳值根据此 {@code UUID} 的 time_low、time_mid 和 time_hi 字段构造。
+ * 所得到的时间戳以 100 毫微秒为单位,从 UTC(通用协调时间) 1582 年 10 月 15 日零时开始。 + * + *

+ * 时间戳值仅在在基于时间的 UUID(其 version 类型为 1)中才有意义。
+ * 如果此 {@code UUID} 不是基于时间的 UUID,则此方法抛出 UnsupportedOperationException。 + * + * @throws UnsupportedOperationException 如果此 {@code UUID} 不是 version 为 1 的 UUID。 + */ + public long timestamp() throws UnsupportedOperationException + { + checkTimeBase(); + return (mostSigBits & 0x0FFFL) << 48// + | ((mostSigBits >> 16) & 0x0FFFFL) << 32// + | mostSigBits >>> 32; + } + + /** + * 与此 UUID 相关联的时钟序列值。 + * + *

+ * 14 位的时钟序列值根据此 UUID 的 clock_seq 字段构造。clock_seq 字段用于保证在基于时间的 UUID 中的时间唯一性。 + *

+ * {@code clockSequence} 值仅在基于时间的 UUID(其 version 类型为 1)中才有意义。 如果此 UUID 不是基于时间的 UUID,则此方法抛出 + * UnsupportedOperationException。 + * + * @return 此 {@code UUID} 的时钟序列 + * + * @throws UnsupportedOperationException 如果此 UUID 的 version 不为 1 + */ + public int clockSequence() throws UnsupportedOperationException + { + checkTimeBase(); + return (int) ((leastSigBits & 0x3FFF000000000000L) >>> 48); + } + + /** + * 与此 UUID 相关的节点值。 + * + *

+ * 48 位的节点值根据此 UUID 的 node 字段构造。此字段旨在用于保存机器的 IEEE 802 地址,该地址用于生成此 UUID 以保证空间唯一性。 + *

+ * 节点值仅在基于时间的 UUID(其 version 类型为 1)中才有意义。
+ * 如果此 UUID 不是基于时间的 UUID,则此方法抛出 UnsupportedOperationException。 + * + * @return 此 {@code UUID} 的节点值 + * + * @throws UnsupportedOperationException 如果此 UUID 的 version 不为 1 + */ + public long node() throws UnsupportedOperationException + { + checkTimeBase(); + return leastSigBits & 0x0000FFFFFFFFFFFFL; + } + + /** + * 返回此{@code UUID} 的字符串表现形式。 + * + *

+ * UUID 的字符串表示形式由此 BNF 描述: + * + *

+     * {@code
+     * UUID                   = ----
+     * time_low               = 4*
+     * time_mid               = 2*
+     * time_high_and_version  = 2*
+     * variant_and_sequence   = 2*
+     * node                   = 6*
+     * hexOctet               = 
+     * hexDigit               = [0-9a-fA-F]
+     * }
+     * 
+ * + * + * + * @return 此{@code UUID} 的字符串表现形式 + * @see #toString(boolean) + */ + @Override + public String toString() + { + return toString(false); + } + + /** + * 返回此{@code UUID} 的字符串表现形式。 + * + *

+ * UUID 的字符串表示形式由此 BNF 描述: + * + *

+     * {@code
+     * UUID                   = ----
+     * time_low               = 4*
+     * time_mid               = 2*
+     * time_high_and_version  = 2*
+     * variant_and_sequence   = 2*
+     * node                   = 6*
+     * hexOctet               = 
+     * hexDigit               = [0-9a-fA-F]
+     * }
+     * 
+ * + * + * + * @param isSimple 是否简单模式,简单模式为不带'-'的UUID字符串 + * @return 此{@code UUID} 的字符串表现形式 + */ + public String toString(boolean isSimple) + { + final StringBuilder builder = new StringBuilder(isSimple ? 32 : 36); + // time_low + builder.append(digits(mostSigBits >> 32, 8)); + if (false == isSimple) + { + builder.append('-'); + } + // time_mid + builder.append(digits(mostSigBits >> 16, 4)); + if (false == isSimple) + { + builder.append('-'); + } + // time_high_and_version + builder.append(digits(mostSigBits, 4)); + if (false == isSimple) + { + builder.append('-'); + } + // variant_and_sequence + builder.append(digits(leastSigBits >> 48, 4)); + if (false == isSimple) + { + builder.append('-'); + } + // node + builder.append(digits(leastSigBits, 12)); + + return builder.toString(); + } + + /** + * 返回此 UUID 的哈希码。 + * + * @return UUID 的哈希码值。 + */ + @Override + public int hashCode() + { + long hilo = mostSigBits ^ leastSigBits; + return ((int) (hilo >> 32)) ^ (int) hilo; + } + + /** + * 将此对象与指定对象比较。 + *

+ * 当且仅当参数不为 {@code null}、而是一个 UUID 对象、具有与此 UUID 相同的 varriant、包含相同的值(每一位均相同)时,结果才为 {@code true}。 + * + * @param obj 要与之比较的对象 + * + * @return 如果对象相同,则返回 {@code true};否则返回 {@code false} + */ + @Override + public boolean equals(Object obj) + { + if ((null == obj) || (obj.getClass() != UUID.class)) + { + return false; + } + UUID id = (UUID) obj; + return (mostSigBits == id.mostSigBits && leastSigBits == id.leastSigBits); + } + + // Comparison Operations + + /** + * 将此 UUID 与指定的 UUID 比较。 + * + *

+ * 如果两个 UUID 不同,且第一个 UUID 的最高有效字段大于第二个 UUID 的对应字段,则第一个 UUID 大于第二个 UUID。 + * + * @param val 与此 UUID 比较的 UUID + * + * @return 在此 UUID 小于、等于或大于 val 时,分别返回 -1、0 或 1。 + * + */ + @Override + public int compareTo(UUID val) + { + // The ordering is intentionally set up so that the UUIDs + // can simply be numerically compared as two numbers + return (this.mostSigBits < val.mostSigBits ? -1 : // + (this.mostSigBits > val.mostSigBits ? 1 : // + (this.leastSigBits < val.leastSigBits ? -1 : // + (this.leastSigBits > val.leastSigBits ? 1 : // + 0)))); + } + + // ------------------------------------------------------------------------------------------------------------------- + // Private method start + /** + * 返回指定数字对应的hex值 + * + * @param val 值 + * @param digits 位 + * @return 值 + */ + private static String digits(long val, int digits) + { + long hi = 1L << (digits * 4); + return Long.toHexString(hi | (val & (hi - 1))).substring(1); + } + + /** + * 检查是否为time-based版本UUID + */ + private void checkTimeBase() + { + if (version() != 1) + { + throw new UnsupportedOperationException("Not a time-based UUID"); + } + } + + /** + * 获取{@link SecureRandom},类提供加密的强随机数生成器 (RNG) + * + * @return {@link SecureRandom} + */ + public static SecureRandom getSecureRandom() + { + try + { + return SecureRandom.getInstance("SHA1PRNG"); + } + catch (NoSuchAlgorithmException e) + { + throw new UtilException(e); + } + } + + /** + * 获取随机数生成器对象
+ * ThreadLocalRandom是JDK 7之后提供并发产生随机数,能够解决多个线程发生的竞争争夺。 + * + * @return {@link ThreadLocalRandom} + */ + public static ThreadLocalRandom getRandom() + { + return ThreadLocalRandom.current(); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/controller/BaseController.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/controller/BaseController.java new file mode 100644 index 0000000..771e42a --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/controller/BaseController.java @@ -0,0 +1,152 @@ +package com.dcsoft.common.core.web.controller; + +import java.beans.PropertyEditorSupport; +import java.util.Date; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.InitBinder; +import com.github.pagehelper.PageInfo; +import com.dcsoft.common.core.constant.HttpStatus; +import com.dcsoft.common.core.utils.DateUtils; +import com.dcsoft.common.core.utils.PageUtils; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDataInfo; + +/** + * web层通用数据处理 + * + * @author dcsoft + */ +public class BaseController +{ + protected final Logger logger = LoggerFactory.getLogger(this.getClass()); + + /** + * 将前台传递过来的日期格式的字符串,自动转化为Date类型 + */ + @InitBinder + public void initBinder(WebDataBinder binder) + { + // Date 类型转换 + binder.registerCustomEditor(Date.class, new PropertyEditorSupport() + { + @Override + public void setAsText(String text) + { + setValue(DateUtils.parseDate(text)); + } + }); + } + + /** + * 设置请求分页数据 + */ + protected void startPage() + { + PageUtils.startPage(); + } + + /** + * 清理分页的线程变量 + */ + protected void clearPage() + { + PageUtils.clearPage(); + } + + /** + * 响应请求分页数据 + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + protected TableDataInfo getDataTable(List list) + { + TableDataInfo rspData = new TableDataInfo(); + rspData.setCode(HttpStatus.SUCCESS); + rspData.setRows(list); + rspData.setMsg("查询成功"); + rspData.setTotal(new PageInfo(list).getTotal()); + return rspData; + } + + protected TableDataInfo getDataTable(List list, int total) + { + TableDataInfo rspData = new TableDataInfo(); + rspData.setCode(HttpStatus.SUCCESS); + rspData.setData(list); + rspData.setMsg("查询成功"); + rspData.setTotal(new PageInfo(list).getTotal()); + return rspData; + } + + /** + * 返回成功 + */ + public AjaxResult success() + { + return AjaxResult.success(); + } + + /** + * 返回成功消息 + */ + public AjaxResult success(String message) + { + return AjaxResult.success(message); + } + + /** + * 返回成功消息 + */ + public AjaxResult success(Object data) + { + return AjaxResult.success(data); + } + + /** + * 返回失败消息 + */ + public AjaxResult error() + { + return AjaxResult.error(); + } + + /** + * 返回失败消息 + */ + public AjaxResult error(String message) + { + return AjaxResult.error(message); + } + + /** + * 返回警告消息 + */ + public AjaxResult warn(String message) + { + return AjaxResult.warn(message); + } + + /** + * 响应返回结果 + * + * @param rows 影响行数 + * @return 操作结果 + */ + protected AjaxResult toAjax(int rows) + { + return rows > 0 ? AjaxResult.success() : AjaxResult.error(); + } + + /** + * 响应返回结果 + * + * @param result 结果 + * @return 操作结果 + */ + protected AjaxResult toAjax(boolean result) + { + return result ? success() : error(); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/domain/AjaxResult.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/domain/AjaxResult.java new file mode 100644 index 0000000..12d16b4 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/domain/AjaxResult.java @@ -0,0 +1,206 @@ +package com.dcsoft.common.core.web.domain; + +import java.util.HashMap; +import java.util.Objects; +import com.dcsoft.common.core.constant.HttpStatus; +import com.dcsoft.common.core.utils.StringUtils; + +/** + * 操作消息提醒 + * + * @author dcsoft + */ +public class AjaxResult extends HashMap +{ + private static final long serialVersionUID = 1L; + + /** 状态码 */ + public static final String CODE_TAG = "code"; + + /** 返回内容 */ + public static final String MSG_TAG = "msg"; + + /** 数据对象 */ + public static final String DATA_TAG = "data"; + + /** + * 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。 + */ + public AjaxResult() + { + } + + /** + * 初始化一个新创建的 AjaxResult 对象 + * + * @param code 状态码 + * @param msg 返回内容 + */ + public AjaxResult(int code, String msg) + { + super.put(CODE_TAG, code); + super.put(MSG_TAG, msg); + } + + /** + * 初始化一个新创建的 AjaxResult 对象 + * + * @param code 状态码 + * @param msg 返回内容 + * @param data 数据对象 + */ + public AjaxResult(int code, String msg, Object data) + { + super.put(CODE_TAG, code); + super.put(MSG_TAG, msg); + if (StringUtils.isNotNull(data)) + { + super.put(DATA_TAG, data); + } + } + + /** + * 返回成功消息 + * + * @return 成功消息 + */ + public static AjaxResult success() + { + return AjaxResult.success("操作成功"); + } + + /** + * 返回成功数据 + * + * @return 成功消息 + */ + public static AjaxResult success(Object data) + { + return AjaxResult.success("操作成功", data); + } + + /** + * 返回成功消息 + * + * @param msg 返回内容 + * @return 成功消息 + */ + public static AjaxResult success(String msg) + { + return AjaxResult.success(msg, null); + } + + /** + * 返回成功消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 成功消息 + */ + public static AjaxResult success(String msg, Object data) + { + return new AjaxResult(HttpStatus.SUCCESS, msg, data); + } + + /** + * 返回警告消息 + * + * @param msg 返回内容 + * @return 警告消息 + */ + public static AjaxResult warn(String msg) + { + return AjaxResult.warn(msg, null); + } + + /** + * 返回警告消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 警告消息 + */ + public static AjaxResult warn(String msg, Object data) + { + return new AjaxResult(HttpStatus.WARN, msg, data); + } + + /** + * 返回错误消息 + * + * @return 错误消息 + */ + public static AjaxResult error() + { + return AjaxResult.error("操作失败"); + } + + /** + * 返回错误消息 + * + * @param msg 返回内容 + * @return 错误消息 + */ + public static AjaxResult error(String msg) + { + return AjaxResult.error(msg, null); + } + + /** + * 返回错误消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 错误消息 + */ + public static AjaxResult error(String msg, Object data) + { + return new AjaxResult(HttpStatus.ERROR, msg, data); + } + + /** + * 返回错误消息 + * + * @param code 状态码 + * @param msg 返回内容 + * @return 错误消息 + */ + public static AjaxResult error(int code, String msg) + { + return new AjaxResult(code, msg, null); + } + + /** + * 是否为成功消息 + * + * @return 结果 + */ + public boolean isSuccess() + { + return Objects.equals(HttpStatus.SUCCESS, this.get(CODE_TAG)); + } + + /** + * 是否为错误消息 + * + * @return 结果 + */ + public boolean isError() + { + return !isSuccess(); + } + + /** + * 方便链式调用 + * + * @param key + * @param value + * @return + */ + @Override + public AjaxResult put(String key, Object value) + { + super.put(key, value); + return this; + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/domain/BaseEntity.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/domain/BaseEntity.java new file mode 100644 index 0000000..ccbae70 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/domain/BaseEntity.java @@ -0,0 +1,118 @@ +package com.dcsoft.common.core.web.domain; + +import java.io.Serializable; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; + +/** + * Entity基类 + * + * @author dcsoft + */ +public class BaseEntity implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 搜索值 */ + @JsonIgnore + private String searchValue; + + /** 创建者 */ + private String createBy; + + /** 创建时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + /** 更新者 */ + private String updateBy; + + /** 更新时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; + + /** 备注 */ + private String remark; + + /** 请求参数 */ + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private Map params; + + public String getSearchValue() + { + return searchValue; + } + + public void setSearchValue(String searchValue) + { + this.searchValue = searchValue; + } + + 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 getRemark() + { + return remark; + } + + public void setRemark(String remark) + { + this.remark = remark; + } + + public Map getParams() + { + if (params == null) + { + params = new HashMap<>(); + } + return params; + } + + public void setParams(Map params) + { + this.params = params; + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/domain/HkResult.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/domain/HkResult.java new file mode 100644 index 0000000..5d7ed76 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/domain/HkResult.java @@ -0,0 +1,91 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.dcsoft.common.core.web.domain; + +import com.dcsoft.common.core.constant.HttpStatus; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; + +/** + * 响应数据 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@ApiModel(value = "响应") +public class HkResult implements Serializable { + private static final long serialVersionUID = 1L; + /** + * 编码:0表示成功,其他值表示失败 + */ + @ApiModelProperty(value = "编码:0表示成功,其他值表示失败") + private int code = 0; + /** + * 消息内容 + */ + @ApiModelProperty(value = "消息内容") + private String errDesc = "success"; + /** + * 响应数据 + */ + @ApiModelProperty(value = "响应数据") + private T data; + + public HkResult ok(T data) { + this.setData(data); + return this; + } + + public boolean success(){ + return code == 0; + } + + + + public HkResult error(int code, String msg) { + this.code = code; + this.errDesc = msg; + return this; + } + + public HkResult error(String msg) { + this.code = HttpStatus.WARN; + this.errDesc = msg; + return this; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + + public String getErrDesc() { + return errDesc; + } + + public void setErrDesc(String errDesc) { + this.errDesc = errDesc; + } + + +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/domain/TreeEntity.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/domain/TreeEntity.java new file mode 100644 index 0000000..0bbffc4 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/domain/TreeEntity.java @@ -0,0 +1,79 @@ +package com.dcsoft.common.core.web.domain; + +import java.util.ArrayList; +import java.util.List; + +/** + * Tree基类 + * + * @author dcsoft + */ +public class TreeEntity extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 父菜单名称 */ + private String parentName; + + /** 父菜单ID */ + private Long parentId; + + /** 显示顺序 */ + private Integer orderNum; + + /** 祖级列表 */ + private String ancestors; + + /** 子部门 */ + private List children = new ArrayList<>(); + + public String getParentName() + { + return parentName; + } + + public void setParentName(String parentName) + { + this.parentName = parentName; + } + + public Long getParentId() + { + return parentId; + } + + public void setParentId(Long parentId) + { + this.parentId = parentId; + } + + public Integer getOrderNum() + { + return orderNum; + } + + public void setOrderNum(Integer orderNum) + { + this.orderNum = orderNum; + } + + public String getAncestors() + { + return ancestors; + } + + public void setAncestors(String ancestors) + { + this.ancestors = ancestors; + } + + public List getChildren() + { + return children; + } + + public void setChildren(List children) + { + this.children = children; + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/page/PageDomain.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/page/PageDomain.java new file mode 100644 index 0000000..acc221f --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/page/PageDomain.java @@ -0,0 +1,101 @@ +package com.dcsoft.common.core.web.page; + +import com.dcsoft.common.core.utils.StringUtils; + +/** + * 分页数据 + * + * @author dcsoft + */ +public class PageDomain +{ + /** 当前记录起始索引 */ + private Integer pageNum; + + /** 每页显示记录数 */ + private Integer pageSize; + + /** 排序列 */ + private String orderByColumn; + + /** 排序的方向desc或者asc */ + private String isAsc = "asc"; + + /** 分页参数合理化 */ + private Boolean reasonable = true; + + public String getOrderBy() + { + if (StringUtils.isEmpty(orderByColumn)) + { + return ""; + } + return StringUtils.toUnderScoreCase(orderByColumn) + " " + isAsc; + } + + public Integer getPageNum() + { + return pageNum; + } + + public void setPageNum(Integer pageNum) + { + this.pageNum = pageNum; + } + + public Integer getPageSize() + { + return pageSize; + } + + public void setPageSize(Integer pageSize) + { + this.pageSize = pageSize; + } + + public String getOrderByColumn() + { + return orderByColumn; + } + + public void setOrderByColumn(String orderByColumn) + { + this.orderByColumn = orderByColumn; + } + + public String getIsAsc() + { + return isAsc; + } + + public void setIsAsc(String isAsc) + { + if (StringUtils.isNotEmpty(isAsc)) + { + // 兼容前端排序类型 + if ("ascending".equals(isAsc)) + { + isAsc = "asc"; + } + else if ("descending".equals(isAsc)) + { + isAsc = "desc"; + } + this.isAsc = isAsc; + } + } + + public Boolean getReasonable() + { + if (StringUtils.isNull(reasonable)) + { + return Boolean.TRUE; + } + return reasonable; + } + + public void setReasonable(Boolean reasonable) + { + this.reasonable = reasonable; + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/page/TableDataInfo.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/page/TableDataInfo.java new file mode 100644 index 0000000..60ca519 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/page/TableDataInfo.java @@ -0,0 +1,96 @@ +package com.dcsoft.common.core.web.page; + +import java.io.Serializable; +import java.util.List; + +/** + * 表格分页数据对象 + * + * @author dcsoft + */ +public class TableDataInfo implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 总记录数 */ + private long total; + + /** 列表数据 */ + private List rows; + + /** 列表数据 */ + private List data; + + /** 消息状态码 */ + private int code; + + /** 消息内容 */ + private String msg; + + /** + * 表格数据对象 + */ + public TableDataInfo() + { + } + + /** + * 分页 + * + * @param list 列表数据 + * @param total 总记录数 + */ + public TableDataInfo(List list, int total) + { + this.rows = list; + this.total = total; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public long getTotal() + { + return total; + } + + public void setTotal(long total) + { + this.total = total; + } + + public List getRows() + { + return rows; + } + + public void setRows(List rows) + { + this.rows = rows; + } + + public int getCode() + { + return code; + } + + public void setCode(int code) + { + this.code = code; + } + + public String getMsg() + { + return msg; + } + + public void setMsg(String msg) + { + this.msg = msg; + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/page/TableDataInfoPage.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/page/TableDataInfoPage.java new file mode 100644 index 0000000..3f13406 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/page/TableDataInfoPage.java @@ -0,0 +1,52 @@ +package com.dcsoft.common.core.web.page; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +@Data +public class TableDataInfoPage implements Serializable { + private static final long serialVersionUID = 1L; + + /** 消息状态码 */ + private int code; + + /** 消息内容 */ + private String msg; + + /** 列表数据 */ + private List data; + + /** 总记录数 */ + private long total; + + /** 当前记录起始索引 */ + private Integer pageNum; + + /** 每页显示记录数 */ + private Integer pageSize; + + /** + * 表格数据对象 + */ + public TableDataInfoPage() + { + } + + /** + * 分页 + * + * @param list 列表数据 + * @param total 总记录数 + */ + public TableDataInfoPage(List list, int total, Integer pageNum, Integer pageSize) + { + this.data = list; + this.total = total; + this.pageNum = pageNum; + this.pageSize = pageSize; + } + + +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/page/TableDatasInfo.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/page/TableDatasInfo.java new file mode 100644 index 0000000..711b32c --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/page/TableDatasInfo.java @@ -0,0 +1,108 @@ +package com.dcsoft.common.core.web.page; + +import org.apache.poi.ss.formula.functions.T; + +import java.io.Serializable; +import java.util.List; + +/** + * 表格分页数据对象 + * + * @author dcsoft + */ +public class TableDatasInfo implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 总记录数 */ + private long total; + + /** 列表数据 */ + private Object data; + + /** 消息状态码 */ + private int code; + + /** 消息内容 */ + private String msg; + + private Integer pageNum; + + /** 每页显示记录数 */ + private Integer pageSize; + + /** + * 表格数据对象 + */ + public TableDatasInfo() + { + } + + /** + * 分页 + * + * @param list 列表数据 + * @param total 总记录数 + */ + public TableDatasInfo(Object list, int total) + { + this.data = list; + this.total = total; + } + + public long getTotal() + { + return total; + } + + public void setTotal(long total) + { + this.total = total; + } + + public Object getData() + { + return data; + } + + public void setData(Object data) + { + this.data = data; + } + + public int getCode() + { + return code; + } + + public void setCode(int code) + { + this.code = code; + } + + public String getMsg() + { + return msg; + } + + public void setMsg(String msg) + { + this.msg = msg; + } + + public Integer getPageNum() { + return pageNum; + } + + public void setPageNum(Integer pageNum) { + this.pageNum = pageNum; + } + + public Integer getPageSize() { + return pageSize; + } + + public void setPageSize(Integer pageSize) { + this.pageSize = pageSize; + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/page/TableSupport.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/page/TableSupport.java new file mode 100644 index 0000000..df13114 --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/web/page/TableSupport.java @@ -0,0 +1,56 @@ +package com.dcsoft.common.core.web.page; + +import com.dcsoft.common.core.text.Convert; +import com.dcsoft.common.core.utils.ServletUtils; + +/** + * 表格数据处理 + * + * @author dcsoft + */ +public class TableSupport +{ + /** + * 当前记录起始索引 + */ + public static final String PAGE_NUM = "pageNum"; + + /** + * 每页显示记录数 + */ + public static final String PAGE_SIZE = "pageSize"; + + /** + * 排序列 + */ + public static final String ORDER_BY_COLUMN = "orderByColumn"; + + /** + * 排序的方向 "desc" 或者 "asc". + */ + public static final String IS_ASC = "isAsc"; + + /** + * 分页参数合理化 + */ + public static final String REASONABLE = "reasonable"; + + /** + * 封装分页对象 + */ + public static PageDomain getPageDomain() + { + PageDomain pageDomain = new PageDomain(); + pageDomain.setPageNum(Convert.toInt(ServletUtils.getParameter(PAGE_NUM), 1)); + pageDomain.setPageSize(Convert.toInt(ServletUtils.getParameter(PAGE_SIZE), 10)); + pageDomain.setOrderByColumn(ServletUtils.getParameter(ORDER_BY_COLUMN)); + pageDomain.setIsAsc(ServletUtils.getParameter(IS_ASC)); + pageDomain.setReasonable(ServletUtils.getParameterToBool(REASONABLE)); + return pageDomain; + } + + public static PageDomain buildPageRequest() + { + return getPageDomain(); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/xss/Xss.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/xss/Xss.java new file mode 100644 index 0000000..470eb8d --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/xss/Xss.java @@ -0,0 +1,27 @@ +package com.dcsoft.common.core.xss; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 自定义xss校验注解 + * + * @author dcsoft + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(value = { ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER }) +@Constraint(validatedBy = { XssValidator.class }) +public @interface Xss +{ + String message() + + default "不允许任何脚本运行"; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/xss/XssValidator.java b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/xss/XssValidator.java new file mode 100644 index 0000000..d4d376d --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/java/com/dcsoft/common/core/xss/XssValidator.java @@ -0,0 +1,34 @@ +package com.dcsoft.common.core.xss; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import com.dcsoft.common.core.utils.StringUtils; + +/** + * 自定义xss校验注解实现 + * + * @author dcsoft + */ +public class XssValidator implements ConstraintValidator +{ + private static final String HTML_PATTERN = "<(\\S*?)[^>]*>.*?|<.*? />"; + + @Override + public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) + { + if (StringUtils.isBlank(value)) + { + return true; + } + return !containsHtml(value); + } + + public static boolean containsHtml(String value) + { + Pattern pattern = Pattern.compile(HTML_PATTERN); + Matcher matcher = pattern.matcher(value); + return matcher.matches(); + } +} diff --git a/dcsoft-common/dcsoft-common-core/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/dcsoft-common/dcsoft-common-core/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..e19a47d --- /dev/null +++ b/dcsoft-common/dcsoft-common-core/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +com.dcsoft.common.core.utils.SpringUtils diff --git a/dcsoft-common/dcsoft-common-datascope/pom.xml b/dcsoft-common/dcsoft-common-datascope/pom.xml new file mode 100644 index 0000000..5e2eeca --- /dev/null +++ b/dcsoft-common/dcsoft-common-datascope/pom.xml @@ -0,0 +1,27 @@ + + + + com.dcsoft + dcsoft-common + 3.6.2 + + 4.0.0 + + dcsoft-common-datascope + + + dcsoft-common-datascope权限范围 + + + + + + + com.dcsoft + dcsoft-common-security + + + + diff --git a/dcsoft-common/dcsoft-common-datascope/src/main/java/com/dcsoft/common/datascope/annotation/DataScope.java b/dcsoft-common/dcsoft-common-datascope/src/main/java/com/dcsoft/common/datascope/annotation/DataScope.java new file mode 100644 index 0000000..2d4641d --- /dev/null +++ b/dcsoft-common/dcsoft-common-datascope/src/main/java/com/dcsoft/common/datascope/annotation/DataScope.java @@ -0,0 +1,33 @@ +package com.dcsoft.common.datascope.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 数据权限过滤注解 + * + * @author dcsoft + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface DataScope +{ + /** + * 部门表的别名 + */ + public String deptAlias() default ""; + + /** + * 用户表的别名 + */ + public String userAlias() default ""; + + /** + * 权限字符(用于多个角色匹配符合要求的权限)默认根据权限注解@RequiresPermissions获取,多个权限用逗号分隔开来 + */ + public String permission() default ""; +} diff --git a/dcsoft-common/dcsoft-common-datascope/src/main/java/com/dcsoft/common/datascope/aspect/DataScopeAspect.java b/dcsoft-common/dcsoft-common-datascope/src/main/java/com/dcsoft/common/datascope/aspect/DataScopeAspect.java new file mode 100644 index 0000000..890ac10 --- /dev/null +++ b/dcsoft-common/dcsoft-common-datascope/src/main/java/com/dcsoft/common/datascope/aspect/DataScopeAspect.java @@ -0,0 +1,167 @@ +package com.dcsoft.common.datascope.aspect; + +import java.util.ArrayList; +import java.util.List; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.springframework.stereotype.Component; +import com.dcsoft.common.core.context.SecurityContextHolder; +import com.dcsoft.common.core.text.Convert; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.web.domain.BaseEntity; +import com.dcsoft.common.datascope.annotation.DataScope; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.api.domain.SysRole; +import com.dcsoft.system.api.domain.SysUser; +import com.dcsoft.system.api.model.LoginUser; + +/** + * 数据过滤处理 + * + * @author dcsoft + */ +@Aspect +@Component +public class DataScopeAspect +{ + /** + * 全部数据权限 + */ + public static final String DATA_SCOPE_ALL = "1"; + + /** + * 自定数据权限 + */ + public static final String DATA_SCOPE_CUSTOM = "2"; + + /** + * 部门数据权限 + */ + public static final String DATA_SCOPE_DEPT = "3"; + + /** + * 部门及以下数据权限 + */ + public static final String DATA_SCOPE_DEPT_AND_CHILD = "4"; + + /** + * 仅本人数据权限 + */ + public static final String DATA_SCOPE_SELF = "5"; + + /** + * 数据权限过滤关键字 + */ + public static final String DATA_SCOPE = "dataScope"; + + @Before("@annotation(controllerDataScope)") + public void doBefore(JoinPoint point, DataScope controllerDataScope) throws Throwable + { + clearDataScope(point); + handleDataScope(point, controllerDataScope); + } + + protected void handleDataScope(final JoinPoint joinPoint, DataScope controllerDataScope) + { + // 获取当前的用户 + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (StringUtils.isNotNull(loginUser)) + { + SysUser currentUser = loginUser.getSysUser(); + // 如果是超级管理员,则不过滤数据 + if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin()) + { + String permission = StringUtils.defaultIfEmpty(controllerDataScope.permission(), SecurityContextHolder.getPermission()); + dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(), + controllerDataScope.userAlias(), permission); + } + } + } + + /** + * 数据范围过滤 + * + * @param joinPoint 切点 + * @param user 用户 + * @param deptAlias 部门别名 + * @param userAlias 用户别名 + * @param permission 权限字符 + */ + public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias, String permission) + { + StringBuilder sqlString = new StringBuilder(); + List conditions = new ArrayList(); + + for (SysRole role : user.getRoles()) + { + String dataScope = role.getDataScope(); + if (!DATA_SCOPE_CUSTOM.equals(dataScope) && conditions.contains(dataScope)) + { + continue; + } + if (StringUtils.isNotEmpty(permission) && StringUtils.isNotEmpty(role.getPermissions()) + && !StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission))) + { + continue; + } + if (DATA_SCOPE_ALL.equals(dataScope)) + { + sqlString = new StringBuilder(); + break; + } + else if (DATA_SCOPE_CUSTOM.equals(dataScope)) + { + sqlString.append(StringUtils.format( + " OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias, + role.getRoleId())); + } + else if (DATA_SCOPE_DEPT.equals(dataScope)) + { + sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId())); + } + else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope)) + { + sqlString.append(StringUtils.format( + " OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )", + deptAlias, user.getDeptId(), user.getDeptId())); + } + else if (DATA_SCOPE_SELF.equals(dataScope)) + { + if (StringUtils.isNotBlank(userAlias)) + { + sqlString.append(StringUtils.format(" OR {}.user_id = {} ", userAlias, user.getUserId())); + } + else + { + // 数据权限为仅本人且没有userAlias别名不查询任何数据 + sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias)); + } + } + conditions.add(dataScope); + } + + if (StringUtils.isNotBlank(sqlString.toString())) + { + Object params = joinPoint.getArgs()[0]; + if (StringUtils.isNotNull(params) && params instanceof BaseEntity) + { + BaseEntity baseEntity = (BaseEntity) params; + baseEntity.getParams().put(DATA_SCOPE, " AND (" + sqlString.substring(4) + ")"); + } + } + } + + /** + * 拼接权限sql前先清空params.dataScope参数防止注入 + */ + private void clearDataScope(final JoinPoint joinPoint) + { + Object params = joinPoint.getArgs()[0]; + if (StringUtils.isNotNull(params) && params instanceof BaseEntity) + { + BaseEntity baseEntity = (BaseEntity) params; + baseEntity.getParams().put(DATA_SCOPE, ""); + } + } +} diff --git a/dcsoft-common/dcsoft-common-datascope/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/dcsoft-common/dcsoft-common-datascope/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..8b15264 --- /dev/null +++ b/dcsoft-common/dcsoft-common-datascope/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +com.dcsoft.common.datascope.aspect.DataScopeAspect diff --git a/dcsoft-common/dcsoft-common-datasource/pom.xml b/dcsoft-common/dcsoft-common-datasource/pom.xml new file mode 100644 index 0000000..4c6ffd3 --- /dev/null +++ b/dcsoft-common/dcsoft-common-datasource/pom.xml @@ -0,0 +1,35 @@ + + + + com.dcsoft + dcsoft-common + 3.6.2 + + 4.0.0 + + dcsoft-common-datasource + + + dcsoft-common-datasource多数据源 + + + + + + + com.alibaba + druid-spring-boot-starter + ${druid.version} + + + + + com.baomidou + dynamic-datasource-spring-boot-starter + ${dynamic-ds.version} + + + + diff --git a/dcsoft-common/dcsoft-common-datasource/src/main/java/com/dcsoft/common/datasource/annotation/Master.java b/dcsoft-common/dcsoft-common-datasource/src/main/java/com/dcsoft/common/datasource/annotation/Master.java new file mode 100644 index 0000000..fcfc639 --- /dev/null +++ b/dcsoft-common/dcsoft-common-datasource/src/main/java/com/dcsoft/common/datasource/annotation/Master.java @@ -0,0 +1,22 @@ +package com.dcsoft.common.datasource.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import com.baomidou.dynamic.datasource.annotation.DS; + +/** + * 主库数据源 + * + * @author dcsoft + */ +@Target({ ElementType.TYPE, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@DS("master") +public @interface Master +{ + +} diff --git a/dcsoft-common/dcsoft-common-datasource/src/main/java/com/dcsoft/common/datasource/annotation/Slave.java b/dcsoft-common/dcsoft-common-datasource/src/main/java/com/dcsoft/common/datasource/annotation/Slave.java new file mode 100644 index 0000000..e4b2d35 --- /dev/null +++ b/dcsoft-common/dcsoft-common-datasource/src/main/java/com/dcsoft/common/datasource/annotation/Slave.java @@ -0,0 +1,22 @@ +package com.dcsoft.common.datasource.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import com.baomidou.dynamic.datasource.annotation.DS; + +/** + * 从库数据源 + * + * @author dcsoft + */ +@Target({ ElementType.TYPE, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@DS("slave") +public @interface Slave +{ + +} diff --git a/dcsoft-common/dcsoft-common-log/pom.xml b/dcsoft-common/dcsoft-common-log/pom.xml new file mode 100644 index 0000000..d606401 --- /dev/null +++ b/dcsoft-common/dcsoft-common-log/pom.xml @@ -0,0 +1,27 @@ + + + + com.dcsoft + dcsoft-common + 3.6.2 + + 4.0.0 + + dcsoft-common-log + + + dcsoft-common-log日志记录 + + + + + + + com.dcsoft + dcsoft-common-security + + + + diff --git a/dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/annotation/Log.java b/dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/annotation/Log.java new file mode 100644 index 0000000..9226b4d --- /dev/null +++ b/dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/annotation/Log.java @@ -0,0 +1,51 @@ +package com.dcsoft.common.log.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.log.enums.OperatorType; + +/** + * 自定义操作日志记录注解 + * + * @author dcsoft + * + */ +@Target({ ElementType.PARAMETER, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Log +{ + /** + * 模块 + */ + public String title() default ""; + + /** + * 功能 + */ + public BusinessType businessType() default BusinessType.OTHER; + + /** + * 操作人类别 + */ + public OperatorType operatorType() default OperatorType.MANAGE; + + /** + * 是否保存请求的参数 + */ + public boolean isSaveRequestData() default true; + + /** + * 是否保存响应的参数 + */ + public boolean isSaveResponseData() default true; + + /** + * 排除指定的请求参数 + */ + public String[] excludeParamNames() default {}; +} diff --git a/dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/aspect/LogAspect.java b/dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/aspect/LogAspect.java new file mode 100644 index 0000000..a08eb4a --- /dev/null +++ b/dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/aspect/LogAspect.java @@ -0,0 +1,249 @@ +package com.dcsoft.common.log.aspect; + +import java.util.Collection; +import java.util.Map; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.ArrayUtils; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.NamedThreadLocal; +import org.springframework.http.HttpMethod; +import org.springframework.stereotype.Component; +import org.springframework.validation.BindingResult; +import org.springframework.web.multipart.MultipartFile; +import com.alibaba.fastjson2.JSON; +import com.dcsoft.common.core.utils.ServletUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.utils.ip.IpUtils; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessStatus; +import com.dcsoft.common.log.filter.PropertyPreExcludeFilter; +import com.dcsoft.common.log.service.AsyncLogService; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.api.domain.SysOperLog; + +/** + * 操作日志记录处理 + * + * @author dcsoft + */ +@Aspect +@Component +public class LogAspect +{ + private static final Logger log = LoggerFactory.getLogger(LogAspect.class); + + /** 排除敏感属性字段 */ + public static final String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" }; + + /** 计算操作消耗时间 */ + private static final ThreadLocal TIME_THREADLOCAL = new NamedThreadLocal("Cost Time"); + + @Autowired + private AsyncLogService asyncLogService; + + /** + * 处理请求前执行 + */ + @Before(value = "@annotation(controllerLog)") + public void boBefore(JoinPoint joinPoint, Log controllerLog) + { + TIME_THREADLOCAL.set(System.currentTimeMillis()); + } + + /** + * 处理完请求后执行 + * + * @param joinPoint 切点 + */ + @AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult") + public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult) + { + handleLog(joinPoint, controllerLog, null, jsonResult); + } + + /** + * 拦截异常操作 + * + * @param joinPoint 切点 + * @param e 异常 + */ + @AfterThrowing(value = "@annotation(controllerLog)", throwing = "e") + public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) + { + handleLog(joinPoint, controllerLog, e, null); + } + + protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) + { + try + { + // *========数据库日志=========*// + SysOperLog operLog = new SysOperLog(); + operLog.setStatus(BusinessStatus.SUCCESS.ordinal()); + // 请求的地址 + String ip = IpUtils.getIpAddr(); + operLog.setOperIp(ip); + operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255)); + String username = SecurityUtils.getUsername(); + if (StringUtils.isNotBlank(username)) + { + operLog.setOperName(username); + } + + if (e != null) + { + operLog.setStatus(BusinessStatus.FAIL.ordinal()); + operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000)); + } + // 设置方法名称 + String className = joinPoint.getTarget().getClass().getName(); + String methodName = joinPoint.getSignature().getName(); + operLog.setMethod(className + "." + methodName + "()"); + // 设置请求方式 + operLog.setRequestMethod(ServletUtils.getRequest().getMethod()); + // 处理设置注解上的参数 + getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult); + // 设置消耗时间 + operLog.setCostTime(System.currentTimeMillis() - TIME_THREADLOCAL.get()); + // 保存数据库 + asyncLogService.saveSysLog(operLog); + } + catch (Exception exp) + { + // 记录本地异常日志 + log.error("异常信息:{}", exp.getMessage()); + exp.printStackTrace(); + } + finally + { + TIME_THREADLOCAL.remove(); + } + } + + /** + * 获取注解中对方法的描述信息 用于Controller层注解 + * + * @param log 日志 + * @param operLog 操作日志 + * @throws Exception + */ + public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog, Object jsonResult) throws Exception + { + // 设置action动作 + operLog.setBusinessType(log.businessType().ordinal()); + // 设置标题 + operLog.setTitle(log.title()); + // 设置操作人类别 + operLog.setOperatorType(log.operatorType().ordinal()); + // 是否需要保存request,参数和值 + if (log.isSaveRequestData()) + { + // 获取参数的信息,传入到数据库中。 + setRequestValue(joinPoint, operLog, log.excludeParamNames()); + } + // 是否需要保存response,参数和值 + if (log.isSaveResponseData() && StringUtils.isNotNull(jsonResult)) + { + operLog.setJsonResult(StringUtils.substring(JSON.toJSONString(jsonResult), 0, 2000)); + } + } + + /** + * 获取请求的参数,放到log中 + * + * @param operLog 操作日志 + * @throws Exception 异常 + */ + private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog, String[] excludeParamNames) throws Exception + { + String requestMethod = operLog.getRequestMethod(); + Map paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest()); + if (StringUtils.isEmpty(paramsMap) + && (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod))) + { + String params = argsArrayToString(joinPoint.getArgs(), excludeParamNames); + operLog.setOperParam(StringUtils.substring(params, 0, 2000)); + } + else + { + operLog.setOperParam(StringUtils.substring(JSON.toJSONString(paramsMap, excludePropertyPreFilter(excludeParamNames)), 0, 2000)); + } + } + + /** + * 参数拼装 + */ + private String argsArrayToString(Object[] paramsArray, String[] excludeParamNames) + { + String params = ""; + if (paramsArray != null && paramsArray.length > 0) + { + for (Object o : paramsArray) + { + if (StringUtils.isNotNull(o) && !isFilterObject(o)) + { + try + { + String jsonObj = JSON.toJSONString(o, excludePropertyPreFilter(excludeParamNames)); + params += jsonObj.toString() + " "; + } + catch (Exception e) + { + } + } + } + } + return params.trim(); + } + + /** + * 忽略敏感属性 + */ + public PropertyPreExcludeFilter excludePropertyPreFilter(String[] excludeParamNames) + { + return new PropertyPreExcludeFilter().addExcludes(ArrayUtils.addAll(EXCLUDE_PROPERTIES, excludeParamNames)); + } + + /** + * 判断是否需要过滤的对象。 + * + * @param o 对象信息。 + * @return 如果是需要过滤的对象,则返回true;否则返回false。 + */ + @SuppressWarnings("rawtypes") + public boolean isFilterObject(final Object o) + { + Class clazz = o.getClass(); + if (clazz.isArray()) + { + return clazz.getComponentType().isAssignableFrom(MultipartFile.class); + } + else if (Collection.class.isAssignableFrom(clazz)) + { + Collection collection = (Collection) o; + for (Object value : collection) + { + return value instanceof MultipartFile; + } + } + else if (Map.class.isAssignableFrom(clazz)) + { + Map map = (Map) o; + for (Object value : map.entrySet()) + { + Map.Entry entry = (Map.Entry) value; + return entry.getValue() instanceof MultipartFile; + } + } + return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse + || o instanceof BindingResult; + } +} diff --git a/dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/enums/BusinessStatus.java b/dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/enums/BusinessStatus.java new file mode 100644 index 0000000..d38151c --- /dev/null +++ b/dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/enums/BusinessStatus.java @@ -0,0 +1,20 @@ +package com.dcsoft.common.log.enums; + +/** + * 操作状态 + * + * @author dcsoft + * + */ +public enum BusinessStatus +{ + /** + * 成功 + */ + SUCCESS, + + /** + * 失败 + */ + FAIL, +} diff --git a/dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/enums/BusinessType.java b/dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/enums/BusinessType.java new file mode 100644 index 0000000..4d06037 --- /dev/null +++ b/dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/enums/BusinessType.java @@ -0,0 +1,59 @@ +package com.dcsoft.common.log.enums; + +/** + * 业务操作类型 + * + * @author dcsoft + */ +public enum BusinessType +{ + /** + * 其它 + */ + OTHER, + + /** + * 新增 + */ + INSERT, + + /** + * 修改 + */ + UPDATE, + + /** + * 删除 + */ + DELETE, + + /** + * 授权 + */ + GRANT, + + /** + * 导出 + */ + EXPORT, + + /** + * 导入 + */ + IMPORT, + + /** + * 强退 + */ + FORCE, + + /** + * 生成代码 + */ + GENCODE, + + /** + * 清空数据 + */ + CLEAN, +} diff --git a/dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/enums/OperatorType.java b/dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/enums/OperatorType.java new file mode 100644 index 0000000..8c4728c --- /dev/null +++ b/dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/enums/OperatorType.java @@ -0,0 +1,24 @@ +package com.dcsoft.common.log.enums; + +/** + * 操作人类别 + * + * @author dcsoft + */ +public enum OperatorType +{ + /** + * 其它 + */ + OTHER, + + /** + * 后台用户 + */ + MANAGE, + + /** + * 手机端用户 + */ + MOBILE +} diff --git a/dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/filter/PropertyPreExcludeFilter.java b/dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/filter/PropertyPreExcludeFilter.java new file mode 100644 index 0000000..da25f2e --- /dev/null +++ b/dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/filter/PropertyPreExcludeFilter.java @@ -0,0 +1,24 @@ +package com.dcsoft.common.log.filter; + +import com.alibaba.fastjson2.filter.SimplePropertyPreFilter; + +/** + * 排除JSON敏感属性 + * + * @author dcsoft + */ +public class PropertyPreExcludeFilter extends SimplePropertyPreFilter +{ + public PropertyPreExcludeFilter() + { + } + + public PropertyPreExcludeFilter addExcludes(String... filters) + { + for (int i = 0; i < filters.length; i++) + { + this.getExcludes().add(filters[i]); + } + return this; + } +} diff --git a/dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/service/AsyncLogService.java b/dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/service/AsyncLogService.java new file mode 100644 index 0000000..b99bd03 --- /dev/null +++ b/dcsoft-common/dcsoft-common-log/src/main/java/com/dcsoft/common/log/service/AsyncLogService.java @@ -0,0 +1,29 @@ +package com.dcsoft.common.log.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; +import com.dcsoft.common.core.constant.SecurityConstants; +import com.dcsoft.system.api.RemoteLogService; +import com.dcsoft.system.api.domain.SysOperLog; + +/** + * 异步调用日志服务 + * + * @author dcsoft + */ +@Service +public class AsyncLogService +{ + @Autowired + private RemoteLogService remoteLogService; + + /** + * 保存系统日志记录 + */ + @Async + public void saveSysLog(SysOperLog sysOperLog) + { + remoteLogService.saveLog(sysOperLog, SecurityConstants.INNER); + } +} diff --git a/dcsoft-common/dcsoft-common-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/dcsoft-common/dcsoft-common-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..9d8e2b9 --- /dev/null +++ b/dcsoft-common/dcsoft-common-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +com.dcsoft.common.log.service.AsyncLogService +com.dcsoft.common.log.aspect.LogAspect diff --git a/dcsoft-common/dcsoft-common-redis/pom.xml b/dcsoft-common/dcsoft-common-redis/pom.xml new file mode 100644 index 0000000..a0c1e0f --- /dev/null +++ b/dcsoft-common/dcsoft-common-redis/pom.xml @@ -0,0 +1,33 @@ + + + + com.dcsoft + dcsoft-common + 3.6.2 + + 4.0.0 + + dcsoft-common-redis + + + dcsoft-common-redis缓存服务 + + + + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + + com.dcsoft + dcsoft-common-core + + + + diff --git a/dcsoft-common/dcsoft-common-redis/src/main/java/com/dcsoft/common/redis/configure/FastJson2JsonRedisSerializer.java b/dcsoft-common/dcsoft-common-redis/src/main/java/com/dcsoft/common/redis/configure/FastJson2JsonRedisSerializer.java new file mode 100644 index 0000000..9466e3f --- /dev/null +++ b/dcsoft-common/dcsoft-common-redis/src/main/java/com/dcsoft/common/redis/configure/FastJson2JsonRedisSerializer.java @@ -0,0 +1,49 @@ +package com.dcsoft.common.redis.configure; + +import java.nio.charset.Charset; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.SerializationException; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONReader; +import com.alibaba.fastjson2.JSONWriter; + +/** + * Redis使用FastJson序列化 + * + * @author dcsoft + */ +public class FastJson2JsonRedisSerializer implements RedisSerializer +{ + public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); + + private Class clazz; + + + public FastJson2JsonRedisSerializer(Class clazz) + { + super(); + this.clazz = clazz; + } + + @Override + public byte[] serialize(T t) throws SerializationException + { + if (t == null) + { + return new byte[0]; + } + return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(DEFAULT_CHARSET); + } + + @Override + public T deserialize(byte[] bytes) throws SerializationException + { + if (bytes == null || bytes.length <= 0) + { + return null; + } + String str = new String(bytes, DEFAULT_CHARSET); + + return JSON.parseObject(str, clazz, JSONReader.Feature.SupportAutoType); + } +} diff --git a/dcsoft-common/dcsoft-common-redis/src/main/java/com/dcsoft/common/redis/configure/RedisConfig.java b/dcsoft-common/dcsoft-common-redis/src/main/java/com/dcsoft/common/redis/configure/RedisConfig.java new file mode 100644 index 0000000..75457fb --- /dev/null +++ b/dcsoft-common/dcsoft-common-redis/src/main/java/com/dcsoft/common/redis/configure/RedisConfig.java @@ -0,0 +1,43 @@ +package com.dcsoft.common.redis.configure; + +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; +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.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +/** + * redis配置 + * + * @author dcsoft + */ +@Configuration +@EnableCaching +@AutoConfigureBefore(RedisAutoConfiguration.class) +public class RedisConfig extends CachingConfigurerSupport +{ + @Bean + @SuppressWarnings(value = { "unchecked", "rawtypes" }) + public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) + { + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(connectionFactory); + + FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class); + + // 使用StringRedisSerializer来序列化和反序列化redis的key值 + template.setKeySerializer(new StringRedisSerializer()); + template.setValueSerializer(serializer); + + // Hash的key也采用StringRedisSerializer的序列化方式 + template.setHashKeySerializer(new StringRedisSerializer()); + template.setHashValueSerializer(serializer); + + template.afterPropertiesSet(); + return template; + } +} diff --git a/dcsoft-common/dcsoft-common-redis/src/main/java/com/dcsoft/common/redis/service/RedisService.java b/dcsoft-common/dcsoft-common-redis/src/main/java/com/dcsoft/common/redis/service/RedisService.java new file mode 100644 index 0000000..c2436fe --- /dev/null +++ b/dcsoft-common/dcsoft-common-redis/src/main/java/com/dcsoft/common/redis/service/RedisService.java @@ -0,0 +1,268 @@ +package com.dcsoft.common.redis.service; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.BoundSetOperations; +import org.springframework.data.redis.core.HashOperations; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.ValueOperations; +import org.springframework.stereotype.Component; + +/** + * spring redis 工具类 + * + * @author dcsoft + **/ +@SuppressWarnings(value = { "unchecked", "rawtypes" }) +@Component +public class RedisService +{ + @Autowired + public RedisTemplate redisTemplate; + + /** + * 缓存基本的对象,Integer、String、实体类等 + * + * @param key 缓存的键值 + * @param value 缓存的值 + */ + public void setCacheObject(final String key, final T value) + { + redisTemplate.opsForValue().set(key, value); + } + + /** + * 缓存基本的对象,Integer、String、实体类等 + * + * @param key 缓存的键值 + * @param value 缓存的值 + * @param timeout 时间 + * @param timeUnit 时间颗粒度 + */ + public void setCacheObject(final String key, final T value, final Long timeout, final TimeUnit timeUnit) + { + redisTemplate.opsForValue().set(key, value, timeout, timeUnit); + } + + /** + * 设置有效时间 + * + * @param key Redis键 + * @param timeout 超时时间 + * @return true=设置成功;false=设置失败 + */ + public boolean expire(final String key, final long timeout) + { + return expire(key, timeout, TimeUnit.SECONDS); + } + + /** + * 设置有效时间 + * + * @param key Redis键 + * @param timeout 超时时间 + * @param unit 时间单位 + * @return true=设置成功;false=设置失败 + */ + public boolean expire(final String key, final long timeout, final TimeUnit unit) + { + return redisTemplate.expire(key, timeout, unit); + } + + /** + * 获取有效时间 + * + * @param key Redis键 + * @return 有效时间 + */ + public long getExpire(final String key) + { + return redisTemplate.getExpire(key); + } + + /** + * 判断 key是否存在 + * + * @param key 键 + * @return true 存在 false不存在 + */ + public Boolean hasKey(String key) + { + return redisTemplate.hasKey(key); + } + + /** + * 获得缓存的基本对象。 + * + * @param key 缓存键值 + * @return 缓存键值对应的数据 + */ + public T getCacheObject(final String key) + { + ValueOperations operation = redisTemplate.opsForValue(); + return operation.get(key); + } + + /** + * 删除单个对象 + * + * @param key + */ + public boolean deleteObject(final String key) + { + return redisTemplate.delete(key); + } + + /** + * 删除集合对象 + * + * @param collection 多个对象 + * @return + */ + public boolean deleteObject(final Collection collection) + { + return redisTemplate.delete(collection) > 0; + } + + /** + * 缓存List数据 + * + * @param key 缓存的键值 + * @param dataList 待缓存的List数据 + * @return 缓存的对象 + */ + public long setCacheList(final String key, final List dataList) + { + Long count = redisTemplate.opsForList().rightPushAll(key, dataList); + return count == null ? 0 : count; + } + + /** + * 获得缓存的list对象 + * + * @param key 缓存的键值 + * @return 缓存键值对应的数据 + */ + public List getCacheList(final String key) + { + return redisTemplate.opsForList().range(key, 0, -1); + } + + /** + * 缓存Set + * + * @param key 缓存键值 + * @param dataSet 缓存的数据 + * @return 缓存数据的对象 + */ + public BoundSetOperations setCacheSet(final String key, final Set dataSet) + { + BoundSetOperations setOperation = redisTemplate.boundSetOps(key); + Iterator it = dataSet.iterator(); + while (it.hasNext()) + { + setOperation.add(it.next()); + } + return setOperation; + } + + /** + * 获得缓存的set + * + * @param key + * @return + */ + public Set getCacheSet(final String key) + { + return redisTemplate.opsForSet().members(key); + } + + /** + * 缓存Map + * + * @param key + * @param dataMap + */ + public void setCacheMap(final String key, final Map dataMap) + { + if (dataMap != null) { + redisTemplate.opsForHash().putAll(key, dataMap); + } + } + + /** + * 获得缓存的Map + * + * @param key + * @return + */ + public Map getCacheMap(final String key) + { + return redisTemplate.opsForHash().entries(key); + } + + /** + * 往Hash中存入数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @param value 值 + */ + public void setCacheMapValue(final String key, final String hKey, final T value) + { + redisTemplate.opsForHash().put(key, hKey, value); + } + + /** + * 获取Hash中的数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @return Hash中的对象 + */ + public T getCacheMapValue(final String key, final String hKey) + { + HashOperations opsForHash = redisTemplate.opsForHash(); + return opsForHash.get(key, hKey); + } + + /** + * 获取多个Hash中的数据 + * + * @param key Redis键 + * @param hKeys Hash键集合 + * @return Hash对象集合 + */ + public List getMultiCacheMapValue(final String key, final Collection hKeys) + { + return redisTemplate.opsForHash().multiGet(key, hKeys); + } + + /** + * 删除Hash中的某条数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @return 是否成功 + */ + public boolean deleteCacheMapValue(final String key, final String hKey) + { + return redisTemplate.opsForHash().delete(key, hKey) > 0; + } + + /** + * 获得缓存的基本对象列表 + * + * @param pattern 字符串前缀 + * @return 对象列表 + */ + public Collection keys(final String pattern) + { + return redisTemplate.keys(pattern); + } +} diff --git a/dcsoft-common/dcsoft-common-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/dcsoft-common/dcsoft-common-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..d5bbc3d --- /dev/null +++ b/dcsoft-common/dcsoft-common-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +com.dcsoft.common.redis.configure.RedisConfig +com.dcsoft.common.redis.service.RedisService diff --git a/dcsoft-common/dcsoft-common-seata/pom.xml b/dcsoft-common/dcsoft-common-seata/pom.xml new file mode 100644 index 0000000..582c063 --- /dev/null +++ b/dcsoft-common/dcsoft-common-seata/pom.xml @@ -0,0 +1,27 @@ + + + + com.dcsoft + dcsoft-common + 3.6.2 + + 4.0.0 + + dcsoft-common-seata + + + dcsoft-common-seata分布式事务 + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-seata + + + + diff --git a/dcsoft-common/dcsoft-common-security/pom.xml b/dcsoft-common/dcsoft-common-security/pom.xml new file mode 100644 index 0000000..7742b6e --- /dev/null +++ b/dcsoft-common/dcsoft-common-security/pom.xml @@ -0,0 +1,39 @@ + + + + com.dcsoft + dcsoft-common + 3.6.2 + + 4.0.0 + + dcsoft-common-security + + + dcsoft-common-security安全模块 + + + + + + + org.springframework + spring-webmvc + + + + + com.dcsoft + dcsoft-api-system + + + + + com.dcsoft + dcsoft-common-redis + + + + + diff --git a/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/EnableCustomConfig.java b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/EnableCustomConfig.java new file mode 100644 index 0000000..7cb3e7c --- /dev/null +++ b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/EnableCustomConfig.java @@ -0,0 +1,31 @@ +package com.dcsoft.common.security.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.context.annotation.Import; +import org.springframework.scheduling.annotation.EnableAsync; +import com.dcsoft.common.security.config.ApplicationConfig; +import com.dcsoft.common.security.feign.FeignAutoConfiguration; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +// 表示通过aop框架暴露该代理对象,AopContext能够访问 +@EnableAspectJAutoProxy(exposeProxy = true) +// 指定要扫描的Mapper类的包的路径 +@MapperScan("com.dcsoft.**.mapper") +// 开启线程异步执行 +@EnableAsync +// 自动加载类 +@Import({ ApplicationConfig.class, FeignAutoConfiguration.class }) +public @interface EnableCustomConfig +{ + +} diff --git a/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/EnableRyFeignClients.java b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/EnableRyFeignClients.java new file mode 100644 index 0000000..1a9a994 --- /dev/null +++ b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/EnableRyFeignClients.java @@ -0,0 +1,27 @@ +package com.dcsoft.common.security.annotation; + +import org.springframework.cloud.openfeign.EnableFeignClients; +import java.lang.annotation.*; + +/** + * 自定义feign注解 + * 添加basePackages路径 + * + * @author dcsoft + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@EnableFeignClients +public @interface EnableRyFeignClients +{ + String[] value() default {}; + + String[] basePackages() default { "com.dcsoft" }; + + Class[] basePackageClasses() default {}; + + Class[] defaultConfiguration() default {}; + + Class[] clients() default {}; +} diff --git a/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/InnerAuth.java b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/InnerAuth.java new file mode 100644 index 0000000..6baa052 --- /dev/null +++ b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/InnerAuth.java @@ -0,0 +1,19 @@ +package com.dcsoft.common.security.annotation; + +import java.lang.annotation.*; + +/** + * 内部认证注解 + * + * @author dcsoft + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface InnerAuth +{ + /** + * 是否校验用户信息 + */ + boolean isUser() default false; +} diff --git a/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/Logical.java b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/Logical.java new file mode 100644 index 0000000..29e3f4c --- /dev/null +++ b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/Logical.java @@ -0,0 +1,20 @@ +package com.dcsoft.common.security.annotation; + +/** + * 权限注解的验证模式 + * + * @author dcsoft + * + */ +public enum Logical +{ + /** + * 必须具有所有的元素 + */ + AND, + + /** + * 只需具有其中一个元素 + */ + OR +} diff --git a/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/RequiresLogin.java b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/RequiresLogin.java new file mode 100644 index 0000000..0401602 --- /dev/null +++ b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/RequiresLogin.java @@ -0,0 +1,18 @@ +package com.dcsoft.common.security.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 登录认证:只有登录之后才能进入该方法 + * + * @author dcsoft + * + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.METHOD, ElementType.TYPE }) +public @interface RequiresLogin +{ +} diff --git a/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/RequiresPermissions.java b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/RequiresPermissions.java new file mode 100644 index 0000000..73fb943 --- /dev/null +++ b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/RequiresPermissions.java @@ -0,0 +1,27 @@ +package com.dcsoft.common.security.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 权限认证:必须具有指定权限才能进入该方法 + * + * @author dcsoft + * + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.METHOD, ElementType.TYPE }) +public @interface RequiresPermissions +{ + /** + * 需要校验的权限码 + */ + String[] value() default {}; + + /** + * 验证模式:AND | OR,默认AND + */ + Logical logical() default Logical.AND; +} diff --git a/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/RequiresRoles.java b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/RequiresRoles.java new file mode 100644 index 0000000..3a8230f --- /dev/null +++ b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/annotation/RequiresRoles.java @@ -0,0 +1,26 @@ +package com.dcsoft.common.security.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 角色认证:必须具有指定角色标识才能进入该方法 + * + * @author dcsoft + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.METHOD, ElementType.TYPE }) +public @interface RequiresRoles +{ + /** + * 需要校验的角色标识 + */ + String[] value() default {}; + + /** + * 验证逻辑:AND | OR,默认AND + */ + Logical logical() default Logical.AND; +} diff --git a/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/aspect/InnerAuthAspect.java b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/aspect/InnerAuthAspect.java new file mode 100644 index 0000000..2044c90 --- /dev/null +++ b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/aspect/InnerAuthAspect.java @@ -0,0 +1,51 @@ +package com.dcsoft.common.security.aspect; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.core.Ordered; +import org.springframework.stereotype.Component; +import com.dcsoft.common.core.constant.SecurityConstants; +import com.dcsoft.common.core.exception.InnerAuthException; +import com.dcsoft.common.core.utils.ServletUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.security.annotation.InnerAuth; + +/** + * 内部服务调用验证处理 + * + * @author dcsoft + */ +@Aspect +@Component +public class InnerAuthAspect implements Ordered +{ + @Around("@annotation(innerAuth)") + public Object innerAround(ProceedingJoinPoint point, InnerAuth innerAuth) throws Throwable + { + String source = ServletUtils.getRequest().getHeader(SecurityConstants.FROM_SOURCE); + // 内部请求验证 + if (!StringUtils.equals(SecurityConstants.INNER, source)) + { + throw new InnerAuthException("没有内部访问权限,不允许访问"); + } + + String userid = ServletUtils.getRequest().getHeader(SecurityConstants.DETAILS_USER_ID); + String username = ServletUtils.getRequest().getHeader(SecurityConstants.DETAILS_USERNAME); + // 用户信息验证 + if (innerAuth.isUser() && (StringUtils.isEmpty(userid) || StringUtils.isEmpty(username))) + { + throw new InnerAuthException("没有设置用户信息,不允许访问 "); + } + return point.proceed(); + } + + /** + * 确保在权限认证aop执行前执行 + */ + @Override + public int getOrder() + { + return Ordered.HIGHEST_PRECEDENCE + 1; + } +} diff --git a/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/aspect/PreAuthorizeAspect.java b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/aspect/PreAuthorizeAspect.java new file mode 100644 index 0000000..ead6d3a --- /dev/null +++ b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/aspect/PreAuthorizeAspect.java @@ -0,0 +1,97 @@ +package com.dcsoft.common.security.aspect; + +import java.lang.reflect.Method; +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 com.dcsoft.common.security.annotation.RequiresLogin; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.common.security.annotation.RequiresRoles; +import com.dcsoft.common.security.auth.AuthUtil; + +/** + * 基于 Spring Aop 的注解鉴权 + * + * @author kong + */ +@Aspect +@Component +public class PreAuthorizeAspect +{ + /** + * 构建 + */ + public PreAuthorizeAspect() + { + } + + /** + * 定义AOP签名 (切入所有使用鉴权注解的方法) + */ + public static final String POINTCUT_SIGN = " @annotation(com.dcsoft.common.security.annotation.RequiresLogin) || " + + "@annotation(com.dcsoft.common.security.annotation.RequiresPermissions) || " + + "@annotation(com.dcsoft.common.security.annotation.RequiresRoles)"; + + /** + * 声明AOP签名 + */ + @Pointcut(POINTCUT_SIGN) + public void pointcut() + { + } + + /** + * 环绕切入 + * + * @param joinPoint 切面对象 + * @return 底层方法执行后的返回值 + * @throws Throwable 底层方法抛出的异常 + */ + @Around("pointcut()") + public Object around(ProceedingJoinPoint joinPoint) throws Throwable + { + // 注解鉴权 + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + checkMethodAnnotation(signature.getMethod()); + try + { + // 执行原有逻辑 + Object obj = joinPoint.proceed(); + return obj; + } + catch (Throwable e) + { + throw e; + } + } + + /** + * 对一个Method对象进行注解检查 + */ + public void checkMethodAnnotation(Method method) + { + // 校验 @RequiresLogin 注解 + RequiresLogin requiresLogin = method.getAnnotation(RequiresLogin.class); + if (requiresLogin != null) + { + AuthUtil.checkLogin(); + } + + // 校验 @RequiresRoles 注解 + RequiresRoles requiresRoles = method.getAnnotation(RequiresRoles.class); + if (requiresRoles != null) + { + AuthUtil.checkRole(requiresRoles); + } + + // 校验 @RequiresPermissions 注解 + RequiresPermissions requiresPermissions = method.getAnnotation(RequiresPermissions.class); + if (requiresPermissions != null) + { + AuthUtil.checkPermi(requiresPermissions); + } + } +} diff --git a/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/auth/AuthLogic.java b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/auth/AuthLogic.java new file mode 100644 index 0000000..c9b9b0e --- /dev/null +++ b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/auth/AuthLogic.java @@ -0,0 +1,373 @@ +package com.dcsoft.common.security.auth; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import org.springframework.util.PatternMatchUtils; +import com.dcsoft.common.core.context.SecurityContextHolder; +import com.dcsoft.common.core.exception.auth.NotLoginException; +import com.dcsoft.common.core.exception.auth.NotPermissionException; +import com.dcsoft.common.core.exception.auth.NotRoleException; +import com.dcsoft.common.core.utils.SpringUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.security.annotation.Logical; +import com.dcsoft.common.security.annotation.RequiresLogin; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.common.security.annotation.RequiresRoles; +import com.dcsoft.common.security.service.TokenService; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.api.model.LoginUser; + +/** + * Token 权限验证,逻辑实现类 + * + * @author dcsoft + */ +public class AuthLogic +{ + /** 所有权限标识 */ + private static final String ALL_PERMISSION = "*:*:*"; + + /** 管理员角色权限标识 */ + private static final String SUPER_ADMIN = "admin"; + + public TokenService tokenService = SpringUtils.getBean(TokenService.class); + + /** + * 会话注销 + */ + public void logout() + { + String token = SecurityUtils.getToken(); + if (token == null) + { + return; + } + logoutByToken(token); + } + + /** + * 会话注销,根据指定Token + */ + public void logoutByToken(String token) + { + tokenService.delLoginUser(token); + } + + /** + * 检验用户是否已经登录,如未登录,则抛出异常 + */ + public void checkLogin() + { + getLoginUser(); + } + + /** + * 获取当前用户缓存信息, 如果未登录,则抛出异常 + * + * @return 用户缓存信息 + */ + public LoginUser getLoginUser() + { + String token = SecurityUtils.getToken(); + if (token == null) + { + throw new NotLoginException("未提供token"); + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (loginUser == null) + { + throw new NotLoginException("无效的token"); + } + return loginUser; + } + + /** + * 获取当前用户缓存信息, 如果未登录,则抛出异常 + * + * @param token 前端传递的认证信息 + * @return 用户缓存信息 + */ + public LoginUser getLoginUser(String token) + { + return tokenService.getLoginUser(token); + } + + /** + * 验证当前用户有效期, 如果相差不足120分钟,自动刷新缓存 + * + * @param loginUser 当前用户信息 + */ + public void verifyLoginUserExpire(LoginUser loginUser) + { + tokenService.verifyToken(loginUser); + } + + /** + * 验证用户是否具备某权限 + * + * @param permission 权限字符串 + * @return 用户是否具备某权限 + */ + public boolean hasPermi(String permission) + { + return hasPermi(getPermiList(), permission); + } + + /** + * 验证用户是否具备某权限, 如果验证未通过,则抛出异常: NotPermissionException + * + * @param permission 权限字符串 + * @return 用户是否具备某权限 + */ + public void checkPermi(String permission) + { + if (!hasPermi(getPermiList(), permission)) + { + throw new NotPermissionException(permission); + } + } + + /** + * 根据注解(@RequiresPermissions)鉴权, 如果验证未通过,则抛出异常: NotPermissionException + * + * @param requiresPermissions 注解对象 + */ + public void checkPermi(RequiresPermissions requiresPermissions) + { + SecurityContextHolder.setPermission(StringUtils.join(requiresPermissions.value(), ",")); + if (requiresPermissions.logical() == Logical.AND) + { + checkPermiAnd(requiresPermissions.value()); + } + else + { + checkPermiOr(requiresPermissions.value()); + } + } + + /** + * 验证用户是否含有指定权限,必须全部拥有 + * + * @param permissions 权限列表 + */ + public void checkPermiAnd(String... permissions) + { + Set permissionList = getPermiList(); + for (String permission : permissions) + { + if (!hasPermi(permissionList, permission)) + { + throw new NotPermissionException(permission); + } + } + } + + /** + * 验证用户是否含有指定权限,只需包含其中一个 + * + * @param permissions 权限码数组 + */ + public void checkPermiOr(String... permissions) + { + Set permissionList = getPermiList(); + for (String permission : permissions) + { + if (hasPermi(permissionList, permission)) + { + return; + } + } + if (permissions.length > 0) + { + throw new NotPermissionException(permissions); + } + } + + /** + * 判断用户是否拥有某个角色 + * + * @param role 角色标识 + * @return 用户是否具备某角色 + */ + public boolean hasRole(String role) + { + return hasRole(getRoleList(), role); + } + + /** + * 判断用户是否拥有某个角色, 如果验证未通过,则抛出异常: NotRoleException + * + * @param role 角色标识 + */ + public void checkRole(String role) + { + if (!hasRole(role)) + { + throw new NotRoleException(role); + } + } + + /** + * 根据注解(@RequiresRoles)鉴权 + * + * @param requiresRoles 注解对象 + */ + public void checkRole(RequiresRoles requiresRoles) + { + if (requiresRoles.logical() == Logical.AND) + { + checkRoleAnd(requiresRoles.value()); + } + else + { + checkRoleOr(requiresRoles.value()); + } + } + + /** + * 验证用户是否含有指定角色,必须全部拥有 + * + * @param roles 角色标识数组 + */ + public void checkRoleAnd(String... roles) + { + Set roleList = getRoleList(); + for (String role : roles) + { + if (!hasRole(roleList, role)) + { + throw new NotRoleException(role); + } + } + } + + /** + * 验证用户是否含有指定角色,只需包含其中一个 + * + * @param roles 角色标识数组 + */ + public void checkRoleOr(String... roles) + { + Set roleList = getRoleList(); + for (String role : roles) + { + if (hasRole(roleList, role)) + { + return; + } + } + if (roles.length > 0) + { + throw new NotRoleException(roles); + } + } + + /** + * 根据注解(@RequiresLogin)鉴权 + * + * @param at 注解对象 + */ + public void checkByAnnotation(RequiresLogin at) + { + this.checkLogin(); + } + + /** + * 根据注解(@RequiresRoles)鉴权 + * + * @param at 注解对象 + */ + public void checkByAnnotation(RequiresRoles at) + { + String[] roleArray = at.value(); + if (at.logical() == Logical.AND) + { + this.checkRoleAnd(roleArray); + } + else + { + this.checkRoleOr(roleArray); + } + } + + /** + * 根据注解(@RequiresPermissions)鉴权 + * + * @param at 注解对象 + */ + public void checkByAnnotation(RequiresPermissions at) + { + String[] permissionArray = at.value(); + if (at.logical() == Logical.AND) + { + this.checkPermiAnd(permissionArray); + } + else + { + this.checkPermiOr(permissionArray); + } + } + + /** + * 获取当前账号的角色列表 + * + * @return 角色列表 + */ + public Set getRoleList() + { + try + { + LoginUser loginUser = getLoginUser(); + return loginUser.getRoles(); + } + catch (Exception e) + { + return new HashSet<>(); + } + } + + /** + * 获取当前账号的权限列表 + * + * @return 权限列表 + */ + public Set getPermiList() + { + try + { + LoginUser loginUser = getLoginUser(); + return loginUser.getPermissions(); + } + catch (Exception e) + { + return new HashSet<>(); + } + } + + /** + * 判断是否包含权限 + * + * @param authorities 权限列表 + * @param permission 权限字符串 + * @return 用户是否具备某权限 + */ + public boolean hasPermi(Collection authorities, String permission) + { + return authorities.stream().filter(StringUtils::hasText) + .anyMatch(x -> ALL_PERMISSION.contains(x) || PatternMatchUtils.simpleMatch(x, permission)); + } + + /** + * 判断是否包含角色 + * + * @param roles 角色列表 + * @param role 角色 + * @return 用户是否具备某角色权限 + */ + public boolean hasRole(Collection roles, String role) + { + return roles.stream().filter(StringUtils::hasText) + .anyMatch(x -> SUPER_ADMIN.contains(x) || PatternMatchUtils.simpleMatch(x, role)); + } +} diff --git a/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/auth/AuthUtil.java b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/auth/AuthUtil.java new file mode 100644 index 0000000..3b54023 --- /dev/null +++ b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/auth/AuthUtil.java @@ -0,0 +1,167 @@ +package com.dcsoft.common.security.auth; + +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.common.security.annotation.RequiresRoles; +import com.dcsoft.system.api.model.LoginUser; + +/** + * Token 权限验证工具类 + * + * @author dcsoft + */ +public class AuthUtil +{ + /** + * 底层的 AuthLogic 对象 + */ + public static AuthLogic authLogic = new AuthLogic(); + + /** + * 会话注销 + */ + public static void logout() + { + authLogic.logout(); + } + + /** + * 会话注销,根据指定Token + * + * @param token 指定token + */ + public static void logoutByToken(String token) + { + authLogic.logoutByToken(token); + } + + /** + * 检验当前会话是否已经登录,如未登录,则抛出异常 + */ + public static void checkLogin() + { + authLogic.checkLogin(); + } + + /** + * 获取当前登录用户信息 + * + * @param token 指定token + * @return 用户信息 + */ + public static LoginUser getLoginUser(String token) + { + return authLogic.getLoginUser(token); + } + + /** + * 验证当前用户有效期 + * + * @param loginUser 用户信息 + */ + public static void verifyLoginUserExpire(LoginUser loginUser) + { + authLogic.verifyLoginUserExpire(loginUser); + } + + /** + * 当前账号是否含有指定角色标识, 返回true或false + * + * @param role 角色标识 + * @return 是否含有指定角色标识 + */ + public static boolean hasRole(String role) + { + return authLogic.hasRole(role); + } + + /** + * 当前账号是否含有指定角色标识, 如果验证未通过,则抛出异常: NotRoleException + * + * @param role 角色标识 + */ + public static void checkRole(String role) + { + authLogic.checkRole(role); + } + + /** + * 根据注解传入参数鉴权, 如果验证未通过,则抛出异常: NotRoleException + * + * @param requiresRoles 角色权限注解 + */ + public static void checkRole(RequiresRoles requiresRoles) + { + authLogic.checkRole(requiresRoles); + } + + /** + * 当前账号是否含有指定角色标识 [指定多个,必须全部验证通过] + * + * @param roles 角色标识数组 + */ + public static void checkRoleAnd(String... roles) + { + authLogic.checkRoleAnd(roles); + } + + /** + * 当前账号是否含有指定角色标识 [指定多个,只要其一验证通过即可] + * + * @param roles 角色标识数组 + */ + public static void checkRoleOr(String... roles) + { + authLogic.checkRoleOr(roles); + } + + /** + * 当前账号是否含有指定权限, 返回true或false + * + * @param permission 权限码 + * @return 是否含有指定权限 + */ + public static boolean hasPermi(String permission) + { + return authLogic.hasPermi(permission); + } + + /** + * 当前账号是否含有指定权限, 如果验证未通过,则抛出异常: NotPermissionException + * + * @param permission 权限码 + */ + public static void checkPermi(String permission) + { + authLogic.checkPermi(permission); + } + + /** + * 根据注解传入参数鉴权, 如果验证未通过,则抛出异常: NotPermissionException + * + * @param requiresPermissions 权限注解 + */ + public static void checkPermi(RequiresPermissions requiresPermissions) + { + authLogic.checkPermi(requiresPermissions); + } + + /** + * 当前账号是否含有指定权限 [指定多个,必须全部验证通过] + * + * @param permissions 权限码数组 + */ + public static void checkPermiAnd(String... permissions) + { + authLogic.checkPermiAnd(permissions); + } + + /** + * 当前账号是否含有指定权限 [指定多个,只要其一验证通过即可] + * + * @param permissions 权限码数组 + */ + public static void checkPermiOr(String... permissions) + { + authLogic.checkPermiOr(permissions); + } +} diff --git a/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/config/ApplicationConfig.java b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/config/ApplicationConfig.java new file mode 100644 index 0000000..d8745e9 --- /dev/null +++ b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/config/ApplicationConfig.java @@ -0,0 +1,22 @@ +package com.dcsoft.common.security.config; + +import java.util.TimeZone; +import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; +import org.springframework.context.annotation.Bean; + +/** + * 系统配置 + * + * @author dcsoft + */ +public class ApplicationConfig +{ + /** + * 时区配置 + */ + @Bean + public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() + { + return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault()); + } +} diff --git a/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/config/WebMvcConfig.java b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/config/WebMvcConfig.java new file mode 100644 index 0000000..b2dae1c --- /dev/null +++ b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/config/WebMvcConfig.java @@ -0,0 +1,33 @@ +package com.dcsoft.common.security.config; + +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import com.dcsoft.common.security.interceptor.HeaderInterceptor; + +/** + * 拦截器配置 + * + * @author dcsoft + */ +public class WebMvcConfig implements WebMvcConfigurer +{ + /** 不需要拦截地址 */ + public static final String[] excludeUrls = { "/login", "/logout", "/refresh", "/validate" }; + + @Override + public void addInterceptors(InterceptorRegistry registry) + { + registry.addInterceptor(getHeaderInterceptor()) + .addPathPatterns("/**") + .excludePathPatterns(excludeUrls) + .order(-10); + } + + /** + * 自定义请求头拦截器 + */ + public HeaderInterceptor getHeaderInterceptor() + { + return new HeaderInterceptor(); + } +} diff --git a/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/feign/FeignAutoConfiguration.java b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/feign/FeignAutoConfiguration.java new file mode 100644 index 0000000..e965dca --- /dev/null +++ b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/feign/FeignAutoConfiguration.java @@ -0,0 +1,20 @@ +package com.dcsoft.common.security.feign; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import feign.RequestInterceptor; + +/** + * Feign 配置注册 + * + * @author dcsoft + **/ +@Configuration +public class FeignAutoConfiguration +{ + @Bean + public RequestInterceptor requestInterceptor() + { + return new FeignRequestInterceptor(); + } +} diff --git a/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/feign/FeignRequestInterceptor.java b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/feign/FeignRequestInterceptor.java new file mode 100644 index 0000000..e5416ec --- /dev/null +++ b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/feign/FeignRequestInterceptor.java @@ -0,0 +1,54 @@ +package com.dcsoft.common.security.feign; + +import java.util.Map; +import javax.servlet.http.HttpServletRequest; +import org.springframework.stereotype.Component; +import com.dcsoft.common.core.constant.SecurityConstants; +import com.dcsoft.common.core.utils.ServletUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.utils.ip.IpUtils; +import feign.RequestInterceptor; +import feign.RequestTemplate; + +/** + * feign 请求拦截器 + * + * @author dcsoft + */ +@Component +public class FeignRequestInterceptor implements RequestInterceptor +{ + @Override + public void apply(RequestTemplate requestTemplate) + { + HttpServletRequest httpServletRequest = ServletUtils.getRequest(); + if (StringUtils.isNotNull(httpServletRequest)) + { + Map headers = ServletUtils.getHeaders(httpServletRequest); + // 传递用户信息请求头,防止丢失 + String userId = headers.get(SecurityConstants.DETAILS_USER_ID); + if (StringUtils.isNotEmpty(userId)) + { + requestTemplate.header(SecurityConstants.DETAILS_USER_ID, userId); + } + String userKey = headers.get(SecurityConstants.USER_KEY); + if (StringUtils.isNotEmpty(userKey)) + { + requestTemplate.header(SecurityConstants.USER_KEY, userKey); + } + String userName = headers.get(SecurityConstants.DETAILS_USERNAME); + if (StringUtils.isNotEmpty(userName)) + { + requestTemplate.header(SecurityConstants.DETAILS_USERNAME, userName); + } + String authentication = headers.get(SecurityConstants.AUTHORIZATION_HEADER); + if (StringUtils.isNotEmpty(authentication)) + { + requestTemplate.header(SecurityConstants.AUTHORIZATION_HEADER, authentication); + } + + // 配置客户端IP + requestTemplate.header("X-Forwarded-For", IpUtils.getIpAddr()); + } + } +} diff --git a/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/handler/GlobalExceptionHandler.java b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/handler/GlobalExceptionHandler.java new file mode 100644 index 0000000..82c835e --- /dev/null +++ b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/handler/GlobalExceptionHandler.java @@ -0,0 +1,136 @@ +package com.dcsoft.common.security.handler; + +import javax.servlet.http.HttpServletRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.validation.BindException; +import org.springframework.web.HttpRequestMethodNotSupportedException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import com.dcsoft.common.core.constant.HttpStatus; +import com.dcsoft.common.core.exception.DemoModeException; +import com.dcsoft.common.core.exception.InnerAuthException; +import com.dcsoft.common.core.exception.ServiceException; +import com.dcsoft.common.core.exception.auth.NotPermissionException; +import com.dcsoft.common.core.exception.auth.NotRoleException; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.web.domain.AjaxResult; + +/** + * 全局异常处理器 + * + * @author dcsoft + */ +@RestControllerAdvice +public class GlobalExceptionHandler +{ + private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class); + + /** + * 权限码异常 + */ + @ExceptionHandler(NotPermissionException.class) + public AjaxResult handleNotPermissionException(NotPermissionException e, HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',权限码校验失败'{}'", requestURI, e.getMessage()); + return AjaxResult.error(HttpStatus.FORBIDDEN, "没有访问权限,请联系管理员授权"); + } + + /** + * 角色权限异常 + */ + @ExceptionHandler(NotRoleException.class) + public AjaxResult handleNotRoleException(NotRoleException e, HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',角色权限校验失败'{}'", requestURI, e.getMessage()); + return AjaxResult.error(HttpStatus.FORBIDDEN, "没有访问权限,请联系管理员授权"); + } + + /** + * 请求方式不支持 + */ + @ExceptionHandler(HttpRequestMethodNotSupportedException.class) + public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, + HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod()); + return AjaxResult.error(e.getMessage()); + } + + /** + * 业务异常 + */ + @ExceptionHandler(ServiceException.class) + public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request) + { + log.error(e.getMessage(), e); + Integer code = e.getCode(); + return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage()); + } + + /** + * 拦截未知的运行时异常 + */ + @ExceptionHandler(RuntimeException.class) + public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',发生未知异常.", requestURI, e); + return AjaxResult.error(e.getMessage()); + } + + /** + * 系统异常 + */ + @ExceptionHandler(Exception.class) + public AjaxResult handleException(Exception e, HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',发生系统异常.", requestURI, e); + return AjaxResult.error(e.getMessage()); + } + + /** + * 自定义验证异常 + */ + @ExceptionHandler(BindException.class) + public AjaxResult handleBindException(BindException e) + { + log.error(e.getMessage(), e); + String message = e.getAllErrors().get(0).getDefaultMessage(); + return AjaxResult.error(message); + } + + /** + * 自定义验证异常 + */ + @ExceptionHandler(MethodArgumentNotValidException.class) + public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) + { + log.error(e.getMessage(), e); + String message = e.getBindingResult().getFieldError().getDefaultMessage(); + return AjaxResult.error(message); + } + + /** + * 内部认证异常 + */ + @ExceptionHandler(InnerAuthException.class) + public AjaxResult handleInnerAuthException(InnerAuthException e) + { + return AjaxResult.error(e.getMessage()); + } + + /** + * 演示模式异常 + */ + @ExceptionHandler(DemoModeException.class) + public AjaxResult handleDemoModeException(DemoModeException e) + { + return AjaxResult.error("演示模式,不允许操作"); + } +} diff --git a/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/interceptor/HeaderInterceptor.java b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/interceptor/HeaderInterceptor.java new file mode 100644 index 0000000..67b1257 --- /dev/null +++ b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/interceptor/HeaderInterceptor.java @@ -0,0 +1,54 @@ +package com.dcsoft.common.security.interceptor; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.AsyncHandlerInterceptor; +import com.dcsoft.common.core.constant.SecurityConstants; +import com.dcsoft.common.core.context.SecurityContextHolder; +import com.dcsoft.common.core.utils.ServletUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.security.auth.AuthUtil; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.api.model.LoginUser; + +/** + * 自定义请求头拦截器,将Header数据封装到线程变量中方便获取 + * 注意:此拦截器会同时验证当前用户有效期自动刷新有效期 + * + * @author dcsoft + */ +public class HeaderInterceptor implements AsyncHandlerInterceptor +{ + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception + { + if (!(handler instanceof HandlerMethod)) + { + return true; + } + + SecurityContextHolder.setUserId(ServletUtils.getHeader(request, SecurityConstants.DETAILS_USER_ID)); + SecurityContextHolder.setUserName(ServletUtils.getHeader(request, SecurityConstants.DETAILS_USERNAME)); + SecurityContextHolder.setUserKey(ServletUtils.getHeader(request, SecurityConstants.USER_KEY)); + + String token = SecurityUtils.getToken(); + if (StringUtils.isNotEmpty(token)) + { + LoginUser loginUser = AuthUtil.getLoginUser(token); + if (StringUtils.isNotNull(loginUser)) + { + AuthUtil.verifyLoginUserExpire(loginUser); + SecurityContextHolder.set(SecurityConstants.LOGIN_USER, loginUser); + } + } + return true; + } + + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) + throws Exception + { + SecurityContextHolder.remove(); + } +} diff --git a/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/service/TokenService.java b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/service/TokenService.java new file mode 100644 index 0000000..0934511 --- /dev/null +++ b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/service/TokenService.java @@ -0,0 +1,169 @@ +package com.dcsoft.common.security.service; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import javax.servlet.http.HttpServletRequest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import com.dcsoft.common.core.constant.CacheConstants; +import com.dcsoft.common.core.constant.SecurityConstants; +import com.dcsoft.common.core.utils.JwtUtils; +import com.dcsoft.common.core.utils.ServletUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.utils.ip.IpUtils; +import com.dcsoft.common.core.utils.uuid.IdUtils; +import com.dcsoft.common.redis.service.RedisService; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.api.model.LoginUser; + +/** + * token验证处理 + * + * @author dcsoft + */ +@Component +public class TokenService +{ + @Autowired + private RedisService redisService; + + protected static final long MILLIS_SECOND = 1000; + + protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND; + + private final static long expireTime = CacheConstants.EXPIRATION; + + private final static String ACCESS_TOKEN = CacheConstants.LOGIN_TOKEN_KEY; + + private final static Long MILLIS_MINUTE_TEN = CacheConstants.REFRESH_TIME * MILLIS_MINUTE; + + /** + * 创建令牌 + */ + public Map createToken(LoginUser loginUser) + { + String token = IdUtils.fastUUID(); + Long userId = loginUser.getSysUser().getUserId(); + String userName = loginUser.getSysUser().getUserName(); + loginUser.setToken(token); + loginUser.setUserid(userId); + loginUser.setUsername(userName); + loginUser.setIpaddr(IpUtils.getIpAddr()); + refreshToken(loginUser); + + // Jwt存储信息 + Map claimsMap = new HashMap(); + claimsMap.put(SecurityConstants.USER_KEY, token); + claimsMap.put(SecurityConstants.DETAILS_USER_ID, userId); + claimsMap.put(SecurityConstants.DETAILS_USERNAME, userName); + + // 接口返回信息 + Map rspMap = new HashMap(); + rspMap.put("access_token", JwtUtils.createToken(claimsMap)); + rspMap.put("expires_in", expireTime); + return rspMap; + } + + /** + * 获取用户身份信息 + * + * @return 用户信息 + */ + public LoginUser getLoginUser() + { + return getLoginUser(ServletUtils.getRequest()); + } + + /** + * 获取用户身份信息 + * + * @return 用户信息 + */ + public LoginUser getLoginUser(HttpServletRequest request) + { + // 获取请求携带的令牌 + String token = SecurityUtils.getToken(request); + return getLoginUser(token); + } + + /** + * 获取用户身份信息 + * + * @return 用户信息 + */ + public LoginUser getLoginUser(String token) + { + LoginUser user = null; + try + { + if (StringUtils.isNotEmpty(token)) + { + String userkey = JwtUtils.getUserKey(token); + user = redisService.getCacheObject(getTokenKey(userkey)); + return user; + } + } + catch (Exception e) + { + } + return user; + } + + /** + * 设置用户身份信息 + */ + public void setLoginUser(LoginUser loginUser) + { + if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) + { + refreshToken(loginUser); + } + } + + /** + * 删除用户缓存信息 + */ + public void delLoginUser(String token) + { + if (StringUtils.isNotEmpty(token)) + { + String userkey = JwtUtils.getUserKey(token); + redisService.deleteObject(getTokenKey(userkey)); + } + } + + /** + * 验证令牌有效期,相差不足120分钟,自动刷新缓存 + * + * @param loginUser + */ + public void verifyToken(LoginUser loginUser) + { + long expireTime = loginUser.getExpireTime(); + long currentTime = System.currentTimeMillis(); + if (expireTime - currentTime <= MILLIS_MINUTE_TEN) + { + refreshToken(loginUser); + } + } + + /** + * 刷新令牌有效期 + * + * @param loginUser 登录信息 + */ + public void refreshToken(LoginUser loginUser) + { + loginUser.setLoginTime(System.currentTimeMillis()); + loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE); + // 根据uuid将loginUser缓存 + String userKey = getTokenKey(loginUser.getToken()); + redisService.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES); + } + + private String getTokenKey(String token) + { + return ACCESS_TOKEN + token; + } +} diff --git a/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/utils/DictUtils.java b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/utils/DictUtils.java new file mode 100644 index 0000000..0656c18 --- /dev/null +++ b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/utils/DictUtils.java @@ -0,0 +1,75 @@ +package com.dcsoft.common.security.utils; + +import java.util.Collection; +import java.util.List; +import com.alibaba.fastjson2.JSONArray; +import com.dcsoft.common.core.constant.CacheConstants; +import com.dcsoft.common.core.utils.SpringUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.redis.service.RedisService; +import com.dcsoft.system.api.domain.SysDictData; + +/** + * 字典工具类 + * + * @author dcsoft + */ +public class DictUtils +{ + /** + * 设置字典缓存 + * + * @param key 参数键 + * @param dictDatas 字典数据列表 + */ + public static void setDictCache(String key, List dictDatas) + { + SpringUtils.getBean(RedisService.class).setCacheObject(getCacheKey(key), dictDatas); + } + + /** + * 获取字典缓存 + * + * @param key 参数键 + * @return dictDatas 字典数据列表 + */ + public static List getDictCache(String key) + { + JSONArray arrayCache = SpringUtils.getBean(RedisService.class).getCacheObject(getCacheKey(key)); + if (StringUtils.isNotNull(arrayCache)) + { + return arrayCache.toList(SysDictData.class); + } + return null; + } + + /** + * 删除指定字典缓存 + * + * @param key 字典键 + */ + public static void removeDictCache(String key) + { + SpringUtils.getBean(RedisService.class).deleteObject(getCacheKey(key)); + } + + /** + * 清空字典缓存 + */ + public static void clearDictCache() + { + Collection keys = SpringUtils.getBean(RedisService.class).keys(CacheConstants.SYS_DICT_KEY + "*"); + SpringUtils.getBean(RedisService.class).deleteObject(keys); + } + + /** + * 设置cache key + * + * @param configKey 参数键 + * @return 缓存键key + */ + public static String getCacheKey(String configKey) + { + return CacheConstants.SYS_DICT_KEY + configKey; + } +} diff --git a/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/utils/SecurityUtils.java b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/utils/SecurityUtils.java new file mode 100644 index 0000000..bf44bd5 --- /dev/null +++ b/dcsoft-common/dcsoft-common-security/src/main/java/com/dcsoft/common/security/utils/SecurityUtils.java @@ -0,0 +1,117 @@ +package com.dcsoft.common.security.utils; + +import javax.servlet.http.HttpServletRequest; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import com.dcsoft.common.core.constant.SecurityConstants; +import com.dcsoft.common.core.constant.TokenConstants; +import com.dcsoft.common.core.context.SecurityContextHolder; +import com.dcsoft.common.core.utils.ServletUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.system.api.model.LoginUser; + +/** + * 权限获取工具类 + * + * @author dcsoft + */ +public class SecurityUtils +{ + /** + * 获取用户ID + */ + public static Long getUserId() + { + return SecurityContextHolder.getUserId(); + } + + /** + * 获取用户名称 + */ + public static String getUsername() + { + return SecurityContextHolder.getUserName(); + } + + /** + * 获取用户key + */ + public static String getUserKey() + { + return SecurityContextHolder.getUserKey(); + } + + /** + * 获取登录用户信息 + */ + public static LoginUser getLoginUser() + { + return SecurityContextHolder.get(SecurityConstants.LOGIN_USER, LoginUser.class); + } + + /** + * 获取请求token + */ + public static String getToken() + { + return getToken(ServletUtils.getRequest()); + } + + /** + * 根据request获取请求token + */ + public static String getToken(HttpServletRequest request) + { + // 从header获取token标识 + String token = request.getHeader(TokenConstants.AUTHENTICATION); + return replaceTokenPrefix(token); + } + + /** + * 裁剪token前缀 + */ + public static String replaceTokenPrefix(String token) + { + // 如果前端设置了令牌前缀,则裁剪掉前缀 + if (StringUtils.isNotEmpty(token) && token.startsWith(TokenConstants.PREFIX)) + { + token = token.replaceFirst(TokenConstants.PREFIX, ""); + } + return token; + } + + /** + * 是否为管理员 + * + * @param userId 用户ID + * @return 结果 + */ + public static boolean isAdmin(Long userId) + { + return userId != null && 1L == userId; + } + + /** + * 生成BCryptPasswordEncoder密码 + * + * @param password 密码 + * @return 加密字符串 + */ + public static String encryptPassword(String password) + { + BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + return passwordEncoder.encode(password); + } + + /** + * 判断密码是否相同 + * + * @param rawPassword 真实密码 + * @param encodedPassword 加密后字符 + * @return 结果 + */ + public static boolean matchesPassword(String rawPassword, String encodedPassword) + { + BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + return passwordEncoder.matches(rawPassword, encodedPassword); + } +} diff --git a/dcsoft-common/dcsoft-common-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/dcsoft-common/dcsoft-common-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..15a0806 --- /dev/null +++ b/dcsoft-common/dcsoft-common-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,5 @@ +com.dcsoft.common.security.config.WebMvcConfig +com.dcsoft.common.security.service.TokenService +com.dcsoft.common.security.aspect.PreAuthorizeAspect +com.dcsoft.common.security.aspect.InnerAuthAspect +com.dcsoft.common.security.handler.GlobalExceptionHandler diff --git a/dcsoft-common/dcsoft-common-sms/pom.xml b/dcsoft-common/dcsoft-common-sms/pom.xml new file mode 100644 index 0000000..54b590a --- /dev/null +++ b/dcsoft-common/dcsoft-common-sms/pom.xml @@ -0,0 +1,42 @@ + + + + com.dcsoft + dcsoft-common + 3.6.2 + + 4.0.0 + + dcsoft-common-sms + + + dcsoft-common-sms 短信模块 + + + + + + com.dcsoft + dcsoft-common-core + + + + com.aliyun + dysmsapi20170525 + true + + + + com.tencentcloudapi + tencentcloud-sdk-java-sms + true + + + org.projectlombok + lombok + + + + + diff --git a/dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/config/SmsAutoConfiguration.java b/dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/config/SmsAutoConfiguration.java new file mode 100644 index 0000000..b09c140 --- /dev/null +++ b/dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/config/SmsAutoConfiguration.java @@ -0,0 +1,49 @@ +package com.dcsoft.common.sms.config; + +import com.dcsoft.common.sms.service.SmsTemplate; +import com.dcsoft.common.sms.service.impl.AliyunSmsTemplate; +import com.dcsoft.common.sms.service.impl.TencentSmsTemplate; +import com.dcsoft.common.sms.config.properties.SmsProperties; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 短信配置类 + * + * @author Lion Li + * @version 4.2.0 + */ +@AutoConfiguration +@EnableConfigurationProperties(SmsProperties.class) +public class SmsAutoConfiguration { + + @Configuration + @ConditionalOnProperty(value = "sms.enabled", havingValue = "true") + @ConditionalOnClass(com.aliyun.dysmsapi20170525.Client.class) + static class AliyunSmsConfiguration { + + @Bean + public SmsTemplate aliyunSmsTemplate(SmsProperties smsProperties) { + return new AliyunSmsTemplate(smsProperties); + } + + } + + @Configuration + @ConditionalOnProperty(value = "sms.enabled", havingValue = "true") + @ConditionalOnClass(com.tencentcloudapi.sms.v20190711.SmsClient.class) + static class TencentSmsConfiguration { + + @Bean + public SmsTemplate tencentSmsTemplate(SmsProperties smsProperties) { + return new TencentSmsTemplate(smsProperties); + } + + } + +} diff --git a/dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/config/properties/SmsProperties.java b/dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/config/properties/SmsProperties.java new file mode 100644 index 0000000..050b32c --- /dev/null +++ b/dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/config/properties/SmsProperties.java @@ -0,0 +1,89 @@ +package com.dcsoft.common.sms.config.properties; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * SMS短信 配置属性 + * + * @author Lion Li + * @version 4.2.0 + */ +@Data +@ConfigurationProperties(prefix = "sms") +public class SmsProperties { + + private Boolean enabled; + + /** + * 配置节点 + * 阿里云 dysmsapi.aliyuncs.com + * 腾讯云 sms.tencentcloudapi.com + */ + private String endpoint; + + /** + * key + */ + private String accessKeyId; + + /** + * 密匙 + */ + private String accessKeySecret; + + /* + * 短信签名 + */ + private String signName; + + /** + * 短信应用ID (腾讯专属) + */ + private String sdkAppId; + + private String template1; + + private String template2; + + /** + * 访客申请审核通知 + */ + private String template3; + + /** + * 访客申请不通过申请 + */ + private String template4; + + /** + * 访客申请二维码成功通知 + */ + private String template5; + + /** + * 物业访客申请审核通知 + */ + private String template6; + + /** + * 物业访客申请成功 + */ + private String template7; + + /** + * 物业访客申请不通过 + */ + private String template8; + + /** + * 兴安访客审核通过 + */ + private String template9; + + /** + * 兴安访客审核不通过 + */ + private String template10; +} diff --git a/dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/entity/SmsResult.java b/dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/entity/SmsResult.java new file mode 100644 index 0000000..ace6861 --- /dev/null +++ b/dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/entity/SmsResult.java @@ -0,0 +1,31 @@ +package com.dcsoft.common.sms.entity; + +import lombok.Builder; +import lombok.Data; + +/** + * 上传返回体 + * + * @author Lion Li + */ +@Data +@Builder +public class SmsResult { + + /** + * 是否成功 + */ + private Boolean isSuccess; + + /** + * 响应消息 + */ + private String message; + + /** + * 实际响应体 + *

+ * 可自行转换为 SDK 对应的 SendSmsResponse + */ + private String response; +} diff --git a/dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/exception/SmsException.java b/dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/exception/SmsException.java new file mode 100644 index 0000000..95c621a --- /dev/null +++ b/dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/exception/SmsException.java @@ -0,0 +1,16 @@ +package com.dcsoft.common.sms.exception; + +/** + * Sms异常类 + * + * @author Lion Li + */ +public class SmsException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public SmsException(String msg) { + super(msg); + } + +} diff --git a/dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/service/SmsTemplate.java b/dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/service/SmsTemplate.java new file mode 100644 index 0000000..5311ec5 --- /dev/null +++ b/dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/service/SmsTemplate.java @@ -0,0 +1,25 @@ +package com.dcsoft.common.sms.service; + +import com.dcsoft.common.sms.entity.SmsResult; + +import java.util.Map; + +/** + * 短信模板 + * + * @author ai-cloud + */ +public interface SmsTemplate { + + /** + * + * + * @param phones 电话号(多个逗号分割) + * @param templateId 模板id + * @param param 模板对应参数 + * 阿里 需使用 模板变量名称对应内容 例如: code=1234 + * 腾讯 需使用 模板变量顺序对应内容 例如: 1=1234, 1为模板内第一个参数 + */ + public SmsResult send(String phones, String templateId, Map param); + +} diff --git a/dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/service/impl/AliyunSmsTemplate.java b/dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/service/impl/AliyunSmsTemplate.java new file mode 100644 index 0000000..a51977e --- /dev/null +++ b/dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/service/impl/AliyunSmsTemplate.java @@ -0,0 +1,65 @@ +package com.dcsoft.common.sms.service.impl; + +import com.aliyun.dysmsapi20170525.Client; +import com.aliyun.dysmsapi20170525.models.SendSmsRequest; +import com.aliyun.dysmsapi20170525.models.SendSmsResponse; +import com.aliyun.teaopenapi.models.Config; +import com.dcsoft.common.core.utils.JsonUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.sms.config.properties.SmsProperties; +import com.dcsoft.common.sms.entity.SmsResult; +import com.dcsoft.common.sms.exception.SmsException; +import com.dcsoft.common.sms.service.SmsTemplate; +import lombok.SneakyThrows; + +import java.util.Map; + +/** + * Aliyun 短信模板 + * + * @author ai-cloud + */ +public class AliyunSmsTemplate implements SmsTemplate { + + private SmsProperties properties; + + private Client client; + + @SneakyThrows(Exception.class) + public AliyunSmsTemplate(SmsProperties smsProperties) { + this.properties = smsProperties; + Config config = new Config() + // 您的AccessKey ID + .setAccessKeyId(smsProperties.getAccessKeyId()) + // 您的AccessKey Secret + .setAccessKeySecret(smsProperties.getAccessKeySecret()) + // 访问的域名 + .setEndpoint(smsProperties.getEndpoint()); + this.client = new Client(config); + } + + public SmsResult send(String phones, String templateId, Map param) { + if (StringUtils.isBlank(phones)) { + throw new SmsException("手机号不能为空"); + } + if (StringUtils.isBlank(templateId)) { + throw new SmsException("模板ID不能为空"); + } + SendSmsRequest req = new SendSmsRequest() + .setPhoneNumbers(phones) + .setSignName(properties.getSignName()) + .setTemplateCode(templateId) + .setTemplateParam(JsonUtils.toJsonString(param)); + try { + SendSmsResponse resp = client.sendSms(req); + return SmsResult.builder() + .isSuccess("OK".equals(resp.getBody().getCode())) + .message(resp.getBody().getMessage()) + .response(JsonUtils.toJsonString(resp)) + .build(); + } catch (Exception e) { + throw new SmsException(e.getMessage()); + } + } + +} diff --git a/dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/service/impl/TencentSmsTemplate.java b/dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/service/impl/TencentSmsTemplate.java new file mode 100644 index 0000000..f037eec --- /dev/null +++ b/dcsoft-common/dcsoft-common-sms/src/main/java/com/dcsoft/common/sms/service/impl/TencentSmsTemplate.java @@ -0,0 +1,82 @@ +package com.dcsoft.common.sms.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ArrayUtil; + +import com.tencentcloudapi.common.Credential; +import com.tencentcloudapi.common.profile.ClientProfile; +import com.tencentcloudapi.common.profile.HttpProfile; +import com.tencentcloudapi.sms.v20190711.SmsClient; +import com.tencentcloudapi.sms.v20190711.models.SendSmsRequest; +import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse; +import com.tencentcloudapi.sms.v20190711.models.SendStatus; +import com.dcsoft.common.core.utils.JsonUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.sms.config.properties.SmsProperties; +import com.dcsoft.common.sms.entity.SmsResult; +import com.dcsoft.common.sms.exception.SmsException; +import com.dcsoft.common.sms.service.SmsTemplate; +import lombok.SneakyThrows; + +import java.util.Arrays; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * Tencent 短信模板 + * + * @author ai-cloud + */ +public class TencentSmsTemplate implements SmsTemplate { + + private SmsProperties properties; + + private SmsClient client; + + @SneakyThrows(Exception.class) + public TencentSmsTemplate(SmsProperties smsProperties) { + this.properties = smsProperties; + Credential credential = new Credential(smsProperties.getAccessKeyId(), smsProperties.getAccessKeySecret()); + HttpProfile httpProfile = new HttpProfile(); + httpProfile.setEndpoint(smsProperties.getEndpoint()); + ClientProfile clientProfile = new ClientProfile(); + clientProfile.setHttpProfile(httpProfile); + this.client = new SmsClient(credential, "", clientProfile); + } + + public SmsResult send(String phones, String templateId, Map param) { + if (StringUtils.isBlank(phones)) { + throw new SmsException("手机号不能为空"); + } + if (StringUtils.isBlank(templateId)) { + throw new SmsException("模板ID不能为空"); + } + SendSmsRequest req = new SendSmsRequest(); + Set set = Arrays.stream(phones.split(",")).map(p -> "+86" + p).collect(Collectors.toSet()); + req.setPhoneNumberSet(ArrayUtil.toArray(set, String.class)); + if (CollUtil.isNotEmpty(param)) { + req.setTemplateParamSet(ArrayUtil.toArray(param.values(), String.class)); + } + req.setTemplateID(templateId); + req.setSign(properties.getSignName()); + req.setSmsSdkAppid(properties.getSdkAppId()); + try { + SendSmsResponse resp = client.SendSms(req); + SmsResult.SmsResultBuilder builder = SmsResult.builder() + .isSuccess(true) + .message("send success") + .response(JsonUtils.toJsonString(resp)); + for (SendStatus sendStatus : resp.getSendStatusSet()) { + if (!"Ok".equals(sendStatus.getCode())) { + builder.isSuccess(false).message(sendStatus.getMessage()); + break; + } + } + return builder.build(); + } catch (Exception e) { + throw new SmsException(e.getMessage()); + } + } + +} diff --git a/dcsoft-common/dcsoft-common-sms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/dcsoft-common/dcsoft-common-sms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..631b5ef --- /dev/null +++ b/dcsoft-common/dcsoft-common-sms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +com.dcsoft.common.sms.config.SmsAutoConfiguration diff --git a/dcsoft-common/dcsoft-common-swagger/pom.xml b/dcsoft-common/dcsoft-common-swagger/pom.xml new file mode 100644 index 0000000..8564f1a --- /dev/null +++ b/dcsoft-common/dcsoft-common-swagger/pom.xml @@ -0,0 +1,34 @@ + + + + com.dcsoft + dcsoft-common + 3.6.2 + + 4.0.0 + + dcsoft-common-swagger + + + dcsoft-common-swagger系统接口 + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + io.springfox + springfox-swagger2 + ${swagger.fox.version} + + + + diff --git a/dcsoft-common/dcsoft-common-swagger/src/main/java/com/dcsoft/common/swagger/annotation/EnableCustomSwagger2.java b/dcsoft-common/dcsoft-common-swagger/src/main/java/com/dcsoft/common/swagger/annotation/EnableCustomSwagger2.java new file mode 100644 index 0000000..0d620c7 --- /dev/null +++ b/dcsoft-common/dcsoft-common-swagger/src/main/java/com/dcsoft/common/swagger/annotation/EnableCustomSwagger2.java @@ -0,0 +1,20 @@ +package com.dcsoft.common.swagger.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.springframework.context.annotation.Import; +import com.dcsoft.common.swagger.config.SwaggerAutoConfiguration; + +@Target({ ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +@Import({ SwaggerAutoConfiguration.class }) +public @interface EnableCustomSwagger2 +{ + +} diff --git a/dcsoft-common/dcsoft-common-swagger/src/main/java/com/dcsoft/common/swagger/config/SwaggerAutoConfiguration.java b/dcsoft-common/dcsoft-common-swagger/src/main/java/com/dcsoft/common/swagger/config/SwaggerAutoConfiguration.java new file mode 100644 index 0000000..c53b838 --- /dev/null +++ b/dcsoft-common/dcsoft-common-swagger/src/main/java/com/dcsoft/common/swagger/config/SwaggerAutoConfiguration.java @@ -0,0 +1,129 @@ +package com.dcsoft.common.swagger.config; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.ApiKey; +import springfox.documentation.service.AuthorizationScope; +import springfox.documentation.service.Contact; +import springfox.documentation.service.SecurityReference; +import springfox.documentation.service.SecurityScheme; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.service.contexts.SecurityContext; +import springfox.documentation.spring.web.plugins.ApiSelectorBuilder; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +@Configuration +@EnableSwagger2 +@EnableAutoConfiguration +@ConditionalOnProperty(name = "swagger.enabled", matchIfMissing = true) +public class SwaggerAutoConfiguration +{ + /** + * 默认的排除路径,排除Spring Boot默认的错误处理路径和端点 + */ + private static final List DEFAULT_EXCLUDE_PATH = Arrays.asList("/error", "/actuator/**"); + + private static final String BASE_PATH = "/**"; + + @Bean + @ConditionalOnMissingBean + public SwaggerProperties swaggerProperties() + { + return new SwaggerProperties(); + } + + @Bean + public Docket api(SwaggerProperties swaggerProperties) + { + // base-path处理 + if (swaggerProperties.getBasePath().isEmpty()) + { + swaggerProperties.getBasePath().add(BASE_PATH); + } + // noinspection unchecked + List> basePath = new ArrayList>(); + swaggerProperties.getBasePath().forEach(path -> basePath.add(PathSelectors.ant(path))); + + // exclude-path处理 + if (swaggerProperties.getExcludePath().isEmpty()) + { + swaggerProperties.getExcludePath().addAll(DEFAULT_EXCLUDE_PATH); + } + + List> excludePath = new ArrayList<>(); + swaggerProperties.getExcludePath().forEach(path -> excludePath.add(PathSelectors.ant(path))); + + ApiSelectorBuilder builder = new Docket(DocumentationType.SWAGGER_2).host(swaggerProperties.getHost()) + .apiInfo(apiInfo(swaggerProperties)).select() + .apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage())); + + swaggerProperties.getBasePath().forEach(p -> builder.paths(PathSelectors.ant(p))); + swaggerProperties.getExcludePath().forEach(p -> builder.paths(PathSelectors.ant(p).negate())); + + return builder.build().securitySchemes(securitySchemes()).securityContexts(securityContexts()).pathMapping("/"); + } + + /** + * 安全模式,这里指定token通过Authorization头请求头传递 + */ + private List securitySchemes() + { + List apiKeyList = new ArrayList(); + apiKeyList.add(new ApiKey("Authorization", "Authorization", "header")); + return apiKeyList; + } + + /** + * 安全上下文 + */ + private List securityContexts() + { + List securityContexts = new ArrayList<>(); + securityContexts.add( + SecurityContext.builder() + .securityReferences(defaultAuth()) + .operationSelector(o -> o.requestMappingPattern().matches("/.*")) + .build()); + return securityContexts; + } + + /** + * 默认的全局鉴权策略 + * + * @return + */ + private List defaultAuth() + { + AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); + AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; + authorizationScopes[0] = authorizationScope; + List securityReferences = new ArrayList<>(); + securityReferences.add(new SecurityReference("Authorization", authorizationScopes)); + return securityReferences; + } + + private ApiInfo apiInfo(SwaggerProperties swaggerProperties) + { + return new ApiInfoBuilder() + .title(swaggerProperties.getTitle()) + .description(swaggerProperties.getDescription()) + .license(swaggerProperties.getLicense()) + .licenseUrl(swaggerProperties.getLicenseUrl()) + .termsOfServiceUrl(swaggerProperties.getTermsOfServiceUrl()) + .contact(new Contact(swaggerProperties.getContact().getName(), swaggerProperties.getContact().getUrl(), swaggerProperties.getContact().getEmail())) + .version(swaggerProperties.getVersion()) + .build(); + } +} diff --git a/dcsoft-common/dcsoft-common-swagger/src/main/java/com/dcsoft/common/swagger/config/SwaggerBeanPostProcessor.java b/dcsoft-common/dcsoft-common-swagger/src/main/java/com/dcsoft/common/swagger/config/SwaggerBeanPostProcessor.java new file mode 100644 index 0000000..c186ff3 --- /dev/null +++ b/dcsoft-common/dcsoft-common-swagger/src/main/java/com/dcsoft/common/swagger/config/SwaggerBeanPostProcessor.java @@ -0,0 +1,54 @@ +package com.dcsoft.common.swagger.config; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.stereotype.Component; +import org.springframework.util.ReflectionUtils; +import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping; +import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider; +import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider; +import java.lang.reflect.Field; +import java.util.List; +import java.util.stream.Collectors; + +/** + * swagger 在 springboot 2.6.x 不兼容问题的处理 + * + * @author dcsoft + */ +@Component +public class SwaggerBeanPostProcessor implements 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); + } + } +} diff --git a/dcsoft-common/dcsoft-common-swagger/src/main/java/com/dcsoft/common/swagger/config/SwaggerProperties.java b/dcsoft-common/dcsoft-common-swagger/src/main/java/com/dcsoft/common/swagger/config/SwaggerProperties.java new file mode 100644 index 0000000..be99dc2 --- /dev/null +++ b/dcsoft-common/dcsoft-common-swagger/src/main/java/com/dcsoft/common/swagger/config/SwaggerProperties.java @@ -0,0 +1,345 @@ +package com.dcsoft.common.swagger.config; + +import java.util.ArrayList; +import java.util.List; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties("swagger") +public class SwaggerProperties +{ + /** + * 是否开启swagger + */ + private Boolean enabled; + + /** + * swagger会解析的包路径 + **/ + private String basePackage = ""; + + /** + * swagger会解析的url规则 + **/ + private List basePath = new ArrayList<>(); + + /** + * 在basePath基础上需要排除的url规则 + **/ + private List excludePath = new ArrayList<>(); + + /** + * 标题 + **/ + private String title = ""; + + /** + * 描述 + **/ + private String description = ""; + + /** + * 版本 + **/ + private String version = ""; + + /** + * 许可证 + **/ + private String license = ""; + + /** + * 许可证URL + **/ + private String licenseUrl = ""; + + /** + * 服务条款URL + **/ + private String termsOfServiceUrl = ""; + + /** + * host信息 + **/ + private String host = ""; + + /** + * 联系人信息 + */ + private Contact contact = new Contact(); + + /** + * 全局统一鉴权配置 + **/ + private Authorization authorization = new Authorization(); + + public Boolean getEnabled() + { + return enabled; + } + + public void setEnabled(Boolean enabled) + { + this.enabled = enabled; + } + + public String getBasePackage() + { + return basePackage; + } + + public void setBasePackage(String basePackage) + { + this.basePackage = basePackage; + } + + public List getBasePath() + { + return basePath; + } + + public void setBasePath(List basePath) + { + this.basePath = basePath; + } + + public List getExcludePath() + { + return excludePath; + } + + public void setExcludePath(List excludePath) + { + this.excludePath = excludePath; + } + + public String getTitle() + { + return title; + } + + public void setTitle(String title) + { + this.title = title; + } + + public String getDescription() + { + return description; + } + + public void setDescription(String description) + { + this.description = description; + } + + public String getVersion() + { + return version; + } + + public void setVersion(String version) + { + this.version = version; + } + + public String getLicense() + { + return license; + } + + public void setLicense(String license) + { + this.license = license; + } + + public String getLicenseUrl() + { + return licenseUrl; + } + + public void setLicenseUrl(String licenseUrl) + { + this.licenseUrl = licenseUrl; + } + + public String getTermsOfServiceUrl() + { + return termsOfServiceUrl; + } + + public void setTermsOfServiceUrl(String termsOfServiceUrl) + { + this.termsOfServiceUrl = termsOfServiceUrl; + } + + public String getHost() + { + return host; + } + + public void setHost(String host) + { + this.host = host; + } + + public Contact getContact() + { + return contact; + } + + public void setContact(Contact contact) + { + this.contact = contact; + } + + public Authorization getAuthorization() + { + return authorization; + } + + public void setAuthorization(Authorization authorization) + { + this.authorization = authorization; + } + + public static class Contact + { + /** + * 联系人 + **/ + private String name = ""; + /** + * 联系人url + **/ + private String url = ""; + /** + * 联系人email + **/ + private String email = ""; + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getUrl() + { + return url; + } + + public void setUrl(String url) + { + this.url = url; + } + + public String getEmail() + { + return email; + } + + public void setEmail(String email) + { + this.email = email; + } + } + + public static class Authorization + { + /** + * 鉴权策略ID,需要和SecurityReferences ID保持一致 + */ + private String name = ""; + + /** + * 需要开启鉴权URL的正则 + */ + private String authRegex = "^.*$"; + + /** + * 鉴权作用域列表 + */ + private List authorizationScopeList = new ArrayList<>(); + + private List tokenUrlList = new ArrayList<>(); + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getAuthRegex() + { + return authRegex; + } + + public void setAuthRegex(String authRegex) + { + this.authRegex = authRegex; + } + + public List getAuthorizationScopeList() + { + return authorizationScopeList; + } + + public void setAuthorizationScopeList(List authorizationScopeList) + { + this.authorizationScopeList = authorizationScopeList; + } + + public List getTokenUrlList() + { + return tokenUrlList; + } + + public void setTokenUrlList(List tokenUrlList) + { + this.tokenUrlList = tokenUrlList; + } + } + + public static class AuthorizationScope + { + /** + * 作用域名称 + */ + private String scope = ""; + + /** + * 作用域描述 + */ + private String description = ""; + + public String getScope() + { + return scope; + } + + public void setScope(String scope) + { + this.scope = scope; + } + + public String getDescription() + { + return description; + } + + public void setDescription(String description) + { + this.description = description; + } + } +} diff --git a/dcsoft-common/dcsoft-common-swagger/src/main/java/com/dcsoft/common/swagger/config/SwaggerWebConfiguration.java b/dcsoft-common/dcsoft-common-swagger/src/main/java/com/dcsoft/common/swagger/config/SwaggerWebConfiguration.java new file mode 100644 index 0000000..ebf9533 --- /dev/null +++ b/dcsoft-common/dcsoft-common-swagger/src/main/java/com/dcsoft/common/swagger/config/SwaggerWebConfiguration.java @@ -0,0 +1,22 @@ +package com.dcsoft.common.swagger.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * swagger 资源映射路径 + * + * @author dcsoft + */ +@Configuration +public class SwaggerWebConfiguration implements WebMvcConfigurer +{ + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) + { + /** swagger-ui 地址 */ + registry.addResourceHandler("/swagger-ui/**") + .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/"); + } +} diff --git a/dcsoft-common/dcsoft-common-swagger/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/dcsoft-common/dcsoft-common-swagger/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..e059a76 --- /dev/null +++ b/dcsoft-common/dcsoft-common-swagger/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,3 @@ +com.dcsoft.common.swagger.config.SwaggerAutoConfiguration +com.dcsoft.common.swagger.config.SwaggerWebConfiguration +com.dcsoft.common.swagger.config.SwaggerBeanPostProcessor diff --git a/dcsoft-common/pom.xml b/dcsoft-common/pom.xml new file mode 100644 index 0000000..5bde11e --- /dev/null +++ b/dcsoft-common/pom.xml @@ -0,0 +1,31 @@ + + + + com.dcsoft + dcsoft + 3.6.2 + + 4.0.0 + + + dcsoft-common-log + dcsoft-common-core + dcsoft-common-redis + dcsoft-common-seata + dcsoft-common-swagger + dcsoft-common-security + dcsoft-common-datascope + dcsoft-common-datasource + dcsoft-common-sms + + + + dcsoft-common + pom + + + dcsoft-common通用模块 + + + diff --git a/dcsoft-gateway/pom.xml b/dcsoft-gateway/pom.xml new file mode 100644 index 0000000..296d7af --- /dev/null +++ b/dcsoft-gateway/pom.xml @@ -0,0 +1,117 @@ + + + com.dcsoft + dcsoft + 3.6.2 + + 4.0.0 + + dcsoft-gateway + + + dcsoft-gateway网关模块 + + + + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + com.alibaba.cloud + spring-cloud-alibaba-sentinel-gateway + + + + + com.alibaba.csp + sentinel-datasource-nacos + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + org.springframework.cloud + spring-cloud-loadbalancer + + + + + pro.fessional + kaptcha + + + + + com.dcsoft + dcsoft-common-redis + + + + + io.springfox + springfox-swagger-ui + ${swagger.fox.version} + + + io.springfox + springfox-swagger2 + ${swagger.fox.version} + + + + + com.github.whvcse + easy-captcha + 1.6.2 + + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + diff --git a/dcsoft-gateway/src/main/java/com/dcsoft/gateway/DCSGatewayApplication.java b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/DCSGatewayApplication.java new file mode 100644 index 0000000..ea7dc0f --- /dev/null +++ b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/DCSGatewayApplication.java @@ -0,0 +1,24 @@ +package com.dcsoft.gateway; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; + +/** + * 网关启动程序 + * + * @author dcsoft + */ +@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class }) +public class DCSGatewayApplication +{ + public static void main(String[] args) + { + SpringApplication.run(com.dcsoft.gateway.DCSGatewayApplication.class, args); + System.out.println("(♥◠‿◠)ノ゙ 网关启动成功 ლ(´ڡ`ლ)゙ \n" + + " ___ ___ ___ \n" + + " | \\ / __| / __| \n" + + " | |) | | (__ \\__ \\ \n" + + " |___/ \\___| |___/ "); + } +} diff --git a/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/CaptchaConfig.java b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/CaptchaConfig.java new file mode 100644 index 0000000..19e1cd8 --- /dev/null +++ b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/CaptchaConfig.java @@ -0,0 +1,83 @@ +package com.dcsoft.gateway.config; + +import java.util.Properties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import com.google.code.kaptcha.impl.DefaultKaptcha; +import com.google.code.kaptcha.util.Config; +import static com.google.code.kaptcha.Constants.*; + +/** + * 验证码配置 + * + * @author dcsoft + */ +@Configuration +public class CaptchaConfig +{ + @Bean(name = "captchaProducer") + public DefaultKaptcha getKaptchaBean() + { + DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); + Properties properties = new Properties(); + // 是否有边框 默认为true 我们可以自己设置yes,no + properties.setProperty(KAPTCHA_BORDER, "yes"); + // 验证码文本字符颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black"); + // 验证码图片宽度 默认为200 + properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); + // 验证码图片高度 默认为50 + properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); + // 验证码文本字符大小 默认为40 + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38"); + // KAPTCHA_SESSION_KEY + properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode"); + // 验证码文本字符长度 默认为5 + properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4"); + // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier"); + // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy + properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy"); + Config config = new Config(properties); + defaultKaptcha.setConfig(config); + return defaultKaptcha; + } + + @Bean(name = "captchaProducerMath") + public DefaultKaptcha getKaptchaBeanMath() + { + DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); + Properties properties = new Properties(); + // 是否有边框 默认为true 我们可以自己设置yes,no + properties.setProperty(KAPTCHA_BORDER, "yes"); + // 边框颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90"); + // 验证码文本字符颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue"); + // 验证码图片宽度 默认为200 + properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); + // 验证码图片高度 默认为50 + properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); + // 验证码文本字符大小 默认为40 + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35"); + // KAPTCHA_SESSION_KEY + properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath"); + // 验证码文本生成器 + properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.dcsoft.gateway.config.KaptchaTextCreator"); + // 验证码文本字符间距 默认为2 + properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3"); + // 验证码文本字符长度 默认为5 + properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6"); + // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier"); + // 验证码噪点颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_NOISE_COLOR, "white"); + // 干扰实现类 + properties.setProperty(KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise"); + // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy + properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy"); + Config config = new Config(properties); + defaultKaptcha.setConfig(config); + return defaultKaptcha; + } +} diff --git a/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/CorsConfig.java b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/CorsConfig.java new file mode 100644 index 0000000..cf2b5aa --- /dev/null +++ b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/CorsConfig.java @@ -0,0 +1,62 @@ +package com.dcsoft.gateway.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.web.cors.reactive.CorsUtils; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.WebFilter; +import org.springframework.web.server.WebFilterChain; +import reactor.core.publisher.Mono; + +/** + * 验证码配置 + * + * @author dcsoft + */ +/** + * 跨域配置 + * + * @author ruoyi + */ +@Configuration +public class CorsConfig +{ + /** + * 这里为支持的请求头,如果有自定义的header字段请自己添加 + */ + private static final String ALLOWED_HEADERS = "X-Requested-With, Content-Type, Authorization, credential, X-XSRF-TOKEN, token, Admin-Token, App-Token"; + private static final String ALLOWED_METHODS = "GET,POST,PUT,DELETE,OPTIONS,HEAD"; + private static final String ALLOWED_ORIGIN = "*"; + private static final String ALLOWED_EXPOSE = "*"; + private static final String MAX_AGE = "18000L"; + + @Bean + public WebFilter corsFilter() + { + return (ServerWebExchange ctx, WebFilterChain chain) -> { + ServerHttpRequest request = ctx.getRequest(); + if (CorsUtils.isCorsRequest(request)) + { + ServerHttpResponse response = ctx.getResponse(); + HttpHeaders headers = response.getHeaders(); + headers.add("Access-Control-Allow-Headers", ALLOWED_HEADERS); + headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS); + headers.add("Access-Control-Allow-Origin", ALLOWED_ORIGIN); + headers.add("Access-Control-Expose-Headers", ALLOWED_EXPOSE); + headers.add("Access-Control-Max-Age", MAX_AGE); + headers.add("Access-Control-Allow-Credentials", "true"); + if (request.getMethod() == HttpMethod.OPTIONS) + { + response.setStatusCode(HttpStatus.OK); + return Mono.empty(); + } + } + return chain.filter(ctx); + }; + } +} diff --git a/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/GatewayConfig.java b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/GatewayConfig.java new file mode 100644 index 0000000..6fc64c0 --- /dev/null +++ b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/GatewayConfig.java @@ -0,0 +1,23 @@ +package com.dcsoft.gateway.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import com.dcsoft.gateway.handler.SentinelFallbackHandler; + +/** + * 网关限流配置 + * + * @author dcsoft + */ +@Configuration +public class GatewayConfig +{ + @Bean + @Order(Ordered.HIGHEST_PRECEDENCE) + public SentinelFallbackHandler sentinelGatewayExceptionHandler() + { + return new SentinelFallbackHandler(); + } +} diff --git a/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/KaptchaTextCreator.java b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/KaptchaTextCreator.java new file mode 100644 index 0000000..5152eb4 --- /dev/null +++ b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/KaptchaTextCreator.java @@ -0,0 +1,75 @@ +package com.dcsoft.gateway.config; + +import java.util.Random; +import com.google.code.kaptcha.text.impl.DefaultTextCreator; + +/** + * 验证码文本生成器 + * + * @author dcsoft + */ +public class KaptchaTextCreator extends DefaultTextCreator +{ + private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(","); + + @Override + public String getText() + { + Integer result = 0; + Random random = new Random(); + int x = random.nextInt(10); + int y = random.nextInt(10); + StringBuilder suChinese = new StringBuilder(); + int randomoperands = random.nextInt(3); + if (randomoperands == 0) + { + result = x * y; + suChinese.append(CNUMBERS[x]); + suChinese.append("*"); + suChinese.append(CNUMBERS[y]); + } + else if (randomoperands == 1) + { + if ((x != 0) && y % x == 0) + { + result = y / x; + suChinese.append(CNUMBERS[y]); + suChinese.append("/"); + suChinese.append(CNUMBERS[x]); + } + else + { + result = x + y; + suChinese.append(CNUMBERS[x]); + suChinese.append("+"); + suChinese.append(CNUMBERS[y]); + } + } + else if (randomoperands == 2) + { + if (x >= y) + { + result = x - y; + suChinese.append(CNUMBERS[x]); + suChinese.append("-"); + suChinese.append(CNUMBERS[y]); + } + else + { + result = y - x; + suChinese.append(CNUMBERS[y]); + suChinese.append("-"); + suChinese.append(CNUMBERS[x]); + } + } + else + { + result = x + y; + suChinese.append(CNUMBERS[x]); + suChinese.append("+"); + suChinese.append(CNUMBERS[y]); + } + suChinese.append("=?@" + result); + return suChinese.toString(); + } +} diff --git a/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/RouterFunctionConfiguration.java b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/RouterFunctionConfiguration.java new file mode 100644 index 0000000..7fca7d4 --- /dev/null +++ b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/RouterFunctionConfiguration.java @@ -0,0 +1,31 @@ +package com.dcsoft.gateway.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.MediaType; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import com.dcsoft.gateway.handler.ValidateCodeHandler; + +/** + * 路由配置信息 + * + * @author dcsoft + */ +@Configuration +public class RouterFunctionConfiguration +{ + @Autowired + private ValidateCodeHandler validateCodeHandler; + + @SuppressWarnings("rawtypes") + @Bean + public RouterFunction routerFunction() + { + return RouterFunctions.route( + RequestPredicates.GET("/code").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), + validateCodeHandler); + } +} diff --git a/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/SwaggerProvider.java b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/SwaggerProvider.java new file mode 100644 index 0000000..44d4464 --- /dev/null +++ b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/SwaggerProvider.java @@ -0,0 +1,79 @@ +package com.dcsoft.gateway.config; + +import java.util.ArrayList; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.gateway.config.GatewayProperties; +import org.springframework.cloud.gateway.route.RouteLocator; +import org.springframework.cloud.gateway.support.NameUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.config.ResourceHandlerRegistry; +import org.springframework.web.reactive.config.WebFluxConfigurer; +import springfox.documentation.swagger.web.SwaggerResource; +import springfox.documentation.swagger.web.SwaggerResourcesProvider; + +/** + * 聚合系统接口 + * + * @author dcsoft + */ +@Component +public class SwaggerProvider implements SwaggerResourcesProvider, WebFluxConfigurer +{ + /** + * Swagger2默认的url后缀 + */ + public static final String SWAGGER2URL = "/v2/api-docs"; + + /** + * 网关路由 + */ + @Lazy + @Autowired + private RouteLocator routeLocator; + + @Autowired + private GatewayProperties gatewayProperties; + + /** + * 聚合其他服务接口 + * + * @return + */ + @Override + public List get() + { + List resourceList = new ArrayList<>(); + List routes = new ArrayList<>(); + // 获取网关中配置的route + routeLocator.getRoutes().subscribe(route -> routes.add(route.getId())); + gatewayProperties.getRoutes().stream() + .filter(routeDefinition -> routes + .contains(routeDefinition.getId())) + .forEach(routeDefinition -> routeDefinition.getPredicates().stream() + .filter(predicateDefinition -> "Path".equalsIgnoreCase(predicateDefinition.getName())) + .filter(predicateDefinition -> !"dcsoft-auth".equalsIgnoreCase(routeDefinition.getId())) + .forEach(predicateDefinition -> resourceList + .add(swaggerResource(routeDefinition.getId(), predicateDefinition.getArgs() + .get(NameUtils.GENERATED_NAME_PREFIX + "0").replace("/**", SWAGGER2URL))))); + return resourceList; + } + + private SwaggerResource swaggerResource(String name, String location) + { + SwaggerResource swaggerResource = new SwaggerResource(); + swaggerResource.setName(name); + swaggerResource.setLocation(location); + swaggerResource.setSwaggerVersion("2.0"); + return swaggerResource; + } + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) + { + /** swagger-ui 地址 */ + registry.addResourceHandler("/swagger-ui/**") + .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/"); + } +} diff --git a/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/properties/CaptchaProperties.java b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/properties/CaptchaProperties.java new file mode 100644 index 0000000..909a214 --- /dev/null +++ b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/properties/CaptchaProperties.java @@ -0,0 +1,46 @@ +package com.dcsoft.gateway.config.properties; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Configuration; + +/** + * 验证码配置 + * + * @author dcsoft + */ +@Configuration +@RefreshScope +@ConfigurationProperties(prefix = "security.captcha") +public class CaptchaProperties +{ + /** + * 验证码开关 + */ + private Boolean enabled; + + /** + * 验证码类型(math 数组计算 char 字符) + */ + private String type; + + public Boolean getEnabled() + { + return enabled; + } + + public void setEnabled(Boolean enabled) + { + this.enabled = enabled; + } + + public String getType() + { + return type; + } + + public void setType(String type) + { + this.type = type; + } +} diff --git a/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/properties/IgnoreWhiteProperties.java b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/properties/IgnoreWhiteProperties.java new file mode 100644 index 0000000..1d8da62 --- /dev/null +++ b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/properties/IgnoreWhiteProperties.java @@ -0,0 +1,33 @@ +package com.dcsoft.gateway.config.properties; + +import java.util.ArrayList; +import java.util.List; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Configuration; + +/** + * 放行白名单配置 + * + * @author dcsoft + */ +@Configuration +@RefreshScope +@ConfigurationProperties(prefix = "security.ignore") +public class IgnoreWhiteProperties +{ + /** + * 放行白名单配置,网关不校验此处的白名单 + */ + private List whites = new ArrayList<>(); + + public List getWhites() + { + return whites; + } + + public void setWhites(List whites) + { + this.whites = whites; + } +} diff --git a/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/properties/XssProperties.java b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/properties/XssProperties.java new file mode 100644 index 0000000..6871347 --- /dev/null +++ b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/config/properties/XssProperties.java @@ -0,0 +1,48 @@ +package com.dcsoft.gateway.config.properties; + +import java.util.ArrayList; +import java.util.List; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Configuration; + +/** + * XSS跨站脚本配置 + * + * @author dcsoft + */ +@Configuration +@RefreshScope +@ConfigurationProperties(prefix = "security.xss") +public class XssProperties +{ + /** + * Xss开关 + */ + private Boolean enabled; + + /** + * 排除路径 + */ + private List excludeUrls = new ArrayList<>(); + + public Boolean getEnabled() + { + return enabled; + } + + public void setEnabled(Boolean enabled) + { + this.enabled = enabled; + } + + public List getExcludeUrls() + { + return excludeUrls; + } + + public void setExcludeUrls(List excludeUrls) + { + this.excludeUrls = excludeUrls; + } +} diff --git a/dcsoft-gateway/src/main/java/com/dcsoft/gateway/filter/AuthFilter.java b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/filter/AuthFilter.java new file mode 100644 index 0000000..c88b751 --- /dev/null +++ b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/filter/AuthFilter.java @@ -0,0 +1,151 @@ +package com.dcsoft.gateway.filter; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.GlobalFilter; +import org.springframework.core.Ordered; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; +import com.dcsoft.common.core.constant.CacheConstants; +import com.dcsoft.common.core.constant.HttpStatus; +import com.dcsoft.common.core.constant.SecurityConstants; +import com.dcsoft.common.core.constant.TokenConstants; +import com.dcsoft.common.core.utils.JwtUtils; +import com.dcsoft.common.core.utils.ServletUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.redis.service.RedisService; +import com.dcsoft.gateway.config.properties.IgnoreWhiteProperties; +import io.jsonwebtoken.Claims; +import reactor.core.publisher.Mono; + +/** + * 网关鉴权 + * + * @author dcsoft + */ +@Component +public class AuthFilter implements GlobalFilter, Ordered +{ + private static final Logger log = LoggerFactory.getLogger(AuthFilter.class); + + // 排除过滤的 uri 地址,nacos自行添加 + @Autowired + private IgnoreWhiteProperties ignoreWhite; + + @Autowired + private RedisService redisService; + + + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) + { + ServerHttpRequest request = exchange.getRequest(); + ServerHttpRequest.Builder mutate = request.mutate(); + + String url = request.getURI().getPath(); + // 跳过不需要验证的路径 + if (StringUtils.matches(url, ignoreWhite.getWhites())) + { + return chain.filter(exchange); + } + + String token = getToken(request); + + // 固定token + if ("Dcs@123".equals(token)) + { + return chain.filter(exchange); + } + + + + if (StringUtils.isEmpty(token)) + { + return unauthorizedResponse(exchange, "令牌不能为空"); + } + Claims claims = JwtUtils.parseToken(token); + if (claims == null) + { + return unauthorizedResponse(exchange, "令牌已过期或验证不正确!"); + } + // 对认证数据表中的appkey进行放行 + String appKey = JwtUtils.getAppKey(claims); + if(StringUtils.isNotEmpty(appKey)) { + return chain.filter(exchange); + } + + String userkey = JwtUtils.getUserKey(claims); + boolean islogin = redisService.hasKey(getTokenKey(userkey)); + if (!islogin) + { + return unauthorizedResponse(exchange, "登录状态已过期"); + } + String userid = JwtUtils.getUserId(claims); + String username = JwtUtils.getUserName(claims); + if (StringUtils.isEmpty(userid) || StringUtils.isEmpty(username)) + { + return unauthorizedResponse(exchange, "令牌验证失败"); + } + + // 设置用户信息到请求 + addHeader(mutate, SecurityConstants.USER_KEY, userkey); + addHeader(mutate, SecurityConstants.DETAILS_USER_ID, userid); + addHeader(mutate, SecurityConstants.DETAILS_USERNAME, username); + // 内部请求来源参数清除 + removeHeader(mutate, SecurityConstants.FROM_SOURCE); + return chain.filter(exchange.mutate().request(mutate.build()).build()); + } + + private void addHeader(ServerHttpRequest.Builder mutate, String name, Object value) + { + if (value == null) + { + return; + } + String valueStr = value.toString(); + String valueEncode = ServletUtils.urlEncode(valueStr); + mutate.header(name, valueEncode); + } + + private void removeHeader(ServerHttpRequest.Builder mutate, String name) + { + mutate.headers(httpHeaders -> httpHeaders.remove(name)).build(); + } + + private Mono unauthorizedResponse(ServerWebExchange exchange, String msg) + { + log.error("[鉴权异常处理]请求路径:{}", exchange.getRequest().getPath()); + return ServletUtils.webFluxResponseWriter(exchange.getResponse(), msg, HttpStatus.UNAUTHORIZED); + } + + /** + * 获取缓存key + */ + private String getTokenKey(String token) + { + return CacheConstants.LOGIN_TOKEN_KEY + token; + } + + /** + * 获取请求token + */ + private String getToken(ServerHttpRequest request) + { + String token = request.getHeaders().getFirst(TokenConstants.AUTHENTICATION); + // 如果前端设置了令牌前缀,则裁剪掉前缀 + if (StringUtils.isNotEmpty(token) && token.startsWith(TokenConstants.PREFIX)) + { + token = token.replaceFirst(TokenConstants.PREFIX, StringUtils.EMPTY); + } + return token; + } + + @Override + public int getOrder() + { + return -200; + } +} diff --git a/dcsoft-gateway/src/main/java/com/dcsoft/gateway/filter/BlackListUrlFilter.java b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/filter/BlackListUrlFilter.java new file mode 100644 index 0000000..cb410c1 --- /dev/null +++ b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/filter/BlackListUrlFilter.java @@ -0,0 +1,65 @@ +package com.dcsoft.gateway.filter; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; +import org.springframework.cloud.gateway.filter.GatewayFilter; +import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; +import org.springframework.stereotype.Component; +import com.dcsoft.common.core.utils.ServletUtils; + +/** + * 黑名单过滤器 + * + * @author dcsoft + */ +@Component +public class BlackListUrlFilter extends AbstractGatewayFilterFactory +{ + @Override + public GatewayFilter apply(Config config) + { + return (exchange, chain) -> { + + String url = exchange.getRequest().getURI().getPath(); + if (config.matchBlacklist(url)) + { + return ServletUtils.webFluxResponseWriter(exchange.getResponse(), "请求地址不允许访问"); + } + + return chain.filter(exchange); + }; + } + + public BlackListUrlFilter() + { + super(Config.class); + } + + public static class Config + { + private List blacklistUrl; + + private List blacklistUrlPattern = new ArrayList<>(); + + public boolean matchBlacklist(String url) + { + return !blacklistUrlPattern.isEmpty() && blacklistUrlPattern.stream().anyMatch(p -> p.matcher(url).find()); + } + + public List getBlacklistUrl() + { + return blacklistUrl; + } + + public void setBlacklistUrl(List blacklistUrl) + { + this.blacklistUrl = blacklistUrl; + this.blacklistUrlPattern.clear(); + this.blacklistUrl.forEach(url -> { + this.blacklistUrlPattern.add(Pattern.compile(url.replaceAll("\\*\\*", "(.*?)"), Pattern.CASE_INSENSITIVE)); + }); + } + } + +} diff --git a/dcsoft-gateway/src/main/java/com/dcsoft/gateway/filter/CacheRequestFilter.java b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/filter/CacheRequestFilter.java new file mode 100644 index 0000000..1eaae67 --- /dev/null +++ b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/filter/CacheRequestFilter.java @@ -0,0 +1,87 @@ +package com.dcsoft.gateway.filter; + +import java.util.Collections; +import java.util.List; +import org.springframework.cloud.gateway.filter.GatewayFilter; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.OrderedGatewayFilter; +import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; +import org.springframework.cloud.gateway.support.ServerWebExchangeUtils; +import org.springframework.http.HttpMethod; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; + +/** + * 获取body请求数据(解决流不能重复读取问题) + * + * @author dcsoft + */ +@Component +public class CacheRequestFilter extends AbstractGatewayFilterFactory +{ + public CacheRequestFilter() + { + super(Config.class); + } + + @Override + public String name() + { + return "CacheRequestFilter"; + } + + @Override + public GatewayFilter apply(Config config) + { + CacheRequestGatewayFilter cacheRequestGatewayFilter = new CacheRequestGatewayFilter(); + Integer order = config.getOrder(); + if (order == null) + { + return cacheRequestGatewayFilter; + } + return new OrderedGatewayFilter(cacheRequestGatewayFilter, order); + } + + public static class CacheRequestGatewayFilter implements GatewayFilter + { + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) + { + // GET DELETE 不过滤 + HttpMethod method = exchange.getRequest().getMethod(); + if (method == null || method == HttpMethod.GET || method == HttpMethod.DELETE) + { + return chain.filter(exchange); + } + return ServerWebExchangeUtils.cacheRequestBodyAndRequest(exchange, (serverHttpRequest) -> { + if (serverHttpRequest == exchange.getRequest()) + { + return chain.filter(exchange); + } + return chain.filter(exchange.mutate().request(serverHttpRequest).build()); + }); + } + } + + @Override + public List shortcutFieldOrder() + { + return Collections.singletonList("order"); + } + + static class Config + { + private Integer order; + + public Integer getOrder() + { + return order; + } + + public void setOrder(Integer order) + { + this.order = order; + } + } +} diff --git a/dcsoft-gateway/src/main/java/com/dcsoft/gateway/filter/ValidateCodeFilter.java b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/filter/ValidateCodeFilter.java new file mode 100644 index 0000000..4f9455d --- /dev/null +++ b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/filter/ValidateCodeFilter.java @@ -0,0 +1,81 @@ +package com.dcsoft.gateway.filter; + +import java.nio.CharBuffer; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.atomic.AtomicReference; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.gateway.filter.GatewayFilter; +import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.core.io.buffer.DataBufferUtils; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.stereotype.Component; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.dcsoft.common.core.utils.ServletUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.gateway.config.properties.CaptchaProperties; +import com.dcsoft.gateway.service.ValidateCodeService; +import reactor.core.publisher.Flux; + +/** + * 验证码过滤器 + * + * @author dcsoft + */ +@Component +public class ValidateCodeFilter extends AbstractGatewayFilterFactory +{ + private final static String[] VALIDATE_URL = new String[] { "/auth/login", "/auth/register" }; + + @Autowired + private ValidateCodeService validateCodeService; + + @Autowired + private CaptchaProperties captchaProperties; + + private static final String CODE = "code"; + + private static final String UUID = "uuid"; + + @Override + public GatewayFilter apply(Object config) + { + return (exchange, chain) -> { + ServerHttpRequest request = exchange.getRequest(); + + // 非登录/注册请求或验证码关闭,不处理 + if (!StringUtils.containsAnyIgnoreCase(request.getURI().getPath(), VALIDATE_URL) || !captchaProperties.getEnabled()) + { + return chain.filter(exchange); + } + + try + { + String rspStr = resolveBodyFromRequest(request); + JSONObject obj = JSON.parseObject(rspStr); + if(StringUtils.isNotEmpty(obj.getString(CODE))) { + validateCodeService.checkCaptcha(obj.getString(CODE), obj.getString(UUID)); + } + } + catch (Exception e) + { + return ServletUtils.webFluxResponseWriter(exchange.getResponse(), e.getMessage()); + } + return chain.filter(exchange); + }; + } + + private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest) + { + // 获取请求体 + Flux body = serverHttpRequest.getBody(); + AtomicReference bodyRef = new AtomicReference<>(); + body.subscribe(buffer -> { + CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer()); + DataBufferUtils.release(buffer); + bodyRef.set(charBuffer.toString()); + }); + return bodyRef.get(); + } +} diff --git a/dcsoft-gateway/src/main/java/com/dcsoft/gateway/filter/XssFilter.java b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/filter/XssFilter.java new file mode 100644 index 0000000..72dfe51 --- /dev/null +++ b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/filter/XssFilter.java @@ -0,0 +1,129 @@ +package com.dcsoft.gateway.filter; + +import java.nio.charset.StandardCharsets; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.GlobalFilter; +import org.springframework.core.Ordered; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.core.io.buffer.DataBufferFactory; +import org.springframework.core.io.buffer.DataBufferUtils; +import org.springframework.core.io.buffer.DefaultDataBufferFactory; +import org.springframework.core.io.buffer.NettyDataBufferFactory; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.http.server.reactive.ServerHttpRequestDecorator; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.utils.html.EscapeUtil; +import com.dcsoft.gateway.config.properties.XssProperties; +import io.netty.buffer.ByteBufAllocator; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +/** + * 跨站脚本过滤器 + * + * @author dcsoft + */ +@Component +@ConditionalOnProperty(value = "security.xss.enabled", havingValue = "true") +public class XssFilter implements GlobalFilter, Ordered +{ + // 跨站脚本的 xss 配置,nacos自行添加 + @Autowired + private XssProperties xss; + + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) + { + ServerHttpRequest request = exchange.getRequest(); + // xss开关未开启 或 通过nacos关闭,不过滤 + if (!xss.getEnabled()) + { + return chain.filter(exchange); + } + // GET DELETE 不过滤 + HttpMethod method = request.getMethod(); + if (method == null || method == HttpMethod.GET || method == HttpMethod.DELETE) + { + return chain.filter(exchange); + } + // 非json类型,不过滤 + if (!isJsonRequest(exchange)) + { + return chain.filter(exchange); + } + // excludeUrls 不过滤 + String url = request.getURI().getPath(); + if (StringUtils.matches(url, xss.getExcludeUrls())) + { + return chain.filter(exchange); + } + ServerHttpRequestDecorator httpRequestDecorator = requestDecorator(exchange); + return chain.filter(exchange.mutate().request(httpRequestDecorator).build()); + + } + + private ServerHttpRequestDecorator requestDecorator(ServerWebExchange exchange) + { + ServerHttpRequestDecorator serverHttpRequestDecorator = new ServerHttpRequestDecorator(exchange.getRequest()) + { + @Override + public Flux getBody() + { + Flux body = super.getBody(); + return body.buffer().map(dataBuffers -> { + DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory(); + DataBuffer join = dataBufferFactory.join(dataBuffers); + byte[] content = new byte[join.readableByteCount()]; + join.read(content); + DataBufferUtils.release(join); + String bodyStr = new String(content, StandardCharsets.UTF_8); + // 防xss攻击过滤 + bodyStr = EscapeUtil.clean(bodyStr); + // 转成字节 + byte[] bytes = bodyStr.getBytes(); + NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT); + DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length); + buffer.write(bytes); + return buffer; + }); + } + + @Override + public HttpHeaders getHeaders() + { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.putAll(super.getHeaders()); + // 由于修改了请求体的body,导致content-length长度不确定,因此需要删除原先的content-length + httpHeaders.remove(HttpHeaders.CONTENT_LENGTH); + httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked"); + return httpHeaders; + } + + }; + return serverHttpRequestDecorator; + } + + /** + * 是否是Json请求 + * + * @param exchange HTTP请求 + */ + public boolean isJsonRequest(ServerWebExchange exchange) + { + String header = exchange.getRequest().getHeaders().getFirst(HttpHeaders.CONTENT_TYPE); + return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE); + } + + @Override + public int getOrder() + { + return -100; + } +} diff --git a/dcsoft-gateway/src/main/java/com/dcsoft/gateway/handler/GatewayExceptionHandler.java b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/handler/GatewayExceptionHandler.java new file mode 100644 index 0000000..e9b0983 --- /dev/null +++ b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/handler/GatewayExceptionHandler.java @@ -0,0 +1,56 @@ +package com.dcsoft.gateway.handler; + +import org.springframework.cloud.gateway.support.NotFoundException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.web.server.ResponseStatusException; +import org.springframework.web.server.ServerWebExchange; +import com.dcsoft.common.core.utils.ServletUtils; +import reactor.core.publisher.Mono; + +/** + * 网关统一异常处理 + * + * @author dcsoft + */ +@Order(-1) +@Configuration +public class GatewayExceptionHandler implements ErrorWebExceptionHandler +{ + private static final Logger log = LoggerFactory.getLogger(GatewayExceptionHandler.class); + + @Override + public Mono handle(ServerWebExchange exchange, Throwable ex) + { + ServerHttpResponse response = exchange.getResponse(); + + if (exchange.getResponse().isCommitted()) + { + return Mono.error(ex); + } + + String msg; + + if (ex instanceof NotFoundException) + { + msg = "服务未找到"; + } + else if (ex instanceof ResponseStatusException) + { + ResponseStatusException responseStatusException = (ResponseStatusException) ex; + msg = responseStatusException.getMessage(); + } + else + { + msg = "内部服务器错误"; + } + + log.error("[网关异常处理]请求路径:{},异常信息:{}", exchange.getRequest().getPath(), ex.getMessage()); + + return ServletUtils.webFluxResponseWriter(response, msg); + } +} diff --git a/dcsoft-gateway/src/main/java/com/dcsoft/gateway/handler/SentinelFallbackHandler.java b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/handler/SentinelFallbackHandler.java new file mode 100644 index 0000000..bf1e146 --- /dev/null +++ b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/handler/SentinelFallbackHandler.java @@ -0,0 +1,41 @@ +package com.dcsoft.gateway.handler; + +import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager; +import com.alibaba.csp.sentinel.slots.block.BlockException; +import com.dcsoft.common.core.utils.ServletUtils; +import org.springframework.web.reactive.function.server.ServerResponse; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.WebExceptionHandler; +import reactor.core.publisher.Mono; + +/** + * 自定义限流异常处理 + * + * @author dcsoft + */ +public class SentinelFallbackHandler implements WebExceptionHandler +{ + private Mono writeResponse(ServerResponse response, ServerWebExchange exchange) + { + return ServletUtils.webFluxResponseWriter(exchange.getResponse(), "请求超过最大数,请稍候再试"); + } + + @Override + public Mono handle(ServerWebExchange exchange, Throwable ex) + { + if (exchange.getResponse().isCommitted()) + { + return Mono.error(ex); + } + if (!BlockException.isBlockException(ex)) + { + return Mono.error(ex); + } + return handleBlockedRequest(exchange, ex).flatMap(response -> writeResponse(response, exchange)); + } + + private Mono handleBlockedRequest(ServerWebExchange exchange, Throwable throwable) + { + return GatewayCallbackManager.getBlockHandler().handleRequest(exchange, throwable); + } +} diff --git a/dcsoft-gateway/src/main/java/com/dcsoft/gateway/handler/SwaggerHandler.java b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/handler/SwaggerHandler.java new file mode 100644 index 0000000..fd052ad --- /dev/null +++ b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/handler/SwaggerHandler.java @@ -0,0 +1,56 @@ +package com.dcsoft.gateway.handler; + +import java.util.Optional; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Mono; +import springfox.documentation.swagger.web.SecurityConfiguration; +import springfox.documentation.swagger.web.SecurityConfigurationBuilder; +import springfox.documentation.swagger.web.SwaggerResourcesProvider; +import springfox.documentation.swagger.web.UiConfiguration; +import springfox.documentation.swagger.web.UiConfigurationBuilder; + +@RestController +@RequestMapping("/swagger-resources") +public class SwaggerHandler +{ + @Autowired(required = false) + private SecurityConfiguration securityConfiguration; + + @Autowired(required = false) + private UiConfiguration uiConfiguration; + + private final SwaggerResourcesProvider swaggerResources; + + @Autowired + public SwaggerHandler(SwaggerResourcesProvider swaggerResources) + { + this.swaggerResources = swaggerResources; + } + + @GetMapping("/configuration/security") + public Mono> securityConfiguration() + { + return Mono.just(new ResponseEntity<>( + Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), + HttpStatus.OK)); + } + + @GetMapping("/configuration/ui") + public Mono> uiConfiguration() + { + return Mono.just(new ResponseEntity<>( + Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK)); + } + + @SuppressWarnings("rawtypes") + @GetMapping("") + public Mono swaggerResources() + { + return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK))); + } +} diff --git a/dcsoft-gateway/src/main/java/com/dcsoft/gateway/handler/ValidateCodeHandler.java b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/handler/ValidateCodeHandler.java new file mode 100644 index 0000000..fc47f75 --- /dev/null +++ b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/handler/ValidateCodeHandler.java @@ -0,0 +1,41 @@ +package com.dcsoft.gateway.handler; + +import java.io.IOException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.BodyInserters; +import org.springframework.web.reactive.function.server.HandlerFunction; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import com.dcsoft.common.core.exception.CaptchaException; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.gateway.service.ValidateCodeService; +import reactor.core.publisher.Mono; + +/** + * 验证码获取 + * + * @author dcsoft + */ +@Component +public class ValidateCodeHandler implements HandlerFunction +{ + @Autowired + private ValidateCodeService validateCodeService; + + @Override + public Mono handle(ServerRequest serverRequest) + { + AjaxResult ajax; + try + { + ajax = validateCodeService.createCaptcha(); + } + catch (CaptchaException | IOException e) + { + return Mono.error(e); + } + return ServerResponse.status(HttpStatus.OK).body(BodyInserters.fromValue(ajax)); + } +} diff --git a/dcsoft-gateway/src/main/java/com/dcsoft/gateway/service/ValidateCodeService.java b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/service/ValidateCodeService.java new file mode 100644 index 0000000..8bf36d0 --- /dev/null +++ b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/service/ValidateCodeService.java @@ -0,0 +1,23 @@ +package com.dcsoft.gateway.service; + +import java.io.IOException; +import com.dcsoft.common.core.exception.CaptchaException; +import com.dcsoft.common.core.web.domain.AjaxResult; + +/** + * 验证码处理 + * + * @author dcsoft + */ +public interface ValidateCodeService +{ + /** + * 生成验证码 + */ + public AjaxResult createCaptcha() throws IOException, CaptchaException; + + /** + * 校验验证码 + */ + public void checkCaptcha(String key, String value) throws CaptchaException; +} diff --git a/dcsoft-gateway/src/main/java/com/dcsoft/gateway/service/impl/ValidateCodeServiceImpl.java b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/service/impl/ValidateCodeServiceImpl.java new file mode 100644 index 0000000..3e64626 --- /dev/null +++ b/dcsoft-gateway/src/main/java/com/dcsoft/gateway/service/impl/ValidateCodeServiceImpl.java @@ -0,0 +1,130 @@ +package com.dcsoft.gateway.service.impl; + +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import javax.annotation.Resource; +import javax.imageio.ImageIO; + +import com.wf.captcha.ArithmeticCaptcha; +import com.wf.captcha.SpecCaptcha; +import com.wf.captcha.base.Captcha; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.FastByteArrayOutputStream; +import com.google.code.kaptcha.Producer; +import com.dcsoft.common.core.constant.CacheConstants; +import com.dcsoft.common.core.constant.Constants; +import com.dcsoft.common.core.exception.CaptchaException; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.utils.sign.Base64; +import com.dcsoft.common.core.utils.uuid.IdUtils; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.redis.service.RedisService; +import com.dcsoft.gateway.config.properties.CaptchaProperties; +import com.dcsoft.gateway.service.ValidateCodeService; + +/** + * 验证码实现处理 + * + * @author dcsoft + */ +@Service +public class ValidateCodeServiceImpl implements ValidateCodeService +{ + @Resource(name = "captchaProducer") + private Producer captchaProducer; + + @Resource(name = "captchaProducerMath") + private Producer captchaProducerMath; + + @Autowired + private RedisService redisService; + + @Autowired + private CaptchaProperties captchaProperties; + + /** + * 生成验证码 + */ + @Override + public AjaxResult createCaptcha() throws IOException, CaptchaException + { + AjaxResult ajax = AjaxResult.success(); + boolean captchaEnabled = captchaProperties.getEnabled(); + ajax.put("captchaEnabled", captchaEnabled); + if (!captchaEnabled) + { + return ajax; + } + + // 保存验证码信息 + String uuid = IdUtils.simpleUUID(); + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; + + // String capStr = null, code = null; + //BufferedImage image = null; + + String captchaType = captchaProperties.getType(); + //验证码EasyCaptcha工具 + Captcha captcha = null; + // 生成验证码 + if ("math".equals(captchaType)) + { + String capText = captchaProducerMath.createText(); + /* capStr = capText.substring(0, capText.lastIndexOf("@")); + code = capText.substring(capText.lastIndexOf("@") + 1); + image = captchaProducerMath.createImage(capStr);*/ + captcha = new ArithmeticCaptcha(115, 42); + + } + else if ("char".equals(captchaType)) + { + /* capStr = code = captchaProducer.createText(); + image = captchaProducer.createImage(capStr);*/ + captcha = new SpecCaptcha(115,42); + } + //得到验证码的值 + String code = captcha.text(); + + redisService.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); + /*// 转换流信息写出 + FastByteArrayOutputStream os = new FastByteArrayOutputStream(); + try + { + ImageIO.write(image, "jpg", os); + } + catch (IOException e) + { + return AjaxResult.error(e.getMessage()); + }*/ + + ajax.put("uuid", uuid); + ajax.put("img", captcha.toBase64()); + return ajax; + } + + /** + * 校验验证码 + */ + @Override + public void checkCaptcha(String code, String uuid) throws CaptchaException + { + if (StringUtils.isEmpty(code)) + { + throw new CaptchaException("验证码不能为空"); + } + if (StringUtils.isEmpty(uuid)) + { + throw new CaptchaException("验证码已失效"); + } + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; + String captcha = redisService.getCacheObject(verifyKey); + redisService.deleteObject(verifyKey); + + if (!code.equalsIgnoreCase(captcha)) + { + throw new CaptchaException("验证码错误"); + } + } +} diff --git a/dcsoft-gateway/src/main/resources/banner.txt b/dcsoft-gateway/src/main/resources/banner.txt new file mode 100644 index 0000000..dfc21cd --- /dev/null +++ b/dcsoft-gateway/src/main/resources/banner.txt @@ -0,0 +1,7 @@ +Spring Boot Version: ${spring-boot.version} +Spring Application Name: ${spring.application.name} + + ___ ___ ___ ___ ___ _____ ___ __ __ ___ __ __ + | \ / __| / __| ___ / __| / \ |_ _| | __| \ \ / // \ \ \ / / + | |) | | (__ \__ \ |___| | (_ | | - | | | | _| \ \/\/ / | - | \ V / + |___/ \___| |___/ _____ \___| |_|_| _|_|_ |___| \_/\_/ |_|_| _|_|_ diff --git a/dcsoft-gateway/src/main/resources/bootstrap.yml b/dcsoft-gateway/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..355dfdc --- /dev/null +++ b/dcsoft-gateway/src/main/resources/bootstrap.yml @@ -0,0 +1,40 @@ +# Tomcat +server: + port: 6609 + +# Spring +spring: + application: + # 应用名称 + name: dcsoft-gateway + profiles: + # 环境配置 + active: dev + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: 127.0.0.1:8848 + config: + # 配置中心地址 + server-addr: 127.0.0.1:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + sentinel: + # 取消控制台懒加载 + eager: true + transport: + # 控制台地址 + dashboard: 127.0.0.1:8718 + # nacos配置持久化 + datasource: + ds1: + nacos: + server-addr: 127.0.0.1:8848 + dataId: sentinel-dcsoft-gateway + groupId: DEFAULT_GROUP + data-type: json + rule-type: gw-flow diff --git a/dcsoft-gateway/src/main/resources/logback.xml b/dcsoft-gateway/src/main/resources/logback.xml new file mode 100644 index 0000000..54e2809 --- /dev/null +++ b/dcsoft-gateway/src/main/resources/logback.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/info.log + + + + ${log.path}/info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/error.log + + + + ${log.path}/error.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + + + + + + + + + + + + + diff --git a/dcsoft-modules/dcsoft-file/pom.xml b/dcsoft-modules/dcsoft-file/pom.xml new file mode 100644 index 0000000..f058f84 --- /dev/null +++ b/dcsoft-modules/dcsoft-file/pom.xml @@ -0,0 +1,89 @@ + + + + com.dcsoft + dcsoft-modules + 3.6.2 + + 4.0.0 + + dcsoft-modules-file + + + dcsoft-modules-file文件服务 + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + com.github.tobato + fastdfs-client + + + + + io.minio + minio + ${minio.version} + + + + + com.dcsoft + dcsoft-api-system + + + + + com.dcsoft + dcsoft-common-swagger + + + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + diff --git a/dcsoft-modules/dcsoft-file/src/main/java/com/Main.java b/dcsoft-modules/dcsoft-file/src/main/java/com/Main.java new file mode 100644 index 0000000..247d15f --- /dev/null +++ b/dcsoft-modules/dcsoft-file/src/main/java/com/Main.java @@ -0,0 +1,159 @@ +package com; + +import com.uniubi.Register.FaceBox; +import com.uniubi.Register.UfaceRegister; +import com.uniubi.Register.UfaceRegisterJNI; + +import javax.imageio.stream.FileImageOutputStream; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.Objects; + +class MyThread extends Thread { + private final String name; + private final File[] files; + + public MyThread(String name, File[] files) { + this.name = name; + this.files = files; + } + + public void run() { + System.out.println("SDK version : " + UfaceRegisterJNI.GetSDKVersion()); + UfaceRegister.SetLogMode(2); +// UfaceRegister.SetModelPath(""); + int res = UfaceRegister.Auth("dongbang", "NvJZ9pHhVbtX", "verify.lic"); + System.out.println("Auth status : " + res); + UfaceRegister u = new UfaceRegister(); + int need_handle_num = files.length; + for (int i = 0; i < need_handle_num; i++) { + try { + byte[] image1 = Files.readAllBytes(new File(files[i].toString()).toPath()); + FaceBox box1 = new FaceBox(); +// res = u.JudgeImage(image1, box1); + float score = u.DynamicQuality(image1, box1); + System.out.println(name + ",i = " + i + ",all" + need_handle_num + ",fileName = " + files[i] + ",code " + box1.code + " score " + score); + } catch (IOException e) { + e.printStackTrace(); + } + + } + u.release(); + } +} + +public class Main { + public static void test_GetSimpleImage() { + System.out.println("SDK version : " + UfaceRegisterJNI.GetSDKVersion()); + UfaceRegister.SetLogMode(2); + //UfaceRegister.SetModelPath(""); + int res = UfaceRegister.Auth("decheng", "kbSfmCwalEFU", "verify.lic"); + System.out.println("Auth status : " + res); + UfaceRegister u = new UfaceRegister(); + String path = ""; + File file = new File(path); + File[] tempList = file.listFiles(); + + try { + for (int i = 0; i < Objects.requireNonNull(tempList).length; i++) { + System.out.println(tempList[i] + " " + i); + byte[] image = Files.readAllBytes(new File(tempList[i].toString()).toPath()); + FaceBox box = new FaceBox(); + res = u.JudgeImage(image, box); + if (res == 0) { + String feature_src = u.GetFeature(image, 110, box); + System.out.println("before box xmin:" + box.xmin + ",ymin:" + box.ymin + ",xmax:" + box.xmax + ",ymax:" + box.ymax); + byte[] small_image = u.GetSimpleImage(image, box, 1, 300); + System.out.println("after box xmin:" + box.xmin + ",ymin:" + box.ymin + ",xmax:" + box.xmax + ",ymax:" + box.ymax); + if (small_image != null) { + FileImageOutputStream os = new FileImageOutputStream(new File("test.jpg")); + System.out.println("small_image.length : " + small_image.length); + os.write(small_image, 0, small_image.length); + os.flush(); + os.close(); + } + String feature = u.GetFeature(small_image, 110, box); + float score = u.CompareFeat(feature_src, feature); + System.out.println("score : " + score); +// System.out.println("feature : " + feature); + } else { + System.out.println("res == " + res); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void main(String[] args) throws InterruptedException { + //test_thread +// test_thread(); + //test_GetSimpleImage +// test_GetSimpleImage(); + //test_compare_two_pic + test_compare_two_pic(); + } + + public static void test_compare_two_pic() { + System.out.println("SDK version : " + UfaceRegisterJNI.GetSDKVersion()); + UfaceRegister.SetLogMode(2); + UfaceRegister.SetModelPath("/usr/uface_sdk/models"); + int res = UfaceRegister.Auth("decheng","kbSfmCwalEFU", "verify.lic"); + System.out.println("Auth status : " + res); + UfaceRegister u = new UfaceRegister(); + + try { + byte[] image1 = Files.readAllBytes(new File("/usr/face_img/A003.jpg").toPath()); + FaceBox box1 = new FaceBox(); + int res1 = u.JudgeImage(image1, box1); + String feature1 = ""; + if (res1 == 0) { + feature1 = u.GetFeature(image1, 110, box1); + } else { + System.out.println("res1 == " + res1); + } + + byte[] image2 = Files.readAllBytes(new File("/usr/face_img/A004.jpg").toPath()); + FaceBox box2 = new FaceBox(); + int res2 = u.JudgeImage(image2, box2); + String feature2 = ""; + if (res2 == 0) { + feature2 = u.GetFeature(image2, 110, box2); + } else { + System.out.println("res2 == " + res2); + } + + float score = u.CompareFeat(feature1, feature2); + System.out.println("score : " + score); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void test_thread() { + int thread_num = 1; + + String path = ""; + File file = new File(path); + File[] tempList = file.listFiles(); + assert tempList != null; + int per_thread_handle_nums = tempList.length / thread_num; + System.out.println(" per_thread_handle_nums: " + per_thread_handle_nums); + for (int i = 0; i < thread_num; i++) { + if (i != thread_num - 1) { + File[] test = new File[per_thread_handle_nums]; + System.arraycopy(tempList, i * per_thread_handle_nums, test, 0, per_thread_handle_nums); + MyThread mt = new MyThread("thread" + i, test); + mt.start(); + } else { + File[] test = new File[per_thread_handle_nums + tempList.length % thread_num]; + System.arraycopy(tempList, i * per_thread_handle_nums, test, 0, per_thread_handle_nums + tempList.length % thread_num); + MyThread mt = new MyThread("thread" + i, test); + mt.start(); + } + } + } + +} + diff --git a/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/DCSFileApplication.java b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/DCSFileApplication.java new file mode 100644 index 0000000..6feeb7e --- /dev/null +++ b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/DCSFileApplication.java @@ -0,0 +1,61 @@ +package com.dcsoft.file; + +import com.dcsoft.file.config.FileListener; +import org.apache.commons.io.monitor.FileAlterationMonitor; +import org.apache.commons.io.monitor.FileAlterationObserver; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import com.dcsoft.common.swagger.annotation.EnableCustomSwagger2; + +import java.io.File; +import java.util.concurrent.TimeUnit; + +/** + * 文件服务 + * + * @author dcsoft + */ +@EnableCustomSwagger2 +@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class }) +public class DCSFileApplication +{ + /* public static String rootDir; + + @Value("${backImg.rootDir}") + public void setRootDir(String rootDir) { + this.rootDir = rootDir; + } + + public static String copyDir; + + @Value("${backImg.copyDir}") + public void setCopyDir(String copyDir) { + this.copyDir = copyDir; + }*/ + + public static void main(String[] args) + { + SpringApplication.run(DCSFileApplication.class, args); + System.out.println("(♥◠‿◠)ノ゙ 文件服务模块启动成功 ლ(´ڡ`ლ)゙ \n" + + " ___ ___ ___ \n" + + " | \\ / __| / __| \n" + + " | |) | | (__ \\__ \\ \n" + + " |___/ \\___| |___/ "); + + /* // 轮询间隔 5 秒 + long interval = TimeUnit.SECONDS.toMillis(5); + // 不使用过滤器 + FileAlterationObserver observer = new FileAlterationObserver(new File(rootDir)); + observer.addListener(new FileListener(rootDir,copyDir)); + // 创建文件变化监听器 + FileAlterationMonitor monitor = new FileAlterationMonitor(interval, observer); + // 开始监控 + try { + monitor.start(); + } catch (Exception e) { + throw new RuntimeException(e); + }*/ + } +} diff --git a/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/config/FileListener.java b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/config/FileListener.java new file mode 100644 index 0000000..8570c72 --- /dev/null +++ b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/config/FileListener.java @@ -0,0 +1,83 @@ +package com.dcsoft.file.config; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.io.monitor.FileAlterationListenerAdaptor; +import org.apache.commons.io.monitor.FileAlterationMonitor; +import org.apache.commons.io.monitor.FileAlterationObserver; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Slf4j +public class FileListener extends FileAlterationListenerAdaptor { + + public String rootDir; + public String copyDir; + + public FileListener(String root, String copy) { + this.rootDir=root; + this.copyDir=copy; + } + + /** + * 文件创建执行 + */ + public void onFileCreate(File file) { + log.info("[新建]:" + file.getPath()); + //文件同步到另一个文件夹中 + String path=file.getPath().replace(rootDir,copyDir); + File dest=new File(path); + if (!(dest.exists() && dest.isDirectory())) { + new File(path.substring(0, path.lastIndexOf(File.separator))).mkdirs(); + } + try { + Files.copy(file.toPath(), dest.toPath()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + /** + * 文件修改 + */ + public void onFileChange(File file) { + log.info("[修改]:" + file.getAbsolutePath()); + } + /** + * 文件删除 + */ + public void onFileDelete(File file) { + log.info("[删除]:" + file.getAbsolutePath()); + } + /** + * 目录创建 + */ + public void onDirectoryCreate(File directory) { + log.info("[新建]:" + directory.getAbsolutePath()); + } + /** + * 目录修改 + */ + public void onDirectoryChange(File directory) { + log.info("[修改]:" + directory.getAbsolutePath()); + } + /** + * 目录删除 + */ + public void onDirectoryDelete(File directory) { + log.info("[删除]:" + directory.getAbsolutePath()); + } + public void onStart(FileAlterationObserver observer) { + super.onStart(observer); + } + public void onStop(FileAlterationObserver observer) { + super.onStop(observer); + } + + + +} diff --git a/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/config/MinioConfig.java b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/config/MinioConfig.java new file mode 100644 index 0000000..bb80bd8 --- /dev/null +++ b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/config/MinioConfig.java @@ -0,0 +1,82 @@ +package com.dcsoft.file.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import io.minio.MinioClient; + +/** + * Minio 配置信息 + * + * @author dcsoft + */ +@Configuration +@ConfigurationProperties(prefix = "minio") +public class MinioConfig +{ + /** + * 服务地址 + */ + private String url; + + /** + * 用户名 + */ + private String accessKey; + + /** + * 密码 + */ + private String secretKey; + + /** + * 存储桶名称 + */ + private String bucketName; + + public String getUrl() + { + return url; + } + + public void setUrl(String url) + { + this.url = url; + } + + public String getAccessKey() + { + return accessKey; + } + + public void setAccessKey(String accessKey) + { + this.accessKey = accessKey; + } + + public String getSecretKey() + { + return secretKey; + } + + public void setSecretKey(String secretKey) + { + this.secretKey = secretKey; + } + + public String getBucketName() + { + return bucketName; + } + + public void setBucketName(String bucketName) + { + this.bucketName = bucketName; + } + + @Bean + public MinioClient getMinioClient() + { + return MinioClient.builder().endpoint(url).credentials(accessKey, secretKey).build(); + } +} diff --git a/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/config/ResourcesConfig.java b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/config/ResourcesConfig.java new file mode 100644 index 0000000..7c2c111 --- /dev/null +++ b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/config/ResourcesConfig.java @@ -0,0 +1,50 @@ +package com.dcsoft.file.config; + +import java.io.File; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * 通用映射配置 + * + * @author dcsoft + */ +@Configuration +public class ResourcesConfig implements WebMvcConfigurer +{ + /** + * 上传文件存储在本地的根路径 + */ + @Value("${file.path}") + private String localFilePath; + + /** + * 资源映射路径 前缀 + */ + @Value("${file.prefix}") + public String localFilePrefix; + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) + { + /** 本地文件上传路径 */ + registry.addResourceHandler(localFilePrefix + "/**") + .addResourceLocations("file:" + localFilePath + File.separator); + } + + /** + * 开启跨域 + */ + @Override + public void addCorsMappings(CorsRegistry registry) { + // 设置允许跨域的路由 + registry.addMapping(localFilePrefix + "/**") + // 设置允许跨域请求的域名 + .allowedOrigins("*") + // 设置允许的方法 + .allowedMethods("GET"); + } +} diff --git a/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/controller/MinIO.java b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/controller/MinIO.java new file mode 100644 index 0000000..ab6db05 --- /dev/null +++ b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/controller/MinIO.java @@ -0,0 +1,81 @@ +package com.dcsoft.file.controller; + +import io.minio.BucketExistsArgs; +import io.minio.MinioClient; +import io.minio.PutObjectArgs; +import io.minio.RemoveObjectArgs; +import lombok.Data; +import org.springframework.web.multipart.MultipartFile; + +import java.text.SimpleDateFormat; +import java.util.Date; + +@Data +public class MinIO { + + private String address; //IP地址 + private String userName; //用户名 + private String password; //密码 + private MinioClient minioClient; //操作对象 + MinIO(String address, String userName, String password) { + this.address = address; + this.userName = userName; + this.password = password; + } + //获取操作对象: + public MinioClient getMinioClient() { + if (this.minioClient == null) { + this.minioClient = MinioClient.builder() + .endpoint(this.getAddress()) + .credentials(this.getUserName(), this.getPassword()) + .build(); + } + return this.minioClient; + } + //上传文件: + public String upload(MultipartFile multipartFile, String bucketName) throws Exception { + //一、设置文件存放的路径信息 + String fileName = multipartFile.getName(); //获取文件名称: + String timeRandom = String.valueOf(System.currentTimeMillis()); //获取当前时间戳: + fileName = timeRandom + "_" + fileName; //拼接文件名: + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); //格式化当前日期: + String objectName = sdf.format(new Date()) + "/" + fileName; //最后存储的路径: 格式为:时间/文件 + //二、上传文件 + this.getMinioClient().putObject(PutObjectArgs.builder(). + bucket(bucketName) //桶名称 + .object(objectName) //路径 + //以下为默认配置: + .stream(multipartFile.getInputStream(), multipartFile.getSize(), -1) + .contentType(multipartFile.getContentType()) + .build()); + //三、访问路径: + return this.address + "/" + bucketName + "/" + objectName; + } + //删除文件: + public void delete(String bucketName,String fileName) { + /** + * String bucketName = "test2"; + * String fileName = "/2023-04-07/16808560218465670_img.png"; + * address+bucketName+fileName 就是访问路径,删除需要后两个参数。 + */ + try { + this.getMinioClient().removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(fileName).build()); + } catch (Exception e) { + System.out.println("删除失败"); + } + System.out.println("删除成功"); + } + //查询某个桶是否存在: + public Boolean isExit(String bucketName) throws Exception { + boolean found = + this.getMinioClient().bucketExists(BucketExistsArgs.builder().bucket(bucketName).build()); + if (found) { + System.out.println("存储桶存在!"); + return true; + } else { + System.out.println("存储桶不存在!"); + return false; + } + } + +} diff --git a/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/controller/SysFileController.java b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/controller/SysFileController.java new file mode 100644 index 0000000..7ee03d6 --- /dev/null +++ b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/controller/SysFileController.java @@ -0,0 +1,436 @@ +package com.dcsoft.file.controller; + +import com.alibaba.csp.sentinel.slots.block.BlockException; +import com.alibaba.csp.sentinel.slots.block.RuleConstant; +import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; +import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.dcsoft.common.core.exception.ServiceException; +import com.dcsoft.file.service.IAlgoService; +import com.dcsoft.file.service.IFaceService; +import com.dcsoft.file.utils.*; +import com.dcsoft.system.api.RemoteStudentService; +import io.minio.MinioClient; +import io.minio.RemoveObjectArgs; +import net.coobird.thumbnailator.Thumbnails; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.aspectj.lang.reflect.MethodSignature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.MediaType; +import org.springframework.util.ClassUtils; +import org.springframework.util.MultiValueMap; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import com.dcsoft.common.core.domain.R; +import com.dcsoft.common.core.utils.file.FileUtils; +import com.dcsoft.file.service.ISysFileService; +import com.dcsoft.system.api.domain.SysFile; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static com.dcsoft.file.utils.MinioUtil.getBase64String; + +/** + * 文件请求处理 + * + * @author dcsoft + */ +@RestController +public class SysFileController +{ + private static final Logger log = LoggerFactory.getLogger(SysFileController.class); + + /** 获取yml配置类里的桶名称*/ + @Value("${minio.bucket-name}") + private String bucketName; + + @Autowired + private ISysFileService sysFileService; + + @Value("${minio.bucket-name1}") + private String bucketName1; + + @Autowired + private IAlgoService algoService; + + @Autowired + private IFaceService faceService; + + @Value("${minio.accessKey}") + private String accessKey; + + @Value("${minio.secretKey}") + private String secretKey; + + @Value("${minio.url}") + private String miniourl; + + @Value("${sdk.upload}") + public String upload; + + @Value("${minio.gwurl}") + private String miniogwurl; + + @Value("${minio.bucket-name2}") + private String bucketName2; + + @Value("${file.domain}") + private String fileurl; + + @Value("${file.gwurl}") + private String filegwurl; + + /** + * 文件上传请求 + */ + @PostMapping("upload") + public R upload(MultipartFile file) + { + try + { + // 上传并返回访问地址 + String url = sysFileService.uploadFile(file); + SysFile sysFile = new SysFile(); + sysFile.setName(FileUtils.getName(url)); + url=url.replace(fileurl,filegwurl); + sysFile.setUrl(url); + return R.ok(sysFile); + } + catch (Exception e) + { + log.error("上传文件失败", e); + return R.fail(e.getMessage()); + } + } + + /** + * 文件上传请求 + */ + @PostMapping("avatar") + public R avatar(@RequestParam("avatarfile") MultipartFile file) + { + try + { + // 上传并返回访问地址 + String url = sysFileService.uploadFile(file); + SysFile sysFile = new SysFile(); + sysFile.setName(FileUtils.getName(url)); + sysFile.setUrl(url); + return R.ok(sysFile); + } + catch (Exception e) + { + log.error("上传文件失败", e); + return R.fail(e.getMessage()); + } + } + + @PostMapping("uploadMinioCar") + public R uploadMinioCar(@RequestParam("file") MultipartFile file) + { + try + { + String fileNames = FileUploadUtils.uploadMinio(file,this.bucketName2,file.getName()); + SysFile sysFile = new SysFile(); + sysFile.setName(FileUtils.getName(fileNames)); + fileNames=fileNames.replace(miniourl,miniogwurl); + sysFile.setUrl(fileNames); + return R.ok(sysFile); + }catch (Exception e){ + log.error("上传文件失败", e); + return R.fail(e.getMessage()); + } + } + + + + /** + * 文件上传请求 + */ + @PostMapping("uploadMinio") + public R uploadMinio(MultipartFile file, String fileName) + { + /* //判断压缩图片 + if((1024 * 1024 * 0.1) <= file.getSize()){ + // 小于 1M 的 + try { + String fileNames1 = file.getOriginalFilename(); + File newFile = new File(fileNames1); + if ((1024 * 1024 * 0.1) <= file.getSize() && file.getSize() <= (1024 * 1024)) { + Thumbnails.of(file.getInputStream()).scale(1f).outputQuality(0.4f).toFile(newFile); + } + // 1 - 2M 的 + else if ((1024 * 1024) < file.getSize() && file.getSize() <= (1024 * 1024 * 2)) { + Thumbnails.of(file.getInputStream()).scale(1f).outputQuality(0.2f).toFile(newFile); + } + // 2M 以上的 + else if ((1024 * 1024 * 2) < file.getSize()) { + Thumbnails.of(file.getInputStream()).scale(1f).outputQuality(0.1f).toFile(newFile); + } + // 转为 MultipartFile + file = PictureUtils.getMultipartFile(newFile); + newFile.delete(); + } catch (IOException e) { + throw new RuntimeException(e); + } + }*/ + try + { + /*initFlowRules();// + // 上传并返回访问地址 + //上传前进行人脸检测 + String base64String=MinioUtil.getBase64String(file); + int data=faceService.judgeImageBase64(base64String); + log.info("人脸检测返回值==========="+data); + if(data!=0){ + log.error("人脸检测不符合要求"); + return R.fail("人脸检测不符合要求"); + } + //提取特征值 + String feature=faceService.getFeature(base64String);*/ + String fileNames = FileUploadUtils.uploadMinio(file,this.bucketName,fileName); + SysFile sysFile = new SysFile(); + sysFile.setName(FileUtils.getName(fileNames)); + fileNames=fileNames.replace(miniourl,miniogwurl); + + sysFile.setUrl(fileNames); + //sysFile.setFeature(feature); + return R.ok(sysFile); + }catch (Exception e){ + log.error("上传文件失败", e); + return R.fail(e.getMessage()); + } + } + + /** + * 文件上传请求 + */ + @PostMapping("uploadMinios") + public R uploadMinios(MultipartFile file,String fileName) + { + + //判断压缩图片 + if((1024 * 1024 * 0.1) <= file.getSize()){ + // 小于 1M 的 + try { + String fileNames1 = file.getOriginalFilename(); + File newFile = new File(fileNames1); + if ((1024 * 1024 * 0.1) <= file.getSize() && file.getSize() <= (1024 * 1024)) { + Thumbnails.of(file.getInputStream()).scale(1f).outputQuality(0.4f).toFile(newFile); + } + // 1 - 2M 的 + else if ((1024 * 1024) < file.getSize() && file.getSize() <= (1024 * 1024 * 2)) { + Thumbnails.of(file.getInputStream()).scale(1f).outputQuality(0.2f).toFile(newFile); + } + // 2M 以上的 + else if ((1024 * 1024 * 2) < file.getSize()) { + Thumbnails.of(file.getInputStream()).scale(1f).outputQuality(0.1f).toFile(newFile); + } + // 获取输入流 + FileInputStream input = new FileInputStream(newFile); + // 转为 MultipartFile + file = PictureUtils.getMultipartFile(newFile); + newFile.delete(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + try + { + // 上传并返回访问地址 + String fileNames = FileUploadUtils.uploadMinio(file,this.bucketName,fileName); + SysFile sysFile = new SysFile(); + sysFile.setName(FileUtils.getName(fileNames)); + sysFile.setUrl(fileNames); + return R.ok(sysFile); + }catch (Exception e){ + log.error("上传文件失败", e); + return R.fail(e.getMessage()); + } + } + + /** + * 文件非证件照上传请求 + */ + @PostMapping("uploadMinio1") + public R uploadMinio1(MultipartFile file, String fileName) { + try { + //判断压缩图片 + if ((1024 * 1024 * 0.1) <= file.getSize()) { + // 小于 1M 的 + try { + String fileNames1 = file.getOriginalFilename(); + File newFile = new File(fileNames1); + if ((1024 * 1024 * 0.1) <= file.getSize() && file.getSize() <= (1024 * 1024)) { + Thumbnails.of(file.getInputStream()).scale(1f).outputQuality(0.4f).toFile(newFile); + } + // 1 - 2M 的 + else if ((1024 * 1024) < file.getSize() && file.getSize() <= (1024 * 1024 * 2)) { + Thumbnails.of(file.getInputStream()).scale(1f).outputQuality(0.2f).toFile(newFile); + } + // 2M 以上的 + else if ((1024 * 1024 * 2) < file.getSize()) { + Thumbnails.of(file.getInputStream()).scale(1f).outputQuality(0.1f).toFile(newFile); + } + // 转为 MultipartFile + file = PictureUtils.getMultipartFile(newFile); + newFile.delete(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + initFlowRules(); + //上传前进行人脸检测 + String imgBase64 = MinioUtil.getBase64String(file); + checkPhoto(imgBase64); + + // 上传并返回访问地址 + String fileNames = FileUploadUtils.uploadMinio(file, this.bucketName1, fileName); + SysFile sysFile = new SysFile(); + sysFile.setName(FileUtils.getName(fileNames)); + fileNames = fileNames.replace(miniourl, miniogwurl); + sysFile.setUrl(fileNames); + return R.ok(sysFile); + } catch (Exception e) { + log.error("上传文件失败", e); + return R.fail(e.getMessage()); + } + } + + /** + * 校验人脸质量是否合格 + * + * @param imgBase64 + */ + private void checkPhoto(String imgBase64) { + if (StringUtils.isNotEmpty(imgBase64)) { + Map map = new HashMap<>(); + map.put("imgBase64", imgBase64); + String body = HttpUtil.postData(upload, map); + log.info("checkPhoto_body:{}", body); + JSONObject object = JSONObject.parseObject(body); + log.info("返回校验结果:{}", JSON.toJSONString(object)); + if (501 == object.getInteger("code")) { + throw new ServiceException("系统繁忙,请稍后再试!"); + } else if (200 != object.getInteger("code")) { + throw new ServiceException("未检测到人脸信息,请重新上传!"); + } else if (null != object.getInteger("data") && 90 > object.getInteger("data")) { + throw new ServiceException("人脸照片校验不合格,请重新上传!"); + } + } + } + + + + @PostMapping("uploadMinio2") + public R uploadMinio2(MultipartFile file,String fileName, String name) + { + try + { + // 上传并返回访问地址 + String fileNames = FileUploadUtils.uploadMinio(file,this.bucketName1,fileName); + SysFile sysFile = new SysFile(); + sysFile.setName(URLEncoder.encode(name, "UTF-8")); + fileNames=fileNames.replace(miniourl,miniogwurl); + sysFile.setUrl(fileNames); + return R.ok(sysFile); + } + catch (Exception e) + { + log.error("上传文件失败", e); + return R.fail(e.getMessage()); + } + } + + + /** + * 文件上传请求 + */ + @GetMapping("compareTwoPic") + public R compareTwoPic(@RequestParam("url1") String url1,@RequestParam("url2") String url2){ + try + { + //进行人脸1v1 + byte[] image1= Base64.decodeBase64(ImageToBase64Utils.getImgUrlToBase64(url1)); + byte[] image2=Base64.decodeBase64(ImageToBase64Utils.getImgUrlToBase64(url2)); + float data=faceService.compareTwoPic(image1,image2); + return R.ok(data); + } + catch (Exception e) + { + log.error("上传文件失败", e); + return R.fail(e.getMessage()); + } + } + + /** + * 文件上传请求 + */ + @GetMapping("comparePic") + public R comparePic(@RequestParam("feature1") String feature1,@RequestParam("feature2") String feature2){ + try + { + //进行人脸1v1 + float data=faceService.compareTwoPic(feature1,feature2); + return R.ok(data); + } + catch (Exception e) + { + log.error("上传文件失败", e); + return R.fail(e.getMessage()); + } + } + + private static void initFlowRules(){ + List rules = new ArrayList<>(); + FlowRule rule = new FlowRule(); + rule.setResource("HelloWorld"); + //通过QPS来限流 + rule.setGrade(RuleConstant.FLOW_GRADE_QPS); + //设置QPS为20. + rule.setCount(10); + rule.setLimitApp("default"); + rule.setStrategy(RuleConstant.STRATEGY_DIRECT); + rules.add(rule); + FlowRuleManager.loadRules(rules); + } + + + @PostMapping("/deleteFile") + public R deleteFile(String fileName) { + try { + // 创建MinIO客户端 + MinioClient minioClient = MinioClient.builder() + .endpoint(miniourl) + .credentials(accessKey, secretKey) + .build(); + + // 删除文件 + minioClient.removeObject(RemoveObjectArgs.builder() + .bucket(bucketName1) // 替换为你实际的存储桶名称 + .object(fileName) + .build()); + + return R.ok("文件删除成功"); + } catch (Exception e) { + e.printStackTrace(); + return R.fail("文件删除失败:" + e.getMessage()); + } + } + +} diff --git a/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/controller/test.java b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/controller/test.java new file mode 100644 index 0000000..a2aa71e --- /dev/null +++ b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/controller/test.java @@ -0,0 +1,28 @@ +package com.dcsoft.file.controller; + +import org.springframework.http.MediaType; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.FileInputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; + +public class test { + public static void main(String[] args) throws Exception { + MinIO minIO = new MinIO("http://192.168.124.185:9000","minioadmin","minioadmin"); + String bucket = "visitor"; + //一、上传文件: + //将file转化为MultipartFile (图片在项目的resources目录下,必须将文件转化为为MultipartFile类型) +// File file = new File("src/main/resources/img.png"); +// FileInputStream fileInputStream = new FileInputStream(file); +// MultipartFile multipartFile = new MockMultipartFile(file.getName(), file.getName(), +// MediaType.IMAGE_PNG_VALUE //PNG类型的图片,所以用这个枚举。点击MediaType有对应类型 +// , fileInputStream); +// String url = minIO.upload(multipartFile, bucket);//上传 +// System.out.println("上传之后的URL为:"+url); + //二、删除刚刚上传的图片: + String fileName = "/insurancePolicy1/1FUe3OV4yKlD41feaef8ea19ed5e94c0749d84dc749320240529153149A026.pdf"; + minIO.delete(bucket,fileName); + } +} diff --git a/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/controller/zctest.java b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/controller/zctest.java new file mode 100644 index 0000000..59b7f91 --- /dev/null +++ b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/controller/zctest.java @@ -0,0 +1,55 @@ +package com.dcsoft.file.controller; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.dcsoft.common.core.exception.ServiceException; +import com.dcsoft.file.utils.HttpUtil; +import com.dcsoft.file.utils.MinioUtil; +import com.dcsoft.file.utils.PictureUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class zctest { + + private static final ExecutorService executorService = Executors.newFixedThreadPool(2); + + + public static void main(String[] args) { +// for (int i = 0; i < 6; i++) { +// executorService.execute(connectTcpTask); +// } + } + + + static Runnable connectTcpTask = new Runnable() { + @Override + public void run() { + String filePath = "C:\\Users\\jingy\\Pictures\\test4.jpg"; + File file = new File(filePath); + MultipartFile multipartFile = PictureUtils.getMultipartFile(file); + String imgBase64 = null; + try { + imgBase64 = MinioUtil.getBase64String(multipartFile); + } catch (IOException e) { + throw new RuntimeException(e); + } + checkPhoto(imgBase64); + }}; + + private static void checkPhoto(String imgBase64) { + if (StringUtils.isNotEmpty(imgBase64)) { + Map map = new HashMap<>(); + map.put("imgBase64", imgBase64); + String body = HttpUtil.postData("http://81.68.71.142:7701/check/judgeImage", map); + JSONObject object = JSONObject.parseObject(body); + System.out.println("结果:" + object.toJSONString()); + } + } +} diff --git a/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/AlgoServiceImpl.java b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/AlgoServiceImpl.java new file mode 100644 index 0000000..32a2a68 --- /dev/null +++ b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/AlgoServiceImpl.java @@ -0,0 +1,59 @@ +package com.dcsoft.file.service; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.dcsoft.common.core.constant.CacheConstants; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.file.utils.HttpUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.math.BigInteger; +import java.security.MessageDigest; +import java.util.*; + +/** + * 用户管理 服务层处理 + * + * @author xueyi + */ +@Service +public class AlgoServiceImpl implements IAlgoService { + + + @Value("${uni.faceUrl}") + public String uniUrl; + + + //检测图片 + public String judgeImage(String admitGuids){ + String url=uniUrl+"/algo/wrapper/judgeImage"; + Map paramMap=new HashMap(); + paramMap.put("imageDataBase64",admitGuids); + String response= HttpUtil.postData(url,null,paramMap); + return response; + } + + /* //提取特征值 + public String getFeature(String admitGuids){ + String url=uniUrl+"/algo/wrapper/getFeature"; + Map headMap=new HashMap(); + Map paramMap=new HashMap(); + paramMap.put("admitGuids",admitGuids); + String response= HttpUtil.postData(url,headMap,paramMap); + return response; + } + + //图片压缩 + public String getSimpleImage(String admitGuids){ + String url=uniUrl+"/algo/wrapper/getSimpleImage"; + Map headMap=new HashMap(); + Map paramMap=new HashMap(); + paramMap.put("admitGuids",admitGuids); + String response= HttpUtil.postData(url,headMap,paramMap); + return response; + } +*/ +} diff --git a/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/FaceServiceImpl.java b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/FaceServiceImpl.java new file mode 100644 index 0000000..17e11e3 --- /dev/null +++ b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/FaceServiceImpl.java @@ -0,0 +1,123 @@ +package com.dcsoft.file.service; + +import com.dcsoft.file.utils.HttpUtil; +import com.dcsoft.file.utils.ImageToBase64Utils; +import com.uniubi.Register.FaceBox; +import com.uniubi.Register.UfaceRegister; +import com.uniubi.Register.UfaceRegisterJNI; +import org.apache.commons.codec.binary.Base64; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.HashMap; +import java.util.Map; + +/** + * 用户管理 服务层处理 + * + * @author xueyi + */ +@Service +public class FaceServiceImpl implements IFaceService { + + //@Value("${uni.modelPath}") + public String modelPath; + + //@Value("${uni.userName}") + public String userName; + + //@Value("${uni.passWord}") + public String passWord; + + //@Value("${uni.license}") + public String license; + + /** + * 项目启动时,初始化参数到缓存 + */ + @PostConstruct + public void init() + { + /*System.out.println("SDK version : " + UfaceRegisterJNI.GetSDKVersion()); + UfaceRegister.SetLogMode(2); + UfaceRegister.SetModelPath(modelPath); + UfaceRegister.Auth(userName,passWord, license);*/ + } + + //检测图片 + public int judgeImageUrl(String url){ + UfaceRegister u = new UfaceRegister(); + System.out.println("UfaceRegister : " + u ); + byte[] image1 = Base64.decodeBase64(ImageToBase64Utils.getImgUrlToBase64(url)); + FaceBox box1 = new FaceBox(); + return u.JudgeImage(image1, box1); + } + + //检测图片 + public int judgeImageBase64(String base64){ + UfaceRegister u = new UfaceRegister(); + byte[] image1 = Base64.decodeBase64(base64); + FaceBox box1 = new FaceBox(); + return u.JudgeImage(image1, box1); + } + + //提取特征值 + public String getFeature(String base64){ + UfaceRegister u = new UfaceRegister(); + byte[] image1 = Base64.decodeBase64(base64); + FaceBox box1 = new FaceBox(); + return u.GetFeature(image1, 110,box1); + } + + //图片比对 + public float compareTwoPic(byte[] image1,byte[] image2){ + float score=0; + UfaceRegister u = new UfaceRegister(); + FaceBox box1 = new FaceBox(); + int res1 = u.JudgeImage(image1, box1); + String feature1 = ""; + if (res1 == 0) { + feature1 = u.GetFeature(image1, 110, box1); + } else { + System.out.println("res1 == " + res1); + } + + FaceBox box2 = new FaceBox(); + int res2 = u.JudgeImage(image2, box2); + String feature2 = ""; + if (res2 == 0) { + feature2 = u.GetFeature(image2, 110, box2); + } else { + System.out.println("res2 == " + res2); + } + score = u.CompareFeat(feature1, feature2); + System.out.println("score : " + score); + return score; + } + + + //特征值与图片比对 + public float compareTwoPic(String feature1,String feature2){ + float score=0; + UfaceRegister u = new UfaceRegister(); + score = u.CompareFeat(feature1, feature2); + System.out.println("score : " + score); + return score; + } + +/* + //图片压缩 + public String getSimpleImage(String admitGuids){ + String url=uniUrl+"/algo/wrapper/getSimpleImage"; + Map headMap=new HashMap(); + Map paramMap=new HashMap(); + paramMap.put("admitGuids",admitGuids); + String response= HttpUtil.postData(url,headMap,paramMap); + return response; + } +*/ +} diff --git a/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/FastDfsSysFileServiceImpl.java b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/FastDfsSysFileServiceImpl.java new file mode 100644 index 0000000..8dc2c72 --- /dev/null +++ b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/FastDfsSysFileServiceImpl.java @@ -0,0 +1,42 @@ +package com.dcsoft.file.service; + +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 com.github.tobato.fastdfs.domain.fdfs.StorePath; +import com.github.tobato.fastdfs.service.FastFileStorageClient; +import com.dcsoft.common.core.utils.file.FileTypeUtils; + +/** + * FastDFS 文件存储 + * + * @author dcsoft + */ +@Service +public class FastDfsSysFileServiceImpl implements ISysFileService +{ + /** + * 域名或本机访问地址 + */ + @Value("${fdfs.domain}") + public String domain; + + @Autowired + private FastFileStorageClient storageClient; + + /** + * FastDfs文件上传接口 + * + * @param file 上传的文件 + * @return 访问地址 + * @throws Exception + */ + @Override + public String uploadFile(MultipartFile file) throws Exception + { + StorePath storePath = storageClient.uploadFile(file.getInputStream(), file.getSize(), + FileTypeUtils.getExtension(file), null); + return domain + "/" + storePath.getFullPath(); + } +} diff --git a/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/IAlgoService.java b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/IAlgoService.java new file mode 100644 index 0000000..7245776 --- /dev/null +++ b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/IAlgoService.java @@ -0,0 +1,14 @@ +package com.dcsoft.file.service; +import java.util.List; + +/** + * Uface 服务层 + * + * @author nichun + */ +public interface IAlgoService { + + //检测图片 + String judgeImage(String url); + +} diff --git a/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/IFaceService.java b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/IFaceService.java new file mode 100644 index 0000000..a688799 --- /dev/null +++ b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/IFaceService.java @@ -0,0 +1,23 @@ +package com.dcsoft.file.service; + +/** + * Uface 服务层 + * + * @author nichun + */ +public interface IFaceService { + + //检测图片 + int judgeImageUrl(String url); + + //检测图片 + int judgeImageBase64(String base64); + + //提取特征值 + String getFeature(String base64); + + float compareTwoPic(byte[] image1,byte[] image2); + + float compareTwoPic(String feature1,String feature2); + +} diff --git a/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/ISysFileService.java b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/ISysFileService.java new file mode 100644 index 0000000..b19b25c --- /dev/null +++ b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/ISysFileService.java @@ -0,0 +1,22 @@ +package com.dcsoft.file.service; + +import org.springframework.web.multipart.MultipartFile; + +/** + * 文件上传接口 + * + * @author dcsoft + */ +public interface ISysFileService +{ + /** + * 文件上传接口 + * + * @param file 上传的文件 + * @return 访问地址 + * @throws Exception + */ + public String uploadFile(MultipartFile file) throws Exception; + + +} diff --git a/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/LocalSysFileServiceImpl.java b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/LocalSysFileServiceImpl.java new file mode 100644 index 0000000..32f8a96 --- /dev/null +++ b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/LocalSysFileServiceImpl.java @@ -0,0 +1,56 @@ +package com.dcsoft.file.service; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; +import com.dcsoft.file.utils.FileUploadUtils; + +import java.net.InetAddress; + +/** + * 本地文件存储 + * + * @author dcsoft + */ +@Primary +@Service +public class LocalSysFileServiceImpl implements ISysFileService +{ + /** + * 资源映射路径 前缀 + */ + @Value("${file.prefix}") + public String localFilePrefix; + + /** + * 域名或本机访问地址 + */ + @Value("${file.domain}") + public String domain; + + /** + * 上传文件存储在本地的根路径 + */ + @Value("${file.path}") + private String localFilePath; + + /** + * 本地文件上传接口 + * + * @param file 上传的文件 + * @return 访问地址 + * @throws Exception + */ + @Override + public String uploadFile(MultipartFile file) throws Exception + { +// InetAddress localHost = InetAddress.getLocalHost(); +// String ip = localHost.getHostAddress(); +// String name = FileUploadUtils.upload(localFilePath, file); +// String url = "http://127.0.0.1:9300" + localFilePrefix + name; + String name = FileUploadUtils.upload(localFilePath, file); + String url = domain + localFilePrefix + name; + return url; + } +} diff --git a/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/MinioSysFileServiceImpl.java b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/MinioSysFileServiceImpl.java new file mode 100644 index 0000000..26aeb01 --- /dev/null +++ b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/service/MinioSysFileServiceImpl.java @@ -0,0 +1,45 @@ +package com.dcsoft.file.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; +import com.dcsoft.file.config.MinioConfig; +import com.dcsoft.file.utils.FileUploadUtils; +import io.minio.MinioClient; +import io.minio.PutObjectArgs; + +/** + * Minio 文件存储 + * + * @author dcsoft + */ +@Service +public class MinioSysFileServiceImpl implements ISysFileService +{ + @Autowired + private MinioConfig minioConfig; + + @Autowired + private MinioClient client; + + /** + * 本地文件上传接口 + * + * @param file 上传的文件 + * @return 访问地址 + * @throws Exception + */ + @Override + public String uploadFile(MultipartFile file) throws Exception + { + String fileName = FileUploadUtils.extractFilename(file); + PutObjectArgs args = PutObjectArgs.builder() + .bucket(minioConfig.getBucketName()) + .object(fileName) + .stream(file.getInputStream(), file.getSize(), -1) + .contentType(file.getContentType()) + .build(); + client.putObject(args); + return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + fileName; + } +} diff --git a/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/utils/BASE64DecodedMultipartFile.java b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/utils/BASE64DecodedMultipartFile.java new file mode 100644 index 0000000..7a60346 --- /dev/null +++ b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/utils/BASE64DecodedMultipartFile.java @@ -0,0 +1,57 @@ +package com.dcsoft.file.utils; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; + +public class BASE64DecodedMultipartFile implements MultipartFile { + + private final byte[] imgContent; + private final String header; + + public BASE64DecodedMultipartFile(byte[] imgContent, String header) { + this.imgContent = imgContent; + this.header = header.split(";")[0]; + } + + @Override + public String getName() { + return System.currentTimeMillis() + Math.random() + "." + header.split("/")[1]; + } + + @Override + public String getOriginalFilename() { + return System.currentTimeMillis() + (int) Math.random() * 10000 + "." + header.split("/")[1]; + } + + @Override + public String getContentType() { + return header.split(":")[1]; + } + + @Override + public boolean isEmpty() { + return imgContent == null || imgContent.length == 0; + } + + @Override + public long getSize() { + return imgContent.length; + } + + @Override + public byte[] getBytes() throws IOException { + return imgContent; + } + + @Override + public InputStream getInputStream() throws IOException { + return new ByteArrayInputStream(imgContent); + } + + @Override + public void transferTo(File dest) throws IOException, IllegalStateException { + new FileOutputStream(dest).write(imgContent); + } + +} diff --git a/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/utils/FileUploadUtils.java b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/utils/FileUploadUtils.java new file mode 100644 index 0000000..d38ed9a --- /dev/null +++ b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/utils/FileUploadUtils.java @@ -0,0 +1,236 @@ +package com.dcsoft.file.utils; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.Objects; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FilenameUtils; +import org.springframework.web.multipart.MultipartFile; +import com.dcsoft.common.core.exception.file.FileNameLengthLimitExceededException; +import com.dcsoft.common.core.exception.file.FileSizeLimitExceededException; +import com.dcsoft.common.core.exception.file.InvalidExtensionException; +import com.dcsoft.common.core.utils.DateUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.utils.file.FileTypeUtils; +import com.dcsoft.common.core.utils.file.MimeTypeUtils; +import com.dcsoft.common.core.utils.uuid.Seq; + +/** + * 文件上传工具类 + * + * @author dcsoft + */ +@Slf4j +public class FileUploadUtils +{ + /** + * 默认大小 50M + */ + public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024; + + /** + * 默认的文件名最大长度 100 + */ + public static final int DEFAULT_FILE_NAME_LENGTH = 100; + + /** + * 根据文件路径上传 + * + * @param baseDir 相对应用的基目录 + * @param file 上传的文件 + * @return 文件名称 + * @throws IOException + */ + public static final String upload(String baseDir, MultipartFile file) throws IOException + { + try + { + return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); + } + catch (Exception e) + { + throw new IOException(e.getMessage(), e); + } + } + + /** + * 文件上传 + * + * @param baseDir 相对应用的基目录 + * @param file 上传的文件 + * @param allowedExtension 上传文件类型 + * @return 返回上传成功的文件名 + * @throws FileSizeLimitExceededException 如果超出最大大小 + * @throws FileNameLengthLimitExceededException 文件名太长 + * @throws IOException 比如读写文件出错时 + * @throws InvalidExtensionException 文件校验异常 + */ + public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension) + throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException, + InvalidExtensionException + { + int fileNamelength = Objects.requireNonNull(file.getOriginalFilename()).length(); + if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) + { + throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH); + } + + assertAllowed(file, allowedExtension); + + String fileName = extractFilename(file); + + String absPath = getAbsoluteFile(baseDir, fileName).getAbsolutePath(); + file.transferTo(Paths.get(absPath)); + return getPathFileName(fileName); + } + + /** + * 编码文件名 + */ + public static final String extractFilename(MultipartFile file) + { + return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(), + FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType), FileTypeUtils.getExtension(file)); + } + + private static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException + { + File desc = new File(uploadDir + File.separator + fileName); + + if (!desc.exists()) + { + if (!desc.getParentFile().exists()) + { + desc.getParentFile().mkdirs(); + } + } + return desc.isAbsolute() ? desc : desc.getAbsoluteFile(); + } + + private static final String getPathFileName(String fileName) throws IOException + { + String pathFileName = "/" + fileName; + return pathFileName; + } + + /** + * 文件大小校验 + * + * @param file 上传的文件 + * @throws FileSizeLimitExceededException 如果超出最大大小 + * @throws InvalidExtensionException 文件校验异常 + */ + public static final void assertAllowed(MultipartFile file, String[] allowedExtension) + throws FileSizeLimitExceededException, InvalidExtensionException + { + long size = file.getSize(); + if (size > DEFAULT_MAX_SIZE) + { + throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024); + } + + String fileName = file.getOriginalFilename(); + String extension = FileTypeUtils.getExtension(file); + if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension)) + { + if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION) + { + throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension, + fileName); + } + else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION) + { + throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension, + fileName); + } + else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION) + { + throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension, + fileName); + } + else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION) + { + throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension, + fileName); + } + else + { + throw new InvalidExtensionException(allowedExtension, extension, fileName); + } + } + } + + /** + * 判断MIME类型是否是允许的MIME类型 + * + * @param extension 上传文件类型 + * @param allowedExtension 允许上传文件类型 + * @return true/false + */ + public static final boolean isAllowedExtension(String extension, String[] allowedExtension) + { + for (String str : allowedExtension) + { + if (str.equalsIgnoreCase(extension)) + { + return true; + } + } + return false; + } + + /** 上传到Minio服务器*/ + public static final String uploadMinio(MultipartFile file,String Name,String fileName) throws IOException + { + try + { + String bucketName= Name; + return uploadMinino(bucketName,fileName,file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); + } + catch (Exception e) + { + throw new IOException(e.getMessage(), e); + } + } + + /** 上传前校验方法*/ + private static final String uploadMinino(String bucketName,String fileName, MultipartFile file, String[] allowedExtension) + throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException, + InvalidExtensionException + { + int fileNamelength = file.getOriginalFilename().length(); + if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) + { + throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH); + } + + assertAllowed(file, allowedExtension); + try { + //String fileName = extractFilename(file);//日期格式 + String suffixName = null; + int lastIndex = file.getOriginalFilename().lastIndexOf("."); + if (lastIndex != -1 && lastIndex < file.getOriginalFilename().length() - 1) { + String extension = file.getOriginalFilename().substring(lastIndex + 1); + suffixName = "." + extension; + } else { + suffixName = ".jpg"; + } + log.info("1111" + suffixName); + fileName+="/"+FilenameUtils.getBaseName(file.getOriginalFilename())+ Seq.getId(Seq.uploadSeqType)+suffixName; + //调用自定义MinioUtil类方法 + log.info("bucketName" + bucketName); + log.info("fileName" + fileName); + String pathFileName = MinioUtil.uploadFile(bucketName, fileName, file); + log.info("pathFileName" + pathFileName); + return pathFileName; + } catch (Exception e){ + e.printStackTrace(); + + } + return ""; + + } + +} diff --git a/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/utils/HttpUtil.java b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/utils/HttpUtil.java new file mode 100644 index 0000000..68aba68 --- /dev/null +++ b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/utils/HttpUtil.java @@ -0,0 +1,264 @@ +package com.dcsoft.file.utils; + +import com.alibaba.fastjson.JSONObject; +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.util.*; +import java.util.Map.Entry; + +public class HttpUtil { + + public static String getData(String url) { + CloseableHttpClient httpClient = null; + CloseableHttpResponse response = null; + String result = ""; + try { + // 通过址默认配置创建一个httpClient实例 + httpClient = HttpClients.createDefault(); + // 创建httpGet远程连接实例 + HttpGet httpGet = new HttpGet(url); + // 设置请求头信息,鉴权 + httpGet.setHeader("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0"); + // 设置配置请求参数 + RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 连接主机服务超时时间 + .setConnectionRequestTimeout(35000)// 请求超时时间 + .setSocketTimeout(60000)// 数据读取超时时间 + .build(); + // 为httpGet实例设置配置 + httpGet.setConfig(requestConfig); + // 执行get请求得到返回对象 + response = httpClient.execute(httpGet); + // 通过返回对象获取返回数据 + HttpEntity entity = response.getEntity(); + // 通过EntityUtils中的toString方法将结果转换为字符串 + result = EntityUtils.toString(entity); + } catch (ClientProtocolException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + // 关闭资源 + if (null != response) { + try { + response.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (null != httpClient) { + try { + httpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return result; + } + + public static String postData(String url, Map paramMap) { + HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); + HttpPost post = new HttpPost(url); + String result = ""; + try (CloseableHttpClient closeableHttpClient = httpClientBuilder.build()) { + // HttpEntity entity = new StringEntity(jsonStrData); + // 修复 POST json 导致中文乱码 + HttpEntity entity = new StringEntity(JSONObject.toJSONString(paramMap), "UTF-8"); + post.setEntity(entity); + post.setHeader("Content-type", "application/json"); + HttpResponse resp = closeableHttpClient.execute(post); + try { + InputStream respIs = resp.getEntity().getContent(); + byte[] respBytes = IOUtils.toByteArray(respIs); + result = new String(respBytes, Charset.forName("UTF-8")); + } catch (Exception e) { + e.printStackTrace(); + } + return result; + } catch (IOException e) { + e.printStackTrace(); + } + return result; + } + + + /** + * form表单提交 + * + * @param url + * @param paramMap + * @return + */ + public static String sendxwwwform(String url, Map paramMap) { + CloseableHttpClient httpClient = null; + CloseableHttpResponse httpResponse = null; + String result = ""; + // 创建httpClient实例 + httpClient = HttpClients.createDefault(); + // 创建httpPost远程连接实例 + HttpPost httpPost = new HttpPost(url); + // 配置请求参数实例 + RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 设置连接主机服务超时时间 + .setConnectionRequestTimeout(35000)// 设置连接请求超时时间 + .setSocketTimeout(60000)// 设置读取数据连接超时时间 + .build(); + // 为httpPost实例设置配置 + httpPost.setConfig(requestConfig); + // 设置请求头 + httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded"); + // 封装post请求参数 + if (null != paramMap && paramMap.size() > 0) { + List nvps = new ArrayList(); + // 通过map集成entrySet方法获取entity + Set> entrySet = paramMap.entrySet(); + // 循环遍历,获取迭代器 + Iterator> iterator = entrySet.iterator(); + while (iterator.hasNext()) { + Entry mapEntry = iterator.next(); + nvps.add(new BasicNameValuePair(mapEntry.getKey(), mapEntry.getValue().toString())); + } + + // 为httpPost设置封装好的请求参数 + try { + httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8")); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } + try { + // httpClient对象执行post请求,并返回响应参数对象 + httpResponse = httpClient.execute(httpPost); + // 从响应对象中获取响应内容 + HttpEntity entity = httpResponse.getEntity(); + result = EntityUtils.toString(entity); + } catch (ClientProtocolException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + // 关闭资源 + if (null != httpResponse) { + try { + httpResponse.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (null != httpClient) { + try { + httpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return result; + } + + public static String getUrl(String url,Map headMap,String projectGuid ) { + CloseableHttpClient httpClient = null; + CloseableHttpResponse response = null; + String result = ""; + try { + // 通过址默认配置创建一个httpClient实例 + httpClient = HttpClients.createDefault(); + // 创建httpGet远程连接实例 + StringBuffer sb = new StringBuffer(url); + sb.append("projectGuid=" + projectGuid); + HttpGet httpGet = new HttpGet(sb.toString()); + // 设置请求头信息,鉴权 + httpGet.setHeader("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0"); + httpGet.setHeader("appKey",headMap.get("appKey").toString()); + httpGet.setHeader("timestamp",headMap.get("timestamp").toString()); + httpGet.setHeader("sign",headMap.get("sign").toString()); + // 设置配置请求参数 + RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 连接主机服务超时时间 + .setConnectionRequestTimeout(35000)// 请求超时时间 + .setSocketTimeout(60000)// 数据读取超时时间 + .build(); + // 为httpGet实例设置配置 + httpGet.setConfig(requestConfig); + // 执行get请求得到返回对象 + response = httpClient.execute(httpGet); + // 通过返回对象获取返回数据 + HttpEntity entity = response.getEntity(); + // 通过EntityUtils中的toString方法将结果转换为字符串 + result = EntityUtils.toString(entity); + } catch (ClientProtocolException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + // 关闭资源 + if (null != response) { + try { + response.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (null != httpClient) { + try { + httpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return result; + } + + public static String postData(String url,Map headMap, Map paramMap) { + HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); + HttpPost post = new HttpPost(url); + String result = ""; + try (CloseableHttpClient closeableHttpClient = httpClientBuilder.build()) { + // HttpEntity entity = new StringEntity(jsonStrData); + // 修复 POST json 导致中文乱码 + HttpEntity entity = new StringEntity(JSONObject.toJSONString(paramMap), "UTF-8"); + post.setEntity(entity); + post.setHeader("Content-type", "application/json"); + if (null != headMap && headMap.size() > 0) { + // 通过map集成entrySet方法获取entity + Set> entrySet = headMap.entrySet(); + // 循环遍历,获取迭代器 + Iterator> iterator = entrySet.iterator(); + while (iterator.hasNext()) { + Entry mapEntry = iterator.next(); + post.setHeader(mapEntry.getKey(),mapEntry.getValue().toString()); + } + } + HttpResponse resp = closeableHttpClient.execute(post); + try { + InputStream respIs = resp.getEntity().getContent(); + byte[] respBytes = IOUtils.toByteArray(respIs); + result = new String(respBytes, Charset.forName("UTF-8")); + } catch (Exception e) { + e.printStackTrace(); + } + return result; + } catch (IOException e) { + e.printStackTrace(); + } + return result; + } +} diff --git a/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/utils/ImageToBase64Utils.java b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/utils/ImageToBase64Utils.java new file mode 100644 index 0000000..5d353ef --- /dev/null +++ b/dcsoft-modules/dcsoft-file/src/main/java/com/dcsoft/file/utils/ImageToBase64Utils.java @@ -0,0 +1,155 @@ +package com.dcsoft.file.utils; + + +import org.apache.commons.codec.binary.Base64; + +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URL; + + +public class ImageToBase64Utils { + /** + * 本地图片转base64 + */ + public static String getImgFileToBase642(String imgFile) { + //将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] buffer = null; + //读取图片字节数组 + try(InputStream inputStream = new FileInputStream(imgFile);){ + int count = 0; + while (count == 0) { + count = inputStream.available(); + } + buffer = new byte[count]; + inputStream.read(buffer); + } catch (IOException e) { + e.printStackTrace(); + } + // 对字节数组Base64编码 + return new String(Base64.encodeBase64(buffer)); + } + + /** + * 网络图片转base64 + */ + public static String getImgUrlToBase64(String imgUrl) { + byte[] buffer = null; + InputStream inputStream = null; + try ( + ByteArrayOutputStream outputStream = new ByteArrayOutputStream();){ + // 创建URL + URL url = new URL(imgUrl); + // 创建链接 + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("GET"); + conn.setConnectTimeout(5000); + inputStream = conn.getInputStream(); + // 将内容读取内存中 + buffer = new byte[1024]; + int len = -1; + while ((len = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, len); + } + buffer = outputStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (inputStream != null) { + try { + // 关闭inputStream流 + inputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + // 对字节数组Base64编码 + return new String(Base64.encodeBase64(buffer)); + } + + /** + * 本地或网络图片转base64 + */ + public static String getImgStrToBase64(String imgStr) { + InputStream inputStream = null; + byte[] buffer = null; + try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream();){ + //判断网络链接图片文件/本地目录图片文件 + if (imgStr.startsWith("http://") || imgStr.startsWith("https://")) { + // 创建URL + URL url = new URL(imgStr); + // 创建链接 + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("GET"); + conn.setConnectTimeout(5000); + inputStream = conn.getInputStream(); + // 将内容读取内存中 + buffer = new byte[1024]; + int len = -1; + while ((len = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, len); + } + buffer = outputStream.toByteArray(); + } else { + inputStream = new FileInputStream(imgStr); + int count = 0; + while (count == 0) { + count = inputStream.available(); + } + buffer = new byte[count]; + inputStream.read(buffer); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (inputStream != null) { + try { + // 关闭inputStream流 + inputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + // 对字节数组Base64编码 + + return new String(Base64.encodeBase64(buffer)); + } + + /** + * 对字节数组字符串进行Base64解码并生成图片 + * @param imgStr 图片数据 + * @param imgFilePath 保存图片全路径地址 + * @return + */ + public static boolean generateImage(String imgStr,String imgFilePath){ + // + if (imgStr == null) //图像数据为空 + return false; + try + { + //Base64解码 + byte[] b = Base64.decodeBase64(imgStr); + for(int i=0;i + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/info.log + + + + ${log.path}/info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/error.log + + + + ${log.path}/error.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + + + + + + + + + + + + + diff --git a/dcsoft-modules/dcsoft-gen/pom.xml b/dcsoft-modules/dcsoft-gen/pom.xml new file mode 100644 index 0000000..5349663 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/pom.xml @@ -0,0 +1,94 @@ + + + + com.dcsoft + dcsoft-modules + 3.6.2 + + 4.0.0 + + dcsoft-modules-gen + + + dcsoft-modules-gen代码生成 + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + io.springfox + springfox-swagger-ui + ${swagger.fox.version} + + + + + org.apache.velocity + velocity-engine-core + + + + + mysql + mysql-connector-java + + + + + com.dcsoft + dcsoft-common-log + + + + + com.dcsoft + dcsoft-common-swagger + + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + diff --git a/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/DCSGenApplication.java b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/DCSGenApplication.java new file mode 100644 index 0000000..9ed0a69 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/DCSGenApplication.java @@ -0,0 +1,34 @@ +package com.dcsoft.gen; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import com.dcsoft.common.security.annotation.EnableCustomConfig; +import com.dcsoft.common.security.annotation.EnableRyFeignClients; +import com.dcsoft.common.swagger.annotation.EnableCustomSwagger2; + +/** + * 代码生成 + * + * @author dcsoft + */ +@EnableCustomConfig +@EnableCustomSwagger2 +@EnableRyFeignClients +@SpringBootApplication +public class DCSGenApplication +{ + public static void main(String[] args) + { + SpringApplication.run(DCSGenApplication.class, args); + System.out.println("(♥◠‿◠)ノ゙ 代码生成模块启动成功 ლ(´ڡ`ლ)゙ \n" + + " .-------. ____ __ \n" + + " | _ _ \\ \\ \\ / / \n" + + " | ( ' ) | \\ _. / ' \n" + + " |(_ o _) / _( )_ .' \n" + + " | (_,_).' __ ___(_ o _)' \n" + + " | |\\ \\ | || |(_,_)' \n" + + " | | \\ `' /| `-' / \n" + + " | | \\ / \\ / \n" + + " ''-' `'-' `-..-' "); + } +} diff --git a/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/config/GenConfig.java b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/config/GenConfig.java new file mode 100644 index 0000000..a80ca99 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/config/GenConfig.java @@ -0,0 +1,66 @@ +package com.dcsoft.gen.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * 代码生成相关配置 + * + * @author dcsoft + */ +@Component +@ConfigurationProperties(prefix = "gen") +public class GenConfig +{ + /** 作者 */ + public static String author; + + /** 生成包路径 */ + public static String packageName; + + /** 自动去除表前缀,默认是false */ + public static boolean autoRemovePre; + + /** 表前缀(类名不会包含表前缀) */ + public static String tablePrefix; + + public static String getAuthor() + { + return author; + } + + public void setAuthor(String author) + { + GenConfig.author = author; + } + + public static String getPackageName() + { + return packageName; + } + + public void setPackageName(String packageName) + { + GenConfig.packageName = packageName; + } + + public static boolean getAutoRemovePre() + { + return autoRemovePre; + } + + public void setAutoRemovePre(boolean autoRemovePre) + { + GenConfig.autoRemovePre = autoRemovePre; + } + + public static String getTablePrefix() + { + return tablePrefix; + } + + public void setTablePrefix(String tablePrefix) + { + GenConfig.tablePrefix = tablePrefix; + } +} diff --git a/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/controller/GenController.java b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/controller/GenController.java new file mode 100644 index 0000000..2eb4c36 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/controller/GenController.java @@ -0,0 +1,211 @@ +package com.dcsoft.gen.controller; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.io.IOUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.core.text.Convert; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDataInfo; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.gen.domain.GenTable; +import com.dcsoft.gen.domain.GenTableColumn; +import com.dcsoft.gen.service.IGenTableColumnService; +import com.dcsoft.gen.service.IGenTableService; + +/** + * 代码生成 操作处理 + * + * @author dcsoft + */ +@RequestMapping("/gen") +@RestController +public class GenController extends BaseController +{ + @Autowired + private IGenTableService genTableService; + + @Autowired + private IGenTableColumnService genTableColumnService; + + /** + * 查询代码生成列表 + */ + @RequiresPermissions("tool:gen:list") + @GetMapping("/list") + public TableDataInfo genList(GenTable genTable) + { + startPage(); + List list = genTableService.selectGenTableList(genTable); + return getDataTable(list); + } + + /** + * 修改代码生成业务 + */ + @RequiresPermissions("tool:gen:query") + @GetMapping(value = "/{tableId}") + public AjaxResult getInfo(@PathVariable Long tableId) + { + GenTable table = genTableService.selectGenTableById(tableId); + List tables = genTableService.selectGenTableAll(); + List list = genTableColumnService.selectGenTableColumnListByTableId(tableId); + Map map = new HashMap(); + map.put("info", table); + map.put("rows", list); + map.put("tables", tables); + return success(map); + } + + /** + * 查询数据库列表 + */ + @RequiresPermissions("tool:gen:list") + @GetMapping("/db/list") + public TableDataInfo dataList(GenTable genTable) + { + startPage(); + List list = genTableService.selectDbTableList(genTable); + return getDataTable(list); + } + + /** + * 查询数据表字段列表 + */ + @GetMapping(value = "/column/{tableId}") + public TableDataInfo columnList(Long tableId) + { + TableDataInfo dataInfo = new TableDataInfo(); + List list = genTableColumnService.selectGenTableColumnListByTableId(tableId); + dataInfo.setRows(list); + dataInfo.setTotal(list.size()); + return dataInfo; + } + + /** + * 导入表结构(保存) + */ + @RequiresPermissions("tool:gen:import") + @Log(title = "代码生成", businessType = BusinessType.IMPORT) + @PostMapping("/importTable") + public AjaxResult importTableSave(String tables) + { + String[] tableNames = Convert.toStrArray(tables); + // 查询表信息 + List tableList = genTableService.selectDbTableListByNames(tableNames); + genTableService.importGenTable(tableList); + return success(); + } + + /** + * 修改保存代码生成业务 + */ + @RequiresPermissions("tool:gen:edit") + @Log(title = "代码生成", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult editSave(@Validated @RequestBody GenTable genTable) + { + genTableService.validateEdit(genTable); + genTableService.updateGenTable(genTable); + return success(); + } + + /** + * 删除代码生成 + */ + @RequiresPermissions("tool:gen:remove") + @Log(title = "代码生成", businessType = BusinessType.DELETE) + @DeleteMapping("/{tableIds}") + public AjaxResult remove(@PathVariable Long[] tableIds) + { + genTableService.deleteGenTableByIds(tableIds); + return success(); + } + + /** + * 预览代码 + */ + @RequiresPermissions("tool:gen:preview") + @GetMapping("/preview/{tableId}") + public AjaxResult preview(@PathVariable("tableId") Long tableId) throws IOException + { + Map dataMap = genTableService.previewCode(tableId); + return success(dataMap); + } + + /** + * 生成代码(下载方式) + */ + @RequiresPermissions("tool:gen:code") + @Log(title = "代码生成", businessType = BusinessType.GENCODE) + @GetMapping("/download/{tableName}") + public void download(HttpServletResponse response, @PathVariable("tableName") String tableName) throws IOException + { + byte[] data = genTableService.downloadCode(tableName); + genCode(response, data); + } + + /** + * 生成代码(自定义路径) + */ + @RequiresPermissions("tool:gen:code") + @Log(title = "代码生成", businessType = BusinessType.GENCODE) + @GetMapping("/genCode/{tableName}") + public AjaxResult genCode(@PathVariable("tableName") String tableName) + { + genTableService.generatorCode(tableName); + return success(); + } + + /** + * 同步数据库 + */ + @RequiresPermissions("tool:gen:edit") + @Log(title = "代码生成", businessType = BusinessType.UPDATE) + @GetMapping("/synchDb/{tableName}") + public AjaxResult synchDb(@PathVariable("tableName") String tableName) + { + genTableService.synchDb(tableName); + return success(); + } + + /** + * 批量生成代码 + */ + @RequiresPermissions("tool:gen:code") + @Log(title = "代码生成", businessType = BusinessType.GENCODE) + @GetMapping("/batchGenCode") + public void batchGenCode(HttpServletResponse response, String tables) throws IOException + { + String[] tableNames = Convert.toStrArray(tables); + byte[] data = genTableService.downloadCode(tableNames); + genCode(response, data); + } + + /** + * 生成zip文件 + */ + private void genCode(HttpServletResponse response, byte[] data) throws IOException + { + response.reset(); + response.setHeader("Content-Disposition", "attachment; filename=\"dcsoft.zip\""); + response.addHeader("Content-Length", "" + data.length); + response.setContentType("application/octet-stream; charset=UTF-8"); + IOUtils.write(data, response.getOutputStream()); + } +} diff --git a/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/domain/GenTable.java b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/domain/GenTable.java new file mode 100644 index 0000000..c207d62 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/domain/GenTable.java @@ -0,0 +1,370 @@ +package com.dcsoft.gen.domain; + +import java.util.List; +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import org.apache.commons.lang3.ArrayUtils; +import com.dcsoft.common.core.constant.GenConstants; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.web.domain.BaseEntity; + +/** + * 业务表 gen_table + * + * @author dcsoft + */ +public class GenTable extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 编号 */ + private Long tableId; + + /** 表名称 */ + @NotBlank(message = "表名称不能为空") + private String tableName; + + /** 表描述 */ + @NotBlank(message = "表描述不能为空") + private String tableComment; + + /** 关联父表的表名 */ + private String subTableName; + + /** 本表关联父表的外键名 */ + private String subTableFkName; + + /** 实体类名称(首字母大写) */ + @NotBlank(message = "实体类名称不能为空") + private String className; + + /** 使用的模板(crud单表操作 tree树表操作 sub主子表操作) */ + private String tplCategory; + + /** 生成包路径 */ + @NotBlank(message = "生成包路径不能为空") + private String packageName; + + /** 生成模块名 */ + @NotBlank(message = "生成模块名不能为空") + private String moduleName; + + /** 生成业务名 */ + @NotBlank(message = "生成业务名不能为空") + private String businessName; + + /** 生成功能名 */ + @NotBlank(message = "生成功能名不能为空") + private String functionName; + + /** 生成作者 */ + @NotBlank(message = "作者不能为空") + private String functionAuthor; + + /** 生成代码方式(0zip压缩包 1自定义路径) */ + private String genType; + + /** 生成路径(不填默认项目路径) */ + private String genPath; + + /** 主键信息 */ + private GenTableColumn pkColumn; + + /** 子表信息 */ + private GenTable subTable; + + /** 表列信息 */ + @Valid + private List columns; + + /** 其它生成选项 */ + private String options; + + /** 树编码字段 */ + private String treeCode; + + /** 树父编码字段 */ + private String treeParentCode; + + /** 树名称字段 */ + private String treeName; + + /** 上级菜单ID字段 */ + private String parentMenuId; + + /** 上级菜单名称字段 */ + private String parentMenuName; + + public Long getTableId() + { + return tableId; + } + + public void setTableId(Long tableId) + { + this.tableId = tableId; + } + + public String getTableName() + { + return tableName; + } + + public void setTableName(String tableName) + { + this.tableName = tableName; + } + + public String getTableComment() + { + return tableComment; + } + + public void setTableComment(String tableComment) + { + this.tableComment = tableComment; + } + + public String getSubTableName() + { + return subTableName; + } + + public void setSubTableName(String subTableName) + { + this.subTableName = subTableName; + } + + public String getSubTableFkName() + { + return subTableFkName; + } + + public void setSubTableFkName(String subTableFkName) + { + this.subTableFkName = subTableFkName; + } + + public String getClassName() + { + return className; + } + + public void setClassName(String className) + { + this.className = className; + } + + public String getTplCategory() + { + return tplCategory; + } + + public void setTplCategory(String tplCategory) + { + this.tplCategory = tplCategory; + } + + public String getPackageName() + { + return packageName; + } + + public void setPackageName(String packageName) + { + this.packageName = packageName; + } + + public String getModuleName() + { + return moduleName; + } + + public void setModuleName(String moduleName) + { + this.moduleName = moduleName; + } + + public String getBusinessName() + { + return businessName; + } + + public void setBusinessName(String businessName) + { + this.businessName = businessName; + } + + public String getFunctionName() + { + return functionName; + } + + public void setFunctionName(String functionName) + { + this.functionName = functionName; + } + + public String getFunctionAuthor() + { + return functionAuthor; + } + + public void setFunctionAuthor(String functionAuthor) + { + this.functionAuthor = functionAuthor; + } + + public String getGenType() + { + return genType; + } + + public void setGenType(String genType) + { + this.genType = genType; + } + + public String getGenPath() + { + return genPath; + } + + public void setGenPath(String genPath) + { + this.genPath = genPath; + } + + public GenTableColumn getPkColumn() + { + return pkColumn; + } + + public void setPkColumn(GenTableColumn pkColumn) + { + this.pkColumn = pkColumn; + } + + public GenTable getSubTable() + { + return subTable; + } + + public void setSubTable(GenTable subTable) + { + this.subTable = subTable; + } + public List getColumns() + { + return columns; + } + + public void setColumns(List columns) + { + this.columns = columns; + } + + public String getOptions() + { + return options; + } + + public void setOptions(String options) + { + this.options = options; + } + + public String getTreeCode() + { + return treeCode; + } + + public void setTreeCode(String treeCode) + { + this.treeCode = treeCode; + } + + public String getTreeParentCode() + { + return treeParentCode; + } + + public void setTreeParentCode(String treeParentCode) + { + this.treeParentCode = treeParentCode; + } + + public String getTreeName() + { + return treeName; + } + + public void setTreeName(String treeName) + { + this.treeName = treeName; + } + + public String getParentMenuId() + { + return parentMenuId; + } + + public void setParentMenuId(String parentMenuId) + { + this.parentMenuId = parentMenuId; + } + + public String getParentMenuName() + { + return parentMenuName; + } + + public void setParentMenuName(String parentMenuName) + { + this.parentMenuName = parentMenuName; + } + + public boolean isSub() + { + return isSub(this.tplCategory); + } + + public static boolean isSub(String tplCategory) + { + return tplCategory != null && StringUtils.equals(GenConstants.TPL_SUB, tplCategory); + } + public boolean isTree() + { + return isTree(this.tplCategory); + } + + public static boolean isTree(String tplCategory) + { + return tplCategory != null && StringUtils.equals(GenConstants.TPL_TREE, tplCategory); + } + + public boolean isCrud() + { + return isCrud(this.tplCategory); + } + + public static boolean isCrud(String tplCategory) + { + return tplCategory != null && StringUtils.equals(GenConstants.TPL_CRUD, tplCategory); + } + + public boolean isSuperColumn(String javaField) + { + return isSuperColumn(this.tplCategory, javaField); + } + + public static boolean isSuperColumn(String tplCategory, String javaField) + { + if (isTree(tplCategory)) + { + return StringUtils.equalsAnyIgnoreCase(javaField, + ArrayUtils.addAll(GenConstants.TREE_ENTITY, GenConstants.BASE_ENTITY)); + } + return StringUtils.equalsAnyIgnoreCase(javaField, GenConstants.BASE_ENTITY); + } +} diff --git a/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/domain/GenTableColumn.java b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/domain/GenTableColumn.java new file mode 100644 index 0000000..f14ef15 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/domain/GenTableColumn.java @@ -0,0 +1,374 @@ +package com.dcsoft.gen.domain; + +import javax.validation.constraints.NotBlank; + +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.web.domain.BaseEntity; + +/** + * 代码生成业务字段表 gen_table_column + * + * @author dcsoft + */ +public class GenTableColumn extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 编号 */ + private Long columnId; + + /** 归属表编号 */ + private Long tableId; + + /** 列名称 */ + private String columnName; + + /** 列描述 */ + private String columnComment; + + /** 列类型 */ + private String columnType; + + /** JAVA类型 */ + private String javaType; + + /** JAVA字段名 */ + @NotBlank(message = "Java属性不能为空") + private String javaField; + + /** 是否主键(1是) */ + private String isPk; + + /** 是否自增(1是) */ + private String isIncrement; + + /** 是否必填(1是) */ + private String isRequired; + + /** 是否为插入字段(1是) */ + private String isInsert; + + /** 是否编辑字段(1是) */ + private String isEdit; + + /** 是否列表字段(1是) */ + private String isList; + + /** 是否查询字段(1是) */ + private String isQuery; + + /** 查询方式(EQ等于、NE不等于、GT大于、LT小于、LIKE模糊、BETWEEN范围) */ + private String queryType; + + /** 显示类型(input文本框、textarea文本域、select下拉框、checkbox复选框、radio单选框、datetime日期控件、image图片上传控件、upload文件上传控件、editor富文本控件) */ + private String htmlType; + + /** 字典类型 */ + private String dictType; + + /** 排序 */ + private Integer sort; + + public void setColumnId(Long columnId) + { + this.columnId = columnId; + } + + public Long getColumnId() + { + return columnId; + } + + public void setTableId(Long tableId) + { + this.tableId = tableId; + } + + public Long getTableId() + { + return tableId; + } + + public void setColumnName(String columnName) + { + this.columnName = columnName; + } + + public String getColumnName() + { + return columnName; + } + + public void setColumnComment(String columnComment) + { + this.columnComment = columnComment; + } + + public String getColumnComment() + { + return columnComment; + } + + public void setColumnType(String columnType) + { + this.columnType = columnType; + } + + public String getColumnType() + { + return columnType; + } + + public void setJavaType(String javaType) + { + this.javaType = javaType; + } + + public String getJavaType() + { + return javaType; + } + + public void setJavaField(String javaField) + { + this.javaField = javaField; + } + + public String getJavaField() + { + return javaField; + } + + public String getCapJavaField() + { + return StringUtils.capitalize(javaField); + } + + public void setIsPk(String isPk) + { + this.isPk = isPk; + } + + public String getIsPk() + { + return isPk; + } + + public boolean isPk() + { + return isPk(this.isPk); + } + + public boolean isPk(String isPk) + { + return isPk != null && StringUtils.equals("1", isPk); + } + + public String getIsIncrement() + { + return isIncrement; + } + + public void setIsIncrement(String isIncrement) + { + this.isIncrement = isIncrement; + } + + public boolean isIncrement() + { + return isIncrement(this.isIncrement); + } + + public boolean isIncrement(String isIncrement) + { + return isIncrement != null && StringUtils.equals("1", isIncrement); + } + + public void setIsRequired(String isRequired) + { + this.isRequired = isRequired; + } + + public String getIsRequired() + { + return isRequired; + } + + public boolean isRequired() + { + return isRequired(this.isRequired); + } + + public boolean isRequired(String isRequired) + { + return isRequired != null && StringUtils.equals("1", isRequired); + } + + public void setIsInsert(String isInsert) + { + this.isInsert = isInsert; + } + + public String getIsInsert() + { + return isInsert; + } + + public boolean isInsert() + { + return isInsert(this.isInsert); + } + + public boolean isInsert(String isInsert) + { + return isInsert != null && StringUtils.equals("1", isInsert); + } + + public void setIsEdit(String isEdit) + { + this.isEdit = isEdit; + } + + public String getIsEdit() + { + return isEdit; + } + + public boolean isEdit() + { + return isInsert(this.isEdit); + } + + public boolean isEdit(String isEdit) + { + return isEdit != null && StringUtils.equals("1", isEdit); + } + + public void setIsList(String isList) + { + this.isList = isList; + } + + public String getIsList() + { + return isList; + } + + public boolean isList() + { + return isList(this.isList); + } + + public boolean isList(String isList) + { + return isList != null && StringUtils.equals("1", isList); + } + + public void setIsQuery(String isQuery) + { + this.isQuery = isQuery; + } + + public String getIsQuery() + { + return isQuery; + } + + public boolean isQuery() + { + return isQuery(this.isQuery); + } + + public boolean isQuery(String isQuery) + { + return isQuery != null && StringUtils.equals("1", isQuery); + } + + public void setQueryType(String queryType) + { + this.queryType = queryType; + } + + public String getQueryType() + { + return queryType; + } + + public String getHtmlType() + { + return htmlType; + } + + public void setHtmlType(String htmlType) + { + this.htmlType = htmlType; + } + + public void setDictType(String dictType) + { + this.dictType = dictType; + } + + public String getDictType() + { + return dictType; + } + + public void setSort(Integer sort) + { + this.sort = sort; + } + + public Integer getSort() + { + return sort; + } + + public boolean isSuperColumn() + { + return isSuperColumn(this.javaField); + } + + public static boolean isSuperColumn(String javaField) + { + return StringUtils.equalsAnyIgnoreCase(javaField, + // BaseEntity + "createBy", "createTime", "updateBy", "updateTime", "remark", + // TreeEntity + "parentName", "parentId", "orderNum", "ancestors"); + } + + public boolean isUsableColumn() + { + return isUsableColumn(javaField); + } + + public static boolean isUsableColumn(String javaField) + { + // isSuperColumn()中的名单用于避免生成多余Domain属性,若某些属性在生成页面时需要用到不能忽略,则放在此处白名单 + return StringUtils.equalsAnyIgnoreCase(javaField, "parentId", "orderNum", "remark"); + } + + public String readConverterExp() + { + String remarks = StringUtils.substringBetween(this.columnComment, "(", ")"); + StringBuffer sb = new StringBuffer(); + if (StringUtils.isNotEmpty(remarks)) + { + for (String value : remarks.split(" ")) + { + if (StringUtils.isNotEmpty(value)) + { + Object startStr = value.subSequence(0, 1); + String endStr = value.substring(1); + sb.append("").append(startStr).append("=").append(endStr).append(","); + } + } + return sb.deleteCharAt(sb.length() - 1).toString(); + } + else + { + return this.columnComment; + } + } +} diff --git a/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/mapper/GenTableColumnMapper.java b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/mapper/GenTableColumnMapper.java new file mode 100644 index 0000000..0c2f19c --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/mapper/GenTableColumnMapper.java @@ -0,0 +1,60 @@ +package com.dcsoft.gen.mapper; + +import java.util.List; +import com.dcsoft.gen.domain.GenTableColumn; + +/** + * 业务字段 数据层 + * + * @author dcsoft + */ +public interface GenTableColumnMapper +{ + /** + * 根据表名称查询列信息 + * + * @param tableName 表名称 + * @return 列信息 + */ + public List selectDbTableColumnsByName(String tableName); + + /** + * 查询业务字段列表 + * + * @param tableId 业务字段编号 + * @return 业务字段集合 + */ + public List selectGenTableColumnListByTableId(Long tableId); + + /** + * 新增业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + public int insertGenTableColumn(GenTableColumn genTableColumn); + + /** + * 修改业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + public int updateGenTableColumn(GenTableColumn genTableColumn); + + /** + * 删除业务字段 + * + * @param genTableColumns 列数据 + * @return 结果 + */ + public int deleteGenTableColumns(List genTableColumns); + + /** + * 批量删除业务字段 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteGenTableColumnByIds(Long[] ids); +} diff --git a/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/mapper/GenTableMapper.java b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/mapper/GenTableMapper.java new file mode 100644 index 0000000..b581267 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/mapper/GenTableMapper.java @@ -0,0 +1,83 @@ +package com.dcsoft.gen.mapper; + +import java.util.List; +import com.dcsoft.gen.domain.GenTable; + +/** + * 业务 数据层 + * + * @author dcsoft + */ +public interface GenTableMapper +{ + /** + * 查询业务列表 + * + * @param genTable 业务信息 + * @return 业务集合 + */ + public List selectGenTableList(GenTable genTable); + + /** + * 查询据库列表 + * + * @param genTable 业务信息 + * @return 数据库表集合 + */ + public List selectDbTableList(GenTable genTable); + + /** + * 查询据库列表 + * + * @param tableNames 表名称组 + * @return 数据库表集合 + */ + public List selectDbTableListByNames(String[] tableNames); + + /** + * 查询所有表信息 + * + * @return 表信息集合 + */ + public List selectGenTableAll(); + + /** + * 查询表ID业务信息 + * + * @param id 业务ID + * @return 业务信息 + */ + public GenTable selectGenTableById(Long id); + + /** + * 查询表名称业务信息 + * + * @param tableName 表名称 + * @return 业务信息 + */ + public GenTable selectGenTableByName(String tableName); + + /** + * 新增业务 + * + * @param genTable 业务信息 + * @return 结果 + */ + public int insertGenTable(GenTable genTable); + + /** + * 修改业务 + * + * @param genTable 业务信息 + * @return 结果 + */ + public int updateGenTable(GenTable genTable); + + /** + * 批量删除业务 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteGenTableByIds(Long[] ids); +} diff --git a/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/service/GenTableColumnServiceImpl.java b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/service/GenTableColumnServiceImpl.java new file mode 100644 index 0000000..381b9d3 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/service/GenTableColumnServiceImpl.java @@ -0,0 +1,68 @@ +package com.dcsoft.gen.service; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.dcsoft.common.core.text.Convert; +import com.dcsoft.gen.domain.GenTableColumn; +import com.dcsoft.gen.mapper.GenTableColumnMapper; + +/** + * 业务字段 服务层实现 + * + * @author dcsoft + */ +@Service +public class GenTableColumnServiceImpl implements IGenTableColumnService +{ + @Autowired + private GenTableColumnMapper genTableColumnMapper; + + /** + * 查询业务字段列表 + * + * @param tableId 业务字段编号 + * @return 业务字段集合 + */ + @Override + public List selectGenTableColumnListByTableId(Long tableId) + { + return genTableColumnMapper.selectGenTableColumnListByTableId(tableId); + } + + /** + * 新增业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + @Override + public int insertGenTableColumn(GenTableColumn genTableColumn) + { + return genTableColumnMapper.insertGenTableColumn(genTableColumn); + } + + /** + * 修改业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + @Override + public int updateGenTableColumn(GenTableColumn genTableColumn) + { + return genTableColumnMapper.updateGenTableColumn(genTableColumn); + } + + /** + * 删除业务字段对象 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + @Override + public int deleteGenTableColumnByIds(String ids) + { + return genTableColumnMapper.deleteGenTableColumnByIds(Convert.toLongArray(ids)); + } +} diff --git a/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/service/GenTableServiceImpl.java b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/service/GenTableServiceImpl.java new file mode 100644 index 0000000..9657e09 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/service/GenTableServiceImpl.java @@ -0,0 +1,521 @@ +package com.dcsoft.gen.service; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.Velocity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.dcsoft.common.core.constant.Constants; +import com.dcsoft.common.core.constant.GenConstants; +import com.dcsoft.common.core.exception.ServiceException; +import com.dcsoft.common.core.text.CharsetKit; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.gen.domain.GenTable; +import com.dcsoft.gen.domain.GenTableColumn; +import com.dcsoft.gen.mapper.GenTableColumnMapper; +import com.dcsoft.gen.mapper.GenTableMapper; +import com.dcsoft.gen.util.GenUtils; +import com.dcsoft.gen.util.VelocityInitializer; +import com.dcsoft.gen.util.VelocityUtils; + +/** + * 业务 服务层实现 + * + * @author dcsoft + */ +@Service +public class GenTableServiceImpl implements IGenTableService +{ + private static final Logger log = LoggerFactory.getLogger(GenTableServiceImpl.class); + + @Autowired + private GenTableMapper genTableMapper; + + @Autowired + private GenTableColumnMapper genTableColumnMapper; + + /** + * 查询业务信息 + * + * @param id 业务ID + * @return 业务信息 + */ + @Override + public GenTable selectGenTableById(Long id) + { + GenTable genTable = genTableMapper.selectGenTableById(id); + setTableFromOptions(genTable); + return genTable; + } + + /** + * 查询业务列表 + * + * @param genTable 业务信息 + * @return 业务集合 + */ + @Override + public List selectGenTableList(GenTable genTable) + { + return genTableMapper.selectGenTableList(genTable); + } + + /** + * 查询据库列表 + * + * @param genTable 业务信息 + * @return 数据库表集合 + */ + @Override + public List selectDbTableList(GenTable genTable) + { + return genTableMapper.selectDbTableList(genTable); + } + + /** + * 查询据库列表 + * + * @param tableNames 表名称组 + * @return 数据库表集合 + */ + @Override + public List selectDbTableListByNames(String[] tableNames) + { + return genTableMapper.selectDbTableListByNames(tableNames); + } + + /** + * 查询所有表信息 + * + * @return 表信息集合 + */ + @Override + public List selectGenTableAll() + { + return genTableMapper.selectGenTableAll(); + } + + /** + * 修改业务 + * + * @param genTable 业务信息 + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void updateGenTable(GenTable genTable) + { + String options = JSON.toJSONString(genTable.getParams()); + genTable.setOptions(options); + int row = genTableMapper.updateGenTable(genTable); + if (row > 0) + { + for (GenTableColumn cenTableColumn : genTable.getColumns()) + { + genTableColumnMapper.updateGenTableColumn(cenTableColumn); + } + } + } + + /** + * 删除业务对象 + * + * @param tableIds 需要删除的数据ID + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteGenTableByIds(Long[] tableIds) + { + genTableMapper.deleteGenTableByIds(tableIds); + genTableColumnMapper.deleteGenTableColumnByIds(tableIds); + } + + /** + * 导入表结构 + * + * @param tableList 导入表列表 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void importGenTable(List tableList) + { + String operName = SecurityUtils.getUsername(); + try + { + for (GenTable table : tableList) + { + String tableName = table.getTableName(); + GenUtils.initTable(table, operName); + int row = genTableMapper.insertGenTable(table); + if (row > 0) + { + // 保存列信息 + List genTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName); + for (GenTableColumn column : genTableColumns) + { + GenUtils.initColumnField(column, table); + genTableColumnMapper.insertGenTableColumn(column); + } + } + } + } + catch (Exception e) + { + throw new ServiceException("导入失败:" + e.getMessage()); + } + } + + /** + * 预览代码 + * + * @param tableId 表编号 + * @return 预览数据列表 + */ + @Override + public Map previewCode(Long tableId) + { + Map dataMap = new LinkedHashMap<>(); + // 查询表信息 + GenTable table = genTableMapper.selectGenTableById(tableId); + // 设置主子表信息 + setSubTable(table); + // 设置主键列信息 + setPkColumn(table); + VelocityInitializer.initVelocity(); + + VelocityContext context = VelocityUtils.prepareContext(table); + + // 获取模板列表 + List templates = VelocityUtils.getTemplateList(table.getTplCategory()); + for (String template : templates) + { + // 渲染模板 + StringWriter sw = new StringWriter(); + Template tpl = Velocity.getTemplate(template, Constants.UTF8); + tpl.merge(context, sw); + dataMap.put(template, sw.toString()); + } + return dataMap; + } + + /** + * 生成代码(下载方式) + * + * @param tableName 表名称 + * @return 数据 + */ + @Override + public byte[] downloadCode(String tableName) + { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + ZipOutputStream zip = new ZipOutputStream(outputStream); + generatorCode(tableName, zip); + IOUtils.closeQuietly(zip); + return outputStream.toByteArray(); + } + + /** + * 生成代码(自定义路径) + * + * @param tableName 表名称 + */ + @Override + public void generatorCode(String tableName) + { + // 查询表信息 + GenTable table = genTableMapper.selectGenTableByName(tableName); + // 设置主子表信息 + setSubTable(table); + // 设置主键列信息 + setPkColumn(table); + + VelocityInitializer.initVelocity(); + + VelocityContext context = VelocityUtils.prepareContext(table); + + // 获取模板列表 + List templates = VelocityUtils.getTemplateList(table.getTplCategory()); + for (String template : templates) + { + if (!StringUtils.containsAny(template, "sql.vm", "api.js.vm", "index.vue.vm", "index-tree.vue.vm")) + { + // 渲染模板 + StringWriter sw = new StringWriter(); + Template tpl = Velocity.getTemplate(template, Constants.UTF8); + tpl.merge(context, sw); + try + { + String path = getGenPath(table, template); + FileUtils.writeStringToFile(new File(path), sw.toString(), CharsetKit.UTF_8); + } + catch (IOException e) + { + throw new ServiceException("渲染模板失败,表名:" + table.getTableName()); + } + } + } + } + + /** + * 同步数据库 + * + * @param tableName 表名称 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void synchDb(String tableName) + { + GenTable table = genTableMapper.selectGenTableByName(tableName); + List tableColumns = table.getColumns(); + Map tableColumnMap = tableColumns.stream().collect(Collectors.toMap(GenTableColumn::getColumnName, Function.identity())); + + List dbTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName); + if (StringUtils.isEmpty(dbTableColumns)) + { + throw new ServiceException("同步数据失败,原表结构不存在"); + } + List dbTableColumnNames = dbTableColumns.stream().map(GenTableColumn::getColumnName).collect(Collectors.toList()); + + dbTableColumns.forEach(column -> { + GenUtils.initColumnField(column, table); + if (tableColumnMap.containsKey(column.getColumnName())) + { + GenTableColumn prevColumn = tableColumnMap.get(column.getColumnName()); + column.setColumnId(prevColumn.getColumnId()); + if (column.isList()) + { + // 如果是列表,继续保留查询方式/字典类型选项 + column.setDictType(prevColumn.getDictType()); + column.setQueryType(prevColumn.getQueryType()); + } + if (StringUtils.isNotEmpty(prevColumn.getIsRequired()) && !column.isPk() + && (column.isInsert() || column.isEdit()) + && ((column.isUsableColumn()) || (!column.isSuperColumn()))) + { + // 如果是(新增/修改&非主键/非忽略及父属性),继续保留必填/显示类型选项 + column.setIsRequired(prevColumn.getIsRequired()); + column.setHtmlType(prevColumn.getHtmlType()); + } + genTableColumnMapper.updateGenTableColumn(column); + } + else + { + genTableColumnMapper.insertGenTableColumn(column); + } + }); + + List delColumns = tableColumns.stream().filter(column -> !dbTableColumnNames.contains(column.getColumnName())).collect(Collectors.toList()); + if (StringUtils.isNotEmpty(delColumns)) + { + genTableColumnMapper.deleteGenTableColumns(delColumns); + } + } + + /** + * 批量生成代码(下载方式) + * + * @param tableNames 表数组 + * @return 数据 + */ + @Override + public byte[] downloadCode(String[] tableNames) + { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + ZipOutputStream zip = new ZipOutputStream(outputStream); + for (String tableName : tableNames) + { + generatorCode(tableName, zip); + } + IOUtils.closeQuietly(zip); + return outputStream.toByteArray(); + } + + /** + * 查询表信息并生成代码 + */ + private void generatorCode(String tableName, ZipOutputStream zip) + { + // 查询表信息 + GenTable table = genTableMapper.selectGenTableByName(tableName); + // 设置主子表信息 + setSubTable(table); + // 设置主键列信息 + setPkColumn(table); + + VelocityInitializer.initVelocity(); + + VelocityContext context = VelocityUtils.prepareContext(table); + + // 获取模板列表 + List templates = VelocityUtils.getTemplateList(table.getTplCategory()); + for (String template : templates) + { + // 渲染模板 + StringWriter sw = new StringWriter(); + Template tpl = Velocity.getTemplate(template, Constants.UTF8); + tpl.merge(context, sw); + try + { + // 添加到zip + zip.putNextEntry(new ZipEntry(VelocityUtils.getFileName(template, table))); + IOUtils.write(sw.toString(), zip, Constants.UTF8); + IOUtils.closeQuietly(sw); + zip.flush(); + zip.closeEntry(); + } + catch (IOException e) + { + log.error("渲染模板失败,表名:" + table.getTableName(), e); + } + } + } + + /** + * 修改保存参数校验 + * + * @param genTable 业务信息 + */ + @Override + public void validateEdit(GenTable genTable) + { + if (GenConstants.TPL_TREE.equals(genTable.getTplCategory())) + { + String options = JSON.toJSONString(genTable.getParams()); + JSONObject paramsObj = JSON.parseObject(options); + if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_CODE))) + { + throw new ServiceException("树编码字段不能为空"); + } + else if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_PARENT_CODE))) + { + throw new ServiceException("树父编码字段不能为空"); + } + else if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_NAME))) + { + throw new ServiceException("树名称字段不能为空"); + } + else if (GenConstants.TPL_SUB.equals(genTable.getTplCategory())) + { + if (StringUtils.isEmpty(genTable.getSubTableName())) + { + throw new ServiceException("关联子表的表名不能为空"); + } + else if (StringUtils.isEmpty(genTable.getSubTableFkName())) + { + throw new ServiceException("子表关联的外键名不能为空"); + } + } + } + } + + /** + * 设置主键列信息 + * + * @param table 业务表信息 + */ + public void setPkColumn(GenTable table) + { + for (GenTableColumn column : table.getColumns()) + { + if (column.isPk()) + { + table.setPkColumn(column); + break; + } + } + if (StringUtils.isNull(table.getPkColumn())) + { + table.setPkColumn(table.getColumns().get(0)); + } + if (GenConstants.TPL_SUB.equals(table.getTplCategory())) + { + for (GenTableColumn column : table.getSubTable().getColumns()) + { + if (column.isPk()) + { + table.getSubTable().setPkColumn(column); + break; + } + } + if (StringUtils.isNull(table.getSubTable().getPkColumn())) + { + table.getSubTable().setPkColumn(table.getSubTable().getColumns().get(0)); + } + } + } + + /** + * 设置主子表信息 + * + * @param table 业务表信息 + */ + public void setSubTable(GenTable table) + { + String subTableName = table.getSubTableName(); + if (StringUtils.isNotEmpty(subTableName)) + { + table.setSubTable(genTableMapper.selectGenTableByName(subTableName)); + } + } + + /** + * 设置代码生成其他选项值 + * + * @param genTable 设置后的生成对象 + */ + public void setTableFromOptions(GenTable genTable) + { + JSONObject paramsObj = JSON.parseObject(genTable.getOptions()); + if (StringUtils.isNotNull(paramsObj)) + { + String treeCode = paramsObj.getString(GenConstants.TREE_CODE); + String treeParentCode = paramsObj.getString(GenConstants.TREE_PARENT_CODE); + String treeName = paramsObj.getString(GenConstants.TREE_NAME); + String parentMenuId = paramsObj.getString(GenConstants.PARENT_MENU_ID); + String parentMenuName = paramsObj.getString(GenConstants.PARENT_MENU_NAME); + + genTable.setTreeCode(treeCode); + genTable.setTreeParentCode(treeParentCode); + genTable.setTreeName(treeName); + genTable.setParentMenuId(parentMenuId); + genTable.setParentMenuName(parentMenuName); + } + } + + /** + * 获取代码生成地址 + * + * @param table 业务表信息 + * @param template 模板文件路径 + * @return 生成地址 + */ + public static String getGenPath(GenTable table, String template) + { + String genPath = table.getGenPath(); + if (StringUtils.equals(genPath, "/")) + { + return System.getProperty("user.dir") + File.separator + "src" + File.separator + VelocityUtils.getFileName(template, table); + } + return genPath + File.separator + VelocityUtils.getFileName(template, table); + } +} diff --git a/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/service/IGenTableColumnService.java b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/service/IGenTableColumnService.java new file mode 100644 index 0000000..da44a99 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/service/IGenTableColumnService.java @@ -0,0 +1,44 @@ +package com.dcsoft.gen.service; + +import java.util.List; +import com.dcsoft.gen.domain.GenTableColumn; + +/** + * 业务字段 服务层 + * + * @author dcsoft + */ +public interface IGenTableColumnService +{ + /** + * 查询业务字段列表 + * + * @param tableId 业务字段编号 + * @return 业务字段集合 + */ + public List selectGenTableColumnListByTableId(Long tableId); + + /** + * 新增业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + public int insertGenTableColumn(GenTableColumn genTableColumn); + + /** + * 修改业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + public int updateGenTableColumn(GenTableColumn genTableColumn); + + /** + * 删除业务字段信息 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteGenTableColumnByIds(String ids); +} diff --git a/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/service/IGenTableService.java b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/service/IGenTableService.java new file mode 100644 index 0000000..575c737 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/service/IGenTableService.java @@ -0,0 +1,121 @@ +package com.dcsoft.gen.service; + +import java.util.List; +import java.util.Map; +import com.dcsoft.gen.domain.GenTable; + +/** + * 业务 服务层 + * + * @author dcsoft + */ +public interface IGenTableService +{ + /** + * 查询业务列表 + * + * @param genTable 业务信息 + * @return 业务集合 + */ + public List selectGenTableList(GenTable genTable); + + /** + * 查询据库列表 + * + * @param genTable 业务信息 + * @return 数据库表集合 + */ + public List selectDbTableList(GenTable genTable); + + /** + * 查询据库列表 + * + * @param tableNames 表名称组 + * @return 数据库表集合 + */ + public List selectDbTableListByNames(String[] tableNames); + + /** + * 查询所有表信息 + * + * @return 表信息集合 + */ + public List selectGenTableAll(); + + /** + * 查询业务信息 + * + * @param id 业务ID + * @return 业务信息 + */ + public GenTable selectGenTableById(Long id); + + /** + * 修改业务 + * + * @param genTable 业务信息 + * @return 结果 + */ + public void updateGenTable(GenTable genTable); + + /** + * 删除业务信息 + * + * @param tableIds 需要删除的表数据ID + * @return 结果 + */ + public void deleteGenTableByIds(Long[] tableIds); + + /** + * 导入表结构 + * + * @param tableList 导入表列表 + */ + public void importGenTable(List tableList); + + /** + * 预览代码 + * + * @param tableId 表编号 + * @return 预览数据列表 + */ + public Map previewCode(Long tableId); + + /** + * 生成代码(下载方式) + * + * @param tableName 表名称 + * @return 数据 + */ + public byte[] downloadCode(String tableName); + + /** + * 生成代码(自定义路径) + * + * @param tableName 表名称 + * @return 数据 + */ + public void generatorCode(String tableName); + + /** + * 同步数据库 + * + * @param tableName 表名称 + */ + public void synchDb(String tableName); + + /** + * 批量生成代码(下载方式) + * + * @param tableNames 表数组 + * @return 数据 + */ + public byte[] downloadCode(String[] tableNames); + + /** + * 修改保存参数校验 + * + * @param genTable 业务信息 + */ + public void validateEdit(GenTable genTable); +} diff --git a/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/util/GenUtils.java b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/util/GenUtils.java new file mode 100644 index 0000000..f601f98 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/util/GenUtils.java @@ -0,0 +1,257 @@ +package com.dcsoft.gen.util; + +import java.util.Arrays; +import org.apache.commons.lang3.RegExUtils; +import com.dcsoft.common.core.constant.GenConstants; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.gen.config.GenConfig; +import com.dcsoft.gen.domain.GenTable; +import com.dcsoft.gen.domain.GenTableColumn; + +/** + * 代码生成器 工具类 + * + * @author dcsoft + */ +public class GenUtils +{ + /** + * 初始化表信息 + */ + public static void initTable(GenTable genTable, String operName) + { + genTable.setClassName(convertClassName(genTable.getTableName())); + genTable.setPackageName(GenConfig.getPackageName()); + genTable.setModuleName(getModuleName(GenConfig.getPackageName())); + genTable.setBusinessName(getBusinessName(genTable.getTableName())); + genTable.setFunctionName(replaceText(genTable.getTableComment())); + genTable.setFunctionAuthor(GenConfig.getAuthor()); + genTable.setCreateBy(operName); + } + + /** + * 初始化列属性字段 + */ + public static void initColumnField(GenTableColumn column, GenTable table) + { + String dataType = getDbType(column.getColumnType()); + String columnName = column.getColumnName(); + column.setTableId(table.getTableId()); + column.setCreateBy(table.getCreateBy()); + // 设置java字段名 + column.setJavaField(StringUtils.toCamelCase(columnName)); + // 设置默认类型 + column.setJavaType(GenConstants.TYPE_STRING); + column.setQueryType(GenConstants.QUERY_EQ); + + if (arraysContains(GenConstants.COLUMNTYPE_STR, dataType) || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType)) + { + // 字符串长度超过500设置为文本域 + Integer columnLength = getColumnLength(column.getColumnType()); + String htmlType = columnLength >= 500 || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType) ? GenConstants.HTML_TEXTAREA : GenConstants.HTML_INPUT; + column.setHtmlType(htmlType); + } + else if (arraysContains(GenConstants.COLUMNTYPE_TIME, dataType)) + { + column.setJavaType(GenConstants.TYPE_DATE); + column.setHtmlType(GenConstants.HTML_DATETIME); + } + else if (arraysContains(GenConstants.COLUMNTYPE_NUMBER, dataType)) + { + column.setHtmlType(GenConstants.HTML_INPUT); + + // 如果是浮点型 统一用BigDecimal + String[] str = StringUtils.split(StringUtils.substringBetween(column.getColumnType(), "(", ")"), ","); + if (str != null && str.length == 2 && Integer.parseInt(str[1]) > 0) + { + column.setJavaType(GenConstants.TYPE_BIGDECIMAL); + } + // 如果是整形 + else if (str != null && str.length == 1 && Integer.parseInt(str[0]) <= 10) + { + column.setJavaType(GenConstants.TYPE_INTEGER); + } + // 长整形 + else + { + column.setJavaType(GenConstants.TYPE_LONG); + } + } + + // 插入字段(默认所有字段都需要插入) + column.setIsInsert(GenConstants.REQUIRE); + + // 编辑字段 + if (!arraysContains(GenConstants.COLUMNNAME_NOT_EDIT, columnName) && !column.isPk()) + { + column.setIsEdit(GenConstants.REQUIRE); + } + // 列表字段 + if (!arraysContains(GenConstants.COLUMNNAME_NOT_LIST, columnName) && !column.isPk()) + { + column.setIsList(GenConstants.REQUIRE); + } + // 查询字段 + if (!arraysContains(GenConstants.COLUMNNAME_NOT_QUERY, columnName) && !column.isPk()) + { + column.setIsQuery(GenConstants.REQUIRE); + } + + // 查询字段类型 + if (StringUtils.endsWithIgnoreCase(columnName, "name")) + { + column.setQueryType(GenConstants.QUERY_LIKE); + } + // 状态字段设置单选框 + if (StringUtils.endsWithIgnoreCase(columnName, "status")) + { + column.setHtmlType(GenConstants.HTML_RADIO); + } + // 类型&性别字段设置下拉框 + else if (StringUtils.endsWithIgnoreCase(columnName, "type") + || StringUtils.endsWithIgnoreCase(columnName, "sex")) + { + column.setHtmlType(GenConstants.HTML_SELECT); + } + // 图片字段设置图片上传控件 + else if (StringUtils.endsWithIgnoreCase(columnName, "image")) + { + column.setHtmlType(GenConstants.HTML_IMAGE_UPLOAD); + } + // 文件字段设置文件上传控件 + else if (StringUtils.endsWithIgnoreCase(columnName, "file")) + { + column.setHtmlType(GenConstants.HTML_FILE_UPLOAD); + } + // 内容字段设置富文本控件 + else if (StringUtils.endsWithIgnoreCase(columnName, "content")) + { + column.setHtmlType(GenConstants.HTML_EDITOR); + } + } + + /** + * 校验数组是否包含指定值 + * + * @param arr 数组 + * @param targetValue 值 + * @return 是否包含 + */ + public static boolean arraysContains(String[] arr, String targetValue) + { + return Arrays.asList(arr).contains(targetValue); + } + + /** + * 获取模块名 + * + * @param packageName 包名 + * @return 模块名 + */ + public static String getModuleName(String packageName) + { + int lastIndex = packageName.lastIndexOf("."); + int nameLength = packageName.length(); + return StringUtils.substring(packageName, lastIndex + 1, nameLength); + } + + /** + * 获取业务名 + * + * @param tableName 表名 + * @return 业务名 + */ + public static String getBusinessName(String tableName) + { + int lastIndex = tableName.lastIndexOf("_"); + int nameLength = tableName.length(); + return StringUtils.substring(tableName, lastIndex + 1, nameLength); + } + + /** + * 表名转换成Java类名 + * + * @param tableName 表名称 + * @return 类名 + */ + public static String convertClassName(String tableName) + { + boolean autoRemovePre = GenConfig.getAutoRemovePre(); + String tablePrefix = GenConfig.getTablePrefix(); + if (autoRemovePre && StringUtils.isNotEmpty(tablePrefix)) + { + String[] searchList = StringUtils.split(tablePrefix, ","); + tableName = replaceFirst(tableName, searchList); + } + return StringUtils.convertToCamelCase(tableName); + } + + /** + * 批量替换前缀 + * + * @param replacementm 替换值 + * @param searchList 替换列表 + * @return + */ + public static String replaceFirst(String replacementm, String[] searchList) + { + String text = replacementm; + for (String searchString : searchList) + { + if (replacementm.startsWith(searchString)) + { + text = replacementm.replaceFirst(searchString, ""); + break; + } + } + return text; + } + + /** + * 关键字替换 + * + * @param text 需要被替换的名字 + * @return 替换后的名字 + */ + public static String replaceText(String text) + { + return RegExUtils.replaceAll(text, "(?:表|若依)", ""); + } + + /** + * 获取数据库类型字段 + * + * @param columnType 列类型 + * @return 截取后的列类型 + */ + public static String getDbType(String columnType) + { + if (StringUtils.indexOf(columnType, "(") > 0) + { + return StringUtils.substringBefore(columnType, "("); + } + else + { + return columnType; + } + } + + /** + * 获取字段长度 + * + * @param columnType 列类型 + * @return 截取后的列类型 + */ + public static Integer getColumnLength(String columnType) + { + if (StringUtils.indexOf(columnType, "(") > 0) + { + String length = StringUtils.substringBetween(columnType, "(", ")"); + return Integer.valueOf(length); + } + else + { + return 0; + } + } +} diff --git a/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/util/VelocityInitializer.java b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/util/VelocityInitializer.java new file mode 100644 index 0000000..8963269 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/util/VelocityInitializer.java @@ -0,0 +1,34 @@ +package com.dcsoft.gen.util; + +import java.util.Properties; +import org.apache.velocity.app.Velocity; +import com.dcsoft.common.core.constant.Constants; + +/** + * VelocityEngine工厂 + * + * @author dcsoft + */ +public class VelocityInitializer +{ + /** + * 初始化vm方法 + */ + public static void initVelocity() + { + Properties p = new Properties(); + try + { + // 加载classpath目录下的vm文件 + p.setProperty("resource.loader.file.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); + // 定义字符集 + p.setProperty(Velocity.INPUT_ENCODING, Constants.UTF8); + // 初始化Velocity引擎,指定配置Properties + Velocity.init(p); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } +} diff --git a/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/util/VelocityUtils.java b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/util/VelocityUtils.java new file mode 100644 index 0000000..6b3e303 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/java/com/dcsoft/gen/util/VelocityUtils.java @@ -0,0 +1,402 @@ +package com.dcsoft.gen.util; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.apache.velocity.VelocityContext; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.dcsoft.common.core.constant.GenConstants; +import com.dcsoft.common.core.utils.DateUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.gen.domain.GenTable; +import com.dcsoft.gen.domain.GenTableColumn; + +/** + * 模板工具类 + * + * @author dcsoft + */ +public class VelocityUtils +{ + /** 项目空间路径 */ + private static final String PROJECT_PATH = "main/java"; + + /** mybatis空间路径 */ + private static final String MYBATIS_PATH = "main/resources/mapper"; + + /** 默认上级菜单,系统工具 */ + private static final String DEFAULT_PARENT_MENU_ID = "3"; + + /** + * 设置模板变量信息 + * + * @return 模板列表 + */ + public static VelocityContext prepareContext(GenTable genTable) + { + String moduleName = genTable.getModuleName(); + String businessName = genTable.getBusinessName(); + String packageName = genTable.getPackageName(); + String tplCategory = genTable.getTplCategory(); + String functionName = genTable.getFunctionName(); + + VelocityContext velocityContext = new VelocityContext(); + velocityContext.put("tplCategory", genTable.getTplCategory()); + velocityContext.put("tableName", genTable.getTableName()); + velocityContext.put("functionName", StringUtils.isNotEmpty(functionName) ? functionName : "【请填写功能名称】"); + velocityContext.put("ClassName", genTable.getClassName()); + velocityContext.put("className", StringUtils.uncapitalize(genTable.getClassName())); + velocityContext.put("moduleName", genTable.getModuleName()); + velocityContext.put("BusinessName", StringUtils.capitalize(genTable.getBusinessName())); + velocityContext.put("businessName", genTable.getBusinessName()); + velocityContext.put("basePackage", getPackagePrefix(packageName)); + velocityContext.put("packageName", packageName); + velocityContext.put("author", genTable.getFunctionAuthor()); + velocityContext.put("datetime", DateUtils.getDate()); + velocityContext.put("pkColumn", genTable.getPkColumn()); + velocityContext.put("importList", getImportList(genTable)); + velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName)); + velocityContext.put("columns", genTable.getColumns()); + velocityContext.put("table", genTable); + velocityContext.put("dicts", getDicts(genTable)); + setMenuVelocityContext(velocityContext, genTable); + if (GenConstants.TPL_TREE.equals(tplCategory)) + { + setTreeVelocityContext(velocityContext, genTable); + } + if (GenConstants.TPL_SUB.equals(tplCategory)) + { + setSubVelocityContext(velocityContext, genTable); + } + return velocityContext; + } + + public static void setMenuVelocityContext(VelocityContext context, GenTable genTable) + { + String options = genTable.getOptions(); + JSONObject paramsObj = JSON.parseObject(options); + String parentMenuId = getParentMenuId(paramsObj); + context.put("parentMenuId", parentMenuId); + } + + public static void setTreeVelocityContext(VelocityContext context, GenTable genTable) + { + String options = genTable.getOptions(); + JSONObject paramsObj = JSON.parseObject(options); + String treeCode = getTreecode(paramsObj); + String treeParentCode = getTreeParentCode(paramsObj); + String treeName = getTreeName(paramsObj); + + context.put("treeCode", treeCode); + context.put("treeParentCode", treeParentCode); + context.put("treeName", treeName); + context.put("expandColumn", getExpandColumn(genTable)); + if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) + { + context.put("tree_parent_code", paramsObj.getString(GenConstants.TREE_PARENT_CODE)); + } + if (paramsObj.containsKey(GenConstants.TREE_NAME)) + { + context.put("tree_name", paramsObj.getString(GenConstants.TREE_NAME)); + } + } + + public static void setSubVelocityContext(VelocityContext context, GenTable genTable) + { + GenTable subTable = genTable.getSubTable(); + String subTableName = genTable.getSubTableName(); + String subTableFkName = genTable.getSubTableFkName(); + String subClassName = genTable.getSubTable().getClassName(); + String subTableFkClassName = StringUtils.convertToCamelCase(subTableFkName); + + context.put("subTable", subTable); + context.put("subTableName", subTableName); + context.put("subTableFkName", subTableFkName); + context.put("subTableFkClassName", subTableFkClassName); + context.put("subTableFkclassName", StringUtils.uncapitalize(subTableFkClassName)); + context.put("subClassName", subClassName); + context.put("subclassName", StringUtils.uncapitalize(subClassName)); + context.put("subImportList", getImportList(genTable.getSubTable())); + } + + /** + * 获取模板信息 + * + * @return 模板列表 + */ + public static List getTemplateList(String tplCategory) + { + List templates = new ArrayList(); + templates.add("vm/java/domain.java.vm"); + templates.add("vm/java/mapper.java.vm"); + templates.add("vm/java/service.java.vm"); + templates.add("vm/java/serviceImpl.java.vm"); + templates.add("vm/java/controller.java.vm"); + templates.add("vm/xml/mapper.xml.vm"); + templates.add("vm/sql/sql.vm"); + templates.add("vm/js/api.js.vm"); + if (GenConstants.TPL_CRUD.equals(tplCategory)) + { + templates.add("vm/vue/index.vue.vm"); + } + else if (GenConstants.TPL_TREE.equals(tplCategory)) + { + templates.add("vm/vue/index-tree.vue.vm"); + } + else if (GenConstants.TPL_SUB.equals(tplCategory)) + { + templates.add("vm/vue/index.vue.vm"); + templates.add("vm/java/sub-domain.java.vm"); + } + return templates; + } + + /** + * 获取文件名 + */ + public static String getFileName(String template, GenTable genTable) + { + // 文件名称 + String fileName = ""; + // 包路径 + String packageName = genTable.getPackageName(); + // 模块名 + String moduleName = genTable.getModuleName(); + // 大写类名 + String className = genTable.getClassName(); + // 业务名称 + String businessName = genTable.getBusinessName(); + + String javaPath = PROJECT_PATH + "/" + StringUtils.replace(packageName, ".", "/"); + String mybatisPath = MYBATIS_PATH + "/" + moduleName; + String vuePath = "vue"; + + if (template.contains("domain.java.vm")) + { + fileName = StringUtils.format("{}/domain/{}.java", javaPath, className); + } + if (template.contains("sub-domain.java.vm") && StringUtils.equals(GenConstants.TPL_SUB, genTable.getTplCategory())) + { + fileName = StringUtils.format("{}/domain/{}.java", javaPath, genTable.getSubTable().getClassName()); + } + else if (template.contains("mapper.java.vm")) + { + fileName = StringUtils.format("{}/mapper/{}Mapper.java", javaPath, className); + } + else if (template.contains("service.java.vm")) + { + fileName = StringUtils.format("{}/service/I{}Service.java", javaPath, className); + } + else if (template.contains("serviceImpl.java.vm")) + { + fileName = StringUtils.format("{}/service/impl/{}ServiceImpl.java", javaPath, className); + } + else if (template.contains("controller.java.vm")) + { + fileName = StringUtils.format("{}/controller/{}Controller.java", javaPath, className); + } + else if (template.contains("mapper.xml.vm")) + { + fileName = StringUtils.format("{}/{}Mapper.xml", mybatisPath, className); + } + else if (template.contains("sql.vm")) + { + fileName = businessName + "Menu.sql"; + } + else if (template.contains("api.js.vm")) + { + fileName = StringUtils.format("{}/api/{}/{}.js", vuePath, moduleName, businessName); + } + else if (template.contains("index.vue.vm")) + { + fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName); + } + else if (template.contains("index-tree.vue.vm")) + { + fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName); + } + return fileName; + } + + /** + * 获取包前缀 + * + * @param packageName 包名称 + * @return 包前缀名称 + */ + public static String getPackagePrefix(String packageName) + { + int lastIndex = packageName.lastIndexOf("."); + return StringUtils.substring(packageName, 0, lastIndex); + } + + /** + * 根据列类型获取导入包 + * + * @param genTable 业务表对象 + * @return 返回需要导入的包列表 + */ + public static HashSet getImportList(GenTable genTable) + { + List columns = genTable.getColumns(); + GenTable subGenTable = genTable.getSubTable(); + HashSet importList = new HashSet(); + if (StringUtils.isNotNull(subGenTable)) + { + importList.add("java.util.List"); + } + for (GenTableColumn column : columns) + { + if (!column.isSuperColumn() && GenConstants.TYPE_DATE.equals(column.getJavaType())) + { + importList.add("java.util.Date"); + importList.add("com.fasterxml.jackson.annotation.JsonFormat"); + } + else if (!column.isSuperColumn() && GenConstants.TYPE_BIGDECIMAL.equals(column.getJavaType())) + { + importList.add("java.math.BigDecimal"); + } + } + return importList; + } + + /** + * 根据列类型获取字典组 + * + * @param genTable 业务表对象 + * @return 返回字典组 + */ + public static String getDicts(GenTable genTable) + { + List columns = genTable.getColumns(); + Set dicts = new HashSet(); + addDicts(dicts, columns); + if (StringUtils.isNotNull(genTable.getSubTable())) + { + List subColumns = genTable.getSubTable().getColumns(); + addDicts(dicts, subColumns); + } + return StringUtils.join(dicts, ", "); + } + + /** + * 添加字典列表 + * + * @param dicts 字典列表 + * @param columns 列集合 + */ + public static void addDicts(Set dicts, List columns) + { + for (GenTableColumn column : columns) + { + if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny( + column.getHtmlType(), + new String[] { GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX })) + { + dicts.add("'" + column.getDictType() + "'"); + } + } + } + + /** + * 获取权限前缀 + * + * @param moduleName 模块名称 + * @param businessName 业务名称 + * @return 返回权限前缀 + */ + public static String getPermissionPrefix(String moduleName, String businessName) + { + return StringUtils.format("{}:{}", moduleName, businessName); + } + + /** + * 获取上级菜单ID字段 + * + * @param paramsObj 生成其他选项 + * @return 上级菜单ID字段 + */ + public static String getParentMenuId(JSONObject paramsObj) + { + if (StringUtils.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.PARENT_MENU_ID) + && StringUtils.isNotEmpty(paramsObj.getString(GenConstants.PARENT_MENU_ID))) + { + return paramsObj.getString(GenConstants.PARENT_MENU_ID); + } + return DEFAULT_PARENT_MENU_ID; + } + + /** + * 获取树编码 + * + * @param paramsObj 生成其他选项 + * @return 树编码 + */ + public static String getTreecode(JSONObject paramsObj) + { + if (paramsObj.containsKey(GenConstants.TREE_CODE)) + { + return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_CODE)); + } + return StringUtils.EMPTY; + } + + /** + * 获取树父编码 + * + * @param paramsObj 生成其他选项 + * @return 树父编码 + */ + public static String getTreeParentCode(JSONObject paramsObj) + { + if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) + { + return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_PARENT_CODE)); + } + return StringUtils.EMPTY; + } + + /** + * 获取树名称 + * + * @param paramsObj 生成其他选项 + * @return 树名称 + */ + public static String getTreeName(JSONObject paramsObj) + { + if (paramsObj.containsKey(GenConstants.TREE_NAME)) + { + return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_NAME)); + } + return StringUtils.EMPTY; + } + + /** + * 获取需要在哪一列上面显示展开按钮 + * + * @param genTable 业务表对象 + * @return 展开按钮列序号 + */ + public static int getExpandColumn(GenTable genTable) + { + String options = genTable.getOptions(); + JSONObject paramsObj = JSON.parseObject(options); + String treeName = paramsObj.getString(GenConstants.TREE_NAME); + int num = 0; + for (GenTableColumn column : genTable.getColumns()) + { + if (column.isList()) + { + num++; + String columnName = column.getColumnName(); + if (columnName.equals(treeName)) + { + break; + } + } + } + return num; + } +} diff --git a/dcsoft-modules/dcsoft-gen/src/main/resources/banner.txt b/dcsoft-modules/dcsoft-gen/src/main/resources/banner.txt new file mode 100644 index 0000000..05f528c --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/resources/banner.txt @@ -0,0 +1,10 @@ +Spring Boot Version: ${spring-boot.version} +Spring Application Name: ${spring.application.name} + _ + (_) + _ __ _ _ ___ _ _ _ ______ __ _ ___ _ __ +| '__|| | | | / _ \ | | | || ||______| / _` | / _ \| '_ \ +| | | |_| || (_) || |_| || | | (_| || __/| | | | +|_| \__,_| \___/ \__, ||_| \__, | \___||_| |_| + __/ | __/ | + |___/ |___/ \ No newline at end of file diff --git a/dcsoft-modules/dcsoft-gen/src/main/resources/bootstrap.yml b/dcsoft-modules/dcsoft-gen/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..4bf7b55 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/resources/bootstrap.yml @@ -0,0 +1,25 @@ +# Tomcat +server: + port: 9202 + +# Spring +spring: + application: + # 应用名称 + name: dcsoft-gen + profiles: + # 环境配置 + active: dev + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: 127.0.0.1:8848 + config: + # 配置中心地址 + server-addr: 127.0.0.1:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} diff --git a/dcsoft-modules/dcsoft-gen/src/main/resources/logback.xml b/dcsoft-modules/dcsoft-gen/src/main/resources/logback.xml new file mode 100644 index 0000000..8671d92 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/resources/logback.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/info.log + + + + ${log.path}/info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/error.log + + + + ${log.path}/error.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + + + + + + + + + + + + + diff --git a/dcsoft-modules/dcsoft-gen/src/main/resources/mapper/generator/GenTableColumnMapper.xml b/dcsoft-modules/dcsoft-gen/src/main/resources/mapper/generator/GenTableColumnMapper.xml new file mode 100644 index 0000000..a863e6a --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/resources/mapper/generator/GenTableColumnMapper.xml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select column_id, table_id, column_name, column_comment, column_type, java_type, java_field, is_pk, is_increment, is_required, is_insert, is_edit, is_list, is_query, query_type, html_type, dict_type, sort, create_by, create_time, update_by, update_time from gen_table_column + + + + + + + + insert into gen_table_column ( + table_id, + column_name, + column_comment, + column_type, + java_type, + java_field, + is_pk, + is_increment, + is_required, + is_insert, + is_edit, + is_list, + is_query, + query_type, + html_type, + dict_type, + sort, + create_by, + create_time + )values( + #{tableId}, + #{columnName}, + #{columnComment}, + #{columnType}, + #{javaType}, + #{javaField}, + #{isPk}, + #{isIncrement}, + #{isRequired}, + #{isInsert}, + #{isEdit}, + #{isList}, + #{isQuery}, + #{queryType}, + #{htmlType}, + #{dictType}, + #{sort}, + #{createBy}, + sysdate() + ) + + + + update gen_table_column + + column_comment = #{columnComment}, + java_type = #{javaType}, + java_field = #{javaField}, + is_insert = #{isInsert}, + is_edit = #{isEdit}, + is_list = #{isList}, + is_query = #{isQuery}, + is_required = #{isRequired}, + query_type = #{queryType}, + html_type = #{htmlType}, + dict_type = #{dictType}, + sort = #{sort}, + update_by = #{updateBy}, + update_time = sysdate() + + where column_id = #{columnId} + + + + delete from gen_table_column where table_id in + + #{tableId} + + + + + delete from gen_table_column where column_id in + + #{item.columnId} + + + + diff --git a/dcsoft-modules/dcsoft-gen/src/main/resources/mapper/generator/GenTableMapper.xml b/dcsoft-modules/dcsoft-gen/src/main/resources/mapper/generator/GenTableMapper.xml new file mode 100644 index 0000000..cefdaec --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/resources/mapper/generator/GenTableMapper.xml @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select table_id, table_name, table_comment, sub_table_name, sub_table_fk_name, class_name, tpl_category, package_name, module_name, business_name, function_name, function_author, gen_type, gen_path, options, create_by, create_time, update_by, update_time, remark from gen_table + + + + + + + + + + + + + + + + + + insert into gen_table ( + table_name, + table_comment, + class_name, + tpl_category, + package_name, + module_name, + business_name, + function_name, + function_author, + gen_type, + gen_path, + remark, + create_by, + create_time + )values( + #{tableName}, + #{tableComment}, + #{className}, + #{tplCategory}, + #{packageName}, + #{moduleName}, + #{businessName}, + #{functionName}, + #{functionAuthor}, + #{genType}, + #{genPath}, + #{remark}, + #{createBy}, + sysdate() + ) + + + + update gen_table + + table_name = #{tableName}, + table_comment = #{tableComment}, + sub_table_name = #{subTableName}, + sub_table_fk_name = #{subTableFkName}, + class_name = #{className}, + function_author = #{functionAuthor}, + gen_type = #{genType}, + gen_path = #{genPath}, + tpl_category = #{tplCategory}, + package_name = #{packageName}, + module_name = #{moduleName}, + business_name = #{businessName}, + function_name = #{functionName}, + options = #{options}, + update_by = #{updateBy}, + remark = #{remark}, + update_time = sysdate() + + where table_id = #{tableId} + + + + delete from gen_table where table_id in + + #{tableId} + + + + diff --git a/dcsoft-modules/dcsoft-gen/src/main/resources/vm/java/controller.java.vm b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/java/controller.java.vm new file mode 100644 index 0000000..9b0c777 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/java/controller.java.vm @@ -0,0 +1,115 @@ +package ${packageName}.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import ${packageName}.domain.${ClassName}; +import ${packageName}.service.I${ClassName}Service; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +#if($table.crud || $table.sub) +import com.dcsoft.common.core.web.page.TableDataInfo; +#elseif($table.tree) +#end + +/** + * ${functionName}Controller + * + * @author ${author} + * @date ${datetime} + */ +@RestController +@RequestMapping("/${businessName}") +public class ${ClassName}Controller extends BaseController +{ + @Autowired + private I${ClassName}Service ${className}Service; + + /** + * 查询${functionName}列表 + */ + @RequiresPermissions("${permissionPrefix}:list") + @GetMapping("/list") +#if($table.crud || $table.sub) + public TableDataInfo list(${ClassName} ${className}) + { + startPage(); + List<${ClassName}> list = ${className}Service.select${ClassName}List(${className}); + return getDataTable(list); + } +#elseif($table.tree) + public AjaxResult list(${ClassName} ${className}) + { + List<${ClassName}> list = ${className}Service.select${ClassName}List(${className}); + return success(list); + } +#end + + /** + * 导出${functionName}列表 + */ + @RequiresPermissions("${permissionPrefix}:export") + @Log(title = "${functionName}", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, ${ClassName} ${className}) + { + List<${ClassName}> list = ${className}Service.select${ClassName}List(${className}); + ExcelUtil<${ClassName}> util = new ExcelUtil<${ClassName}>(${ClassName}.class); + util.exportExcel(response, list, "${functionName}数据"); + } + + /** + * 获取${functionName}详细信息 + */ + @RequiresPermissions("${permissionPrefix}:query") + @GetMapping(value = "/{${pkColumn.javaField}}") + public AjaxResult getInfo(@PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField}) + { + return success(${className}Service.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField})); + } + + /** + * 新增${functionName} + */ + @RequiresPermissions("${permissionPrefix}:add") + @Log(title = "${functionName}", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody ${ClassName} ${className}) + { + return toAjax(${className}Service.insert${ClassName}(${className})); + } + + /** + * 修改${functionName} + */ + @RequiresPermissions("${permissionPrefix}:edit") + @Log(title = "${functionName}", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody ${ClassName} ${className}) + { + return toAjax(${className}Service.update${ClassName}(${className})); + } + + /** + * 删除${functionName} + */ + @RequiresPermissions("${permissionPrefix}:remove") + @Log(title = "${functionName}", businessType = BusinessType.DELETE) + @DeleteMapping("/{${pkColumn.javaField}s}") + public AjaxResult remove(@PathVariable ${pkColumn.javaType}[] ${pkColumn.javaField}s) + { + return toAjax(${className}Service.delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaField}s)); + } +} diff --git a/dcsoft-modules/dcsoft-gen/src/main/resources/vm/java/domain.java.vm b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/java/domain.java.vm new file mode 100644 index 0000000..a919536 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/java/domain.java.vm @@ -0,0 +1,101 @@ +package ${packageName}.domain; + +#foreach ($import in $importList) +import ${import}; +#end +import com.dcsoft.common.core.annotation.Excel; +#if($table.crud || $table.sub) +#elseif($table.tree) +#end + +/** + * ${functionName}对象 ${tableName} + * + * @author ${author} + * @date ${datetime} + */ +#if($table.crud || $table.sub) +#set($Entity="BaseEntity") +#elseif($table.tree) +#set($Entity="TreeEntity") +#end +public class ${ClassName} extends ${Entity} +{ + private static final long serialVersionUID = 1L; + +#foreach ($column in $columns) +#if(!$table.isSuperColumn($column.javaField)) + /** $column.columnComment */ +#if($column.list) +#set($parentheseIndex=$column.columnComment.indexOf("(")) +#if($parentheseIndex != -1) +#set($comment=$column.columnComment.substring(0, $parentheseIndex)) +#else +#set($comment=$column.columnComment) +#end +#if($parentheseIndex != -1) + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") +#elseif($column.javaType == 'Date') + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd") +#else + @Excel(name = "${comment}") +#end +#end + private $column.javaType $column.javaField; + +#end +#end +#if($table.sub) + /** $table.subTable.functionName信息 */ + private List<${subClassName}> ${subclassName}List; + +#end +#foreach ($column in $columns) +#if(!$table.isSuperColumn($column.javaField)) +#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) +#set($AttrName=$column.javaField) +#else +#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) +#end + public void set${AttrName}($column.javaType $column.javaField) + { + this.$column.javaField = $column.javaField; + } + + public $column.javaType get${AttrName}() + { + return $column.javaField; + } +#end +#end + +#if($table.sub) + public List<${subClassName}> get${subClassName}List() + { + return ${subclassName}List; + } + + public void set${subClassName}List(List<${subClassName}> ${subclassName}List) + { + this.${subclassName}List = ${subclassName}List; + } + +#end + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) +#foreach ($column in $columns) +#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) +#set($AttrName=$column.javaField) +#else +#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) +#end + .append("${column.javaField}", get${AttrName}()) +#end +#if($table.sub) + .append("${subclassName}List", get${subClassName}List()) +#end + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-gen/src/main/resources/vm/java/mapper.java.vm b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/java/mapper.java.vm new file mode 100644 index 0000000..7e7d7c2 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/java/mapper.java.vm @@ -0,0 +1,91 @@ +package ${packageName}.mapper; + +import java.util.List; +import ${packageName}.domain.${ClassName}; +#if($table.sub) +import ${packageName}.domain.${subClassName}; +#end + +/** + * ${functionName}Mapper接口 + * + * @author ${author} + * @date ${datetime} + */ +public interface ${ClassName}Mapper +{ + /** + * 查询${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return ${functionName} + */ + public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); + + /** + * 查询${functionName}列表 + * + * @param ${className} ${functionName} + * @return ${functionName}集合 + */ + public List<${ClassName}> select${ClassName}List(${ClassName} ${className}); + + /** + * 新增${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ + public int insert${ClassName}(${ClassName} ${className}); + + /** + * 修改${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ + public int update${ClassName}(${ClassName} ${className}); + + /** + * 删除${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return 结果 + */ + public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); + + /** + * 批量删除${functionName} + * + * @param ${pkColumn.javaField}s 需要删除的数据主键集合 + * @return 结果 + */ + public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); +#if($table.sub) + + /** + * 批量删除${subTable.functionName} + * + * @param ${pkColumn.javaField}s 需要删除的数据主键集合 + * @return 结果 + */ + public int delete${subClassName}By${subTableFkClassName}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); + + /** + * 批量新增${subTable.functionName} + * + * @param ${subclassName}List ${subTable.functionName}列表 + * @return 结果 + */ + public int batch${subClassName}(List<${subClassName}> ${subclassName}List); + + + /** + * 通过${functionName}主键删除${subTable.functionName}信息 + * + * @param ${pkColumn.javaField} ${functionName}ID + * @return 结果 + */ + public int delete${subClassName}By${subTableFkClassName}(${pkColumn.javaType} ${pkColumn.javaField}); +#end +} diff --git a/dcsoft-modules/dcsoft-gen/src/main/resources/vm/java/service.java.vm b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/java/service.java.vm new file mode 100644 index 0000000..264882b --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/java/service.java.vm @@ -0,0 +1,61 @@ +package ${packageName}.service; + +import java.util.List; +import ${packageName}.domain.${ClassName}; + +/** + * ${functionName}Service接口 + * + * @author ${author} + * @date ${datetime} + */ +public interface I${ClassName}Service +{ + /** + * 查询${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return ${functionName} + */ + public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); + + /** + * 查询${functionName}列表 + * + * @param ${className} ${functionName} + * @return ${functionName}集合 + */ + public List<${ClassName}> select${ClassName}List(${ClassName} ${className}); + + /** + * 新增${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ + public int insert${ClassName}(${ClassName} ${className}); + + /** + * 修改${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ + public int update${ClassName}(${ClassName} ${className}); + + /** + * 批量删除${functionName} + * + * @param ${pkColumn.javaField}s 需要删除的${functionName}主键集合 + * @return 结果 + */ + public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); + + /** + * 删除${functionName}信息 + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return 结果 + */ + public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); +} diff --git a/dcsoft-modules/dcsoft-gen/src/main/resources/vm/java/serviceImpl.java.vm b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/java/serviceImpl.java.vm new file mode 100644 index 0000000..542ed8b --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/java/serviceImpl.java.vm @@ -0,0 +1,169 @@ +package ${packageName}.service.impl; + +import java.util.List; +#foreach ($column in $columns) +#if($column.javaField == 'createTime' || $column.javaField == 'updateTime') +import com.dcsoft.common.core.utils.DateUtils; +#break +#end +#end +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +#if($table.sub) +import java.util.ArrayList; +import com.dcsoft.common.core.utils.StringUtils; +import org.springframework.transaction.annotation.Transactional; +import ${packageName}.domain.${subClassName}; +#end +import ${packageName}.mapper.${ClassName}Mapper; +import ${packageName}.domain.${ClassName}; +import ${packageName}.service.I${ClassName}Service; + +/** + * ${functionName}Service业务层处理 + * + * @author ${author} + * @date ${datetime} + */ +@Service +public class ${ClassName}ServiceImpl implements I${ClassName}Service +{ + @Autowired + private ${ClassName}Mapper ${className}Mapper; + + /** + * 查询${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return ${functionName} + */ + @Override + public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}) + { + return ${className}Mapper.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}); + } + + /** + * 查询${functionName}列表 + * + * @param ${className} ${functionName} + * @return ${functionName} + */ + @Override + public List<${ClassName}> select${ClassName}List(${ClassName} ${className}) + { + return ${className}Mapper.select${ClassName}List(${className}); + } + + /** + * 新增${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int insert${ClassName}(${ClassName} ${className}) + { +#foreach ($column in $columns) +#if($column.javaField == 'createTime') + ${className}.setCreateTime(DateUtils.getNowDate()); +#end +#end +#if($table.sub) + int rows = ${className}Mapper.insert${ClassName}(${className}); + insert${subClassName}(${className}); + return rows; +#else + return ${className}Mapper.insert${ClassName}(${className}); +#end + } + + /** + * 修改${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int update${ClassName}(${ClassName} ${className}) + { +#foreach ($column in $columns) +#if($column.javaField == 'updateTime') + ${className}.setUpdateTime(DateUtils.getNowDate()); +#end +#end +#if($table.sub) + ${className}Mapper.delete${subClassName}By${subTableFkClassName}(${className}.get${pkColumn.capJavaField}()); + insert${subClassName}(${className}); +#end + return ${className}Mapper.update${ClassName}(${className}); + } + + /** + * 批量删除${functionName} + * + * @param ${pkColumn.javaField}s 需要删除的${functionName}主键 + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s) + { +#if($table.sub) + ${className}Mapper.delete${subClassName}By${subTableFkClassName}s(${pkColumn.javaField}s); +#end + return ${className}Mapper.delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaField}s); + } + + /** + * 删除${functionName}信息 + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}) + { +#if($table.sub) + ${className}Mapper.delete${subClassName}By${subTableFkClassName}(${pkColumn.javaField}); +#end + return ${className}Mapper.delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}); + } +#if($table.sub) + + /** + * 新增${subTable.functionName}信息 + * + * @param ${className} ${functionName}对象 + */ + public void insert${subClassName}(${ClassName} ${className}) + { + List<${subClassName}> ${subclassName}List = ${className}.get${subClassName}List(); + ${pkColumn.javaType} ${pkColumn.javaField} = ${className}.get${pkColumn.capJavaField}(); + if (StringUtils.isNotNull(${subclassName}List)) + { + List<${subClassName}> list = new ArrayList<${subClassName}>(); + for (${subClassName} ${subclassName} : ${subclassName}List) + { + ${subclassName}.set${subTableFkClassName}(${pkColumn.javaField}); + list.add(${subclassName}); + } + if (list.size() > 0) + { + ${className}Mapper.batch${subClassName}(list); + } + } + } +#end +} diff --git a/dcsoft-modules/dcsoft-gen/src/main/resources/vm/java/sub-domain.java.vm b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/java/sub-domain.java.vm new file mode 100644 index 0000000..0552b24 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/java/sub-domain.java.vm @@ -0,0 +1,73 @@ +package ${packageName}.domain; + +#foreach ($import in $subImportList) +import ${import}; +#end +import com.dcsoft.common.core.annotation.Excel; + +/** + * ${subTable.functionName}对象 ${subTableName} + * + * @author ${author} + * @date ${datetime} + */ +public class ${subClassName} extends BaseEntity +{ + private static final long serialVersionUID = 1L; + +#foreach ($column in $subTable.columns) +#if(!$table.isSuperColumn($column.javaField)) + /** $column.columnComment */ +#if($column.list) +#set($parentheseIndex=$column.columnComment.indexOf("(")) +#if($parentheseIndex != -1) +#set($comment=$column.columnComment.substring(0, $parentheseIndex)) +#else +#set($comment=$column.columnComment) +#end +#if($parentheseIndex != -1) + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") +#elseif($column.javaType == 'Date') + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd") +#else + @Excel(name = "${comment}") +#end +#end + private $column.javaType $column.javaField; + +#end +#end +#foreach ($column in $subTable.columns) +#if(!$table.isSuperColumn($column.javaField)) +#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) +#set($AttrName=$column.javaField) +#else +#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) +#end + public void set${AttrName}($column.javaType $column.javaField) + { + this.$column.javaField = $column.javaField; + } + + public $column.javaType get${AttrName}() + { + return $column.javaField; + } +#end +#end + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) +#foreach ($column in $subTable.columns) +#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) +#set($AttrName=$column.javaField) +#else +#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) +#end + .append("${column.javaField}", get${AttrName}()) +#end + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-gen/src/main/resources/vm/js/api.js.vm b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/js/api.js.vm new file mode 100644 index 0000000..9295524 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/js/api.js.vm @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 查询${functionName}列表 +export function list${BusinessName}(query) { + return request({ + url: '/${moduleName}/${businessName}/list', + method: 'get', + params: query + }) +} + +// 查询${functionName}详细 +export function get${BusinessName}(${pkColumn.javaField}) { + return request({ + url: '/${moduleName}/${businessName}/' + ${pkColumn.javaField}, + method: 'get' + }) +} + +// 新增${functionName} +export function add${BusinessName}(data) { + return request({ + url: '/${moduleName}/${businessName}', + method: 'post', + data: data + }) +} + +// 修改${functionName} +export function update${BusinessName}(data) { + return request({ + url: '/${moduleName}/${businessName}', + method: 'put', + data: data + }) +} + +// 删除${functionName} +export function del${BusinessName}(${pkColumn.javaField}) { + return request({ + url: '/${moduleName}/${businessName}/' + ${pkColumn.javaField}, + method: 'delete' + }) +} diff --git a/dcsoft-modules/dcsoft-gen/src/main/resources/vm/sql/sql.vm b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/sql/sql.vm new file mode 100644 index 0000000..0575583 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/sql/sql.vm @@ -0,0 +1,22 @@ +-- 菜单 SQL +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}', '${parentMenuId}', '1', '${businessName}', '${moduleName}/${businessName}/index', 1, 0, 'C', '0', '0', '${permissionPrefix}:list', '#', 'admin', sysdate(), '', null, '${functionName}菜单'); + +-- 按钮父菜单ID +SELECT @parentId := LAST_INSERT_ID(); + +-- 按钮 SQL +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}查询', @parentId, '1', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:query', '#', 'admin', sysdate(), '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}新增', @parentId, '2', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:add', '#', 'admin', sysdate(), '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}修改', @parentId, '3', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:edit', '#', 'admin', sysdate(), '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}删除', @parentId, '4', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:remove', '#', 'admin', sysdate(), '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}导出', @parentId, '5', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:export', '#', 'admin', sysdate(), '', null, ''); \ No newline at end of file diff --git a/dcsoft-modules/dcsoft-gen/src/main/resources/vm/vue/index-tree.vue.vm b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/vue/index-tree.vue.vm new file mode 100644 index 0000000..a4c64a0 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/vue/index-tree.vue.vm @@ -0,0 +1,505 @@ + + + diff --git a/dcsoft-modules/dcsoft-gen/src/main/resources/vm/vue/index.vue.vm b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/vue/index.vue.vm new file mode 100644 index 0000000..6296014 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/vue/index.vue.vm @@ -0,0 +1,602 @@ + + + diff --git a/dcsoft-modules/dcsoft-gen/src/main/resources/vm/vue/v3/index-tree.vue.vm b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/vue/v3/index-tree.vue.vm new file mode 100644 index 0000000..7bbd2fc --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/vue/v3/index-tree.vue.vm @@ -0,0 +1,474 @@ + + + diff --git a/dcsoft-modules/dcsoft-gen/src/main/resources/vm/vue/v3/index.vue.vm b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/vue/v3/index.vue.vm new file mode 100644 index 0000000..8b25665 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/vue/v3/index.vue.vm @@ -0,0 +1,590 @@ + + + diff --git a/dcsoft-modules/dcsoft-gen/src/main/resources/vm/vue/v3/readme.txt b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/vue/v3/readme.txt new file mode 100644 index 0000000..10362d6 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/vue/v3/readme.txt @@ -0,0 +1 @@ +ʹõRuoYi-Cloud-Vue3ǰˣôҪһ´Ŀ¼ģindex.vue.vmindex-tree.vue.vmļϼvueĿ¼ \ No newline at end of file diff --git a/dcsoft-modules/dcsoft-gen/src/main/resources/vm/xml/mapper.xml.vm b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/xml/mapper.xml.vm new file mode 100644 index 0000000..0ceb3d8 --- /dev/null +++ b/dcsoft-modules/dcsoft-gen/src/main/resources/vm/xml/mapper.xml.vm @@ -0,0 +1,135 @@ + + + + + +#foreach ($column in $columns) + +#end + +#if($table.sub) + + + + + + +#foreach ($column in $subTable.columns) + +#end + +#end + + + select#foreach($column in $columns) $column.columnName#if($foreach.count != $columns.size()),#end#end from ${tableName} + + + + + + + + insert into ${tableName} + +#foreach($column in $columns) +#if($column.columnName != $pkColumn.columnName || !$pkColumn.increment) + $column.columnName, +#end +#end + + +#foreach($column in $columns) +#if($column.columnName != $pkColumn.columnName || !$pkColumn.increment) + #{$column.javaField}, +#end +#end + + + + + update ${tableName} + +#foreach($column in $columns) +#if($column.columnName != $pkColumn.columnName) + $column.columnName = #{$column.javaField}, +#end +#end + + where ${pkColumn.columnName} = #{${pkColumn.javaField}} + + + + delete from ${tableName} where ${pkColumn.columnName} = #{${pkColumn.javaField}} + + + + delete from ${tableName} where ${pkColumn.columnName} in + + #{${pkColumn.javaField}} + + +#if($table.sub) + + + delete from ${subTableName} where ${subTableFkName} in + + #{${subTableFkclassName}} + + + + + delete from ${subTableName} where ${subTableFkName} = #{${subTableFkclassName}} + + + + insert into ${subTableName}(#foreach($column in $subTable.columns) $column.columnName#if($foreach.count != $subTable.columns.size()),#end#end) values + + (#foreach($column in $subTable.columns) #{item.$column.javaField}#if($foreach.count != $subTable.columns.size()),#end#end) + + +#end + \ No newline at end of file diff --git a/dcsoft-modules/dcsoft-job/pom.xml b/dcsoft-modules/dcsoft-job/pom.xml new file mode 100644 index 0000000..48c7781 --- /dev/null +++ b/dcsoft-modules/dcsoft-job/pom.xml @@ -0,0 +1,106 @@ + + + + com.dcsoft + dcsoft-modules + 3.6.2 + + 4.0.0 + + dcsoft-modules-job + + + dcsoft-modules-job定时任务 + + + + + + cn.hutool + hutool-all + 5.3.3 + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + io.springfox + springfox-swagger-ui + ${swagger.fox.version} + + + + + org.quartz-scheduler + quartz + + + com.mchange + c3p0 + + + + + + + mysql + mysql-connector-java + + + + + com.dcsoft + dcsoft-common-log + + + + + com.dcsoft + dcsoft-common-swagger + + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/DCSJobApplication.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/DCSJobApplication.java new file mode 100644 index 0000000..d91fc68 --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/DCSJobApplication.java @@ -0,0 +1,34 @@ +package com.dcsoft.job; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import com.dcsoft.common.security.annotation.EnableCustomConfig; +import com.dcsoft.common.security.annotation.EnableRyFeignClients; +import com.dcsoft.common.swagger.annotation.EnableCustomSwagger2; + +/** + * 定时任务 + * + * @author dcsoft + */ +@EnableCustomConfig +@EnableCustomSwagger2 +@EnableRyFeignClients +@SpringBootApplication +public class DCSJobApplication +{ + public static void main(String[] args) + { + SpringApplication.run(com.dcsoft.job.DCSJobApplication.class, args); + System.out.println("(♥◠‿◠)ノ゙ 定时任务模块启动成功 ლ(´ڡ`ლ)゙ \n" + + " .-------. ____ __ \n" + + " | _ _ \\ \\ \\ / / \n" + + " | ( ' ) | \\ _. / ' \n" + + " |(_ o _) / _( )_ .' \n" + + " | (_,_).' __ ___(_ o _)' \n" + + " | |\\ \\ | || |(_,_)' \n" + + " | | \\ `' /| `-' / \n" + + " | | \\ / \\ / \n" + + " ''-' `'-' `-..-' "); + } +} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/config/ScheduleConfig.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/config/ScheduleConfig.java new file mode 100644 index 0000000..6846188 --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/config/ScheduleConfig.java @@ -0,0 +1,57 @@ +//package com.dcsoft.job.config; +// +//import java.util.Properties; +//import javax.sql.DataSource; +//import org.springframework.context.annotation.Bean; +//import org.springframework.context.annotation.Configuration; +//import org.springframework.scheduling.quartz.SchedulerFactoryBean; +// +///** +// * 定时任务配置(单机部署建议删除此类和qrtz数据库表,默认走内存会最高效) +// * +// * @author dcsoft +// */ +//@Configuration +//public class ScheduleConfig +//{ +// @Bean +// public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) +// { +// SchedulerFactoryBean factory = new SchedulerFactoryBean(); +// factory.setDataSource(dataSource); +// +// // quartz参数 +// Properties prop = new Properties(); +// prop.put("org.quartz.scheduler.instanceName", "RuoyiScheduler"); +// prop.put("org.quartz.scheduler.instanceId", "AUTO"); +// // 线程池配置 +// prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool"); +// prop.put("org.quartz.threadPool.threadCount", "20"); +// prop.put("org.quartz.threadPool.threadPriority", "5"); +// // JobStore配置 +// prop.put("org.quartz.jobStore.class", "org.springframework.scheduling.quartz.LocalDataSourceJobStore"); +// // 集群配置 +// prop.put("org.quartz.jobStore.isClustered", "true"); +// prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000"); +// prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1"); +// prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true"); +// +// // sqlserver 启用 +// // prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?"); +// prop.put("org.quartz.jobStore.misfireThreshold", "12000"); +// prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_"); +// factory.setQuartzProperties(prop); +// +// factory.setSchedulerName("RuoyiScheduler"); +// // 延时启动 +// factory.setStartupDelay(1); +// factory.setApplicationContextSchedulerContextKey("applicationContextKey"); +// // 可选,QuartzScheduler +// // 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 +// factory.setOverwriteExistingJobs(true); +// // 设置自动启动,默认为true +// factory.setAutoStartup(true); +// +// return factory; +// } +//} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/controller/SysJobController.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/controller/SysJobController.java new file mode 100644 index 0000000..4b02ba6 --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/controller/SysJobController.java @@ -0,0 +1,186 @@ +package com.dcsoft.job.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.quartz.SchedulerException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.core.constant.Constants; +import com.dcsoft.common.core.exception.job.TaskException; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDataInfo; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.job.domain.SysJob; +import com.dcsoft.job.service.ISysJobService; +import com.dcsoft.job.util.CronUtils; +import com.dcsoft.job.util.ScheduleUtils; + +/** + * 调度任务信息操作处理 + * + * @author dcsoft + */ +@RestController +@RequestMapping("/job") +public class SysJobController extends BaseController +{ + @Autowired + private ISysJobService jobService; + + /** + * 查询定时任务列表 + */ + @RequiresPermissions("monitor:job:list") + @GetMapping("/list") + public TableDataInfo list(SysJob sysJob) + { + startPage(); + List list = jobService.selectJobList(sysJob); + return getDataTable(list); + } + + /** + * 导出定时任务列表 + */ + @RequiresPermissions("monitor:job:export") + @Log(title = "定时任务", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysJob sysJob) + { + List list = jobService.selectJobList(sysJob); + ExcelUtil util = new ExcelUtil(SysJob.class); + util.exportExcel(response, list, "定时任务"); + } + + /** + * 获取定时任务详细信息 + */ + @RequiresPermissions("monitor:job:query") + @GetMapping(value = "/{jobId}") + public AjaxResult getInfo(@PathVariable("jobId") Long jobId) + { + return success(jobService.selectJobById(jobId)); + } + + /** + * 新增定时任务 + */ + @RequiresPermissions("monitor:job:add") + @Log(title = "定时任务", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SysJob job) throws SchedulerException, TaskException + { + if (!CronUtils.isValid(job.getCronExpression())) + { + return error("新增任务'" + job.getJobName() + "'失败,Cron表达式不正确"); + } + else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI)) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.LOOKUP_LDAP, Constants.LOOKUP_LDAPS })) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS })) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR)) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串存在违规"); + } + else if (!ScheduleUtils.whiteList(job.getInvokeTarget())) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不在白名单内"); + } + job.setCreateBy(SecurityUtils.getUsername()); + return toAjax(jobService.insertJob(job)); + } + + /** + * 修改定时任务 + */ + @RequiresPermissions("monitor:job:edit") + @Log(title = "定时任务", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysJob job) throws SchedulerException, TaskException + { + if (!CronUtils.isValid(job.getCronExpression())) + { + return error("修改任务'" + job.getJobName() + "'失败,Cron表达式不正确"); + } + else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI)) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.LOOKUP_LDAP, Constants.LOOKUP_LDAPS })) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS })) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR)) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串存在违规"); + } + else if (!ScheduleUtils.whiteList(job.getInvokeTarget())) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不在白名单内"); + } + job.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(jobService.updateJob(job)); + } + + /** + * 定时任务状态修改 + */ + @RequiresPermissions("monitor:job:changeStatus") + @Log(title = "定时任务", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public AjaxResult changeStatus(@RequestBody SysJob job) throws SchedulerException + { + SysJob newJob = jobService.selectJobById(job.getJobId()); + newJob.setStatus(job.getStatus()); + return toAjax(jobService.changeStatus(newJob)); + } + + /** + * 定时任务立即执行一次 + */ + @RequiresPermissions("monitor:job:changeStatus") + @Log(title = "定时任务", businessType = BusinessType.UPDATE) + @PutMapping("/run") + public AjaxResult run(@RequestBody SysJob job) throws SchedulerException + { + boolean result = jobService.run(job); + return result ? success() : error("任务不存在或已过期!"); + } + + /** + * 删除定时任务 + */ + @RequiresPermissions("monitor:job:remove") + @Log(title = "定时任务", businessType = BusinessType.DELETE) + @DeleteMapping("/{jobIds}") + public AjaxResult remove(@PathVariable Long[] jobIds) throws SchedulerException, TaskException + { + jobService.deleteJobByIds(jobIds); + return success(); + } +} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/controller/SysJobLogController.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/controller/SysJobLogController.java new file mode 100644 index 0000000..7e9a2a3 --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/controller/SysJobLogController.java @@ -0,0 +1,91 @@ +package com.dcsoft.job.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDataInfo; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.job.domain.SysJobLog; +import com.dcsoft.job.service.ISysJobLogService; + +/** + * 调度日志操作处理 + * + * @author dcsoft + */ +@RestController +@RequestMapping("/job/log") +public class SysJobLogController extends BaseController +{ + @Autowired + private ISysJobLogService jobLogService; + + /** + * 查询定时任务调度日志列表 + */ + @RequiresPermissions("monitor:job:list") + @GetMapping("/list") + public TableDataInfo list(SysJobLog sysJobLog) + { + startPage(); + List list = jobLogService.selectJobLogList(sysJobLog); + return getDataTable(list); + } + + /** + * 导出定时任务调度日志列表 + */ + @RequiresPermissions("monitor:job:export") + @Log(title = "任务调度日志", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysJobLog sysJobLog) + { + List list = jobLogService.selectJobLogList(sysJobLog); + ExcelUtil util = new ExcelUtil(SysJobLog.class); + util.exportExcel(response, list, "调度日志"); + } + + /** + * 根据调度编号获取详细信息 + */ + @RequiresPermissions("monitor:job:query") + @GetMapping(value = "/{jobLogId}") + public AjaxResult getInfo(@PathVariable Long jobLogId) + { + return success(jobLogService.selectJobLogById(jobLogId)); + } + + /** + * 删除定时任务调度日志 + */ + @RequiresPermissions("monitor:job:remove") + @Log(title = "定时任务调度日志", businessType = BusinessType.DELETE) + @DeleteMapping("/{jobLogIds}") + public AjaxResult remove(@PathVariable Long[] jobLogIds) + { + return toAjax(jobLogService.deleteJobLogByIds(jobLogIds)); + } + + /** + * 清空定时任务调度日志 + */ + @RequiresPermissions("monitor:job:remove") + @Log(title = "调度日志", businessType = BusinessType.CLEAN) + @DeleteMapping("/clean") + public AjaxResult clean() + { + jobLogService.cleanJobLog(); + return success(); + } +} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/domain/DeviceVo.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/domain/DeviceVo.java new file mode 100644 index 0000000..734e7eb --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/domain/DeviceVo.java @@ -0,0 +1,11 @@ +package com.dcsoft.job.domain; + +import lombok.Data; + +@Data +public class DeviceVo { + + private String ip; + private String password; + private String state; +} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/domain/HolidayVo.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/domain/HolidayVo.java new file mode 100644 index 0000000..9b2eec2 --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/domain/HolidayVo.java @@ -0,0 +1,33 @@ +package com.dcsoft.job.domain; + +public class HolidayVo { + private String data;//日期 + + private String status;//状态:0工作日/1周末/2法定节假日/3节假日调休补班 + + private String msg;//描述 + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } +} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/domain/KqHoliday.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/domain/KqHoliday.java new file mode 100644 index 0000000..8b5c1ec --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/domain/KqHoliday.java @@ -0,0 +1,130 @@ +package com.dcsoft.job.domain; + + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.Date; + +/** + * 假期设置对象 kq_holiday + * + * @author dcsoft + * @date 2023-01-11 + */ +public class KqHoliday extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 假期id */ + private Long holidayId; + + /** 假期时长 */ + @Excel(name = "假期时长") + private Long timeStamp; + + /** 假期时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "假期时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date time; + + /** 删除标志(0代表存在 2代表删除) */ + private String delFlag; + + private Long selectTimeStep; + + private Long startTimeStep; + + private Long endTimeStep; + + private String status; + + + + + public void setHolidayId(Long holidayId) + { + this.holidayId = holidayId; + } + + public Long getHolidayId() + { + return holidayId; + } + public void setTimeStamp(Long timeStamp) + { + this.timeStamp = timeStamp; + } + + public Long getTimeStamp() + { + return timeStamp; + } + public void setTime(Date time) + { + this.time = time; + } + + public Date getTime() + { + return time; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + public Long getSelectTimeStep() { + return selectTimeStep; + } + + public void setSelectTimeStep(Long selectTimeStep) { + this.selectTimeStep = selectTimeStep; + } + + public Long getStartTimeStep() { + return startTimeStep; + } + + public void setStartTimeStep(Long startTimeStep) { + this.startTimeStep = startTimeStep; + } + + public Long getEndTimeStep() { + return endTimeStep; + } + + public void setEndTimeStep(Long endTimeStep) { + this.endTimeStep = endTimeStep; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("holidayId", getHolidayId()) + .append("timeStamp", getTimeStamp()) + .append("time", getTime()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/domain/SysJob.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/domain/SysJob.java new file mode 100644 index 0000000..146a6dc --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/domain/SysJob.java @@ -0,0 +1,171 @@ +package com.dcsoft.job.domain; + +import java.util.Date; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.annotation.Excel.ColumnType; +import com.dcsoft.common.core.constant.ScheduleConstants; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.web.domain.BaseEntity; +import com.dcsoft.job.util.CronUtils; + +/** + * 定时任务调度表 sys_job + * + * @author dcsoft + */ +public class SysJob extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 任务ID */ + @Excel(name = "任务序号", cellType = ColumnType.NUMERIC) + private Long jobId; + + /** 任务名称 */ + @Excel(name = "任务名称") + private String jobName; + + /** 任务组名 */ + @Excel(name = "任务组名") + private String jobGroup; + + /** 调用目标字符串 */ + @Excel(name = "调用目标字符串") + private String invokeTarget; + + /** cron执行表达式 */ + @Excel(name = "执行表达式 ") + private String cronExpression; + + /** cron计划策略 */ + @Excel(name = "计划策略 ", readConverterExp = "0=默认,1=立即触发执行,2=触发一次执行,3=不触发立即执行") + private String misfirePolicy = ScheduleConstants.MISFIRE_DEFAULT; + + /** 是否并发执行(0允许 1禁止) */ + @Excel(name = "并发执行", readConverterExp = "0=允许,1=禁止") + private String concurrent; + + /** 任务状态(0正常 1暂停) */ + @Excel(name = "任务状态", readConverterExp = "0=正常,1=暂停") + private String status; + + public Long getJobId() + { + return jobId; + } + + public void setJobId(Long jobId) + { + this.jobId = jobId; + } + + @NotBlank(message = "任务名称不能为空") + @Size(min = 0, max = 64, message = "任务名称不能超过64个字符") + public String getJobName() + { + return jobName; + } + + public void setJobName(String jobName) + { + this.jobName = jobName; + } + + public String getJobGroup() + { + return jobGroup; + } + + public void setJobGroup(String jobGroup) + { + this.jobGroup = jobGroup; + } + + @NotBlank(message = "调用目标字符串不能为空") + @Size(min = 0, max = 500, message = "调用目标字符串长度不能超过500个字符") + public String getInvokeTarget() + { + return invokeTarget; + } + + public void setInvokeTarget(String invokeTarget) + { + this.invokeTarget = invokeTarget; + } + + @NotBlank(message = "Cron执行表达式不能为空") + @Size(min = 0, max = 255, message = "Cron执行表达式不能超过255个字符") + public String getCronExpression() + { + return cronExpression; + } + + public void setCronExpression(String cronExpression) + { + this.cronExpression = cronExpression; + } + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + public Date getNextValidTime() + { + if (StringUtils.isNotEmpty(cronExpression)) + { + return CronUtils.getNextExecution(cronExpression); + } + return null; + } + + public String getMisfirePolicy() + { + return misfirePolicy; + } + + public void setMisfirePolicy(String misfirePolicy) + { + this.misfirePolicy = misfirePolicy; + } + + public String getConcurrent() + { + return concurrent; + } + + public void setConcurrent(String concurrent) + { + this.concurrent = concurrent; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("jobId", getJobId()) + .append("jobName", getJobName()) + .append("jobGroup", getJobGroup()) + .append("cronExpression", getCronExpression()) + .append("nextValidTime", getNextValidTime()) + .append("misfirePolicy", getMisfirePolicy()) + .append("concurrent", getConcurrent()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/domain/SysJobLog.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/domain/SysJobLog.java new file mode 100644 index 0000000..2b1031a --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/domain/SysJobLog.java @@ -0,0 +1,155 @@ +package com.dcsoft.job.domain; + +import java.util.Date; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; + +/** + * 定时任务调度日志表 sys_job_log + * + * @author dcsoft + */ +public class SysJobLog extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** ID */ + @Excel(name = "日志序号") + private Long jobLogId; + + /** 任务名称 */ + @Excel(name = "任务名称") + private String jobName; + + /** 任务组名 */ + @Excel(name = "任务组名") + private String jobGroup; + + /** 调用目标字符串 */ + @Excel(name = "调用目标字符串") + private String invokeTarget; + + /** 日志信息 */ + @Excel(name = "日志信息") + private String jobMessage; + + /** 执行状态(0正常 1失败) */ + @Excel(name = "执行状态", readConverterExp = "0=正常,1=失败") + private String status; + + /** 异常信息 */ + @Excel(name = "异常信息") + private String exceptionInfo; + + /** 开始时间 */ + private Date startTime; + + /** 停止时间 */ + private Date stopTime; + + public Long getJobLogId() + { + return jobLogId; + } + + public void setJobLogId(Long jobLogId) + { + this.jobLogId = jobLogId; + } + + public String getJobName() + { + return jobName; + } + + public void setJobName(String jobName) + { + this.jobName = jobName; + } + + public String getJobGroup() + { + return jobGroup; + } + + public void setJobGroup(String jobGroup) + { + this.jobGroup = jobGroup; + } + + public String getInvokeTarget() + { + return invokeTarget; + } + + public void setInvokeTarget(String invokeTarget) + { + this.invokeTarget = invokeTarget; + } + + public String getJobMessage() + { + return jobMessage; + } + + public void setJobMessage(String jobMessage) + { + this.jobMessage = jobMessage; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getExceptionInfo() + { + return exceptionInfo; + } + + public void setExceptionInfo(String exceptionInfo) + { + this.exceptionInfo = exceptionInfo; + } + + public Date getStartTime() + { + return startTime; + } + + public void setStartTime(Date startTime) + { + this.startTime = startTime; + } + + public Date getStopTime() + { + return stopTime; + } + + public void setStopTime(Date stopTime) + { + this.stopTime = stopTime; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("jobLogId", getJobLogId()) + .append("jobName", getJobName()) + .append("jobGroup", getJobGroup()) + .append("jobMessage", getJobMessage()) + .append("status", getStatus()) + .append("exceptionInfo", getExceptionInfo()) + .append("startTime", getStartTime()) + .append("stopTime", getStopTime()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/domain/VisitorVo.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/domain/VisitorVo.java new file mode 100644 index 0000000..09c0530 --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/domain/VisitorVo.java @@ -0,0 +1,10 @@ +package com.dcsoft.job.domain; + +import lombok.Data; + +@Data +public class VisitorVo { + private String guid; + private String faceGuid; + private String userId; +} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/mapper/KqHolidayMapper.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/mapper/KqHolidayMapper.java new file mode 100644 index 0000000..c002840 --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/mapper/KqHolidayMapper.java @@ -0,0 +1,68 @@ +package com.dcsoft.job.mapper; + + + +import com.dcsoft.job.domain.KqHoliday; + +import java.util.List; + +/** + * 假期设置Mapper接口 + * + * @author dcsoft + * @date 2023-01-11 + */ +public interface KqHolidayMapper +{ + /** + * 查询假期设置 + * + * @param holidayId 假期设置主键 + * @return 假期设置 + */ + public KqHoliday selectKqHolidayByHolidayId(Long holidayId); + + /** + * 查询假期设置列表 + * + * @param kqHoliday 假期设置 + * @return 假期设置集合 + */ + public List selectKqHolidayList(KqHoliday kqHoliday); + + /** + * 新增假期设置 + * + * @param kqHoliday 假期设置 + * @return 结果 + */ + public int insertKqHoliday(KqHoliday kqHoliday); + + /** + * 修改假期设置 + * + * @param kqHoliday 假期设置 + * @return 结果 + */ + public int updateKqHoliday(KqHoliday kqHoliday); + + /** + * 删除假期设置 + * + * @param holidayId 假期设置主键 + * @return 结果 + */ + public int deleteKqHolidayByHolidayId(Long holidayId); + + /** + * 批量删除假期设置 + * + * @param holidayIds 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteKqHolidayByHolidayIds(Long[] holidayIds); + + public KqHoliday selectKqHolidayByHolidayTimeStamp(Long timeStamp); + + public int deleteKqHolidayByHolidayTimeStamp(Long holidayId); +} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/mapper/SysJobLogMapper.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/mapper/SysJobLogMapper.java new file mode 100644 index 0000000..3ec4e37 --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/mapper/SysJobLogMapper.java @@ -0,0 +1,94 @@ +package com.dcsoft.job.mapper; + +import java.util.List; + +import com.dcsoft.job.domain.DeviceVo; +import com.dcsoft.job.domain.SysJobLog; +import com.dcsoft.job.domain.VisitorVo; + +/** + * 调度任务日志信息 数据层 + * + * @author dcsoft + */ +public interface SysJobLogMapper +{ + /** + * 获取quartz调度器日志的计划任务 + * + * @param jobLog 调度日志信息 + * @return 调度任务日志集合 + */ + public List selectJobLogList(SysJobLog jobLog); + + /** + * 查询所有调度任务日志 + * + * @return 调度任务日志列表 + */ + public List selectJobLogAll(); + + /** + * 通过调度任务日志ID查询调度信息 + * + * @param jobLogId 调度任务日志ID + * @return 调度任务日志对象信息 + */ + public SysJobLog selectJobLogById(Long jobLogId); + + /** + * 新增任务日志 + * + * @param jobLog 调度日志信息 + * @return 结果 + */ + public int insertJobLog(SysJobLog jobLog); + + /** + * 批量删除调度日志信息 + * + * @param logIds 需要删除的数据ID + * @return 结果 + */ + public int deleteJobLogByIds(Long[] logIds); + + /** + * 删除任务日志 + * + * @param jobId 调度日志ID + * @return 结果 + */ + public int deleteJobLogById(Long jobId); + + /** + * 清空任务日志 + */ + public void cleanJobLog(); + + List queryDevice(List list); + + /** + * 刷新梯口设备在线离线状态 + * @param deviceVos + */ + void updateLadderState(List deviceVos); + + /** + * 查询访guid和faceGuid + * @return + */ + List queryGuidAndFaceGuid(); + + String queryPointId(String userId); + + /** + * 查询通行设备 + * @return + */ + List queryDeviceInfo(); + + /** + * 定时签离访客人员 + */ + void updateVisitorSignOff(); +} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/mapper/SysJobMapper.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/mapper/SysJobMapper.java new file mode 100644 index 0000000..12d3896 --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/mapper/SysJobMapper.java @@ -0,0 +1,67 @@ +package com.dcsoft.job.mapper; + +import java.util.List; +import com.dcsoft.job.domain.SysJob; + +/** + * 调度任务信息 数据层 + * + * @author dcsoft + */ +public interface SysJobMapper +{ + /** + * 查询调度任务日志集合 + * + * @param job 调度信息 + * @return 操作日志集合 + */ + public List selectJobList(SysJob job); + + /** + * 查询所有调度任务 + * + * @return 调度任务列表 + */ + public List selectJobAll(); + + /** + * 通过调度ID查询调度任务信息 + * + * @param jobId 调度ID + * @return 角色对象信息 + */ + public SysJob selectJobById(Long jobId); + + /** + * 通过调度ID删除调度任务信息 + * + * @param jobId 调度ID + * @return 结果 + */ + public int deleteJobById(Long jobId); + + /** + * 批量删除调度任务信息 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteJobByIds(Long[] ids); + + /** + * 修改调度任务信息 + * + * @param job 调度任务信息 + * @return 结果 + */ + public int updateJob(SysJob job); + + /** + * 新增调度任务信息 + * + * @param job 调度任务信息 + * @return 结果 + */ + public int insertJob(SysJob job); +} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/service/IKqHolidayService.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/service/IKqHolidayService.java new file mode 100644 index 0000000..7e5277f --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/service/IKqHolidayService.java @@ -0,0 +1,69 @@ +package com.dcsoft.job.service; + + + +import com.dcsoft.job.domain.KqHoliday; + +import java.util.List; + +/** + * 假期设置Service接口 + * + * @author dcsoft + * @date 2023-01-11 + */ +public interface IKqHolidayService +{ + /** + * 查询假期设置 + * + * @param holidayId 假期设置主键 + * @return 假期设置 + */ + public KqHoliday selectKqHolidayByHolidayId(Long holidayId); + + /** + * 查询假期设置列表 + * + * @param kqHoliday 假期设置 + * @return 假期设置集合 + */ + public List selectKqHolidayList(KqHoliday kqHoliday); + + /** + * 新增假期设置 + * + * @param kqHoliday 假期设置 + * @return 结果 + */ + public int insertKqHoliday(KqHoliday kqHoliday); + + /** + * 修改假期设置 + * + * @param kqHoliday 假期设置 + * @return 结果 + */ + public int updateKqHoliday(KqHoliday kqHoliday); + + /** + * 批量删除假期设置 + * + * @param holidayIds 需要删除的假期设置主键集合 + * @return 结果 + */ + public int deleteKqHolidayByHolidayIds(Long[] holidayIds); + + /** + * 删除假期设置信息 + * + * @param holidayId 假期设置主键 + * @return 结果 + */ + public int deleteKqHolidayByHolidayId(Long holidayId); + + public KqHoliday selectKqHolidayByHolidayTimeStamp(Long timeStamp); + + public int deleteKqHolidayByHolidayTimeStamp(Long timeStamp); + +} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/service/ISysJobLogService.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/service/ISysJobLogService.java new file mode 100644 index 0000000..6e1a4ad --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/service/ISysJobLogService.java @@ -0,0 +1,81 @@ +package com.dcsoft.job.service; + +import java.io.IOException; +import java.net.UnknownHostException; +import java.util.List; +import com.dcsoft.job.domain.SysJobLog; + +/** + * 定时任务调度日志信息信息 服务层 + * + * @author dcsoft + */ +public interface ISysJobLogService +{ + /** + * 获取quartz调度器日志的计划任务 + * + * @param jobLog 调度日志信息 + * @return 调度任务日志集合 + */ + public List selectJobLogList(SysJobLog jobLog); + + /** + * 通过调度任务日志ID查询调度信息 + * + * @param jobLogId 调度任务日志ID + * @return 调度任务日志对象信息 + */ + public SysJobLog selectJobLogById(Long jobLogId); + + /** + * 新增任务日志 + * + * @param jobLog 调度日志信息 + */ + public void addJobLog(SysJobLog jobLog); + + /** + * 批量删除调度日志信息 + * + * @param logIds 需要删除的日志ID + * @return 结果 + */ + public int deleteJobLogByIds(Long[] logIds); + + /** + * 删除任务日志 + * + * @param jobId 调度日志ID + * @return 结果 + */ + public int deleteJobLogById(Long jobId); + + /** + * 清空任务日志 + */ + public void cleanJobLog(); + + void setDeviceCallBackInfo(String sequence); + + /** + * 刷新梯口设备在线离线状态 + * @param sequence + */ + void updateLadderState(String sequence) throws IOException; + + /** + * 删除宇泛人脸设备访客结束时间的数据 + */ + void deleteVisitorFaceDevice(); + + /** + * 设置宇泛二维码回调地址 + */ + void setQRCodeCallback(String sequence); + + /** + * 定时签离访客人员 + */ + void updateVisitorSignOff(); +} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/service/ISysJobService.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/service/ISysJobService.java new file mode 100644 index 0000000..a875cbf --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/service/ISysJobService.java @@ -0,0 +1,102 @@ +package com.dcsoft.job.service; + +import java.util.List; +import org.quartz.SchedulerException; +import com.dcsoft.common.core.exception.job.TaskException; +import com.dcsoft.job.domain.SysJob; + +/** + * 定时任务调度信息信息 服务层 + * + * @author dcsoft + */ +public interface ISysJobService +{ + /** + * 获取quartz调度器的计划任务 + * + * @param job 调度信息 + * @return 调度任务集合 + */ + public List selectJobList(SysJob job); + + /** + * 通过调度任务ID查询调度信息 + * + * @param jobId 调度任务ID + * @return 调度任务对象信息 + */ + public SysJob selectJobById(Long jobId); + + /** + * 暂停任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int pauseJob(SysJob job) throws SchedulerException; + + /** + * 恢复任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int resumeJob(SysJob job) throws SchedulerException; + + /** + * 删除任务后,所对应的trigger也将被删除 + * + * @param job 调度信息 + * @return 结果 + */ + public int deleteJob(SysJob job) throws SchedulerException; + + /** + * 批量删除调度信息 + * + * @param jobIds 需要删除的任务ID + * @return 结果 + */ + public void deleteJobByIds(Long[] jobIds) throws SchedulerException; + + /** + * 任务调度状态修改 + * + * @param job 调度信息 + * @return 结果 + */ + public int changeStatus(SysJob job) throws SchedulerException; + + /** + * 立即运行任务 + * + * @param job 调度信息 + * @return 结果 + */ + public boolean run(SysJob job) throws SchedulerException; + + /** + * 新增任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int insertJob(SysJob job) throws SchedulerException, TaskException; + + /** + * 更新任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int updateJob(SysJob job) throws SchedulerException, TaskException; + + /** + * 校验cron表达式是否有效 + * + * @param cronExpression 表达式 + * @return 结果 + */ + public boolean checkCronExpressionIsValid(String cronExpression); +} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/service/KqHolidayServiceImpl.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/service/KqHolidayServiceImpl.java new file mode 100644 index 0000000..537c99d --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/service/KqHolidayServiceImpl.java @@ -0,0 +1,118 @@ +package com.dcsoft.job.service; + + +import com.dcsoft.common.core.utils.DateUtils; + +import com.dcsoft.job.domain.KqHoliday; +import com.dcsoft.job.mapper.KqHolidayMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 假期设置Service业务层处理 + * + * @author dcsoft + * @date 2023-01-11 + */ +@Service +public class KqHolidayServiceImpl implements IKqHolidayService +{ + @Autowired + private KqHolidayMapper kqHolidayMapper; + + /** + * 查询假期设置 + * + * @param holidayId 假期设置主键 + * @return 假期设置 + */ + @Override + public KqHoliday selectKqHolidayByHolidayId(Long holidayId) + { + return kqHolidayMapper.selectKqHolidayByHolidayId(holidayId); + } + + /** + * 查询假期设置列表 + * + * @param kqHoliday 假期设置 + * @return 假期设置 + */ + @Override + public List selectKqHolidayList(KqHoliday kqHoliday) + { + return kqHolidayMapper.selectKqHolidayList(kqHoliday); + } + + /** + * 新增假期设置 + * + * @param kqHoliday 假期设置 + * @return 结果 + */ + @Override + public int insertKqHoliday(KqHoliday kqHoliday) + { + kqHoliday.setCreateTime(DateUtils.getNowDate()); + return kqHolidayMapper.insertKqHoliday(kqHoliday); + } + + /** + * 修改假期设置 + * + * @param kqHoliday 假期设置 + * @return 结果 + */ + @Override + public int updateKqHoliday(KqHoliday kqHoliday) + { + kqHoliday.setUpdateTime(DateUtils.getNowDate()); + return kqHolidayMapper.updateKqHoliday(kqHoliday); + } + + /** + * 批量删除假期设置 + * + * @param holidayIds 需要删除的假期设置主键 + * @return 结果 + */ + @Override + public int deleteKqHolidayByHolidayIds(Long[] holidayIds) + { + return kqHolidayMapper.deleteKqHolidayByHolidayIds(holidayIds); + } + + /** + * 删除假期设置信息 + * + * @param holidayId 假期设置主键 + * @return 结果 + */ + @Override + public int deleteKqHolidayByHolidayId(Long holidayId) + { + return kqHolidayMapper.deleteKqHolidayByHolidayId(holidayId); + } + + @Override + public KqHoliday selectKqHolidayByHolidayTimeStamp(Long timeStamp) { + return kqHolidayMapper.selectKqHolidayByHolidayTimeStamp(timeStamp); + } + + /** + * 删除假期设置信息 + * + * @param timeStamp 假期设置主键 + * @return 结果 + */ + @Override + public int deleteKqHolidayByHolidayTimeStamp(Long timeStamp) + { + return kqHolidayMapper.deleteKqHolidayByHolidayTimeStamp(timeStamp); + + } + + +} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/service/SysJobLogServiceImpl.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/service/SysJobLogServiceImpl.java new file mode 100644 index 0000000..676fa29 --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/service/SysJobLogServiceImpl.java @@ -0,0 +1,249 @@ +package com.dcsoft.job.service; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.*; + +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.dcsoft.common.core.constant.Constants; +import com.dcsoft.common.core.enums.exception.CommonExceptionEnum; +import com.dcsoft.common.core.exception.ServiceException; +import com.dcsoft.job.domain.DeviceVo; +import com.dcsoft.job.domain.VisitorVo; +import com.dcsoft.job.util.HttpUtils; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.dcsoft.job.domain.SysJobLog; +import com.dcsoft.job.mapper.SysJobLogMapper; + +/** + * 定时任务调度日志信息 服务层 + * + * @author dcsoft + */ +@Service +@Slf4j +public class SysJobLogServiceImpl implements ISysJobLogService +{ + @Autowired + private SysJobLogMapper jobLogMapper; + + /** + * 获取quartz调度器日志的计划任务 + * + * @param jobLog 调度日志信息 + * @return 调度任务日志集合 + */ + @Override + public List selectJobLogList(SysJobLog jobLog) + { + return jobLogMapper.selectJobLogList(jobLog); + } + + /** + * 通过调度任务日志ID查询调度信息 + * + * @param jobLogId 调度任务日志ID + * @return 调度任务日志对象信息 + */ + @Override + public SysJobLog selectJobLogById(Long jobLogId) + { + return jobLogMapper.selectJobLogById(jobLogId); + } + + /** + * 新增任务日志 + * + * @param jobLog 调度日志信息 + */ + @Override + public void addJobLog(SysJobLog jobLog) + { + jobLogMapper.insertJobLog(jobLog); + } + + /** + * 批量删除调度日志信息 + * + * @param logIds 需要删除的数据ID + * @return 结果 + */ + @Override + public int deleteJobLogByIds(Long[] logIds) + { + return jobLogMapper.deleteJobLogByIds(logIds); + } + + /** + * 删除任务日志 + * + * @param jobId 调度日志ID + */ + @Override + public int deleteJobLogById(Long jobId) + { + return jobLogMapper.deleteJobLogById(jobId); + } + + /** + * 清空任务日志 + */ + @Override + public void cleanJobLog() + { + jobLogMapper.cleanJobLog(); + } + + /** + * 梯控刷卡回调接口设置 + * @param sequence + */ + @Override + public void setDeviceCallBackInfo(String sequence) { + if(StringUtils.isNotEmpty(sequence)){ + String[] split = sequence.split(","); + List list = Arrays.asList(split); + List deviceVos = jobLogMapper.queryDevice(list); + for (DeviceVo deviceVo : deviceVos) { + String body = null; + try { + deviceVo.setIp("http://" + deviceVo.getIp() + ":8090" + "/SetDeviceCallBackInfo"); + body = setDeviceCallBackInfo(deviceVo, "http://192.168.255.52:6609/system/sdk/saveLadderRecord"); + } catch (Exception e) { + continue; + } + log.info("设置设备识别回调ip:" + deviceVo.getIp()); + log.info("设置设备识别回调返回参:" + body); + JSONObject object = JSONObject.parseObject(body); + if(!Constants.CODE.equals(object.get("msg"))) { + throw new ServiceException(CommonExceptionEnum.REQUEST_ERROR.getCode(), "设置设备识别回调接口接口" + + CommonExceptionEnum.REQUEST_ERROR.getMessage() + "设置设备识别回调接口接口异常码" + object.get("msg").toString()); + } + } + } + + } + + private String setDeviceCallBackInfo(DeviceVo deviceVo, String url) { + Map map = new HashMap<>(); + map.put("callbackUrl", url); + map.put("pass", deviceVo.getPassword()); + return HttpUtil.createPost(deviceVo.getIp()).timeout(5000).body(JSON.toJSONString(map)).execute().body(); + } + + /** + * 刷新梯控设备在线离线状态 + * @param sequence + */ + @Override + public void updateLadderState(String sequence) throws IOException { + String[] split = sequence.split(","); + List list = Arrays.asList(split); + List deviceVos = jobLogMapper.queryDevice(list); + for (DeviceVo deviceVo : deviceVos) { + InetAddress address = InetAddress.getByName(deviceVo.getIp()); + boolean isIpReachable = address.isReachable(3000); + if(isIpReachable) { + deviceVo.setState(Constants.ZERO); + } else { + deviceVo.setState(Constants.ONE); + } + } + jobLogMapper.updateLadderState(deviceVos); + } + + /** + * 删除宇泛人脸设备访客结束时间的数据 + */ + @Override + public void deleteVisitorFaceDevice() { + List visitorVo = jobLogMapper.queryGuidAndFaceGuid(); + List list = jobLogMapper.queryDeviceInfo(); + for (VisitorVo vo : visitorVo) { + for (DeviceVo deviceVo : list) { + try { + if(StringUtils.isNotEmpty(vo.getFaceGuid())) { + // 删除照片 + imageDelete(vo.getFaceGuid(), deviceVo.getIp(), deviceVo.getPassword()); + } + + if(StringUtils.isNotEmpty(vo.getGuid())) { + // 删除人员 + personDelete(vo.getGuid(), deviceVo.getIp(), deviceVo.getPassword()); + } + + } catch (Exception e) { + log.error("删除宇泛人脸设备访客结束时间的数据:" + deviceVo.getIp() + "异常", e); + } + } + } + } + + /** + * 设置宇泛二维码回调地址 + */ + @Override + public void setQRCodeCallback(String sequence) { + List list = Arrays.asList(sequence.split(",")); + List deviceVos = jobLogMapper.queryDevice(list); + for (DeviceVo deviceVo : deviceVos) { + String body = null; + try { + deviceVo.setIp("http://" + deviceVo.getIp() + ":8090/device/setQRCodeCallback"); + body = setDeviceCallBackInfo(deviceVo, "http://192.168.255.52:6609/system/sdk/backUrlEwm"); + } catch (Exception e) { + continue; + } + log.info("设置宇泛门镜设备识别回调ip:" + deviceVo.getIp()); + log.info("设置宇泛门镜设备识别回调返回参:" + body); + JSONObject object = JSONObject.parseObject(body); + if(!Constants.CODE.equals(object.get("msg"))) { + throw new ServiceException(CommonExceptionEnum.REQUEST_ERROR.getCode(), "设置宇泛门镜设备识别回调接口接口" + + CommonExceptionEnum.REQUEST_ERROR.getMessage() + "设置宇泛门镜设备识别回调接口接口异常码" + object.get("msg").toString()); + } + } + } + + /** + * 定时签离访客人员 + */ + @Override + public void updateVisitorSignOff() { + jobLogMapper.updateVisitorSignOff(); + } + + private String personDelete(String id, String ip, String pass) { + String url="http://"+ip+":8090/person/delete"; + Map paramMap=new HashMap(); + paramMap.put("pass",pass); + paramMap.put("id",id); + String response= HttpUtils.sendxwwwform(url,paramMap); + return response; + } + + private String imageDelete(String faceId, String ip, String pass) { + String url="http://"+ip+":8090/face/delete"; + Map paramMap=new HashMap(); + paramMap.put("pass",pass); + paramMap.put("faceId",faceId);//可不传,设为空 + String response= HttpUtils.sendxwwwform(url,paramMap); + return response; + } + + /** + * 查询设备信息接口 + */ + private String getDeviceInfo(DeviceVo deviceVo) { + Map map = new HashMap<>(); + map.put("pass", deviceVo.getPassword()); + map.put("idcardnum", "11111111"); + return HttpUtil.createGet("http://" + deviceVo.getIp() + ":8090" + "/cardinfo/find").timeout(5000).body(JSON.toJSONString(map)).execute().body(); + } + +} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/service/SysJobServiceImpl.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/service/SysJobServiceImpl.java new file mode 100644 index 0000000..219931f --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/service/SysJobServiceImpl.java @@ -0,0 +1,260 @@ +package com.dcsoft.job.service; + +import java.util.List; +import javax.annotation.PostConstruct; +import org.quartz.JobDataMap; +import org.quartz.JobKey; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.dcsoft.common.core.constant.ScheduleConstants; +import com.dcsoft.common.core.exception.job.TaskException; +import com.dcsoft.job.domain.SysJob; +import com.dcsoft.job.mapper.SysJobMapper; +import com.dcsoft.job.util.CronUtils; +import com.dcsoft.job.util.ScheduleUtils; + +/** + * 定时任务调度信息 服务层 + * + * @author dcsoft + */ +@Service +public class SysJobServiceImpl implements ISysJobService +{ + @Autowired + private Scheduler scheduler; + + @Autowired + private SysJobMapper jobMapper; + + /** + * 项目启动时,初始化定时器 主要是防止手动修改数据库导致未同步到定时任务处理(注:不能手动修改数据库ID和任务组名,否则会导致脏数据) + */ + @PostConstruct + public void init() throws SchedulerException, TaskException + { + scheduler.clear(); + List jobList = jobMapper.selectJobAll(); + for (SysJob job : jobList) + { + ScheduleUtils.createScheduleJob(scheduler, job); + } + } + + /** + * 获取quartz调度器的计划任务列表 + * + * @param job 调度信息 + * @return + */ + @Override + public List selectJobList(SysJob job) + { + return jobMapper.selectJobList(job); + } + + /** + * 通过调度任务ID查询调度信息 + * + * @param jobId 调度任务ID + * @return 调度任务对象信息 + */ + @Override + public SysJob selectJobById(Long jobId) + { + return jobMapper.selectJobById(jobId); + } + + /** + * 暂停任务 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int pauseJob(SysJob job) throws SchedulerException + { + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + job.setStatus(ScheduleConstants.Status.PAUSE.getValue()); + int rows = jobMapper.updateJob(job); + if (rows > 0) + { + scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + return rows; + } + + /** + * 恢复任务 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int resumeJob(SysJob job) throws SchedulerException + { + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + job.setStatus(ScheduleConstants.Status.NORMAL.getValue()); + int rows = jobMapper.updateJob(job); + if (rows > 0) + { + scheduler.resumeJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + return rows; + } + + /** + * 删除任务后,所对应的trigger也将被删除 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int deleteJob(SysJob job) throws SchedulerException + { + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + int rows = jobMapper.deleteJobById(jobId); + if (rows > 0) + { + scheduler.deleteJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + return rows; + } + + /** + * 批量删除调度信息 + * + * @param jobIds 需要删除的任务ID + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteJobByIds(Long[] jobIds) throws SchedulerException + { + for (Long jobId : jobIds) + { + SysJob job = jobMapper.selectJobById(jobId); + deleteJob(job); + } + } + + /** + * 任务调度状态修改 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int changeStatus(SysJob job) throws SchedulerException + { + int rows = 0; + String status = job.getStatus(); + if (ScheduleConstants.Status.NORMAL.getValue().equals(status)) + { + rows = resumeJob(job); + } + else if (ScheduleConstants.Status.PAUSE.getValue().equals(status)) + { + rows = pauseJob(job); + } + return rows; + } + + /** + * 立即运行任务 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean run(SysJob job) throws SchedulerException + { + boolean result = false; + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + SysJob properties = selectJobById(job.getJobId()); + // 参数 + JobDataMap dataMap = new JobDataMap(); + dataMap.put(ScheduleConstants.TASK_PROPERTIES, properties); + JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup); + if (scheduler.checkExists(jobKey)) + { + result = true; + scheduler.triggerJob(jobKey, dataMap); + } + return result; + } + + /** + * 新增任务 + * + * @param job 调度信息 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int insertJob(SysJob job) throws SchedulerException, TaskException + { + job.setStatus(ScheduleConstants.Status.PAUSE.getValue()); + int rows = jobMapper.insertJob(job); + if (rows > 0) + { + ScheduleUtils.createScheduleJob(scheduler, job); + } + return rows; + } + + /** + * 更新任务的时间表达式 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int updateJob(SysJob job) throws SchedulerException, TaskException + { + SysJob properties = selectJobById(job.getJobId()); + int rows = jobMapper.updateJob(job); + if (rows > 0) + { + updateSchedulerJob(job, properties.getJobGroup()); + } + return rows; + } + + /** + * 更新任务 + * + * @param job 任务对象 + * @param jobGroup 任务组名 + */ + public void updateSchedulerJob(SysJob job, String jobGroup) throws SchedulerException, TaskException + { + Long jobId = job.getJobId(); + // 判断是否存在 + JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup); + if (scheduler.checkExists(jobKey)) + { + // 防止创建时存在数据问题 先移除,然后在执行创建操作 + scheduler.deleteJob(jobKey); + } + ScheduleUtils.createScheduleJob(scheduler, job); + } + + /** + * 校验cron表达式是否有效 + * + * @param cronExpression 表达式 + * @return 结果 + */ + @Override + public boolean checkCronExpressionIsValid(String cronExpression) + { + return CronUtils.isValid(cronExpression); + } +} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/task/RyTask.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/task/RyTask.java new file mode 100644 index 0000000..5c7d204 --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/task/RyTask.java @@ -0,0 +1,190 @@ +package com.dcsoft.job.task; + +import com.dcsoft.common.core.constant.SecurityConstants; +import com.dcsoft.job.domain.HolidayVo; +import com.dcsoft.job.domain.KqHoliday; +import com.dcsoft.job.service.IKqHolidayService; +import com.dcsoft.job.service.ISysJobLogService; +import com.dcsoft.job.util.HolidayUtil; +import com.dcsoft.system.api.RemoteStudentService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import com.dcsoft.common.core.utils.StringUtils; + +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; + +/** + * 定时任务调度测试 + * + * @author dcsoft + */ +@Component("ryTask") +public class RyTask +{ + + @Autowired + private IKqHolidayService holidayService; + + @Autowired + private RemoteStudentService remoteStudentService; + + @Autowired + private ISysJobLogService sysJobLogService; + + + public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i) + { + System.out.println(StringUtils.format("执行多参方法: 字符串类型{},布尔类型{},长整型{},浮点型{},整形{}", s, b, l, d, i)); + } + + public void ryParams(String params) + { + System.out.println("执行有参方法:" + params); + } + + public void ryNoParams() + { + System.out.println("执行无参方法"); + } + + public void holiday() + { + try { + Date date=new Date(); + SimpleDateFormat sdf1=new SimpleDateFormat("yyyy"); + ArrayList list=HolidayUtil.getAllHolidayByYear(sdf1.format(date)); + for(HolidayVo h:list){ + if(!"0".equals(h.getStatus())){ + //添加到节假日库中 + KqHoliday kqHoliday=new KqHoliday(); + kqHoliday.setStatus(h.getStatus()); + SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd"); + try { + kqHoliday.setTime(sdf.parse(h.getData())); + kqHoliday.setTimeStamp(sdf.parse(h.getData()).getTime()); + } catch (ParseException e) { + throw new RuntimeException(e); + } + holidayService.insertKqHoliday(kqHoliday); + + } + } + + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public void gatherMonth() + { + remoteStudentService.gatherMonth(SecurityConstants.INNER); + } + + public void backUp() + { + remoteStudentService.backUp(SecurityConstants.INNER); + } + + public void gather() + { + remoteStudentService.gather(SecurityConstants.INNER); + } + + public void peopleLeave() + { + remoteStudentService.peopleLeave(SecurityConstants.INNER); + + } + + /** + * 新增请假信息 + */ + public void saveAskForLeave() { + remoteStudentService.saveAskForLeave(SecurityConstants.INNER); + } + + /** + * 新增补卡信息 + */ + public void saveCardReplacement() { + remoteStudentService.saveCardReplacement(SecurityConstants.INNER); + } + + /** + * 定时批量下发 + */ + public void batchDistribute() { + remoteStudentService.batchDistribute(SecurityConstants.INNER); + } + + /** + * 定时部门 + */ + public void saveBranchTree() { + remoteStudentService.saveBranchTree(SecurityConstants.INNER); + } + + /** + * 定时人员 + */ + public void saveUserInfo() { + remoteStudentService.saveUserInfo(SecurityConstants.INNER); + } + + /** + * 定时岗位 + */ + public void saveStation() { + remoteStudentService.saveStation(SecurityConstants.INNER); + } + + /** + * 定时批量下发部门人员 + */ + public void batchDown() { + remoteStudentService.batchDown(SecurityConstants.INNER); + } + + /** + * 梯控刷卡回调接口设置 + */ + public void setDeviceCallBackInfo(String sequence) { + sysJobLogService.setDeviceCallBackInfo(sequence); + } + + /** + * 刷新梯口设备在线离线状态 + */ + public void updateLadderState(String sequence) throws IOException { + sysJobLogService.updateLadderState(sequence); + } + + + /** + * 删除宇泛人脸设备访客结束时间的数据 + */ + public void deleteVisitorFaceDevice() { + sysJobLogService.deleteVisitorFaceDevice(); + } + + /** + * 设置宇泛二维码回调地址 + */ + public void setQRCodeCallback(String sequence) { + sysJobLogService.setQRCodeCallback(sequence); + } + + /** + * 定时签离访客人员 + */ + public void updateVisitorSignOff() { + sysJobLogService.updateVisitorSignOff(); + } + + + +} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/AbstractQuartzJob.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/AbstractQuartzJob.java new file mode 100644 index 0000000..ddc973e --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/AbstractQuartzJob.java @@ -0,0 +1,106 @@ +package com.dcsoft.job.util; + +import java.util.Date; +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.dcsoft.common.core.constant.ScheduleConstants; +import com.dcsoft.common.core.utils.ExceptionUtil; +import com.dcsoft.common.core.utils.SpringUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.utils.bean.BeanUtils; +import com.dcsoft.job.domain.SysJob; +import com.dcsoft.job.domain.SysJobLog; +import com.dcsoft.job.service.ISysJobLogService; + +/** + * 抽象quartz调用 + * + * @author dcsoft + */ +public abstract class AbstractQuartzJob implements Job +{ + private static final Logger log = LoggerFactory.getLogger(AbstractQuartzJob.class); + + /** + * 线程本地变量 + */ + private static ThreadLocal threadLocal = new ThreadLocal<>(); + + @Override + public void execute(JobExecutionContext context) throws JobExecutionException + { + SysJob sysJob = new SysJob(); + BeanUtils.copyBeanProp(sysJob, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES)); + try + { + before(context, sysJob); + if (sysJob != null) + { + doExecute(context, sysJob); + } + after(context, sysJob, null); + } + catch (Exception e) + { + log.error("任务执行异常 - :", e); + after(context, sysJob, e); + } + } + + /** + * 执行前 + * + * @param context 工作执行上下文对象 + * @param sysJob 系统计划任务 + */ + protected void before(JobExecutionContext context, SysJob sysJob) + { + threadLocal.set(new Date()); + } + + /** + * 执行后 + * + * @param context 工作执行上下文对象 + * @param sysJob 系统计划任务 + */ + protected void after(JobExecutionContext context, SysJob sysJob, Exception e) + { + Date startTime = threadLocal.get(); + threadLocal.remove(); + + final SysJobLog sysJobLog = new SysJobLog(); + sysJobLog.setJobName(sysJob.getJobName()); + sysJobLog.setJobGroup(sysJob.getJobGroup()); + sysJobLog.setInvokeTarget(sysJob.getInvokeTarget()); + sysJobLog.setStartTime(startTime); + sysJobLog.setStopTime(new Date()); + long runMs = sysJobLog.getStopTime().getTime() - sysJobLog.getStartTime().getTime(); + sysJobLog.setJobMessage(sysJobLog.getJobName() + " 总共耗时:" + runMs + "毫秒"); + if (e != null) + { + sysJobLog.setStatus("1"); + String errorMsg = StringUtils.substring(ExceptionUtil.getExceptionMessage(e), 0, 2000); + sysJobLog.setExceptionInfo(errorMsg); + } + else + { + sysJobLog.setStatus("0"); + } + + // 写入数据库当中 + SpringUtils.getBean(ISysJobLogService.class).addJobLog(sysJobLog); + } + + /** + * 执行方法,由子类重载 + * + * @param context 工作执行上下文对象 + * @param sysJob 系统计划任务 + * @throws Exception 执行过程中的异常 + */ + protected abstract void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception; +} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/CronUtils.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/CronUtils.java new file mode 100644 index 0000000..f5ea1df --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/CronUtils.java @@ -0,0 +1,63 @@ +package com.dcsoft.job.util; + +import java.text.ParseException; +import java.util.Date; +import org.quartz.CronExpression; + +/** + * cron表达式工具类 + * + * @author dcsoft + * + */ +public class CronUtils +{ + /** + * 返回一个布尔值代表一个给定的Cron表达式的有效性 + * + * @param cronExpression Cron表达式 + * @return boolean 表达式是否有效 + */ + public static boolean isValid(String cronExpression) + { + return CronExpression.isValidExpression(cronExpression); + } + + /** + * 返回一个字符串值,表示该消息无效Cron表达式给出有效性 + * + * @param cronExpression Cron表达式 + * @return String 无效时返回表达式错误描述,如果有效返回null + */ + public static String getInvalidMessage(String cronExpression) + { + try + { + new CronExpression(cronExpression); + return null; + } + catch (ParseException pe) + { + return pe.getMessage(); + } + } + + /** + * 返回下一个执行时间根据给定的Cron表达式 + * + * @param cronExpression Cron表达式 + * @return Date 下次Cron表达式执行时间 + */ + public static Date getNextExecution(String cronExpression) + { + try + { + CronExpression cron = new CronExpression(cronExpression); + return cron.getNextValidTimeAfter(new Date(System.currentTimeMillis())); + } + catch (ParseException e) + { + throw new IllegalArgumentException(e.getMessage()); + } + } +} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/HolidayUtil.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/HolidayUtil.java new file mode 100644 index 0000000..f209620 --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/HolidayUtil.java @@ -0,0 +1,117 @@ +package com.dcsoft.job.util; + + +import com.dcsoft.job.domain.HolidayVo; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * 节假日工具类 + */ +public class HolidayUtil { + + /** + * 发送get请求 + */ + private static String get(String url){ + StringBuilder inputLine = new StringBuilder(); + String read; + try { + HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection(); + urlConnection.setReadTimeout(30 * 1000); + urlConnection.setConnectTimeout(30 * 1000); + urlConnection.setRequestProperty("Charset", "UTF-8"); + urlConnection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36)"); + BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), StandardCharsets.UTF_8)); + while ((read = in.readLine()) != null) { + inputLine.append(read); + } + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + return inputLine.toString(); + } + + /** + * 调用免费API查询全年工作日、周末、法定节假日、节假日调休补班数据 + * 1、调用 https://api.apihubs.cn/holiday/get?size=500&year=2021 查询全年日历(含周末) + * 2、调用 https://timor.tech/api/holiday/year/2021 查询全年节假日、调休 + */ + public static ArrayList getAllHolidayByYear(String year) throws IOException { + SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd"); + ArrayList holidayVoList = new ArrayList<>(); + HashMap hashMap = new HashMap<>(); + + ObjectMapper mapper = new ObjectMapper(); + //查询全年日历包含周末 + /*String allDayJson = HolidayUtil.get("https://api.apihubs.cn/holiday/get?size=500&year="+year); + Map allDayMap = mapper.readValue(allDayJson,Map.class); + Map allDayData = (Map)allDayMap.get("data"); + List allDayDataList = (List)allDayData.get("list"); + allDayDataList.forEach((value) -> { + HolidayVo holidayVo = new HolidayVo(); + + Map value1 = (Map) value; + String YEAR = value1.get("year").toString(); + String MONTH = value1.get("month").toString().replace(YEAR,""); + String DAY = value1.get("date").toString().replace(YEAR+MONTH,""); + + holidayVo.setData(YEAR + "-" + MONTH + "-" + DAY); + String STATUS = "0"; + String msg = "工作日"; + if("1".equals(value1.get("weekend").toString())){ + STATUS = "1"; + msg = "周末"; + } + holidayVo.setStatus(STATUS); + holidayVo.setMsg(msg); + + hashMap.put(holidayVo.getData(),holidayVo); + });*/ + + //查询全年节假日、调休 + String holidayJson = HolidayUtil.get("https://timor.tech/api/holiday/year/"+year + "/"); + Map holidayMap = mapper.readValue(holidayJson,Map.class); + //LinkedHashMap holidayList = (LinkedHashMap)holidayMap.get("holiday"); + Map> holiday= (Map>) holidayMap.get("holiday"); + Set strings = holiday.keySet(); + for(String str:strings){ + HolidayVo holidayVo = new HolidayVo(); + Map stringObjectMap = holiday.get(str); + Boolean holidays = (Boolean) stringObjectMap.get("holiday"); + if(holidays){ + holidayVo.setStatus("2"); + }else{ + holidayVo.setStatus("1"); + } + String date = (String) stringObjectMap.get("date"); + String dateTime = date; + holidayVo.setData(dateTime); + + holidayVoList.add(holidayVo); + } + + //排序 + holidayVoList.sort((a,b)->{ + try { + return sf.parse(a.getData()).compareTo(sf.parse(b.getData())); + } catch (ParseException e) { + e.printStackTrace(); + } + return 1; + }); + + return holidayVoList; + } +} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/HttpUtils.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/HttpUtils.java new file mode 100644 index 0000000..430ad65 --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/HttpUtils.java @@ -0,0 +1,337 @@ +package com.dcsoft.job.util; + +import com.alibaba.fastjson.JSONObject; +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.util.*; +import java.util.Map.Entry; + +public class HttpUtils { + + public static String getData(String url) { + CloseableHttpClient httpClient = null; + CloseableHttpResponse response = null; + String result = ""; + try { + // 通过址默认配置创建一个httpClient实例 + httpClient = HttpClients.createDefault(); + // 创建httpGet远程连接实例 + HttpGet httpGet = new HttpGet(url); + // 设置请求头信息,鉴权 + httpGet.setHeader("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0"); + // 设置配置请求参数 + RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 连接主机服务超时时间 + .setConnectionRequestTimeout(35000)// 请求超时时间 + .setSocketTimeout(60000)// 数据读取超时时间 + .build(); + // 为httpGet实例设置配置 + httpGet.setConfig(requestConfig); + // 执行get请求得到返回对象 + response = httpClient.execute(httpGet); + // 通过返回对象获取返回数据 + HttpEntity entity = response.getEntity(); + // 通过EntityUtils中的toString方法将结果转换为字符串 + result = EntityUtils.toString(entity); + } catch (ClientProtocolException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + // 关闭资源 + if (null != response) { + try { + response.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (null != httpClient) { + try { + httpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return result; + } + + public static String postData(String url, Map paramMap) { + HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); + HttpPost post = new HttpPost(url); + String result = ""; + try (CloseableHttpClient closeableHttpClient = httpClientBuilder.build()) { + // HttpEntity entity = new StringEntity(jsonStrData); + // 修复 POST json 导致中文乱码 + HttpEntity entity = new StringEntity(JSONObject.toJSONString(paramMap), "UTF-8"); + post.setEntity(entity); + post.setHeader("Content-type", "application/json"); + HttpResponse resp = closeableHttpClient.execute(post); + try { + InputStream respIs = resp.getEntity().getContent(); + byte[] respBytes = IOUtils.toByteArray(respIs); + result = new String(respBytes, Charset.forName("UTF-8")); + } catch (Exception e) { + e.printStackTrace(); + } + return result; + } catch (IOException e) { + e.printStackTrace(); + } + return result; + } + + public static String postDataJson(String url, JSONObject paramMap) { + HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); + HttpPost post = new HttpPost(url); + String result = ""; + try (CloseableHttpClient closeableHttpClient = httpClientBuilder.build()) { + // HttpEntity entity = new StringEntity(jsonStrData); + // 修复 POST json 导致中文乱码 + HttpEntity entity = new StringEntity(paramMap.toJSONString(), "UTF-8"); + post.setEntity(entity); + post.setHeader("Content-type", "application/json"); + HttpResponse resp = closeableHttpClient.execute(post); + try { + InputStream respIs = resp.getEntity().getContent(); + byte[] respBytes = IOUtils.toByteArray(respIs); + result = new String(respBytes, Charset.forName("UTF-8")); + } catch (Exception e) { + e.printStackTrace(); + } + return result; + } catch (IOException e) { + e.printStackTrace(); + } + return result; + } + + + /** + * form表单提交 + * + * @param url + * @param paramMap + * @return + */ + public static String sendxwwwform(String url, Map paramMap) { + CloseableHttpClient httpClient = null; + CloseableHttpResponse httpResponse = null; + String result = ""; + // 创建httpClient实例 + httpClient = HttpClients.createDefault(); + // 创建httpPost远程连接实例 + HttpPost httpPost = new HttpPost(url); + // 配置请求参数实例 + RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 设置连接主机服务超时时间 + .setConnectionRequestTimeout(35000)// 设置连接请求超时时间 + .setSocketTimeout(60000)// 设置读取数据连接超时时间 + .build(); + // 为httpPost实例设置配置 + httpPost.setConfig(requestConfig); + // 设置请求头 + httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded"); + // 封装post请求参数 + if (null != paramMap && paramMap.size() > 0) { + List nvps = new ArrayList(); + // 通过map集成entrySet方法获取entity + Set> entrySet = paramMap.entrySet(); + // 循环遍历,获取迭代器 + Iterator> iterator = entrySet.iterator(); + while (iterator.hasNext()) { + Entry mapEntry = iterator.next(); + nvps.add(new BasicNameValuePair(mapEntry.getKey(), mapEntry.getValue().toString())); + } + + // 为httpPost设置封装好的请求参数 + try { + httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8")); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } + try { + // httpClient对象执行post请求,并返回响应参数对象 + httpResponse = httpClient.execute(httpPost); + // 从响应对象中获取响应内容 + HttpEntity entity = httpResponse.getEntity(); + result = EntityUtils.toString(entity); + } catch (ClientProtocolException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + // 关闭资源 + if (null != httpResponse) { + try { + httpResponse.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (null != httpClient) { + try { + httpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return result; + } + + public static String getUrl(String url,Map headMap,String projectGuid ) { + CloseableHttpClient httpClient = null; + CloseableHttpResponse response = null; + String result = ""; + try { + // 通过址默认配置创建一个httpClient实例 + httpClient = HttpClients.createDefault(); + // 创建httpGet远程连接实例 + StringBuffer sb = new StringBuffer(url); + sb.append("projectGuid=" + projectGuid); + HttpGet httpGet = new HttpGet(sb.toString()); + // 设置请求头信息,鉴权 + httpGet.setHeader("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0"); + httpGet.setHeader("appKey",headMap.get("appKey").toString()); + httpGet.setHeader("timestamp",headMap.get("timestamp").toString()); + httpGet.setHeader("sign",headMap.get("sign").toString()); + // 设置配置请求参数 + RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 连接主机服务超时时间 + .setConnectionRequestTimeout(35000)// 请求超时时间 + .setSocketTimeout(60000)// 数据读取超时时间 + .build(); + // 为httpGet实例设置配置 + httpGet.setConfig(requestConfig); + // 执行get请求得到返回对象 + response = httpClient.execute(httpGet); + // 通过返回对象获取返回数据 + HttpEntity entity = response.getEntity(); + // 通过EntityUtils中的toString方法将结果转换为字符串 + result = EntityUtils.toString(entity); + } catch (ClientProtocolException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + // 关闭资源 + if (null != response) { + try { + response.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (null != httpClient) { + try { + httpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return result; + } + + public static String postData(String url,Map headMap, Map paramMap) { + HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); + HttpPost post = new HttpPost(url); + String result = ""; + try (CloseableHttpClient closeableHttpClient = httpClientBuilder.build()) { + // HttpEntity entity = new StringEntity(jsonStrData); + // 修复 POST json 导致中文乱码 + HttpEntity entity = new StringEntity(JSONObject.toJSONString(paramMap), "UTF-8"); + post.setEntity(entity); + post.setHeader("Content-type", "application/json"); + if (null != headMap && headMap.size() > 0) { + // 通过map集成entrySet方法获取entity + Set> entrySet = headMap.entrySet(); + // 循环遍历,获取迭代器 + Iterator> iterator = entrySet.iterator(); + while (iterator.hasNext()) { + Entry mapEntry = iterator.next(); + post.setHeader(mapEntry.getKey(),mapEntry.getValue().toString()); + } + } + HttpResponse resp = closeableHttpClient.execute(post); + try { + InputStream respIs = resp.getEntity().getContent(); + byte[] respBytes = IOUtils.toByteArray(respIs); + result = new String(respBytes, Charset.forName("UTF-8")); + } catch (Exception e) { + e.printStackTrace(); + } + return result; + } catch (IOException e) { + e.printStackTrace(); + } + return result; + } + + public static String getDataToken(String url,String token) { + CloseableHttpClient httpClient = null; + CloseableHttpResponse response = null; + String result = ""; + try { + // 通过址默认配置创建一个httpClient实例 + httpClient = HttpClients.createDefault(); + // 创建httpGet远程连接实例 + HttpGet httpGet = new HttpGet(url); + // 设置请求头信息,鉴权 + httpGet.setHeader("Authorization", "Bearer "+token); + // 设置配置请求参数 + RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 连接主机服务超时时间 + .setConnectionRequestTimeout(35000)// 请求超时时间 + .setSocketTimeout(60000)// 数据读取超时时间 + .build(); + // 为httpGet实例设置配置 + httpGet.setConfig(requestConfig); + // 执行get请求得到返回对象 + response = httpClient.execute(httpGet); + // 通过返回对象获取返回数据 + HttpEntity entity = response.getEntity(); + // 通过EntityUtils中的toString方法将结果转换为字符串 + result = EntityUtils.toString(entity); + } catch (ClientProtocolException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + // 关闭资源 + if (null != response) { + try { + response.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (null != httpClient) { + try { + httpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return result; + } +} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/JobInvokeUtil.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/JobInvokeUtil.java new file mode 100644 index 0000000..29d70e6 --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/JobInvokeUtil.java @@ -0,0 +1,182 @@ +package com.dcsoft.job.util; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.LinkedList; +import java.util.List; +import com.dcsoft.common.core.utils.SpringUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.job.domain.SysJob; + +/** + * 任务执行工具 + * + * @author dcsoft + */ +public class JobInvokeUtil +{ + /** + * 执行方法 + * + * @param sysJob 系统任务 + */ + public static void invokeMethod(SysJob sysJob) throws Exception + { + String invokeTarget = sysJob.getInvokeTarget(); + String beanName = getBeanName(invokeTarget); + String methodName = getMethodName(invokeTarget); + List methodParams = getMethodParams(invokeTarget); + + if (!isValidClassName(beanName)) + { + Object bean = SpringUtils.getBean(beanName); + invokeMethod(bean, methodName, methodParams); + } + else + { + Object bean = Class.forName(beanName).newInstance(); + invokeMethod(bean, methodName, methodParams); + } + } + + /** + * 调用任务方法 + * + * @param bean 目标对象 + * @param methodName 方法名称 + * @param methodParams 方法参数 + */ + private static void invokeMethod(Object bean, String methodName, List methodParams) + throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, + InvocationTargetException + { + if (StringUtils.isNotNull(methodParams) && methodParams.size() > 0) + { + Method method = bean.getClass().getMethod(methodName, getMethodParamsType(methodParams)); + method.invoke(bean, getMethodParamsValue(methodParams)); + } + else + { + Method method = bean.getClass().getMethod(methodName); + method.invoke(bean); + } + } + + /** + * 校验是否为为class包名 + * + * @param invokeTarget 名称 + * @return true是 false否 + */ + public static boolean isValidClassName(String invokeTarget) + { + return StringUtils.countMatches(invokeTarget, ".") > 1; + } + + /** + * 获取bean名称 + * + * @param invokeTarget 目标字符串 + * @return bean名称 + */ + public static String getBeanName(String invokeTarget) + { + String beanName = StringUtils.substringBefore(invokeTarget, "("); + return StringUtils.substringBeforeLast(beanName, "."); + } + + /** + * 获取bean方法 + * + * @param invokeTarget 目标字符串 + * @return method方法 + */ + public static String getMethodName(String invokeTarget) + { + String methodName = StringUtils.substringBefore(invokeTarget, "("); + return StringUtils.substringAfterLast(methodName, "."); + } + + /** + * 获取method方法参数相关列表 + * + * @param invokeTarget 目标字符串 + * @return method方法相关参数列表 + */ + public static List getMethodParams(String invokeTarget) + { + String methodStr = StringUtils.substringBetween(invokeTarget, "(", ")"); + if (StringUtils.isEmpty(methodStr)) + { + return null; + } + String[] methodParams = methodStr.split(",(?=([^\"']*[\"'][^\"']*[\"'])*[^\"']*$)"); + List classs = new LinkedList<>(); + for (int i = 0; i < methodParams.length; i++) + { + String str = StringUtils.trimToEmpty(methodParams[i]); + // String字符串类型,以'或"开头 + if (StringUtils.startsWithAny(str, "'", "\"")) + { + classs.add(new Object[] { StringUtils.substring(str, 1, str.length() - 1), String.class }); + } + // boolean布尔类型,等于true或者false + else if ("true".equalsIgnoreCase(str) || "false".equalsIgnoreCase(str)) + { + classs.add(new Object[] { Boolean.valueOf(str), Boolean.class }); + } + // long长整形,以L结尾 + else if (StringUtils.endsWith(str, "L")) + { + classs.add(new Object[] { Long.valueOf(StringUtils.substring(str, 0, str.length() - 1)), Long.class }); + } + // double浮点类型,以D结尾 + else if (StringUtils.endsWith(str, "D")) + { + classs.add(new Object[] { Double.valueOf(StringUtils.substring(str, 0, str.length() - 1)), Double.class }); + } + // 其他类型归类为整形 + else + { + classs.add(new Object[] { Integer.valueOf(str), Integer.class }); + } + } + return classs; + } + + /** + * 获取参数类型 + * + * @param methodParams 参数相关列表 + * @return 参数类型列表 + */ + public static Class[] getMethodParamsType(List methodParams) + { + Class[] classs = new Class[methodParams.size()]; + int index = 0; + for (Object[] os : methodParams) + { + classs[index] = (Class) os[1]; + index++; + } + return classs; + } + + /** + * 获取参数值 + * + * @param methodParams 参数相关列表 + * @return 参数值列表 + */ + public static Object[] getMethodParamsValue(List methodParams) + { + Object[] classs = new Object[methodParams.size()]; + int index = 0; + for (Object[] os : methodParams) + { + classs[index] = (Object) os[0]; + index++; + } + return classs; + } +} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/QuartzDisallowConcurrentExecution.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/QuartzDisallowConcurrentExecution.java new file mode 100644 index 0000000..b0ee859 --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/QuartzDisallowConcurrentExecution.java @@ -0,0 +1,22 @@ +package com.dcsoft.job.util; + +import org.quartz.DisallowConcurrentExecution; +import org.quartz.JobExecutionContext; + +import com.dcsoft.job.domain.SysJob; + +/** + * 定时任务处理(禁止并发执行) + * + * @author dcsoft + * + */ +@DisallowConcurrentExecution +public class QuartzDisallowConcurrentExecution extends AbstractQuartzJob +{ + @Override + protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception + { + JobInvokeUtil.invokeMethod(sysJob); + } +} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/QuartzJobExecution.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/QuartzJobExecution.java new file mode 100644 index 0000000..61912e7 --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/QuartzJobExecution.java @@ -0,0 +1,20 @@ +package com.dcsoft.job.util; + +import org.quartz.JobExecutionContext; + +import com.dcsoft.job.domain.SysJob; + +/** + * 定时任务处理(允许并发执行) + * + * @author dcsoft + * + */ +public class QuartzJobExecution extends AbstractQuartzJob +{ + @Override + protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception + { + JobInvokeUtil.invokeMethod(sysJob); + } +} diff --git a/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/ScheduleUtils.java b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/ScheduleUtils.java new file mode 100644 index 0000000..a5148c1 --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/java/com/dcsoft/job/util/ScheduleUtils.java @@ -0,0 +1,139 @@ +package com.dcsoft.job.util; + +import org.quartz.CronScheduleBuilder; +import org.quartz.CronTrigger; +import org.quartz.Job; +import org.quartz.JobBuilder; +import org.quartz.JobDetail; +import org.quartz.JobKey; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import org.quartz.TriggerBuilder; +import org.quartz.TriggerKey; +import com.dcsoft.common.core.constant.Constants; +import com.dcsoft.common.core.constant.ScheduleConstants; +import com.dcsoft.common.core.exception.job.TaskException; +import com.dcsoft.common.core.exception.job.TaskException.Code; +import com.dcsoft.common.core.utils.SpringUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.job.domain.SysJob; + +/** + * 定时任务工具类 + * + * @author dcsoft + * + */ +public class ScheduleUtils +{ + /** + * 得到quartz任务类 + * + * @param sysJob 执行计划 + * @return 具体执行任务类 + */ + private static Class getQuartzJobClass(SysJob sysJob) + { + boolean isConcurrent = "0".equals(sysJob.getConcurrent()); + return isConcurrent ? QuartzJobExecution.class : QuartzDisallowConcurrentExecution.class; + } + + /** + * 构建任务触发对象 + */ + public static TriggerKey getTriggerKey(Long jobId, String jobGroup) + { + return TriggerKey.triggerKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup); + } + + /** + * 构建任务键对象 + */ + public static JobKey getJobKey(Long jobId, String jobGroup) + { + return JobKey.jobKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup); + } + + /** + * 创建定时任务 + */ + public static void createScheduleJob(Scheduler scheduler, SysJob job) throws SchedulerException, TaskException + { + Class jobClass = getQuartzJobClass(job); + // 构建job信息 + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(getJobKey(jobId, jobGroup)).build(); + + // 表达式调度构建器 + CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()); + cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder); + + // 按新的cronExpression表达式构建一个新的trigger + CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(jobId, jobGroup)) + .withSchedule(cronScheduleBuilder).build(); + + // 放入参数,运行时的方法可以获取 + jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job); + + // 判断是否存在 + if (scheduler.checkExists(getJobKey(jobId, jobGroup))) + { + // 防止创建时存在数据问题 先移除,然后在执行创建操作 + scheduler.deleteJob(getJobKey(jobId, jobGroup)); + } + + // 判断任务是否过期 + if (StringUtils.isNotNull(CronUtils.getNextExecution(job.getCronExpression()))) + { + // 执行调度任务 + scheduler.scheduleJob(jobDetail, trigger); + } + + // 暂停任务 + if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue())) + { + scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + } + + /** + * 设置定时任务策略 + */ + public static CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob job, CronScheduleBuilder cb) + throws TaskException + { + switch (job.getMisfirePolicy()) + { + case ScheduleConstants.MISFIRE_DEFAULT: + return cb; + case ScheduleConstants.MISFIRE_IGNORE_MISFIRES: + return cb.withMisfireHandlingInstructionIgnoreMisfires(); + case ScheduleConstants.MISFIRE_FIRE_AND_PROCEED: + return cb.withMisfireHandlingInstructionFireAndProceed(); + case ScheduleConstants.MISFIRE_DO_NOTHING: + return cb.withMisfireHandlingInstructionDoNothing(); + default: + throw new TaskException("The task misfire policy '" + job.getMisfirePolicy() + + "' cannot be used in cron schedule tasks", Code.CONFIG_ERROR); + } + } + + /** + * 检查包名是否为白名单配置 + * + * @param invokeTarget 目标字符串 + * @return 结果 + */ + public static boolean whiteList(String invokeTarget) + { + String packageName = StringUtils.substringBefore(invokeTarget, "("); + int count = StringUtils.countMatches(packageName, "."); + if (count > 1) + { + return StringUtils.containsAnyIgnoreCase(invokeTarget, Constants.JOB_WHITELIST_STR); + } + Object obj = SpringUtils.getBean(StringUtils.split(invokeTarget, ".")[0]); + return StringUtils.containsAnyIgnoreCase(obj.getClass().getPackage().getName(), Constants.JOB_WHITELIST_STR); + } +} diff --git a/dcsoft-modules/dcsoft-job/src/main/resources/banner.txt b/dcsoft-modules/dcsoft-job/src/main/resources/banner.txt new file mode 100644 index 0000000..0b9cd42 --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/resources/banner.txt @@ -0,0 +1,10 @@ +Spring Boot Version: ${spring-boot.version} +Spring Application Name: ${spring.application.name} + _ _ _ + (_) (_) | | + _ __ _ _ ___ _ _ _ ______ _ ___ | |__ +| '__|| | | | / _ \ | | | || ||______| | | / _ \ | '_ \ +| | | |_| || (_) || |_| || | | || (_) || |_) | +|_| \__,_| \___/ \__, ||_| | | \___/ |_.__/ + __/ | _/ | + |___/ |__/ \ No newline at end of file diff --git a/dcsoft-modules/dcsoft-job/src/main/resources/bootstrap.yml b/dcsoft-modules/dcsoft-job/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..ac49e02 --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/resources/bootstrap.yml @@ -0,0 +1,25 @@ +# Tomcat +server: + port: 9203 + +# Spring +spring: + application: + # 应用名称 + name: dcsoft-job + profiles: + # 环境配置 + active: dev + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: 127.0.0.1:8848 + config: + # 配置中心地址 + server-addr: 127.0.0.1:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} diff --git a/dcsoft-modules/dcsoft-job/src/main/resources/logback.xml b/dcsoft-modules/dcsoft-job/src/main/resources/logback.xml new file mode 100644 index 0000000..7804fdf --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/resources/logback.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/info.log + + + + ${log.path}/info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/error.log + + + + ${log.path}/error.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + + + + + + + + + + + + + diff --git a/dcsoft-modules/dcsoft-job/src/main/resources/mapper/job/KqHolidayMapper.xml b/dcsoft-modules/dcsoft-job/src/main/resources/mapper/job/KqHolidayMapper.xml new file mode 100644 index 0000000..4a87c37 --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/resources/mapper/job/KqHolidayMapper.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + select holiday_id, time_stamp, time, del_flag, create_by, create_time, update_by, update_time,status from kq_holiday + + + + + + + + insert into kq_holiday + + time_stamp, + time, + del_flag, + create_by, + create_time, + update_by, + update_time, + status, + + + #{timeStamp}, + #{time}, + #{delFlag}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{status}, + + + + + + update kq_holiday + + time_stamp = #{timeStamp}, + time = #{time}, + del_flag = #{delFlag}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + status = #{status}, + + + where holiday_id = #{holidayId} + + + + delete from kq_holiday where holiday_id = #{holidayId} + + + + delete from kq_holiday where holiday_id in + + #{holidayId} + + + + + + + delete from kq_holiday where time_stamp = #{timeStamp} + + + diff --git a/dcsoft-modules/dcsoft-job/src/main/resources/mapper/job/SysJobLogMapper.xml b/dcsoft-modules/dcsoft-job/src/main/resources/mapper/job/SysJobLogMapper.xml new file mode 100644 index 0000000..20bb1fe --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/resources/mapper/job/SysJobLogMapper.xml @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + select job_log_id, job_name, job_group, invoke_target, job_message, status, exception_info, create_time + from sys_job_log + + + + + + + + + + + + + + delete from sys_job_log where job_log_id = #{jobLogId} + + + + delete from sys_job_log where job_log_id in + + #{jobLogId} + + + + + + truncate table sys_job_log + + + update sys_equipment + + + + + WHEN ip=#{item.ip} THEN #{item.state} + + + + + WHERE ip IN + + #{item.ip} + + + + update vis_visitor set out_time = now(), type = '2' where date_format(end_time, '%Y-%m-%d %H:%i:%s') + date_format(now(), '%Y-%m-%d %H:%i:%s') and type != '2' + + + + insert into sys_job_log( + job_log_id, + job_name, + job_group, + invoke_target, + job_message, + status, + exception_info, + create_time + )values( + #{jobLogId}, + #{jobName}, + #{jobGroup}, + #{invokeTarget}, + #{jobMessage}, + #{status}, + #{exceptionInfo}, + sysdate() + ) + + + + + diff --git a/dcsoft-modules/dcsoft-job/src/main/resources/mapper/job/SysJobMapper.xml b/dcsoft-modules/dcsoft-job/src/main/resources/mapper/job/SysJobMapper.xml new file mode 100644 index 0000000..73ab9b1 --- /dev/null +++ b/dcsoft-modules/dcsoft-job/src/main/resources/mapper/job/SysJobMapper.xml @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + select job_id, job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark + from sys_job + + + + + + + + + + delete from sys_job where job_id = #{jobId} + + + + delete from sys_job where job_id in + + #{jobId} + + + + + update sys_job + + job_name = #{jobName}, + job_group = #{jobGroup}, + invoke_target = #{invokeTarget}, + cron_expression = #{cronExpression}, + misfire_policy = #{misfirePolicy}, + concurrent = #{concurrent}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = sysdate() + + where job_id = #{jobId} + + + + insert into sys_job( + job_id, + job_name, + job_group, + invoke_target, + cron_expression, + misfire_policy, + concurrent, + status, + remark, + create_by, + create_time + )values( + #{jobId}, + #{jobName}, + #{jobGroup}, + #{invokeTarget}, + #{cronExpression}, + #{misfirePolicy}, + #{concurrent}, + #{status}, + #{remark}, + #{createBy}, + sysdate() + ) + + + diff --git a/dcsoft-modules/dcsoft-system/pom.xml b/dcsoft-modules/dcsoft-system/pom.xml new file mode 100644 index 0000000..6e096aa --- /dev/null +++ b/dcsoft-modules/dcsoft-system/pom.xml @@ -0,0 +1,144 @@ + + + + com.dcsoft + dcsoft-modules + 3.6.2 + + 4.0.0 + + dcsoft-modules-system + + + dcsoft-modules-system系统模块 + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + io.springfox + springfox-swagger-ui + ${swagger.fox.version} + + + + + mysql + mysql-connector-java + + + + + com.dcsoft + dcsoft-common-datasource + + + + + com.dcsoft + dcsoft-common-datascope + + + + + com.dcsoft + dcsoft-common-log + + + + + com.dcsoft + dcsoft-common-swagger + + + org.projectlombok + lombok + 1.18.24 + + + + com.dcsoft + dcsoft-common-sms + + + + + + + + com.aliyun + dysmsapi20170525 + true + + + + + org.apache.ant + ant + 1.10.5 + + + + org.apache.httpcomponents + httpmime + 4.5.3 + + + commons-net + commons-net + 3.1 + + + + cn.hutool + hutool-all + 5.3.3 + + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/DCSSystemApplication.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/DCSSystemApplication.java new file mode 100644 index 0000000..cfbe216 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/DCSSystemApplication.java @@ -0,0 +1,29 @@ +package com.dcsoft.system; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import com.dcsoft.common.security.annotation.EnableCustomConfig; +import com.dcsoft.common.security.annotation.EnableRyFeignClients; +import com.dcsoft.common.swagger.annotation.EnableCustomSwagger2; + +/** + * 系统模块 + * + * @author dcsoft + */ +@EnableCustomConfig +@EnableCustomSwagger2 +@EnableRyFeignClients +@SpringBootApplication +public class DCSSystemApplication +{ + public static void main(String[] args) + { + SpringApplication.run(com.dcsoft.system.DCSSystemApplication.class, args); + System.out.println("(♥◠‿◠)ノ゙ 系统模块启动成功 ლ(´ڡ`ლ)゙ \n" + + " ___ ___ ___ \n" + + " | \\ / __| / __| \n" + + " | |) | | (__ \\__ \\ \n" + + " |___/ \\___| |___/ "); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/controller/TbCarController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/controller/TbCarController.java new file mode 100644 index 0000000..3ba7cfd --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/controller/TbCarController.java @@ -0,0 +1,142 @@ +package com.dcsoft.system.car.controller; + +import com.dcsoft.common.core.exception.ServiceException; +import com.dcsoft.common.core.utils.CollUtil; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDataInfo; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.system.car.domain.TbCar; +import com.dcsoft.system.car.service.ITbCarService; +import com.dcsoft.system.service.ISysDictDataService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.Map; + +/** + * 车辆信息Controller + * + * @author nichun + * @date 2023-07-24 + */ +@RestController +@RequestMapping("/car") +public class TbCarController extends BaseController +{ + @Autowired + private ITbCarService tbCarService; + + @Autowired + private ISysDictDataService dictDataService; + + /** + * 查询车辆信息列表 + */ +// @RequiresPermissions("system:car:list") + @GetMapping("/list") + public TableDataInfo list(TbCar tbCar) + { + startPage(); + List list = tbCarService.selectTbCarList(tbCar); + return getDataTable(list); + } + + /** + * 小程序查询车辆信息列表 + */ +// @RequiresPermissions("system:car:list") + @GetMapping("/app/list") + public TableDataInfo appList(TbCar tbCar) + { + startPage(); + List list = tbCarService.selectAppTbCarList(tbCar); + Map map = dictDataService.queryDictData("sys_car_colour"); + try { + for (TbCar car : list) { + if (StringUtils.isNotBlank(car.getPlateColor())) { + car.setPlateColorName(map.get(car.getPlateColor())); + } + } + } catch (ServiceException e) { + throw new ServiceException(e.getMessage()); + } + return getDataTable(list); + } + + /** + * 导出车辆信息列表 + */ + @RequiresPermissions("system:car:export") + @Log(title = "车辆信息", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, TbCar tbCar) + { + List list = tbCarService.selectTbCarList(tbCar); + ExcelUtil util = new ExcelUtil(TbCar.class); + util.exportExcel(response, list, "车辆信息数据"); + } + + /** + * 获取车辆信息详细信息 + */ +// @RequiresPermissions("system:car:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + TbCar tbCar = tbCarService.selectTbCarById(id); + Map map = dictDataService.queryDictData("sys_car_colour"); + if (StringUtils.isNotBlank(tbCar.getPlateColor())) { + tbCar.setPlateColorName(map.get(tbCar.getPlateColor())); + } + return success(tbCar); + } + + /** + * 新增车辆信息 + */ +// @RequiresPermissions("system:car:add") + @Log(title = "车辆信息", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody TbCar tbCar) + { + TbCar query = new TbCar(); + query.setCarNo(tbCar.getCarNo()); + List tbCars = tbCarService.selectTbCarList(query); + if (CollUtil.isNotEmpty(tbCars)) { + throw new ServiceException("该车牌已被绑定,请重新添加车辆信息"); + } + if (null != tbCar && null != tbCar.getId()) { + return toAjax(tbCarService.updateTbCar(tbCar)); + } + return toAjax(tbCarService.insertTbCar(tbCar)); + } + + /** + * 修改车辆信息 + */ +// @RequiresPermissions("system:car:edit") + @Log(title = "车辆信息", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody TbCar tbCar) + { + return toAjax(tbCarService.updateTbCar(tbCar)); + } + + /** + * 删除车辆信息 + */ +// @RequiresPermissions("system:car:remove") + @Log(title = "车辆信息", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(tbCarService.deleteTbCarByIds(ids)); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/controller/TbCarRecordController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/controller/TbCarRecordController.java new file mode 100644 index 0000000..ba900c6 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/controller/TbCarRecordController.java @@ -0,0 +1,98 @@ +package com.dcsoft.system.car.controller; + +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDataInfo; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.system.car.domain.TbCarRecord; +import com.dcsoft.system.car.service.ITbCarRecordService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 车辆通行记录Controller + * + * @author nichun + * @date 2023-07-26 + */ +@RestController +@RequestMapping("/carRecord") +public class TbCarRecordController extends BaseController +{ + @Autowired + private ITbCarRecordService tbCarRecordService; + + /** + * 查询车辆通行记录列表 + */ + @RequiresPermissions("car:carRecord:list") + @GetMapping("/list") + public TableDataInfo list(TbCarRecord tbCarRecord) + { + startPage(); + List list = tbCarRecordService.selectTbCarRecordList(tbCarRecord); + return getDataTable(list); + } + + /** + * 导出车辆通行记录列表 + */ + @RequiresPermissions("car:carRecord:export") + @Log(title = "车辆通行记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, TbCarRecord tbCarRecord) + { + List list = tbCarRecordService.selectTbCarRecordList(tbCarRecord); + ExcelUtil util = new ExcelUtil(TbCarRecord.class); + util.exportExcel(response, list, "车辆通行记录数据"); + } + + /** + * 获取车辆通行记录详细信息 + */ + @RequiresPermissions("car:carRecord:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(tbCarRecordService.selectTbCarRecordById(id)); + } + + /** + * 新增车辆通行记录 + */ + @RequiresPermissions("car:carRecord:add") + @Log(title = "车辆通行记录", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody TbCarRecord tbCarRecord) + { + return toAjax(tbCarRecordService.insertTbCarRecord(tbCarRecord)); + } + + /** + * 修改车辆通行记录 + */ + @RequiresPermissions("car:carRecord:edit") + @Log(title = "车辆通行记录", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody TbCarRecord tbCarRecord) + { + return toAjax(tbCarRecordService.updateTbCarRecord(tbCarRecord)); + } + + /** + * 删除车辆通行记录 + */ + @RequiresPermissions("car:carRecord:remove") + @Log(title = "车辆通行记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(tbCarRecordService.deleteTbCarRecordByIds(ids)); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/domain/TbCar.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/domain/TbCar.java new file mode 100644 index 0000000..783957f --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/domain/TbCar.java @@ -0,0 +1,230 @@ +package com.dcsoft.system.car.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.Date; + +/** + * 车辆信息对象 tb_car + * + * @author nichun + * @date 2023-07-24 + */ +public class TbCar extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** id */ + private Long id; + + /** 用户id */ + private Long userId; + + /** 车辆类型 0:访客车辆 1:物流车辆 */ + private Integer carType; + + /** 驾照图片地址 */ + private String drivingUrl; + + /** 车牌号码 */ + @Excel(name = "车牌号码") + private String carNo; + + /** 车牌类型 4-民用车双行尾牌 8- 新能源车牌 0- 标准民用车与军车车牌 */ + @Excel(name = "车牌类型 4-民用车双行尾牌 8- 新能源车牌 0- 标准民用车与军车车牌") + private String plateType; + + /** 车牌颜色 0- 蓝色车牌 1- 黄色车牌 2- 白色车牌 4- 绿色车牌 */ + @Excel(name = "车牌颜色 0- 蓝色车牌 1- 黄色车牌 2- 白色车牌 4- 绿色车牌") + private String plateColor; + + /** 车牌颜色名称 0- 蓝色车牌 1- 黄色车牌 2- 白色车牌 4- 绿色车牌 */ + private String plateColorName; + + /** 卡号(同步用) */ + private String cardNo; + + /** 有效开始时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "有效开始时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date struStartTime; + + /** 有效结束时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "有效结束时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date struStopTime; + + /** 所属人员 */ + @Excel(name = "所属人员") + private String personNo; + + /** 是否删除 1 是删除 2是未删除 */ + private String isDel; + + /** 同步标识 sync 0是未同步 1是已同步 */ + @Excel(name = "同步标识 sync 0是未同步 1是已同步") + private String sync; + + private String ownerName; + + private String ownerPhone; + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public String getPlateColorName() { + return plateColorName; + } + + public void setPlateColorName(String plateColorName) { + this.plateColorName = plateColorName; + } + + public Integer getCarType() { + return carType; + } + + public void setCarType(Integer carType) { + this.carType = carType; + } + + public String getDrivingUrl() { + return drivingUrl; + } + + public void setDrivingUrl(String drivingUrl) { + this.drivingUrl = drivingUrl; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setCarNo(String carNo) + { + this.carNo = carNo; + } + + public String getCarNo() + { + return carNo; + } + public void setPlateType(String plateType) + { + this.plateType = plateType; + } + + public String getPlateType() + { + return plateType; + } + public void setPlateColor(String plateColor) + { + this.plateColor = plateColor; + } + + public String getPlateColor() + { + return plateColor; + } + public void setCardNo(String cardNo) + { + this.cardNo = cardNo; + } + + public String getCardNo() + { + return cardNo; + } + public void setStruStartTime(Date struStartTime) + { + this.struStartTime = struStartTime; + } + + public Date getStruStartTime() + { + return struStartTime; + } + public void setStruStopTime(Date struStopTime) + { + this.struStopTime = struStopTime; + } + + public Date getStruStopTime() + { + return struStopTime; + } + public void setPersonNo(String personNo) + { + this.personNo = personNo; + } + + public String getPersonNo() + { + return personNo; + } + public void setIsDel(String isDel) + { + this.isDel = isDel; + } + + public String getIsDel() + { + return isDel; + } + public void setSync(String sync) + { + this.sync = sync; + } + + public String getSync() + { + return sync; + } + + public String getOwnerName() { + return ownerName; + } + + public void setOwnerName(String ownerName) { + this.ownerName = ownerName; + } + + public String getOwnerPhone() { + return ownerPhone; + } + + public void setOwnerPhone(String ownerPhone) { + this.ownerPhone = ownerPhone; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("carNo", getCarNo()) + .append("plateType", getPlateType()) + .append("plateColor", getPlateColor()) + .append("cardNo", getCardNo()) + .append("struStartTime", getStruStartTime()) + .append("struStopTime", getStruStopTime()) + .append("personNo", getPersonNo()) + .append("isDel", getIsDel()) + .append("sync", getSync()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/domain/TbCarRecord.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/domain/TbCarRecord.java new file mode 100644 index 0000000..f003150 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/domain/TbCarRecord.java @@ -0,0 +1,327 @@ +package com.dcsoft.system.car.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.Date; + +/** + * 车辆通行记录对象 tb_car_record + * + * @author nichun + * @date 2023-07-26 + */ +public class TbCarRecord extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** id */ + private Long id; + + /** 停车场编号 */ + private String parkCode; + + /** 过车信息唯一标识 */ + private String uniqueNo; + + /** 过车行驶方向 0 入场过车 1出场过车 */ + @Excel(name = "过车行驶方向 0 入场过车 1出场过车") + private String direction; + + /** 车牌号码 */ + @Excel(name = "车牌号码") + private String plateNo; + + /** 卡号 */ + @Excel(name = "卡号") + private String cardNo; + + /** 通行时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "通行时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date passTime; + + /** 车辆类型 */ + @Excel(name = "车辆类型") + private String vehType; + + /** 车辆颜色 */ + @Excel(name = "车辆颜色") + private String vehColor; + + /** 操作员账号 */ + @Excel(name = "操作员账号") + private String operatorName; + + /** 放行的终端编号 */ + private String terminalNo; + + /** 出入口名称 */ + @Excel(name = "出入口名称") + private String gateName; + + /** 放行车道名称 */ + @Excel(name = "放行车道名称") + private String laneName; + + /** 出场对应的入场时间(可选) */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "出场对应的入场时间(可选)", width = 30, dateFormat = "yyyy-MM-dd") + private Date inPassTime; + + /** 出场对应的入场车辆唯一编号(可选) */ + @Excel(name = "出场对应的入场车辆唯一编号(可选)") + private String inUniqueNo; + + /** 出场应付金额 */ + private String shouldPay; + + /** (可选)出场实付金额 单位:分 */ + private String actualPay; + + /** 过车图片相对路径 */ + private String picFilePath; + + /** 车牌图片相对路径 */ + private String picPlateFilePath; + + /** 过车图片数据 (可选)base64 */ + @Excel(name = "过车图片数据 (可选)base64") + private String picVehicleFileData; + + /** 车牌图片数据 (可选)base64 */ + private String picPlateFileData; + + /** 数据类型 0 实时数据 1历史数据 */ + private String dataType; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setParkCode(String parkCode) + { + this.parkCode = parkCode; + } + + public String getParkCode() + { + return parkCode; + } + public void setUniqueNo(String uniqueNo) + { + this.uniqueNo = uniqueNo; + } + + public String getUniqueNo() + { + return uniqueNo; + } + public void setDirection(String direction) + { + this.direction = direction; + } + + public String getDirection() + { + return direction; + } + public void setPlateNo(String plateNo) + { + this.plateNo = plateNo; + } + + public String getPlateNo() + { + return plateNo; + } + public void setCardNo(String cardNo) + { + this.cardNo = cardNo; + } + + public String getCardNo() + { + return cardNo; + } + public void setPassTime(Date passTime) + { + this.passTime = passTime; + } + + public Date getPassTime() + { + return passTime; + } + public void setVehType(String vehType) + { + this.vehType = vehType; + } + + public String getVehType() + { + return vehType; + } + public void setVehColor(String vehColor) + { + this.vehColor = vehColor; + } + + public String getVehColor() + { + return vehColor; + } + public void setOperatorName(String operatorName) + { + this.operatorName = operatorName; + } + + public String getOperatorName() + { + return operatorName; + } + public void setTerminalNo(String terminalNo) + { + this.terminalNo = terminalNo; + } + + public String getTerminalNo() + { + return terminalNo; + } + public void setGateName(String gateName) + { + this.gateName = gateName; + } + + public String getGateName() + { + return gateName; + } + public void setLaneName(String laneName) + { + this.laneName = laneName; + } + + public String getLaneName() + { + return laneName; + } + public void setInPassTime(Date inPassTime) + { + this.inPassTime = inPassTime; + } + + public Date getInPassTime() + { + return inPassTime; + } + public void setInUniqueNo(String inUniqueNo) + { + this.inUniqueNo = inUniqueNo; + } + + public String getInUniqueNo() + { + return inUniqueNo; + } + public void setShouldPay(String shouldPay) + { + this.shouldPay = shouldPay; + } + + public String getShouldPay() + { + return shouldPay; + } + public void setActualPay(String actualPay) + { + this.actualPay = actualPay; + } + + public String getActualPay() + { + return actualPay; + } + public void setPicFilePath(String picFilePath) + { + this.picFilePath = picFilePath; + } + + public String getPicFilePath() + { + return picFilePath; + } + public void setPicPlateFilePath(String picPlateFilePath) + { + this.picPlateFilePath = picPlateFilePath; + } + + public String getPicPlateFilePath() + { + return picPlateFilePath; + } + public void setPicVehicleFileData(String picVehicleFileData) + { + this.picVehicleFileData = picVehicleFileData; + } + + public String getPicVehicleFileData() + { + return picVehicleFileData; + } + public void setPicPlateFileData(String picPlateFileData) + { + this.picPlateFileData = picPlateFileData; + } + + public String getPicPlateFileData() + { + return picPlateFileData; + } + public void setDataType(String dataType) + { + this.dataType = dataType; + } + + public String getDataType() + { + return dataType; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("parkCode", getParkCode()) + .append("uniqueNo", getUniqueNo()) + .append("direction", getDirection()) + .append("plateNo", getPlateNo()) + .append("cardNo", getCardNo()) + .append("passTime", getPassTime()) + .append("vehType", getVehType()) + .append("vehColor", getVehColor()) + .append("operatorName", getOperatorName()) + .append("terminalNo", getTerminalNo()) + .append("gateName", getGateName()) + .append("laneName", getLaneName()) + .append("inPassTime", getInPassTime()) + .append("inUniqueNo", getInUniqueNo()) + .append("shouldPay", getShouldPay()) + .append("actualPay", getActualPay()) + .append("picFilePath", getPicFilePath()) + .append("picPlateFilePath", getPicPlateFilePath()) + .append("picVehicleFileData", getPicVehicleFileData()) + .append("picPlateFileData", getPicPlateFileData()) + .append("dataType", getDataType()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/mapper/TbCarMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/mapper/TbCarMapper.java new file mode 100644 index 0000000..bf7211a --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/mapper/TbCarMapper.java @@ -0,0 +1,62 @@ +package com.dcsoft.system.car.mapper; + +import com.dcsoft.system.car.domain.TbCar; + +import java.util.List; + +/** + * 车辆信息Mapper接口 + * + * @author nichun + * @date 2023-07-24 + */ +public interface TbCarMapper +{ + /** + * 查询车辆信息 + * + * @param id 车辆信息主键 + * @return 车辆信息 + */ + public TbCar selectTbCarById(Long id); + + /** + * 查询车辆信息列表 + * + * @param tbCar 车辆信息 + * @return 车辆信息集合 + */ + public List selectTbCarList(TbCar tbCar); + + /** + * 新增车辆信息 + * + * @param tbCar 车辆信息 + * @return 结果 + */ + public int insertTbCar(TbCar tbCar); + + /** + * 修改车辆信息 + * + * @param tbCar 车辆信息 + * @return 结果 + */ + public int updateTbCar(TbCar tbCar); + + /** + * 删除车辆信息 + * + * @param id 车辆信息主键 + * @return 结果 + */ + public int deleteTbCarById(Long id); + + /** + * 批量删除车辆信息 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteTbCarByIds(Long[] ids); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/mapper/TbCarRecordMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/mapper/TbCarRecordMapper.java new file mode 100644 index 0000000..3f5b7ce --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/mapper/TbCarRecordMapper.java @@ -0,0 +1,62 @@ +package com.dcsoft.system.car.mapper; + +import com.dcsoft.system.car.domain.TbCarRecord; + +import java.util.List; + +/** + * 车辆通行记录Mapper接口 + * + * @author nichun + * @date 2023-07-26 + */ +public interface TbCarRecordMapper +{ + /** + * 查询车辆通行记录 + * + * @param id 车辆通行记录主键 + * @return 车辆通行记录 + */ + public TbCarRecord selectTbCarRecordById(Long id); + + /** + * 查询车辆通行记录列表 + * + * @param tbCarRecord 车辆通行记录 + * @return 车辆通行记录集合 + */ + public List selectTbCarRecordList(TbCarRecord tbCarRecord); + + /** + * 新增车辆通行记录 + * + * @param tbCarRecord 车辆通行记录 + * @return 结果 + */ + public int insertTbCarRecord(TbCarRecord tbCarRecord); + + /** + * 修改车辆通行记录 + * + * @param tbCarRecord 车辆通行记录 + * @return 结果 + */ + public int updateTbCarRecord(TbCarRecord tbCarRecord); + + /** + * 删除车辆通行记录 + * + * @param id 车辆通行记录主键 + * @return 结果 + */ + public int deleteTbCarRecordById(Long id); + + /** + * 批量删除车辆通行记录 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteTbCarRecordByIds(Long[] ids); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/service/ISysPmsService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/service/ISysPmsService.java new file mode 100644 index 0000000..3395ea1 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/service/ISysPmsService.java @@ -0,0 +1,16 @@ +package com.dcsoft.system.car.service; + + +import com.dcsoft.system.car.domain.TbCar; + +/** + * Uface 服务层 + * + * @author nichun + */ +public interface ISysPmsService { + + String addInnerVehicle(TbCar tbCar); + + String delInnerVehicle(TbCar tbCar); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/service/ITbCarRecordService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/service/ITbCarRecordService.java new file mode 100644 index 0000000..65aedc9 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/service/ITbCarRecordService.java @@ -0,0 +1,62 @@ +package com.dcsoft.system.car.service; + +import com.dcsoft.system.car.domain.TbCarRecord; + +import java.util.List; + +/** + * 车辆通行记录Service接口 + * + * @author nichun + * @date 2023-07-26 + */ +public interface ITbCarRecordService +{ + /** + * 查询车辆通行记录 + * + * @param id 车辆通行记录主键 + * @return 车辆通行记录 + */ + public TbCarRecord selectTbCarRecordById(Long id); + + /** + * 查询车辆通行记录列表 + * + * @param tbCarRecord 车辆通行记录 + * @return 车辆通行记录集合 + */ + public List selectTbCarRecordList(TbCarRecord tbCarRecord); + + /** + * 新增车辆通行记录 + * + * @param tbCarRecord 车辆通行记录 + * @return 结果 + */ + public int insertTbCarRecord(TbCarRecord tbCarRecord); + + /** + * 修改车辆通行记录 + * + * @param tbCarRecord 车辆通行记录 + * @return 结果 + */ + public int updateTbCarRecord(TbCarRecord tbCarRecord); + + /** + * 批量删除车辆通行记录 + * + * @param ids 需要删除的车辆通行记录主键集合 + * @return 结果 + */ + public int deleteTbCarRecordByIds(Long[] ids); + + /** + * 删除车辆通行记录信息 + * + * @param id 车辆通行记录主键 + * @return 结果 + */ + public int deleteTbCarRecordById(Long id); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/service/ITbCarService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/service/ITbCarService.java new file mode 100644 index 0000000..1d32a73 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/service/ITbCarService.java @@ -0,0 +1,70 @@ +package com.dcsoft.system.car.service; + +import com.dcsoft.system.car.domain.TbCar; + +import java.util.List; + +/** + * 车辆信息Service接口 + * + * @author nichun + * @date 2023-07-24 + */ +public interface ITbCarService +{ + /** + * 查询车辆信息 + * + * @param id 车辆信息主键 + * @return 车辆信息 + */ + public TbCar selectTbCarById(Long id); + + /** + * 查询车辆信息列表 + * + * @param tbCar 车辆信息 + * @return 车辆信息集合 + */ + public List selectTbCarList(TbCar tbCar); + + /** + * 查询我的车辆信息列表 + * + * @param tbCar 车辆信息 + * @return 车辆信息集合 + */ + public List selectAppTbCarList(TbCar tbCar); + + /** + * 新增车辆信息 + * + * @param tbCar 车辆信息 + * @return 结果 + */ + public int insertTbCar(TbCar tbCar); + + /** + * 修改车辆信息 + * + * @param tbCar 车辆信息 + * @return 结果 + */ + public int updateTbCar(TbCar tbCar); + + /** + * 批量删除车辆信息 + * + * @param ids 需要删除的车辆信息主键集合 + * @return 结果 + */ + public int deleteTbCarByIds(Long[] ids); + + /** + * 删除车辆信息信息 + * + * @param id 车辆信息主键 + * @return 结果 + */ + public int deleteTbCarById(Long id); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/service/impl/SysPmsServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/service/impl/SysPmsServiceImpl.java new file mode 100644 index 0000000..9408301 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/service/impl/SysPmsServiceImpl.java @@ -0,0 +1,64 @@ +package com.dcsoft.system.car.service.impl; + +import com.dcsoft.system.car.domain.TbCar; +import com.dcsoft.system.car.service.ISysPmsService; +import com.dcsoft.system.utils.HttpUtil; +import org.apache.commons.codec.digest.DigestUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + * 用户管理 服务层处理 + * + * @author xueyi + */ +@Service +public class SysPmsServiceImpl implements ISysPmsService { + + + @Value("${pms.url}") + private String pmsUrl; + + @Value("${pms.password}") + private String pmsPassword; + + + + @Override + public String addInnerVehicle(TbCar tbCar) { + SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String strMD5Pwd= DigestUtils.md5Hex(pmsPassword).toUpperCase(); + String strSign= DigestUtils.md5Hex((tbCar.getCarNo()+strMD5Pwd)).toUpperCase(); + String url=pmsUrl+"/addInnerVehicle"; + Map paramMap=new HashMap(); + paramMap.put("plateNo", tbCar.getCarNo()); + paramMap.put("startTime", sdf.format(tbCar.getStruStartTime())); + paramMap.put("endTime", sdf.format(tbCar.getStruStopTime())); + paramMap.put("ownerName", tbCar.getOwnerName()); + paramMap.put("ownerPhone", tbCar.getOwnerPhone()); + paramMap.put("createTime", sdf.format(new Date())); + paramMap.put("sign", strSign); + String response= HttpUtil.postData(url,paramMap); + return response; + } + + @Override + public String delInnerVehicle(TbCar tbCar) { + String strMD5Pwd= DigestUtils.md5Hex(pmsPassword).toUpperCase(); + String strSign= DigestUtils.md5Hex((tbCar.getCarNo()+strMD5Pwd)).toUpperCase(); + String url=pmsUrl+"/delInnerVehicle"; + Map paramMap=new HashMap(); + paramMap.put("plateNo", tbCar.getCarNo()); + paramMap.put("sign", strSign); + String response= HttpUtil.postData(url,paramMap); + return response; + } + + + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/service/impl/TbCarRecordServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/service/impl/TbCarRecordServiceImpl.java new file mode 100644 index 0000000..7539929 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/service/impl/TbCarRecordServiceImpl.java @@ -0,0 +1,94 @@ +package com.dcsoft.system.car.service.impl; + +import com.dcsoft.system.car.domain.TbCarRecord; +import com.dcsoft.system.car.mapper.TbCarRecordMapper; +import com.dcsoft.system.car.service.ITbCarRecordService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 车辆通行记录Service业务层处理 + * + * @author nichun + * @date 2023-07-26 + */ +@Service +public class TbCarRecordServiceImpl implements ITbCarRecordService +{ + @Autowired + private TbCarRecordMapper tbCarRecordMapper; + + /** + * 查询车辆通行记录 + * + * @param id 车辆通行记录主键 + * @return 车辆通行记录 + */ + @Override + public TbCarRecord selectTbCarRecordById(Long id) + { + return tbCarRecordMapper.selectTbCarRecordById(id); + } + + /** + * 查询车辆通行记录列表 + * + * @param tbCarRecord 车辆通行记录 + * @return 车辆通行记录 + */ + @Override + public List selectTbCarRecordList(TbCarRecord tbCarRecord) + { + return tbCarRecordMapper.selectTbCarRecordList(tbCarRecord); + } + + /** + * 新增车辆通行记录 + * + * @param tbCarRecord 车辆通行记录 + * @return 结果 + */ + @Override + public int insertTbCarRecord(TbCarRecord tbCarRecord) + { + return tbCarRecordMapper.insertTbCarRecord(tbCarRecord); + } + + /** + * 修改车辆通行记录 + * + * @param tbCarRecord 车辆通行记录 + * @return 结果 + */ + @Override + public int updateTbCarRecord(TbCarRecord tbCarRecord) + { + return tbCarRecordMapper.updateTbCarRecord(tbCarRecord); + } + + /** + * 批量删除车辆通行记录 + * + * @param ids 需要删除的车辆通行记录主键 + * @return 结果 + */ + @Override + public int deleteTbCarRecordByIds(Long[] ids) + { + return tbCarRecordMapper.deleteTbCarRecordByIds(ids); + } + + /** + * 删除车辆通行记录信息 + * + * @param id 车辆通行记录主键 + * @return 结果 + */ + @Override + public int deleteTbCarRecordById(Long id) + { + return tbCarRecordMapper.deleteTbCarRecordById(id); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/service/impl/TbCarServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/service/impl/TbCarServiceImpl.java new file mode 100644 index 0000000..357edbf --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/car/service/impl/TbCarServiceImpl.java @@ -0,0 +1,135 @@ +package com.dcsoft.system.car.service.impl; + +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.api.model.LoginUser; +import com.dcsoft.system.car.domain.TbCar; +import com.dcsoft.system.car.mapper.TbCarMapper; +import com.dcsoft.system.car.service.ISysPmsService; +import com.dcsoft.system.car.service.ITbCarService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 车辆信息Service业务层处理 + * + * @author nichun + * @date 2023-07-24 + */ +@Service +public class TbCarServiceImpl implements ITbCarService +{ + @Autowired + private TbCarMapper tbCarMapper; + + @Autowired + private ISysPmsService pmsService; + + /** + * 查询车辆信息 + * + * @param id 车辆信息主键 + * @return 车辆信息 + */ + @Override + public TbCar selectTbCarById(Long id) + { + return tbCarMapper.selectTbCarById(id); + } + + /** + * 查询车辆信息列表 + * + * @param tbCar 车辆信息 + * @return 车辆信息 + */ + @Override + public List selectTbCarList(TbCar tbCar) + { + return tbCarMapper.selectTbCarList(tbCar); + } + + /** + * 查询我的车辆信息列表 + * + * @param tbCar 车辆信息 + * @return 车辆信息 + */ + @Override + public List selectAppTbCarList(TbCar tbCar) + { + LoginUser loginUser = SecurityUtils.getLoginUser(); + tbCar.setUserId(loginUser.getUserid()); + return tbCarMapper.selectTbCarList(tbCar); + } + + /** + * 新增车辆信息 + * + * @param tbCar 车辆信息 + * @return 结果 + */ + @Override + public int insertTbCar(TbCar tbCar) + { + //白名单车辆新增或修改 +// String reponse = pmsService.addInnerVehicle(tbCar); +// JSONObject json= JSONObject.parseObject(reponse); +// if("1".equals(json.get("result")+"")) { +// tbCar.setSync("1"); +// } + LoginUser loginUser = SecurityUtils.getLoginUser(); + tbCar.setUserId(loginUser.getUserid()); + return tbCarMapper.insertTbCar(tbCar); + } + + /** + * 修改车辆信息 + * + * @param tbCar 车辆信息 + * @return 结果 + */ + @Override + public int updateTbCar(TbCar tbCar) + { + //白名单车辆新增或修改 +// String reponse=pmsService.addInnerVehicle(tbCar); +// JSONObject json= JSONObject.parseObject(reponse); +// if("1".equals(json.get("result")+"")) { +// tbCar.setSync("1"); +// } + return tbCarMapper.updateTbCar(tbCar); + } + + /** + * 批量删除车辆信息 + * + * @param ids 需要删除的车辆信息主键 + * @return 结果 + */ + @Override + public int deleteTbCarByIds(Long[] ids) + { +// for(Long id:ids){ +// TbCar car=tbCarMapper.selectTbCarById(id); +// String reponse=pmsService.delInnerVehicle(car); +// } + return tbCarMapper.deleteTbCarByIds(ids); + } + + /** + * 删除车辆信息信息 + * + * @param id 车辆信息主键 + * @return 结果 + */ + @Override + public int deleteTbCarById(Long id) + { + //根据车牌删除白名单车辆 + TbCar car=tbCarMapper.selectTbCarById(id); + String reponse=pmsService.delInnerVehicle(car); + return tbCarMapper.deleteTbCarById(id); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/config/AlipayConfig.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/config/AlipayConfig.java new file mode 100644 index 0000000..e69de29 diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/config/WeixinPayConfig.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/config/WeixinPayConfig.java new file mode 100644 index 0000000..e69de29 diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysBackGroupController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysBackGroupController.java new file mode 100644 index 0000000..b31b3a6 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysBackGroupController.java @@ -0,0 +1,99 @@ +package com.dcsoft.system.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.system.domain.SysBackGroup; +import com.dcsoft.system.service.ISysBackGroupService; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.page.TableDataInfo; + +/** + * 背景配置Controller + * + * @author dcsoft + * @date 2024-03-01 + */ +@RestController +@RequestMapping("/backGroup") +public class SysBackGroupController extends BaseController +{ + @Autowired + private ISysBackGroupService sysBackGroupService; + + /** + * 查询背景配置列表 + */ + @GetMapping("/list") + public TableDataInfo list(SysBackGroup sysBackGroup) + { + startPage(); + List list = sysBackGroupService.selectSysBackGroupList(sysBackGroup); + return getDataTable(list); + } + + /** + * 导出背景配置列表 + */ + @Log(title = "背景配置", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysBackGroup sysBackGroup) + { + List list = sysBackGroupService.selectSysBackGroupList(sysBackGroup); + ExcelUtil util = new ExcelUtil(SysBackGroup.class); + util.exportExcel(response, list, "背景配置数据"); + } + + /** + * 获取背景配置详细信息 + */ + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(sysBackGroupService.selectSysBackGroupById(id)); + } + + /** + * 新增背景配置 + */ + @Log(title = "背景配置", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SysBackGroup sysBackGroup) + { + sysBackGroupService.deleteSysBackGroup(); + return toAjax(sysBackGroupService.insertSysBackGroup(sysBackGroup)); + } + + /** + * 修改背景配置 + */ + @Log(title = "背景配置", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysBackGroup sysBackGroup) + { + return toAjax(sysBackGroupService.updateSysBackGroup(sysBackGroup)); + } + + /** + * 删除背景配置 + */ + @Log(title = "背景配置", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(sysBackGroupService.deleteSysBackGroupByIds(ids)); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysBlackListController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysBlackListController.java new file mode 100644 index 0000000..8ca26f2 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysBlackListController.java @@ -0,0 +1,137 @@ +package com.dcsoft.system.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.system.uniubi.service.ISysApiService; +import com.dcsoft.system.visitor.domain.Visitor; +import com.dcsoft.system.visitor.service.IVisitorService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.system.domain.SysBlackList; +import com.dcsoft.system.service.ISysBlackListService; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.page.TableDataInfo; + +/** + * 黑名单管理Controller + * + * @author nichun + * @date 2023-07-03 + */ +@RestController +@RequestMapping("/blackList") +public class SysBlackListController extends BaseController +{ + @Autowired + private ISysBlackListService sysBlackListService; + + @Autowired + private IVisitorService visitorService; + + @Autowired + private ISysApiService sysApiService; + + /** + * 查询黑名单管理列表 + */ + @RequiresPermissions("system:blackList:list") + @GetMapping("/list") + public TableDataInfo list(SysBlackList sysBlackList) + { + startPage(); + List list = sysBlackListService.selectSysBlackListList(sysBlackList); + return getDataTable(list); + } + + /** + * 导出黑名单管理列表 + */ + @RequiresPermissions("system:blackList:export") + @Log(title = "黑名单管理", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysBlackList sysBlackList) + { + List list = sysBlackListService.selectSysBlackListList(sysBlackList); + ExcelUtil util = new ExcelUtil(SysBlackList.class); + util.exportExcel(response, list, "黑名单管理数据"); + } + + /** + * 获取黑名单管理详细信息 + */ + @RequiresPermissions("system:blackList:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(sysBlackListService.selectSysBlackListById(id)); + } + + /** + * 新增黑名单管理 + */ + @RequiresPermissions("system:blackList:add") + @Log(title = "黑名单管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SysBlackList sysBlackList) + { + //查询符合条件的访客人员并将注册人员信息清空并下发设备 + Visitor visitor = visitorService.selectVisitorByPhone(sysBlackList.getPhone()); +// if(StringUtils.isNotEmpty(visitor.getGuid())){ +// String data=sysApiService.admitDelete(visitor.getGuid()); +// } +// visitor.setGuid(""); +// visitor.setFaceGuid(""); + if(visitor != null) { + visitorService.updateVisitor(visitor); + } + + return toAjax(sysBlackListService.insertSysBlackList(sysBlackList)); + } + + /** + * 修改黑名单管理 + */ + @RequiresPermissions("system:blackList:edit") + @Log(title = "黑名单管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysBlackList sysBlackList) + { + //查询符合条件的访客人员并将注册人员信息清空并下发设备 + Visitor visitor = visitorService.selectVisitorByPhone(sysBlackList.getPhone()); +// if(StringUtils.isNotEmpty(visitor.getGuid())){ +// String data=sysApiService.admitDelete(visitor.getGuid()); +// } +// visitor.setGuid(""); +// visitor.setFaceGuid(""); + if(visitor != null) { + visitorService.updateVisitor(visitor); + + } + return toAjax(sysBlackListService.updateSysBlackList(sysBlackList)); + } + + /** + * 删除黑名单管理 + */ + @RequiresPermissions("system:blackList:remove") + @Log(title = "黑名单管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(sysBlackListService.deleteSysBlackListByIds(ids)); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysBranchController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysBranchController.java new file mode 100644 index 0000000..ffb5355 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysBranchController.java @@ -0,0 +1,222 @@ +package com.dcsoft.system.controller; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.UUID; +import javax.servlet.http.HttpServletResponse; + +import cn.hutool.http.HttpResponse; +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson.JSONObject; +import com.dcsoft.common.core.constant.Constants; +import com.dcsoft.common.core.exception.ServiceException; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.system.domain.SysEquipment; +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.domain.SysPeopleRule; +import com.dcsoft.system.domain.vo.JjserInfoVo; +import com.dcsoft.system.service.ISysPeopleRuleService; +import com.dcsoft.system.service.ISysPeopleService; +import org.apache.commons.lang3.ArrayUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.system.domain.SysBranch; +import com.dcsoft.system.service.ISysBranchService; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.page.TableDataInfo; + +/** + * 部门管理Controller + * + * @author dcsoft + * @date 2023-03-07 + */ +@RestController +@RequestMapping("/sysBranch") +public class SysBranchController extends BaseController +{ + @Autowired + private ISysBranchService sysBranchService; + + @Autowired + private ISysPeopleService sysPeopleService; + + + @Autowired + private ISysPeopleRuleService sysPeopleRuleService; + + /** + * 查询部门管理列表 + */ + @RequiresPermissions("system:sysBranch:list") + @GetMapping("/list") + public AjaxResult list(SysBranch sysBranch) + { + List list = sysBranchService.selectSysBranchList(sysBranch); + for (SysBranch branch : list) { + if(StringUtils.isNotEmpty(branch.getIsExamine())) { + branch.setExamine(Constants.ONE.equals(branch.getIsExamine())); + } + } + return success(list); + } + + /** + * 查询部门管理列表 + */ + @RequiresPermissions("system:sysBranch:list") + @GetMapping("/pageList") + public TableDataInfo pageList(SysBranch sysBranch) + { + startPage(); + List list = sysBranchService.selectSysBranchList(sysBranch); + return getDataTable(list); + } + + /** + * 查询部门列表(排除节点) + */ + @RequiresPermissions("system:sysBranch:list") + @GetMapping("/list/exclude/{id}") + public AjaxResult excludeChild(@PathVariable(value = "id", required = false) String id) + { + List depts = sysBranchService.selectSysBranchList(new SysBranch()); + depts.removeIf(d -> d.getId().equals(id) || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), id + "")); + return success(depts); + } + + /** + * 导出部门管理列表 + */ + @RequiresPermissions("system:sysBranch:export") + @Log(title = "部门管理", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysBranch sysBranch) + { + List list = sysBranchService.selectSysBranchList(sysBranch); + ExcelUtil util = new ExcelUtil(SysBranch.class); + util.exportExcel(response, list, "部门管理数据"); + } + + /** + * 获取部门管理详细信息 + */ + @RequiresPermissions("system:sysBranch:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") String id) + { + return success(sysBranchService.selectSysBranchById(id)); + } + + /** + * 新增部门管理 + */ + @RequiresPermissions("system:sysBranch:add") + @Log(title = "部门管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SysBranch sysBranch) + { sysBranch.setId(UUID.randomUUID().toString()); + return toAjax(sysBranchService.insertSysBranch(sysBranch)); + } + + /** + * 修改部门管理 + */ + @RequiresPermissions("system:sysBranch:edit") + @Log(title = "部门管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysBranch sysBranch) + { + return toAjax(sysBranchService.updateSysBranch(sysBranch)); + } + + /** + * 删除部门管理 + */ + @RequiresPermissions("system:sysBranch:remove") + @Log(title = "部门管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable String[] ids) + { + return toAjax(sysBranchService.deleteSysBranchByIds(ids)); + } + + /** + * 获取空间树列表 + */ +// @RequiresPermissions("system:sysBranch:list") + @GetMapping("/branchTree") + public AjaxResult branchTree(SysBranch space) + { + return success(sysBranchService.selectBranchTreeList(space)); + } + + @RequiresPermissions("system:sysBranch:list") + @GetMapping("/queryBranchTree") + public AjaxResult queryBranchTree(SysBranch space) + { + return success(sysBranchService.queryBranchTree(space)); + } + + /** + * 同步部门(锦江) + */ + @PostMapping("/saveBranchTree") + public void saveBranchTree(SysBranch space) { + sysBranchService.saveBranchTree(space); + } + + /** + * 同步岗位(锦江) + */ + @GetMapping("/saveStation") + public void saveStation(SysBranch space) { + sysBranchService.saveStation(space); + } + + + /** + * 获取设备信息详细信息 + */ + @GetMapping(value = "/down/{id}") + public AjaxResult down(@PathVariable("id") Long id) + { + SysPeople people=new SysPeople(); + people.setBranchParent(id); + List peopleList=sysPeopleService.selectSysPeopleList(people); + for(SysPeople p:peopleList){ + if(p.getBranch()!=null){ + SysPeopleRule sysPeopleRule=new SysPeopleRule(); + sysPeopleRule.setRuleId(p.getBranch().getRuleId()); + sysPeopleRule.setPeopleId(p.getId()); + sysPeopleRuleService.insertSysPeopleRule(sysPeopleRule); + p.setDown(0L); + sysPeopleService.updateSysPeople(p); + } + } + return success(peopleList); + } + + /** + * 查询物业子部门 + * @return + */ + @PostMapping("/queryPropertyDept") + public AjaxResult queryPropertyDept() { + return success(sysBranchService.queryPropertyDept("2d93b8fc-d510-47ca-9ba0-a7ad3bdb7c7d")); + } + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysConfigController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysConfigController.java new file mode 100644 index 0000000..7f13756 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysConfigController.java @@ -0,0 +1,173 @@ +package com.dcsoft.system.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDataInfo; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.domain.SysConfig; +import com.dcsoft.system.service.ISysConfigService; + +/** + * 参数配置 信息操作处理 + * + * @author dcsoft + */ +@RestController +@RequestMapping("/config") +public class SysConfigController extends BaseController +{ + @Autowired + private ISysConfigService configService; + + /** + * 获取参数配置列表 + */ + @RequiresPermissions("system:config:list") + @GetMapping("/list") + public TableDataInfo list(SysConfig config) + { + startPage(); + List list = configService.selectConfigList(config); + return getDataTable(list); + } + + @Log(title = "参数管理", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:config:export") + @PostMapping("/export") + public void export(HttpServletResponse response, SysConfig config) + { + List list = configService.selectConfigList(config); + ExcelUtil util = new ExcelUtil(SysConfig.class); + util.exportExcel(response, list, "参数数据"); + } + + /** + * 根据参数编号获取详细信息 + */ + @GetMapping(value = "/{configId}") + public AjaxResult getInfo(@PathVariable Long configId) + { + return success(configService.selectConfigById(configId)); + } + + /** + * 根据参数键名查询参数值 + */ + @GetMapping(value = "/configKey/{configKey}") + public AjaxResult getConfigKey(@PathVariable String configKey) + { + return success(configService.selectConfigByKey(configKey)); + } + + /** + * 新增参数配置 + */ + @RequiresPermissions("system:config:add") + @Log(title = "参数管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysConfig config) + { + if (!configService.checkConfigKeyUnique(config)) + { + return error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在"); + } + config.setCreateBy(SecurityUtils.getUsername()); + return toAjax(configService.insertConfig(config)); + } + + /** + * 修改参数配置 + */ + @RequiresPermissions("system:config:edit") + @Log(title = "参数管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysConfig config) + { + if (!configService.checkConfigKeyUnique(config)) + { + return error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在"); + } + config.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(configService.updateConfig(config)); + } + + /** + * 删除参数配置 + */ + @RequiresPermissions("system:config:remove") + @Log(title = "参数管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{configIds}") + public AjaxResult remove(@PathVariable Long[] configIds) + { + configService.deleteConfigByIds(configIds); + return success(); + } + + /** + * 刷新参数缓存 + */ + @RequiresPermissions("system:config:remove") + @Log(title = "参数管理", businessType = BusinessType.CLEAN) + @DeleteMapping("/refreshCache") + public AjaxResult refreshCache() + { + configService.resetConfigCache(); + return success(); + } + + /** + * 刷新参数缓存 + */ + @Log(title = "数据库备份", businessType = BusinessType.OTHER) + @DeleteMapping("/backUp") + public AjaxResult backUp() + { + configService.backUp(); + return success(); + } + + + @Log(title = "数据库备份", businessType = BusinessType.OTHER) + @PostMapping("/backSql") + public AjaxResult backSql() + { + configService.backUp(); + return success(); + } + + /** + * 刷新参数缓存 + */ + @GetMapping("/listFile") + public AjaxResult listFile() + { + List list=configService.listFile(); + return success(list); + } + + /** + * 根据参数编号获取详细信息 + */ + @GetMapping(value = "recover/{id}") + public AjaxResult recover(@PathVariable String id) + { + return success(configService.recover(id)); + } + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysDeptController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysDeptController.java new file mode 100644 index 0000000..b63e66c --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysDeptController.java @@ -0,0 +1,159 @@ +package com.dcsoft.system.controller; + +import java.util.List; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.dcsoft.system.domain.SysBranch; +import com.dcsoft.system.service.ISysBranchService; +import org.apache.commons.lang3.ArrayUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.core.constant.UserConstants; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.api.domain.SysDept; +import com.dcsoft.system.service.ISysDeptService; + +/** + * 部门信息 + * + * @author dcsoft + */ +@RestController +@RequestMapping("/dept") +public class SysDeptController extends BaseController +{ + @Autowired + private ISysDeptService deptService; + + @Autowired + private ISysBranchService sysBranchService; + + /** + * 获取部门列表 + */ + @RequiresPermissions("system:dept:list") + @GetMapping("/list") + public AjaxResult list(SysDept dept) + { + List depts = deptService.selectDeptList(dept); + return success(depts); + } + + /** + * 查询部门列表(排除节点) + */ + @RequiresPermissions("system:dept:list") + @GetMapping("/list/exclude/{deptId}") + public AjaxResult excludeChild(@PathVariable(value = "deptId", required = false) Long deptId) + { + List depts = deptService.selectDeptList(new SysDept()); + depts.removeIf(d -> d.getDeptId().intValue() == deptId || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), deptId + "")); + return success(depts); + } + + /** + * 根据部门编号获取详细信息 + */ + @RequiresPermissions("system:dept:query") + @GetMapping(value = "/{deptId}") + public AjaxResult getInfo(@PathVariable Long deptId) + { + deptService.checkDeptDataScope(deptId); + return success(deptService.selectDeptById(deptId)); + } + + /** + * 新增部门 + */ + @RequiresPermissions("system:dept:add") + @Log(title = "部门管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDept dept) + { + if (!deptService.checkDeptNameUnique(dept)) + { + return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在"); + } + + dept.setCreateBy(SecurityUtils.getUsername()); + int i=deptService.insertDept(dept); + //查询上级部门绑定被企业园区绑定获取到企业园区的id + try { + SysBranch sysBranch =sysBranchService.selectSysBranchByDeptId(dept.getParentId()); + if(sysBranch!=null){ + SysBranch sysBranch1=new SysBranch(); + sysBranch1.setDeptId(dept.getDeptId()); + sysBranch1.setName(dept.getDeptName()); + sysBranch1.setParentId(sysBranch.getId()); + sysBranch1.setPhone(dept.getPhone()); + sysBranch1.setAncestors(dept.getAncestors()); + sysBranchService.insertSysBranch(sysBranch1); + } + }catch (Exception e){ + e.printStackTrace(); + } + + return toAjax(i); + } + + /** + * 修改部门 + */ + @RequiresPermissions("system:dept:edit") + @Log(title = "部门管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysDept dept) + { + Long deptId = dept.getDeptId(); + deptService.checkDeptDataScope(deptId); + if (!deptService.checkDeptNameUnique(dept)) + { + return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在"); + } + else if (dept.getParentId().equals(deptId)) + { + return error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己"); + } + else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0) + { + return error("该部门包含未停用的子部门!"); + } + dept.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(deptService.updateDept(dept)); + } + + /** + * 删除部门 + */ + @RequiresPermissions("system:dept:remove") + @Log(title = "部门管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{deptId}") + public AjaxResult remove(@PathVariable Long deptId) + { + if (deptService.hasChildByDeptId(deptId)) + { + return warn("存在下级部门,不允许删除"); + } + if (deptService.checkDeptExistUser(deptId)) + { + return warn("部门存在用户,不允许删除"); + } + deptService.checkDeptDataScope(deptId); + return toAjax(deptService.deleteDeptById(deptId)); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysDictDataController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysDictDataController.java new file mode 100644 index 0000000..7f93069 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysDictDataController.java @@ -0,0 +1,122 @@ +package com.dcsoft.system.controller; + +import java.util.ArrayList; +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDataInfo; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.api.domain.SysDictData; +import com.dcsoft.system.service.ISysDictDataService; +import com.dcsoft.system.service.ISysDictTypeService; + +/** + * 数据字典信息 + * + * @author dcsoft + */ +@RestController +@RequestMapping("/dict/data") +public class SysDictDataController extends BaseController +{ + @Autowired + private ISysDictDataService dictDataService; + + @Autowired + private ISysDictTypeService dictTypeService; + + @RequiresPermissions("system:dict:list") + @GetMapping("/list") + public TableDataInfo list(SysDictData dictData) + { + startPage(); + List list = dictDataService.selectDictDataList(dictData); + return getDataTable(list); + } + + @Log(title = "字典数据", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:dict:export") + @PostMapping("/export") + public void export(HttpServletResponse response, SysDictData dictData) + { + List list = dictDataService.selectDictDataList(dictData); + ExcelUtil util = new ExcelUtil(SysDictData.class); + util.exportExcel(response, list, "字典数据"); + } + + /** + * 查询字典数据详细 + */ + @RequiresPermissions("system:dict:query") + @GetMapping(value = "/{dictCode}") + public AjaxResult getInfo(@PathVariable Long dictCode) + { + return success(dictDataService.selectDictDataById(dictCode)); + } + + /** + * 根据字典类型查询字典数据信息 + */ + @GetMapping(value = "/type/{dictType}") + public AjaxResult dictType(@PathVariable String dictType) + { + List data = dictTypeService.selectDictDataByType(dictType); + if (StringUtils.isNull(data)) + { + data = new ArrayList(); + } + return success(data); + } + + /** + * 新增字典类型 + */ + @RequiresPermissions("system:dict:add") + @Log(title = "字典数据", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDictData dict) + { + dict.setCreateBy(SecurityUtils.getUsername()); + return toAjax(dictDataService.insertDictData(dict)); + } + + /** + * 修改保存字典类型 + */ + @RequiresPermissions("system:dict:edit") + @Log(title = "字典数据", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysDictData dict) + { + dict.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(dictDataService.updateDictData(dict)); + } + + /** + * 删除字典类型 + */ + @RequiresPermissions("system:dict:remove") + @Log(title = "字典类型", businessType = BusinessType.DELETE) + @DeleteMapping("/{dictCodes}") + public AjaxResult remove(@PathVariable Long[] dictCodes) + { + dictDataService.deleteDictDataByIds(dictCodes); + return success(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysDictTypeController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysDictTypeController.java new file mode 100644 index 0000000..c4ec31f --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysDictTypeController.java @@ -0,0 +1,132 @@ +package com.dcsoft.system.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDataInfo; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.api.domain.SysDictType; +import com.dcsoft.system.service.ISysDictTypeService; + +/** + * 数据字典信息 + * + * @author dcsoft + */ +@RestController +@RequestMapping("/dict/type") +public class SysDictTypeController extends BaseController +{ + @Autowired + private ISysDictTypeService dictTypeService; + + @RequiresPermissions("system:dict:list") + @GetMapping("/list") + public TableDataInfo list(SysDictType dictType) + { + startPage(); + List list = dictTypeService.selectDictTypeList(dictType); + return getDataTable(list); + } + + @Log(title = "字典类型", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:dict:export") + @PostMapping("/export") + public void export(HttpServletResponse response, SysDictType dictType) + { + List list = dictTypeService.selectDictTypeList(dictType); + ExcelUtil util = new ExcelUtil(SysDictType.class); + util.exportExcel(response, list, "字典类型"); + } + + /** + * 查询字典类型详细 + */ + @RequiresPermissions("system:dict:query") + @GetMapping(value = "/{dictId}") + public AjaxResult getInfo(@PathVariable Long dictId) + { + return success(dictTypeService.selectDictTypeById(dictId)); + } + + /** + * 新增字典类型 + */ + @RequiresPermissions("system:dict:add") + @Log(title = "字典类型", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDictType dict) + { + if (!dictTypeService.checkDictTypeUnique(dict)) + { + return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在"); + } + dict.setCreateBy(SecurityUtils.getUsername()); + return toAjax(dictTypeService.insertDictType(dict)); + } + + /** + * 修改字典类型 + */ + @RequiresPermissions("system:dict:edit") + @Log(title = "字典类型", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysDictType dict) + { + if (!dictTypeService.checkDictTypeUnique(dict)) + { + return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在"); + } + dict.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(dictTypeService.updateDictType(dict)); + } + + /** + * 删除字典类型 + */ + @RequiresPermissions("system:dict:remove") + @Log(title = "字典类型", businessType = BusinessType.DELETE) + @DeleteMapping("/{dictIds}") + public AjaxResult remove(@PathVariable Long[] dictIds) + { + dictTypeService.deleteDictTypeByIds(dictIds); + return success(); + } + + /** + * 刷新字典缓存 + */ + @RequiresPermissions("system:dict:remove") + @Log(title = "字典类型", businessType = BusinessType.CLEAN) + @DeleteMapping("/refreshCache") + public AjaxResult refreshCache() + { + dictTypeService.resetDictCache(); + return success(); + } + + /** + * 获取字典选择框列表 + */ + @GetMapping("/optionselect") + public AjaxResult optionselect() + { + List dictTypes = dictTypeService.selectDictTypeAll(); + return success(dictTypes); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysEmpowerRecordController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysEmpowerRecordController.java new file mode 100644 index 0000000..bb71829 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysEmpowerRecordController.java @@ -0,0 +1,245 @@ +package com.dcsoft.system.controller; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.servlet.http.HttpServletResponse; + +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.dcsoft.common.core.constant.Constants; +import com.dcsoft.common.core.enums.exception.CommonExceptionEnum; +import com.dcsoft.common.core.exception.ServiceException; +import com.dcsoft.system.domain.SysEquipment; +import com.dcsoft.system.domain.SysPeopleEquipment; +import com.dcsoft.system.service.*; +import com.dcsoft.system.uniubi.service.ISysApiService; +import com.dcsoft.system.uniubi.service.ISysSdkService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.system.domain.SysEmpowerRecord; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.page.TableDataInfo; + +/** + * 授权记录Controller + * + * @author nichun + * @date 2023-03-08 + */ +@Slf4j +@RestController +@RequestMapping("/empowerRecord") +public class SysEmpowerRecordController extends BaseController +{ + @Autowired + private ISysEmpowerRecordService sysEmpowerRecordService; + + @Autowired + private ISysApiService sysApiService; + + @Autowired + private ISysEquipmentService equipmentService; + + @Autowired + private ISysRuleService ruleService; + + @Autowired + private ISysPeopleService peopleService; + + @Autowired + private ISysConfigService configService; + + @Autowired + private ISysSdkService sdkService; + + @Autowired + private ISysPeopleEquipmentService peopleEquipmentService; + + @Autowired + private ISysPeopleService sysPeopleService; + + /** + * 卡权限删除接口 + */ + public static final String delete = "/cardinfo/delete"; + + /** + * 查询授权记录列表 + */ + @RequiresPermissions("system:empowerRecord:list") + @GetMapping("/list") + public TableDataInfo list(SysEmpowerRecord sysEmpowerRecord) + { + startPage(); + List list = sysEmpowerRecordService.selectSysEmpowerRecordList(sysEmpowerRecord); + return getDataTable(list); + } + + /** + * 导出授权记录列表 + */ + @RequiresPermissions("system:empowerRecord:export") + @Log(title = "授权记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysEmpowerRecord sysEmpowerRecord) + { + List list = sysEmpowerRecordService.selectSysEmpowerRecordList(sysEmpowerRecord); + ExcelUtil util = new ExcelUtil(SysEmpowerRecord.class); + util.exportExcel(response, list, "授权记录数据"); + } + + /** + * 获取授权记录详细信息 + */ + @RequiresPermissions("system:empowerRecord:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(sysEmpowerRecordService.selectSysEmpowerRecordById(id)); + } + + /** + * 新增授权记录 + */ + @RequiresPermissions("system:empowerRecord:add") + @Log(title = "授权记录", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SysEmpowerRecord sysEmpowerRecord) + { + return toAjax(sysEmpowerRecordService.insertSysEmpowerRecord(sysEmpowerRecord)); + } + + /** + * 修改授权记录 + */ + @RequiresPermissions("system:empowerRecord:edit") + @Log(title = "授权记录", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysEmpowerRecord sysEmpowerRecord) + { + return toAjax(sysEmpowerRecordService.updateSysEmpowerRecord(sysEmpowerRecord)); + } + + /** + * 删除授权记录 + */ + @RequiresPermissions("system:empowerRecord:remove") + @Log(title = "授权记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + String cloud = configService.selectConfigByKey("sys.equipment.cloud"); + if("true".equals(cloud)){ + for(Long id:ids){ + SysEmpowerRecord record=sysEmpowerRecordService.selectSysEmpowerRecordById(id); + String data=sysApiService.authDeviceRevoke(equipmentService.selectSysEquipmentById(record.getEquipmentId()),peopleService.selectSysPeopleById(Long.parseLong(record.getPeopleId()))); + JSONObject json= JSONObject.parseObject(data); + if(!"1".equals(json.get("result")+"")){ + return error(json.get("msg")+""); + } + } + }else{ + for(Long id:ids){ + SysEmpowerRecord record=sysEmpowerRecordService.selectSysEmpowerRecordById(id); + SysEquipment equipment=equipmentService.selectSysEquipmentById(record.getEquipmentId()); + List peopleEquipmentList = peopleEquipmentService.selectSysPeopleEquipmentByPeopleId(record.getPeopleId()); + for(SysPeopleEquipment peopleEquipment:peopleEquipmentList){ + sdkService.personDelete(peopleEquipment.getGuid(), equipment.getIp(), equipment.getPassword()); + } + + if(5L == equipment.getProductId()){ + String doorNo = sysPeopleService.selectDoorNo(id); + SysEquipment sysEquipment = new SysEquipment(); + sysEquipment.setIp(equipment.getIp()); + sysEquipment.setPassword(equipment.getPassword()); + sysEquipment.setDoorNo(StringUtils.isEmpty(doorNo) ? "1" : doorNo); + deleteLadder(sysEquipment); + } + } + } + return toAjax(sysEmpowerRecordService.deleteSysEmpowerRecordByIds(ids)); + } + + private void deleteLadder(SysEquipment sysEquipment) { + log.info("梯控删除:" + sysEquipment); + log.info("梯控删除地址:" + "http://" + sysEquipment.getIp() + ":8090" + delete); + Map map = new HashMap<>(); + map.put("idcardnum", sysEquipment.getDoorNo()); + map.put("pass", sysEquipment.getPassword()); + String body = HttpUtil.createPost("http://" + sysEquipment.getIp() + ":8090" + delete).timeout(5000).body(JSON.toJSONString(map)).execute().body(); + log.info("梯控删除卡号接口返回:" + body); + JSONObject object = JSONObject.parseObject(body); + if(!Constants.CODE.equals(object.get("msg"))) { + log.error("梯控删除卡号接口异常码:" + object.get("msg").toString()); + throw new ServiceException(CommonExceptionEnum.REQUEST_ERROR.getCode(), "梯控删除卡号接口" + CommonExceptionEnum.REQUEST_ERROR.getMessage()); + } + } + + /** + * 查询授权管理记录详细 + */ + @GetMapping(value = "forbidRecordApi/{ids}/{type}") + public AjaxResult forbidRecordApi(@PathVariable List ids, @PathVariable("type") String type) { + Boolean flag=false; + String cloud = configService.selectConfigByKey("sys.equipment.cloud"); + if("true".equals(cloud)) { + for (Long id : ids) { + flag = true; + SysEmpowerRecord record = sysEmpowerRecordService.selectSysEmpowerRecordById(id); + record.setStatus(type); + if ("1".equals(type)) {//禁用 + String data = sysApiService.authDeviceRevoke(equipmentService.selectSysEquipmentById(record.getEquipmentId()), peopleService.selectSysPeopleById(Long.parseLong(record.getPeopleId()))); + JSONObject json = JSONObject.parseObject(data); + if (!"1".equals(json.get("result") + "")) { + return error(json.get("msg") + ""); + } + } else { + String data = sysApiService.authDevice(ruleService.selectSysRuleById(record.getRuleId()), peopleService.selectSysPeopleById(Long.parseLong(record.getPeopleId())), equipmentService.selectSysEquipmentById(record.getEquipmentId())); + JSONObject json = JSONObject.parseObject(data); + if (!"1".equals(json.get("result") + "")) { + return error(json.get("msg") + ""); + } + } + sysEmpowerRecordService.updateSysEmpowerRecord(record); + } + }else{ + for (Long id : ids) { + flag = true; + SysEmpowerRecord record = sysEmpowerRecordService.selectSysEmpowerRecordById(id); + record.setStatus(type); + if ("1".equals(type)) {//禁用 + SysEquipment equipment=equipmentService.selectSysEquipmentById(record.getEquipmentId()); + List peopleEquipmentList= peopleEquipmentService.selectSysPeopleEquipmentByPeopleId(record.getPeopleId()); + for(SysPeopleEquipment peopleEquipment:peopleEquipmentList){ + sdkService.personDelete(peopleEquipment.getGuid(), equipment.getIp(), equipment.getPassword()); + } + } else { + String data = sdkService.authDevice(ruleService.selectSysRuleById(record.getRuleId()), peopleService.selectSysPeopleById(Long.parseLong(record.getPeopleId())), equipmentService.selectSysEquipmentById(record.getEquipmentId())); + JSONObject json = JSONObject.parseObject(data); + if (!"1".equals(json.get("result") + "")) { + return error(json.get("msg") + ""); + } + } + sysEmpowerRecordService.updateSysEmpowerRecord(record); + } + } + return flag ? AjaxResult.success() : AjaxResult.error(); + } + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysEquipmentController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysEquipmentController.java new file mode 100644 index 0000000..09bbfa5 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysEquipmentController.java @@ -0,0 +1,350 @@ +package com.dcsoft.system.controller; + +import java.util.List; +import java.util.Map; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.dcsoft.system.domain.SysPeopleRule; +import com.dcsoft.system.service.ISysConfigService; +import com.dcsoft.system.service.ISysPeopleRuleService; +import com.dcsoft.system.uniubi.service.ISysApiService; +import com.dcsoft.system.uniubi.service.ISysSdkService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.CollectionUtils; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.system.domain.SysEquipment; +import com.dcsoft.system.service.ISysEquipmentService; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.page.TableDataInfo; + +/** + * 设备信息Controller + * + * @author nichun + * @date 2023-03-08 + */ +@RestController +@RequestMapping("/equipment") +public class SysEquipmentController extends BaseController +{ + @Autowired + private ISysEquipmentService sysEquipmentService; + + @Autowired + private ISysApiService sysApiService; + + @Autowired + private ISysConfigService configService; + + @Autowired + private ISysSdkService sdkService; + + @Autowired + private ISysPeopleRuleService sysPeopleRuleService; + + + + /** + * 查询设备信息列表 + */ + @RequiresPermissions("system:equipment:list") + @GetMapping("/list") + public TableDataInfo list(SysEquipment sysEquipment) + { + startPage(); + List list = sysEquipmentService.selectSysEquipmentList(sysEquipment); + return getDataTable(list); + } + + @GetMapping("/alllist") + public AjaxResult alllist(SysEquipment sysEquipment) + { + List list = sysEquipmentService.selectSysEquipmentList(sysEquipment); + return AjaxResult.success(list); + } + + /** + * 导出设备信息列表 + */ + @RequiresPermissions("system:equipment:export") + @Log(title = "设备信息", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysEquipment sysEquipment) + { + List list = sysEquipmentService.selectSysEquipmentList(sysEquipment); + ExcelUtil util = new ExcelUtil(SysEquipment.class); + util.exportExcel(response, list, "设备信息数据"); + } + + /** + * 获取设备信息详细信息 + */ + @RequiresPermissions("system:equipment:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + //判断设备是否上云 + String cloud = configService.selectConfigByKey("sys.equipment.cloud"); + if("true".equals(cloud)){ + //获取设备配置参数 + SysEquipment equipment=sysEquipmentService.selectSysEquipmentById(id); + if(StringUtils.isEmpty(equipment.getFaceEnable())){ + String datas=sysApiService.deviceSettingQuery(equipment); + JSONObject jsons= JSONObject.parseObject(datas); + if("1".equals(jsons.get("result")+"")) { + JSONArray objs= (JSONArray) jsons.get("data"); + Map map = JSON.parseObject(JSON.toJSONString(equipment), Map.class); + for(int i=0;i> list=sysEquipmentService.selectSysEquipmentPeopleById(id); + for(Map obj:list){ + Long peopleId=Long.parseLong(obj.get("people_id")+""); + SysPeopleRule sysPeopleRule=new SysPeopleRule(); + sysPeopleRule.setPeopleId(peopleId); + sysPeopleRule.setEquipmentId(id); + sysPeopleRuleService.insertSysPeopleRule(sysPeopleRule); + } + return success(list); + } + + /** + * 根据设备序列号查询设备信息 + * @param sysEquipment + * @return + */ + @PostMapping(value = "/queryEquipmentByDeviceKey") + public AjaxResult queryEquipmentByDeviceKey(@RequestBody SysEquipment sysEquipment) { + return success(sysEquipmentService.queryEquipmentByDeviceKey(sysEquipment)); + } + + /** + * 根据设备序列号修改设备密码 + * @param sysEquipment + * @return + */ + @PostMapping(value = "/updateEquipmentByDeviceKey") + public AjaxResult updateEquipmentByDeviceKey(@RequestBody SysEquipment sysEquipment) { + sysEquipmentService.updateEquipmentByDeviceKey(sysEquipment); + return success(); + } + + /** + * 根据设备序列号修改设备轮播文件 + * @param sysEquipment + * @return + */ + @PostMapping(value = "/updateEquipmentFile") + public AjaxResult updateEquipmentFile(@RequestBody SysEquipment sysEquipment) { + sysEquipmentService.updateEquipmentFile(sysEquipment); + return success(); + } + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysLogininforController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysLogininforController.java new file mode 100644 index 0000000..0629727 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysLogininforController.java @@ -0,0 +1,92 @@ +package com.dcsoft.system.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.core.constant.CacheConstants; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDataInfo; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.redis.service.RedisService; +import com.dcsoft.common.security.annotation.InnerAuth; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.system.api.domain.SysLogininfor; +import com.dcsoft.system.service.ISysLogininforService; + +/** + * 系统访问记录 + * + * @author dcsoft + */ +@RestController +@RequestMapping("/logininfor") +public class SysLogininforController extends BaseController +{ + @Autowired + private ISysLogininforService logininforService; + + @Autowired + private RedisService redisService; + + @RequiresPermissions("system:logininfor:list") + @GetMapping("/list") + public TableDataInfo list(SysLogininfor logininfor) + { + startPage(); + List list = logininforService.selectLogininforList(logininfor); + return getDataTable(list); + } + + @Log(title = "登录日志", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:logininfor:export") + @PostMapping("/export") + public void export(HttpServletResponse response, SysLogininfor logininfor) + { + List list = logininforService.selectLogininforList(logininfor); + ExcelUtil util = new ExcelUtil(SysLogininfor.class); + util.exportExcel(response, list, "登录日志"); + } + + @RequiresPermissions("system:logininfor:remove") + @Log(title = "登录日志", businessType = BusinessType.DELETE) + @DeleteMapping("/{infoIds}") + public AjaxResult remove(@PathVariable Long[] infoIds) + { + return toAjax(logininforService.deleteLogininforByIds(infoIds)); + } + + @RequiresPermissions("system:logininfor:remove") + @Log(title = "登录日志", businessType = BusinessType.DELETE) + @DeleteMapping("/clean") + public AjaxResult clean() + { + logininforService.cleanLogininfor(); + return success(); + } + + @RequiresPermissions("system:logininfor:unlock") + @Log(title = "账户解锁", businessType = BusinessType.OTHER) + @GetMapping("/unlock/{userName}") + public AjaxResult unlock(@PathVariable("userName") String userName) + { + redisService.deleteObject(CacheConstants.PWD_ERR_CNT_KEY + userName); + return success(); + } + + @InnerAuth + @PostMapping + public AjaxResult add(@RequestBody SysLogininfor logininfor) + { + return toAjax(logininforService.insertLogininfor(logininfor)); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysManageRecordController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysManageRecordController.java new file mode 100644 index 0000000..9b778f6 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysManageRecordController.java @@ -0,0 +1,202 @@ +package com.dcsoft.system.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.domain.SysRule; +import com.dcsoft.system.service.ISysConfigService; +import com.dcsoft.system.service.ISysPeopleService; +import com.dcsoft.system.service.ISysRuleService; +import com.dcsoft.system.uniubi.service.ISysApiService; +import com.dcsoft.system.uniubi.service.ISysSdkService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.system.domain.SysManageRecord; +import com.dcsoft.system.service.ISysManageRecordService; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.page.TableDataInfo; + +/** + * 授权管理记录Controller + * + * @author dcsoft + * @date 2023-03-09 + */ +@RestController +@RequestMapping("/manageRecord") +public class SysManageRecordController extends BaseController +{ + @Autowired + private ISysManageRecordService sysManageRecordService; + + @Autowired + private ISysRuleService ruleService; + + @Autowired + private ISysPeopleService peopleService; + + @Autowired + private ISysApiService sysApiService; + + @Autowired + private ISysConfigService configService; + + @Autowired + protected ISysSdkService sdkService; + + /** + * 查询授权管理记录列表 + */ + @GetMapping("/list") + public TableDataInfo list(SysManageRecord sysManageRecord) + { + startPage(); + List list = sysManageRecordService.selectSysManageRecordList(sysManageRecord); + return getDataTable(list); + } + + /** + * 导出授权管理记录列表 + */ + @Log(title = "授权管理记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysManageRecord sysManageRecord) + { + List list = sysManageRecordService.selectSysManageRecordList(sysManageRecord); + ExcelUtil util = new ExcelUtil(SysManageRecord.class); + util.exportExcel(response, list, "授权管理记录数据"); + } + + /** + * 获取授权管理记录详细信息 + */ + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(sysManageRecordService.selectSysManageRecordById(id)); + } + + /** + * 新增授权管理记录 + */ + @Log(title = "授权管理记录", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SysManageRecord manageRecord) + { + Boolean flag=false; + String cloud = configService.selectConfigByKey("sys.equipment.cloud"); + if("true".equals(cloud)){ + if(manageRecord.getType()==2){//人员授权管理 + if(StringUtils.isNotEmpty(manageRecord.getPeopleIds()+"")){ + for(String peopleId:manageRecord.getPeopleIds()){ + flag=true; + manageRecord.setPeopleId(Long.parseLong(peopleId)); + SysRule rule=ruleService.selectSysRuleById(manageRecord.getRuleId()); + SysPeople people =peopleService.selectSysPeopleById(Long.parseLong(peopleId)); + //添加人员授权信息 + String data=sysApiService.authDevice(rule,people); + if("".equals(data)){ + return AjaxResult.error("该规则未绑定设备!"); + } + sysManageRecordService.insertSysManageRecord(manageRecord); + } + } + } + if(manageRecord.getType()==1) {//部门授权管理 + if (StringUtils.isNotEmpty(manageRecord.getBranchIds() + "")) { + for (String branchId : manageRecord.getBranchIds()) { + flag = true; + manageRecord.setBranchId(Long.parseLong(branchId)); + sysManageRecordService.insertSysManageRecord(manageRecord); + //添加部门人员授权信息 + SysRule rule=ruleService.selectSysRuleById(manageRecord.getRuleId()); + SysPeople peoples=new SysPeople(); + peoples.setBranchId(branchId); + List peopleList=peopleService.selectSysPeopleList(peoples); + for(SysPeople people:peopleList){ + String data=sysApiService.authDevice(rule,people); + if("".equals(data)){ + return AjaxResult.error("该规则未绑定设备!"); + } + manageRecord.setPeopleId(people.getId()); + sysManageRecordService.insertSysManageRecord(manageRecord); + } + } + } + } + }else{ + if(manageRecord.getType()==2){//人员授权管理 + if(StringUtils.isNotEmpty(manageRecord.getPeopleIds()+"")) { + for(String peopleId:manageRecord.getPeopleIds()){ + flag=true; + manageRecord.setPeopleId(Long.parseLong(peopleId)); + SysRule rule=ruleService.selectSysRuleById(manageRecord.getRuleId()); + SysPeople people =peopleService.selectSysPeopleById(Long.parseLong(peopleId)); + //添加人员授权信息 + String data=sdkService.authDevice(rule,people); + if("".equals(data)){ + return AjaxResult.error("该规则未绑定设备!"); + } + sysManageRecordService.insertSysManageRecord(manageRecord); + } + } + } + if(manageRecord.getType()==1) {//部门授权管理 + if (StringUtils.isNotEmpty(manageRecord.getBranchIds() + "")) { + for (String branchId : manageRecord.getBranchIds()) { + flag = true; + manageRecord.setBranchId(Long.parseLong(branchId)); + sysManageRecordService.insertSysManageRecord(manageRecord); + //添加部门人员授权信息 + SysRule rule=ruleService.selectSysRuleById(manageRecord.getRuleId()); + SysPeople peoples=new SysPeople(); + peoples.setBranchId(branchId); + List peopleList=peopleService.selectSysPeopleList(peoples); + for(SysPeople people:peopleList){ + String data=sdkService.authDevice(rule,people); + if("".equals(data)){ + return AjaxResult.error("该规则未绑定设备!"); + } + manageRecord.setPeopleId(people.getId()); + sysManageRecordService.insertSysManageRecord(manageRecord); + } + } + } + } + } + return flag ? AjaxResult.success() : AjaxResult.error(); + } + + /** + * 修改授权管理记录 + */ + @Log(title = "授权管理记录", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysManageRecord sysManageRecord) + { + return toAjax(sysManageRecordService.updateSysManageRecord(sysManageRecord)); + } + + /** + * 删除授权管理记录 + */ + @Log(title = "授权管理记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(sysManageRecordService.deleteSysManageRecordByIds(ids)); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysMenuController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysMenuController.java new file mode 100644 index 0000000..2c741cd --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysMenuController.java @@ -0,0 +1,159 @@ +package com.dcsoft.system.controller; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.core.constant.UserConstants; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.domain.SysMenu; +import com.dcsoft.system.service.ISysMenuService; + +/** + * 菜单信息 + * + * @author dcsoft + */ +@RestController +@RequestMapping("/menu") +public class SysMenuController extends BaseController +{ + @Autowired + private ISysMenuService menuService; + + /** + * 获取菜单列表 + */ + @RequiresPermissions("system:menu:list") + @GetMapping("/list") + public AjaxResult list(SysMenu menu) + { + Long userId = SecurityUtils.getUserId(); + List menus = menuService.selectMenuList(menu, userId); + return success(menus); + } + + /** + * 根据菜单编号获取详细信息 + */ + @RequiresPermissions("system:menu:query") + @GetMapping(value = "/{menuId}") + public AjaxResult getInfo(@PathVariable Long menuId) + { + return success(menuService.selectMenuById(menuId)); + } + + /** + * 获取菜单下拉树列表 + */ + @GetMapping("/treeselect") + public AjaxResult treeselect(SysMenu menu) + { + Long userId = SecurityUtils.getUserId(); + List menus = menuService.selectMenuList(menu, userId); + return success(menuService.buildMenuTreeSelect(menus)); + } + + /** + * 加载对应角色菜单列表树 + */ + @GetMapping(value = "/roleMenuTreeselect/{roleId}") + public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId) + { + Long userId = SecurityUtils.getUserId(); + List menus = menuService.selectMenuList(userId); + AjaxResult ajax = AjaxResult.success(); + ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId)); + ajax.put("menus", menuService.buildMenuTreeSelect(menus)); + return ajax; + } + + /** + * 新增菜单 + */ + @RequiresPermissions("system:menu:add") + @Log(title = "菜单管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysMenu menu) + { + if (!menuService.checkMenuNameUnique(menu)) + { + return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); + } + else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) + { + return error("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); + } + menu.setCreateBy(SecurityUtils.getUsername()); + return toAjax(menuService.insertMenu(menu)); + } + + /** + * 修改菜单 + */ + @RequiresPermissions("system:menu:edit") + @Log(title = "菜单管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysMenu menu) + { + if (!menuService.checkMenuNameUnique(menu)) + { + return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); + } + else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) + { + return error("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); + } + else if (menu.getMenuId().equals(menu.getParentId())) + { + return error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己"); + } + menu.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(menuService.updateMenu(menu)); + } + + /** + * 删除菜单 + */ + @RequiresPermissions("system:menu:remove") + @Log(title = "菜单管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{menuId}") + public AjaxResult remove(@PathVariable("menuId") Long menuId) + { + if (menuService.hasChildByMenuId(menuId)) + { + return warn("存在子菜单,不允许删除"); + } + if (menuService.checkMenuExistRole(menuId)) + { + return warn("菜单已分配,不允许删除"); + } + return toAjax(menuService.deleteMenuById(menuId)); + } + + /** + * 获取路由信息 + * + * @return 路由信息 + */ + @GetMapping("getRouters") + public AjaxResult getRouters() + { + Long userId = SecurityUtils.getUserId(); + List menus = menuService.selectMenuTreeByUserId(userId); + return success(menuService.buildMenus(menus)); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysNoticeController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysNoticeController.java new file mode 100644 index 0000000..35018fb --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysNoticeController.java @@ -0,0 +1,92 @@ +package com.dcsoft.system.controller; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDataInfo; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.domain.SysNotice; +import com.dcsoft.system.service.ISysNoticeService; + +/** + * 公告 信息操作处理 + * + * @author dcsoft + */ +@RestController +@RequestMapping("/notice") +public class SysNoticeController extends BaseController +{ + @Autowired + private ISysNoticeService noticeService; + + /** + * 获取通知公告列表 + */ + @RequiresPermissions("system:notice:list") + @GetMapping("/list") + public TableDataInfo list(SysNotice notice) + { + startPage(); + List list = noticeService.selectNoticeList(notice); + return getDataTable(list); + } + + /** + * 根据通知公告编号获取详细信息 + */ + @RequiresPermissions("system:notice:query") + @GetMapping(value = "/{noticeId}") + public AjaxResult getInfo(@PathVariable Long noticeId) + { + return success(noticeService.selectNoticeById(noticeId)); + } + + /** + * 新增通知公告 + */ + @RequiresPermissions("system:notice:add") + @Log(title = "通知公告", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysNotice notice) + { + notice.setCreateBy(SecurityUtils.getUsername()); + return toAjax(noticeService.insertNotice(notice)); + } + + /** + * 修改通知公告 + */ + @RequiresPermissions("system:notice:edit") + @Log(title = "通知公告", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysNotice notice) + { + notice.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(noticeService.updateNotice(notice)); + } + + /** + * 删除通知公告 + */ + @RequiresPermissions("system:notice:remove") + @Log(title = "通知公告", businessType = BusinessType.DELETE) + @DeleteMapping("/{noticeIds}") + public AjaxResult remove(@PathVariable Long[] noticeIds) + { + return toAjax(noticeService.deleteNoticeByIds(noticeIds)); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysOperlogController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysOperlogController.java new file mode 100644 index 0000000..7bc8360 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysOperlogController.java @@ -0,0 +1,78 @@ +package com.dcsoft.system.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDataInfo; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.InnerAuth; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.system.api.domain.SysOperLog; +import com.dcsoft.system.service.ISysOperLogService; + +/** + * 操作日志记录 + * + * @author dcsoft + */ +@RestController +@RequestMapping("/operlog") +public class SysOperlogController extends BaseController +{ + @Autowired + private ISysOperLogService operLogService; + + @RequiresPermissions("system:operlog:list") + @GetMapping("/list") + public TableDataInfo list(SysOperLog operLog) + { + startPage(); + List list = operLogService.selectOperLogList(operLog); + return getDataTable(list); + } + + @Log(title = "操作日志", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:operlog:export") + @PostMapping("/export") + public void export(HttpServletResponse response, SysOperLog operLog) + { + List list = operLogService.selectOperLogList(operLog); + ExcelUtil util = new ExcelUtil(SysOperLog.class); + util.exportExcel(response, list, "操作日志"); + } + + @Log(title = "操作日志", businessType = BusinessType.DELETE) + @RequiresPermissions("system:operlog:remove") + @DeleteMapping("/{operIds}") + public AjaxResult remove(@PathVariable Long[] operIds) + { + return toAjax(operLogService.deleteOperLogByIds(operIds)); + } + + @RequiresPermissions("system:operlog:remove") + @Log(title = "操作日志", businessType = BusinessType.CLEAN) + @DeleteMapping("/clean") + public AjaxResult clean() + { + operLogService.cleanOperLog(); + return success(); + } + + @InnerAuth + @PostMapping + public AjaxResult add(@RequestBody SysOperLog operLog) + { + return toAjax(operLogService.insertOperlog(operLog)); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysPeopleController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysPeopleController.java new file mode 100644 index 0000000..35e8d0d --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysPeopleController.java @@ -0,0 +1,1260 @@ +package com.dcsoft.system.controller; + +import cn.hutool.http.HttpResponse; +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.dcsoft.common.core.constant.Constants; +import com.dcsoft.common.core.domain.R; +import com.dcsoft.common.core.enums.CompanyType; +import com.dcsoft.common.core.exception.ServiceException; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.utils.uuid.IdUtils; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDataInfo; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.api.RemoteFileService; +import com.dcsoft.system.api.domain.SysFile; +import com.dcsoft.system.api.domain.SysUser; +import com.dcsoft.system.domain.*; +import com.dcsoft.system.domain.vo.JjserInfoVo; +import com.dcsoft.system.service.*; +import com.dcsoft.system.uniubi.domain.Person; +import com.dcsoft.system.uniubi.service.ISysApiService; +import com.dcsoft.system.uniubi.service.ISysSdkService; +import com.dcsoft.system.utils.PictureUtils; +import com.dcsoft.system.visitor.service.IVisitorService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.util.CollectionUtils; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.stream.Collectors; + +/** + * 人员管理Controller + * + * @author nichun + * @date 2023-03-08 + */ +@RestController +@RequestMapping("/sysPeople") +@Slf4j +public class SysPeopleController extends BaseController +{ + @Autowired + private ISysPeopleService sysPeopleService; + + @Autowired + private ISysApiService sysApiService; + + @Autowired + private ISysConfigService configService; + + @Autowired + protected ISysSdkService sdkService; + + @Autowired + private ISysEquipmentService equipmentService; + + @Autowired + private RemoteFileService fileService; + + @Autowired + protected ISysPeopleEquipmentService peopleEquipmentService; + + @Autowired + private ISysUserService userService; + + @Autowired + private ISysBranchService sysBranchService; + + @Autowired + private ISysRuleService sysRuleService; + + @Autowired + private ISysPeopleRuleService sysPeopleRuleService; + + @Autowired + private ISysSyncRuleService sysSyncRuleService; + + @Autowired + private IVisitorService visitorService; + + @Value("${park.tdGuid}") + public String tdGuid; + + public static ExecutorService service = Executors.newFixedThreadPool(10); + + + /** + * 查询人员管理列表 + */ + @GetMapping("/list") + public TableDataInfo list(SysPeople sysPeople) + { + List list = sysPeopleService.selectSysPeopleList(sysPeople); + return getDataTable(list); + } + + @GetMapping("/queryPeopleList") + public AjaxResult queryPeopleList(SysPeople sysPeople) { + List list = sysPeopleService.queryPeopleList(sysPeople); + return success(list); + } + + /** + * 导出人员管理列表 + */ + @RequiresPermissions("system:sysPeople:export") + @Log(title = "人员管理", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysPeople sysPeople) + { + List list = sysPeopleService.selectSysPeopleLists(sysPeople); + ExcelUtil util = new ExcelUtil(SysPeople.class); + util.exportExcel(response, list, "人员管理数据"); + } + + /** + * 获取人员管理详细信息 + */ + @RequiresPermissions("system:sysPeople:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(sysPeopleService.selectSysPeopleById(id)); + } + + /** + * 新增人员管理 + */ + @RequiresPermissions("system:sysPeople:add") + @Log(title = "人员管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SysPeople sysPeople) throws ExecutionException, InterruptedException { + SysPeople people = sysPeopleService.selectSysPeopleByGh(sysPeople.getGh()); + if(people != null) { + return error("该工号已存在"); + } + if(StringUtils.isNotEmpty(sysPeople.getDoorNo())) { + SysPeople doorNo = sysPeopleService.selectSysPeopleByDoorNo(sysPeople.getDoorNo()); + if(doorNo != null) { + return error("该门禁号已存在"); + } + } + + //判断设备是否上云 + String cloud = configService.selectConfigByKey("sys.equipment.cloud"); + int i=0; + if("true".equals(cloud)){ + String data=sysApiService.admitCreate(sysPeople); + JSONObject json= JSONObject.parseObject(data); + if("1".equals(json.get("result")+"")){ + JSONObject obj= (JSONObject) json.get("data"); + String admitGuid=obj.get("admitGuid")+""; + sysPeople.setGuid(admitGuid); + //人像注册,如果注册失败将人像置空 + String datas=sysApiService.faceRegister(sysPeople); + JSONObject jsons= JSONObject.parseObject(datas); + if("1".equals(jsons.get("result")+"")){ + JSONObject objs= (JSONObject) jsons.get("data"); + String faceGuid=objs.get("faceGuid")+""; + sysPeople.setFaceGuid(faceGuid); + } + }else{ + return error(json.get("msg")+""); + } + i=sysPeopleService.insertSysPeople(sysPeople); + }else{ + //注册设备进行注册 + if(StringUtils.isNotEmpty(sysPeople.getAvatar())) {//是否上传头像,检测照片是否合格 + SysEquipment equipment=new SysEquipment(); + equipment.setIsCj("1"); + equipment.setFlag("0"); + List list=equipmentService.selectSysEquipmentList(equipment); + if(list.size()>0){ + //人员是否注册 + String ip=list.get(0).getIp(); + String pass=list.get(0).getPassword(); + if(StringUtils.isEmpty(sysPeople.getGuid())){ + Person person=new Person(); + person.setName(sysPeople.getName()); + person.setiDNumber(sysPeople.getIdcard()); + person.setPhone(sysPeople.getPhone()); + String data=sdkService.personCreate(person,ip,pass); + JSONObject json= JSONObject.parseObject(data); + if("1".equals(json.get("result")+"")) { + JSONObject obj= (JSONObject) json.get("data"); + String admitGuid=obj.get("id")+""; + sysPeople.setGuid(admitGuid); + }else{ + return error(json.get("msg")+""); + } + }else{//更新人员信息 + sdkService.personDelete(sysPeople.getGuid(),ip,pass); + Person person=new Person(); + person.setId(sysPeople.getGuid()); + person.setName(sysPeople.getName()); + person.setiDNumber(sysPeople.getIdcard()); + person.setPhone(sysPeople.getPhone()); + String data=sdkService.personCreate(person,ip,pass); + JSONObject json= JSONObject.parseObject(data); + if("1".equals(json.get("result")+"")) { + }else{ + return error(json.get("msg")+""); + } + } + //人像是否注册 + String datas = sdkService.imageCreateUrl(sysPeople.getGuid(), sysPeople.getAvatar(), ip, pass); + JSONObject jsons = JSONObject.parseObject(datas); + if ("1".equals(jsons.get("result")+"")) { + if(jsons.get("data")!=null){ + String faceGuid = jsons.get("data")+""; + sysPeople.setFaceGuid(faceGuid); + } + }else{ + return error(jsons.get("msg")+""); + } + //照片检测后删除注册设备人员 + sdkService.personDelete(sysPeople.getGuid(),ip,pass); + }else{ + Long userId=SecurityUtils.getUserId(); + SysUser user=userService.selectUserById(userId); + if(user.getEquipmentId()!=null){ + SysEquipment equipments = equipmentService.selectSysEquipmentById(user.getEquipmentId()); + String ip = equipments.getIp(); + String pass = equipments.getPassword(); + String flag = equipments.getFlag(); + if("0".equals(flag)){ + Person person=new Person(); + person.setName(sysPeople.getName()); + person.setiDNumber(sysPeople.getIdcard()); + person.setPhone(sysPeople.getPhone()); + String data=sdkService.personCreate(person,ip,pass); + JSONObject json= JSONObject.parseObject(data); + if("1".equals(json.get("result")+"")) { + JSONObject obj= (JSONObject) json.get("data"); + String admitGuid=obj.get("id")+""; + sysPeople.setGuid(admitGuid); + }else{ + return error(json.get("msg")+""); + } + String datas = sdkService.imageCreateUrl(sysPeople.getGuid(), sysPeople.getAvatar(), ip, pass); + JSONObject jsons = JSONObject.parseObject(datas); + if ("1".equals(jsons.get("result")+"")) { + if(jsons.get("data")!=null){ + String faceGuid = jsons.get("data")+""; + sysPeople.setFaceGuid(faceGuid); + } + }else{ + return error(jsons.get("msg")+""); + } + //照片检测后删除注册设备人员 + sdkService.personDelete(sysPeople.getGuid(),ip,pass); + }else { + return error("默认设备设备已离线"); + } + } + } + }else{ + sysPeople.setGuid(IdUtils.simpleUUID()); + } + + //下发设备 + if(sysPeople.getBranchId()!=null){ + SysBranch branch=sysBranchService.selectSysBranchById(sysPeople.getBranchId()); + if (branch.getRuleId()!= null) { + //添加人员授权信息 + SysRule rule=sysRuleService.selectSysRuleById(branch.getRuleId()); + String data=sdkService.authDeviceNew(rule,sysPeople); + if("".equals(data)){ + return AjaxResult.error("该规则未绑定设备!"); + } + sysPeople.setDown(1L); + } + } + + i=sysPeopleService.insertSysPeople(sysPeople); + + } + return toAjax(i); + } + + + /** + * 修改人员管理 + */ + @RequiresPermissions("system:sysPeople:edit") + @Log(title = "人员管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysPeople sysPeople) + { + //判断设备是否上云 + String cloud = configService.selectConfigByKey("sys.equipment.cloud"); + if("true".equals(cloud)) { + if (StringUtils.isEmpty(sysPeople.getGuid())) { + String data = sysApiService.admitUpdate(sysPeople); + JSONObject json = JSONObject.parseObject(data); + if ("1".equals(json.get("result") + "")) { + //人像注册,如果注册失败将人像置空 + if (StringUtils.isEmpty(sysPeople.getFaceGuid())) { + String datas = sysApiService.faceRegister(sysPeople); + JSONObject jsons = JSONObject.parseObject(datas); + if ("1".equals(jsons.get("result") + "")) { + JSONObject objs = (JSONObject) jsons.get("data"); + String faceGuid = objs.get("faceGuid") + ""; + sysPeople.setFaceGuid(faceGuid); + } + } + } else { + return error(json.get("msg") + ""); + } + }else { + //人像注册,如果注册失败将人像置空 + if (StringUtils.isEmpty(sysPeople.getFaceGuid())) { + String datas = sysApiService.faceRegister(sysPeople); + JSONObject jsons = JSONObject.parseObject(datas); + if ("1".equals(jsons.get("result") + "")) { + JSONObject objs = (JSONObject) jsons.get("data"); + String faceGuid = objs.get("faceGuid") + ""; + sysPeople.setFaceGuid(faceGuid); + } + } + } + }else{ + //注册设备进行注册 + if(StringUtils.isNotEmpty(sysPeople.getAvatar())) {//是否上传头像,检测照片是否合格 + SysEquipment equipment=new SysEquipment(); + equipment.setIsCj("1"); + equipment.setFlag("0"); + List list=equipmentService.selectSysEquipmentList(equipment); + if(list.size()>0){ + //人员是否注册 + String ip=list.get(0).getIp(); + String pass=list.get(0).getPassword(); + if(StringUtils.isEmpty(sysPeople.getGuid())){ + Person person=new Person(); + person.setName(sysPeople.getName()); + person.setiDNumber(sysPeople.getIdcard()); + person.setPhone(sysPeople.getPhone()); + String data=sdkService.personCreate(person,ip,pass); + JSONObject json= JSONObject.parseObject(data); + log.info("人员修改-personCreate-result:{}", json.toJSONString()); + if("1".equals(json.get("result")+"")) { + JSONObject obj= (JSONObject) json.get("data"); + String admitGuid=obj.get("id")+""; + sysPeople.setGuid(admitGuid); + }else{ + return error(json.get("msg")+""); + } + }else{//更新人员信息 + sdkService.personDelete(sysPeople.getGuid(),ip,pass); + Person person=new Person(); + person.setId(sysPeople.getGuid()); + person.setName(sysPeople.getName()); + person.setiDNumber(sysPeople.getIdcard()); + person.setPhone(sysPeople.getPhone()); + String data=sdkService.personCreate(person,ip,pass); + JSONObject json= JSONObject.parseObject(data); + log.info("人员修改-personCreate2-result:{}", json.toJSONString()); + if("1".equals(json.get("result")+"")) { + }else{ + return error(json.get("msg")+""); + } + } + + //人像是否注册 + String datas = sdkService.imageCreateUrl(sysPeople.getGuid(), sysPeople.getAvatar(), ip, pass); + JSONObject jsons = JSONObject.parseObject(datas); + log.info("人员修改-imageCreateUrl-result:{}", jsons.toJSONString()); + if ("1".equals(jsons.get("result")+"")) { + if(jsons.get("data")!=null){ + String faceGuid = jsons.get("data")+""; + sysPeople.setFaceGuid(faceGuid); + } + }else{ + return error(jsons.get("msg")+""); + } + //照片检测后删除注册设备人员 + sdkService.personDelete(sysPeople.getGuid(),ip,pass); + }else{ + Long userId=SecurityUtils.getUserId(); + SysUser user=userService.selectUserById(userId); + if(user.getEquipmentId()!=null){ + SysEquipment equipments = equipmentService.selectSysEquipmentById(user.getEquipmentId()); + String ip = equipments.getIp(); + String pass = equipments.getPassword(); + String flag = equipments.getFlag(); + if("0".equals(flag)){ + if(StringUtils.isEmpty(sysPeople.getGuid())){ + Person person=new Person(); + person.setName(sysPeople.getName()); + person.setiDNumber(sysPeople.getIdcard()); + person.setPhone(sysPeople.getPhone()); + String data=sdkService.personCreate(person,ip,pass); + JSONObject json= JSONObject.parseObject(data); + if("1".equals(json.get("result")+"")) { + JSONObject obj= (JSONObject) json.get("data"); + String admitGuid=obj.get("id")+""; + sysPeople.setGuid(admitGuid); + }else{ + return error(json.get("msg")+""); + } + if(StringUtils.isNotEmpty(sysPeople.getAvatar())){ + String datas = sdkService.imageCreateUrl(sysPeople.getGuid(), sysPeople.getAvatar(), ip, pass); + JSONObject jsons = JSONObject.parseObject(datas); + if ("true".equals(jsons.get("success") + "")) { + if(jsons.get("data")!=null){ + String faceGuid = jsons.get("data")+""; + sysPeople.setFaceGuid(faceGuid); + } + }else{ + return error(jsons.get("msg")+""); + } + } + //照片检测后删除注册设备人员 + sdkService.personDelete(sysPeople.getGuid(),ip,pass); + }else{ + if(StringUtils.isEmpty(sysPeople.getFaceGuid())){ + String datas = sdkService.imageCreateUrl(sysPeople.getGuid(), sysPeople.getAvatar(), ip, pass); + JSONObject jsons = JSONObject.parseObject(datas); + logger.info("进入无jsons==============="+jsons); + if ("true".equals(jsons.get("success") + "")) { + if(jsons.get("data")!=null){ + String faceGuid = jsons.get("data")+""; + logger.info("进入无faceguid==============="+faceGuid); + sysPeople.setFaceGuid(faceGuid); + } + } + //照片检测后删除注册设备人员 + sdkService.personDelete(sysPeople.getGuid(),ip,pass); + } + } + + }else { + return error("默认设备设备已离线"); + } + } + } + } + } + //下发设备 + if(sysPeople.getBranchId()!=null){ + SysBranch branch=sysBranchService.selectSysBranchById(sysPeople.getBranchId()); + if (branch.getRuleId()!= null) { + //添加人员授权信息 + SysRule rule=sysRuleService.selectSysRuleById(branch.getRuleId()); + String data=sdkService.authDeviceNew(rule,sysPeople); + log.info("人员修改-authDeviceNew-result:{}", data); + sysPeople.setDown(1L); + if("".equals(data)){ + return AjaxResult.error("该规则未绑定设备!"); + } + } + } + + SysPeople peopleInfo = sysPeopleService.selectSysPeopleById(sysPeople.getId()); + return toAjax(sysPeopleService.updateSysPeople(sysPeople)); + } + + + + @Log(title = "手机端人员管理", businessType = BusinessType.UPDATE) + @PutMapping("/update") + public AjaxResult update(@RequestBody SysPeople sysPeople) + { + //判断设备是否上云 + String cloud = configService.selectConfigByKey("sys.equipment.cloud"); + if("true".equals(cloud)) { + if (StringUtils.isEmpty(sysPeople.getGuid())) { + String data = sysApiService.admitUpdate(sysPeople); + JSONObject json = JSONObject.parseObject(data); + if ("1".equals(json.get("result") + "")) { + //人像注册,如果注册失败将人像置空 + if (StringUtils.isEmpty(sysPeople.getFaceGuid())) { + String datas = sysApiService.faceRegister(sysPeople); + JSONObject jsons = JSONObject.parseObject(datas); + if ("1".equals(jsons.get("result") + "")) { + JSONObject objs = (JSONObject) jsons.get("data"); + String faceGuid = objs.get("faceGuid") + ""; + sysPeople.setFaceGuid(faceGuid); + } + } + } else { + return error(json.get("msg") + ""); + } + }else { + //人像注册,如果注册失败将人像置空 + if (StringUtils.isEmpty(sysPeople.getFaceGuid())) { + String datas = sysApiService.faceRegister(sysPeople); + JSONObject jsons = JSONObject.parseObject(datas); + if ("true".equals(jsons.get("success") + "")) { + JSONObject objs = (JSONObject) jsons.get("data"); + String faceGuid = objs.get("faceGuid") + ""; + sysPeople.setFaceGuid(faceGuid); + }else{ + error(jsons.get("msg")+""); + } + } + } + }else{ + //注册设备进行注册 + if(StringUtils.isNotEmpty(sysPeople.getAvatar())) {//是否上传头像,检测照片是否合格 + SysEquipment equipment=new SysEquipment(); + equipment.setIsCj("1"); + equipment.setFlag("0"); + List list=equipmentService.selectSysEquipmentList(equipment); + if(list.size()>0){ + //人员是否注册 + String ip=list.get(0).getIp(); + String pass=list.get(0).getPassword(); + if(StringUtils.isEmpty(sysPeople.getGuid())){ + Person person=new Person(); + person.setName(sysPeople.getName()); + person.setiDNumber(sysPeople.getIdcard()); + person.setPhone(sysPeople.getPhone()); + String data=sdkService.personCreate(person,ip,pass); + JSONObject json= JSONObject.parseObject(data); + if("1".equals(json.get("result")+"")) { + JSONObject obj= (JSONObject) json.get("data"); + String admitGuid=obj.get("id")+""; + sysPeople.setGuid(admitGuid); + }else{ + return error(json.get("msg")+""); + } + }else{//更新人员信息 + sdkService.personDelete(sysPeople.getGuid(),ip,pass); + Person person=new Person(); + person.setId(sysPeople.getGuid()); + person.setName(sysPeople.getName()); + person.setiDNumber(sysPeople.getIdcard()); + person.setPhone(sysPeople.getPhone()); + String data=sdkService.personCreate(person,ip,pass); + JSONObject json= JSONObject.parseObject(data); + if("1".equals(json.get("result")+"")) { + }else{ + return error(json.get("msg")+""); + } + } + + //查看是否有底图,有底图就注册 + SysPeople sysPeoples=sysPeopleService.selectSysPeopleById(sysPeople.getId()); + if(StringUtils.isNotEmpty(sysPeoples.getAvatar())){ + sdkService.imageCreateUrl(sysPeople.getGuid(), sysPeoples.getAvatar(), ip, pass); + } + + //人像是否注册 + String datas = sdkService.imageCreateUrl(sysPeople.getGuid(), sysPeople.getAvatar(), ip, pass); + JSONObject jsons = JSONObject.parseObject(datas); + if ("true".equals(jsons.get("success")+"")) { + if(jsons.get("data")!=null){ + String faceGuid = jsons.get("data")+""; + sysPeople.setFaceGuid(faceGuid); + //照片检测后删除注册设备人员 + sdkService.personDelete(sysPeople.getGuid(),ip,pass); + } + }else{ + //照片检测后删除注册设备人员 + sdkService.personDelete(sysPeople.getGuid(),ip,pass); + return error(jsons.get("msg")+""); + } + } + } + } + //下发设备 + if(sysPeople.getBranchId()!=null){ + SysBranch branch=sysBranchService.selectSysBranchById(sysPeople.getBranchId()); + if (branch.getRuleId()!= null) { + //添加人员授权信息 + SysRule rule=sysRuleService.selectSysRuleById(branch.getRuleId()); + String data=sdkService.authDeviceNew(rule,sysPeople); + sysPeople.setDown(1L); + if("".equals(data)){ + return AjaxResult.error("该规则未绑定设备!"); + } + } + } + return toAjax(sysPeopleService.updateSysPeople(sysPeople)); + } + + + /** + * 删除人员管理 + */ + @RequiresPermissions("system:sysPeople:remove") + @Log(title = "人员管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + String cloud = configService.selectConfigByKey("sys.equipment.cloud"); + if("true".equals(cloud)) { + String admitGuids = ""; + for (Long id : ids) { + SysPeople people = sysPeopleService.selectSysPeopleById(id); + admitGuids += people.getGuid() + ","; + } + if (!"".equals(admitGuids)) { + admitGuids = admitGuids.substring(0, admitGuids.length() - 1); + if (!"null".equals(admitGuids)) { + String data = sysApiService.admitDelete(admitGuids); + JSONObject json = JSONObject.parseObject(data); + if ("1".equals(json.get("result") + "")) { + } else { + // return error(json.get("msg")+""); + } + } + } + }else{ + String admitGuids = ""; + for (Long id : ids) { + SysPeople people = sysPeopleService.selectSysPeopleById(id); + admitGuids += people.getGuid() + ","; + } + if (!"".equals(admitGuids)) { + admitGuids = admitGuids.substring(0, admitGuids.length() - 1); + if (!"null".equals(admitGuids)) { + SysEquipment equipment=new SysEquipment(); + equipment.setFlag("0"); + equipment.setProductId(3L); + List list = equipmentService.selectSysEquipmentList(equipment); + for(SysEquipment e:list){ + sdkService.personDelete(admitGuids,e.getIp(),e.getPassword()); + } + } + } + } + //暂未处理离线设备人员数据删除 + return toAjax(sysPeopleService.deleteSysPeopleByIds(ids)); + } + + /** + * 获取人员管理详细信息 + */ + @GetMapping(value = "/getUser/{userId}") + public AjaxResult getUser(@PathVariable("userId") Long userId) + { + return success(sysPeopleService.selectSysPeopleByUserId(userId)); + } + + /** + * 获取人员管理详细信息 + */ + @GetMapping(value = "/queryPeopleById") + public AjaxResult queryPeopleById(String id) + { + return success(sysPeopleService.queryPeopleById(id)); + } + + /** + * 获取人员管理详细信息 + */ + @GetMapping(value = "/getUserName/{branchName}/{userName}") + public AjaxResult getUserName(@PathVariable("branchName") String branchName,@PathVariable("userName") String userName) + { + return success(sysPeopleService.selectSysPeopleByBranchUser(branchName,userName)); + } + + /** + * 指纹采集 + */ + @PutMapping(value = "/dactylogram") + public AjaxResult dactylogram(@RequestBody SysPeople sysPeople) { + SysEquipment equipment=new SysEquipment(); + equipment.setIsCj("1"); + List list = equipmentService.selectSysEquipmentList(equipment); + if (list.size() > 0) { + String ip = list.get(0).getIp(); + String pass = list.get(0).getPassword(); + String flag = list.get(0).getFlag(); + if("0".equals(flag)){ + if (StringUtils.isEmpty(sysPeople.getGuid())) { + //判断设备人员是否能注册上设备后再删除掉 + Person person = new Person(); + person.setName(sysPeople.getName()); + person.setiDNumber(sysPeople.getIdcard()); + person.setPhone(sysPeople.getPhone()); + String data = sdkService.personCreate(person, ip, pass); + JSONObject json = JSONObject.parseObject(data); + if ("1".equals(json.get("result") + "")) { + JSONObject obj = (JSONObject) json.get("data"); + String admitGuid = obj.get("id") + ""; + sysPeople.setGuid(admitGuid); + //注册指纹 + String datas = sdkService.fingerRegist(admitGuid, ip, pass); + } else { + return error(json.get("msg") + ""); + } + }else {//只注册指纹 + String data = sdkService.fingerRegist(sysPeople.getGuid(), ip, pass); + } + }else { + return error("采集设备已离线"); + } + } + + return success(sysPeople); + } + + /** + * 人脸采集 + */ + @PutMapping(value = "/faceCollect") + public AjaxResult faceCollect(@RequestBody SysPeople sysPeople) { + //查询当前用户默认的采集端 + Long userId=SecurityUtils.getUserId(); + SysUser user=userService.selectUserById(userId); + if(user.getEquipmentId()!=null){ + SysEquipment equipment = equipmentService.selectSysEquipmentById(user.getEquipmentId()); + String ip = equipment.getIp(); + String pass = equipment.getPassword(); + String flag = equipment.getFlag(); + if("0".equals(flag)){ + if (StringUtils.isEmpty(sysPeople.getGuid())) { + //判断设备人员是否能注册上设备后再删除掉 + Person person = new Person(); + person.setName(sysPeople.getName()); + person.setiDNumber(sysPeople.getIdcard()); + person.setPhone(sysPeople.getPhone()); + String data = sdkService.personCreate(person, ip, pass); + JSONObject json = JSONObject.parseObject(data); + if ("1".equals(json.get("result") + "")) { + JSONObject obj = (JSONObject) json.get("data"); + String admitGuid = obj.get("id") + ""; + sysPeople.setGuid(admitGuid); + //注册人脸 + String datas = sdkService.takeImg(admitGuid, ip, pass); + } else { + return error(json.get("msg") + ""); + } + }else {//只注册人脸 + //删除采集设备已有人脸 + Person person = new Person(); + person.setName(sysPeople.getName()); + person.setiDNumber(sysPeople.getIdcard()); + person.setPhone(sysPeople.getPhone()); + person.setId(sysPeople.getGuid()); + sdkService.personCreate(person, ip, pass); + try{ + SysPeople people = sysPeopleService.selectByGuid(sysPeople); + if(StringUtils.isNotEmpty(people.getFaceGuid())){ + sdkService.imageDeletel(people.getFaceGuid(),ip,pass); + } + }catch (Exception e){ + e.printStackTrace(); + } + + String data = sdkService.takeImg(sysPeople.getGuid(), ip, pass); + } + }else { + return error("采集设备已离线"); + } + }else{ + SysEquipment equipment=new SysEquipment(); + equipment.setIsCj("1"); + List list = equipmentService.selectSysEquipmentList(equipment); + if (list.size() > 0) { + String ip = list.get(0).getIp(); + String pass = list.get(0).getPassword(); + String flag = list.get(0).getFlag(); + if("0".equals(flag)){ + if (StringUtils.isEmpty(sysPeople.getGuid())) { + //判断设备人员是否能注册上设备后再删除掉 + Person person = new Person(); + person.setName(sysPeople.getName()); + person.setiDNumber(sysPeople.getIdcard()); + person.setPhone(sysPeople.getPhone()); + String data = sdkService.personCreate(person, ip, pass); + JSONObject json = JSONObject.parseObject(data); + if ("1".equals(json.get("result") + "")) { + JSONObject obj = (JSONObject) json.get("data"); + String admitGuid = obj.get("id") + ""; + sysPeople.setGuid(admitGuid); + //注册人脸 + String datas = sdkService.takeImg(admitGuid, ip, pass); + } else { + return error(json.get("msg") + ""); + } + }else {//只注册人脸 + //删除采集设备已有人脸 + try{ + SysPeople people = sysPeopleService.selectByGuid(sysPeople); + sdkService.imageDeletel(people.getFaceGuid(),ip,pass); + }catch (Exception e){ + e.printStackTrace(); + } + String data = sdkService.takeImg(sysPeople.getGuid(), ip, pass); + } + }else { + return error("采集设备已离线"); + } + } + } + + + return success(sysPeople); + } + + /** + * 注册卡号 + */ + @PutMapping(value = "/icCardRegist") + public AjaxResult icCardRegist(@RequestBody SysPeople sysPeople) { + Long userId=SecurityUtils.getUserId(); + SysUser user=userService.selectUserById(userId); + if(user.getEquipmentId()!=null){ + SysEquipment equipment = equipmentService.selectSysEquipmentById(user.getEquipmentId()); + String ip = equipment.getIp(); + String pass = equipment.getPassword(); + String flag = equipment.getFlag(); + if("0".equals(flag)){ + if (StringUtils.isEmpty(sysPeople.getGuid())) { + //判断设备人员是否能注册上设备后再删除掉 + Person person = new Person(); + person.setName(sysPeople.getName()); + person.setiDNumber(sysPeople.getIdcard()); + person.setPhone(sysPeople.getPhone()); + String data = sdkService.personCreate(person, ip, pass); + JSONObject json = JSONObject.parseObject(data); + if ("1".equals(json.get("result") + "")) { + JSONObject obj = (JSONObject) json.get("data"); + String admitGuid = obj.get("id") + ""; + sysPeople.setGuid(admitGuid); + //注册门卡 + String datas = sdkService.icCardRegist(admitGuid, ip, pass); + } else { + return error(json.get("msg") + ""); + } + }else {//注册门卡 + sdkService.personDelete(sysPeople.getGuid(), ip, pass); + Person person = new Person(); + person.setName(sysPeople.getName()); + person.setiDNumber(sysPeople.getIdcard()); + person.setPhone(sysPeople.getPhone()); + person.setId(sysPeople.getGuid()); + person.setIdcardNum(""); + String data = sdkService.personCreate(person, ip, pass); + JSONObject json = JSONObject.parseObject(data); + if ("1".equals(json.get("result") + "")) { + JSONObject obj = (JSONObject) json.get("data"); + String admitGuid = obj.get("id") + ""; + sysPeople.setGuid(admitGuid); + //注册门卡 + String datas = sdkService.icCardRegist(admitGuid, ip, pass); + } + } + }else { + return error("采集设备已离线"); + } + }else{ + SysEquipment equipment=new SysEquipment(); + equipment.setIsCj("1"); + List list = equipmentService.selectSysEquipmentList(equipment); + if (list.size() > 0) { + String ip = list.get(0).getIp(); + String pass = list.get(0).getPassword(); + String flag = list.get(0).getFlag(); + if("0".equals(flag)){ + if (StringUtils.isEmpty(sysPeople.getGuid())) { + //判断设备人员是否能注册上设备后再删除掉 + Person person = new Person(); + person.setName(sysPeople.getName()); + person.setiDNumber(sysPeople.getIdcard()); + person.setPhone(sysPeople.getPhone()); + String data = sdkService.personCreate(person, ip, pass); + JSONObject json = JSONObject.parseObject(data); + if ("1".equals(json.get("result") + "")) { + JSONObject obj = (JSONObject) json.get("data"); + String admitGuid = obj.get("id") + ""; + sysPeople.setGuid(admitGuid); + //注册门卡 + String datas = sdkService.icCardRegist(admitGuid, ip, pass); + } else { + return error(json.get("msg") + ""); + } + }else {//注册门卡 + //删除门卡 + Person person = new Person(); + person.setName(sysPeople.getName()); + person.setiDNumber(sysPeople.getIdcard()); + person.setPhone(sysPeople.getPhone()); + person.setId(sysPeople.getGuid()); + person.setIdcardNum(""); + sdkService.personCreate(person, ip, pass); + + String data = sdkService.icCardRegist(sysPeople.getGuid(), ip, pass); + } + }else { + return error("采集设备已离线"); + } + } + } + return success(sysPeople); + } + + /** + * 人脸采集 + */ + @PutMapping(value = "/featureInfo") + public AjaxResult featureInfo(@RequestBody SysPeople sysPeople) { + SysEquipment equipment=new SysEquipment(); + equipment.setIsCj("1"); + List list = equipmentService.selectSysEquipmentList(equipment); + try{ + if (list.size() > 0) { + String ip = list.get(0).getIp(); + String pass = list.get(0).getPassword(); + //指纹查询 + String data = sdkService.featureInfo(sysPeople.getGuid(), ip, pass); + JSONObject json = JSONObject.parseObject(data); + if (StringUtils.isNotEmpty(json.get("data") + "")) { + JSONArray obj = (JSONArray) json.get("data"); + if(obj!=null){ + if(obj.get(0)!=null){ + JSONObject objs = (JSONObject) obj.get(0); + String feature=objs.get("feature")+""; + sysPeople.setFingerprint(feature); + } + } + } + } + }catch (Exception e){ + e.printStackTrace(); + } + return success(sysPeople); + } + + + + /* + * 人脸获取 + */ + @PutMapping(value = "/faceFind") + public AjaxResult faceFind(@RequestBody SysPeople sysPeople) { + Long userId=SecurityUtils.getUserId(); + SysUser user=userService.selectUserById(userId); + if(user.getEquipmentId()!=null){ + SysEquipment equipment = equipmentService.selectSysEquipmentById(user.getEquipmentId()); + String ip = equipment.getIp(); + String pass = equipment.getPassword(); + //人脸查询 + String data = sdkService.faceFind(sysPeople.getGuid(), ip, pass); + JSONObject json = JSONObject.parseObject(data); + if (StringUtils.isNotEmpty(json.get("data")+"")) { + JSONArray obj = (JSONArray) json.get("data"); + if(obj!=null){ + if(StringUtils.isNotEmpty(obj.get(0)+"")){ + JSONObject objs = (JSONObject) obj.get(0); + String path=objs.get("path")+""; + String facleId=objs.get("faceId")+""; + if(StringUtils.isNotEmpty(path)){ + //String paths=getImg(path,ip,pass); + //http://192.168.1.30:8090/download/image?pass=123123aa&filename=/data/record/RegisterPhoto//2023-07-28/17/173420_310.jpg + String urls="http://"+ip+":8090/download/image?pass="+pass+"&filename="+path; + MultipartFile file= PictureUtils.createMultipartFile(urls,facleId+".jpg"); + R datas= fileService.uploadMinio(file,facleId); + sysPeople.setAvatar(datas.getData().getUrl()); + sysPeople.setFaceGuid(facleId); + } + } + } + } + }else{ + SysEquipment equipment=new SysEquipment(); + equipment.setIsCj("1"); + List list = equipmentService.selectSysEquipmentList(equipment); + try{ + if (list.size() > 0) { + String ip = list.get(0).getIp(); + String pass = list.get(0).getPassword(); + //人脸查询 + String data = sdkService.faceFind(sysPeople.getGuid(), ip, pass); + JSONObject json = JSONObject.parseObject(data); + if (StringUtils.isNotEmpty(json.get("data")+"")) { + JSONArray obj = (JSONArray) json.get("data"); + if(obj!=null){ + if(StringUtils.isNotEmpty(obj.get(0)+"")){ + JSONObject objs = (JSONObject) obj.get(0); + String path=objs.get("path")+""; + String facleId=objs.get("faceId")+""; + if(StringUtils.isNotEmpty(path)){ + //String paths=getImg(path,ip,pass); + //http://192.168.1.30:8090/download/image?pass=123123aa&filename=/data/record/RegisterPhoto//2023-07-28/17/173420_310.jpg + String urls="http://"+ip+":8090/download/image?pass="+pass+"&filename="+path; + MultipartFile file= PictureUtils.createMultipartFile(urls,facleId+".jpg"); + R datas= fileService.uploadMinio(file,facleId); + sysPeople.setAvatar(datas.getData().getUrl()); + sysPeople.setFaceGuid(facleId); + } + } + } + } + } + }catch (Exception e){ + e.printStackTrace(); + } + } + return success(sysPeople); + } + + /* + * 人脸获取 + */ + @PutMapping(value = "/personFind") + public AjaxResult personFind(@RequestBody SysPeople sysPeople) { + Long userId=SecurityUtils.getUserId(); + SysUser user=userService.selectUserById(userId); + if(user.getEquipmentId()!=null){ + SysEquipment equipment = equipmentService.selectSysEquipmentById(user.getEquipmentId()); + String ip = equipment.getIp(); + String pass = equipment.getPassword(); + //人脸查询 + String data = sdkService.personFind(sysPeople.getGuid(), ip, pass); + JSONObject json = JSONObject.parseObject(data); + if ("1".equals(json.get("result") + "")) { + JSONArray obj = (JSONArray) json.get("data"); + if(obj!=null){ + if(StringUtils.isNotEmpty(obj.get(0)+"")){ + JSONObject objs = (JSONObject) obj.get(0); + String idcardNum=objs.get("idcardNum")+""; + sysPeople.setDoorNo(idcardNum.replaceFirst("^0*","")); + } + } + } + }else{ + SysEquipment equipment=new SysEquipment(); + equipment.setIsCj("1"); + List list = equipmentService.selectSysEquipmentList(equipment); + try{ + if (list.size() > 0) { + String ip = list.get(0).getIp(); + String pass = list.get(0).getPassword(); + //人脸查询 + String data = sdkService.personFind(sysPeople.getGuid(), ip, pass); + JSONObject json = JSONObject.parseObject(data); + if ("1".equals(json.get("result") + "")) { + JSONArray obj = (JSONArray) json.get("data"); + if(obj!=null){ + if(StringUtils.isNotEmpty(obj.get(0)+"")){ + JSONObject objs = (JSONObject) obj.get(0); + String idcardNum=objs.get("idcardNum")+""; + sysPeople.setDoorNo(idcardNum.replaceFirst("^0*","")); + } + } + } + } + }catch (Exception e){ + e.printStackTrace(); + } + } + + + return success(sysPeople); + } + + + @GetMapping("/down/{ids}") + public AjaxResult down(@PathVariable Long[] ids) + { + + SysEquipment equipment=new SysEquipment(); + equipment.setFlag("0"); + List list = equipmentService.selectSysEquipmentList(equipment); + if(list.size()>0){ + for(Long id:ids){//下发到设备上 + SysPeople people=sysPeopleService.selectSysPeopleById(id); + //下发设备 + if(people.getBranchId()!=null){ + SysBranch branch=sysBranchService.selectSysBranchById(people.getBranchId()); + if (branch.getRuleId()!= null) { + //添加人员授权信息 + SysRule rule=sysRuleService.selectSysRuleById(branch.getRuleId()); + String data=sdkService.authDeviceNew(rule,people); + people.setDown(1L); + if("".equals(data)){ + return AjaxResult.error("该规则未绑定设备!"); + } + } + } + sysPeopleService.updateSysPeople(people); + } + } + return toAjax(1); + } + + + @Log(title = "人员信息", businessType = BusinessType.IMPORT) + @RequiresPermissions("system:sysPeople:import") + @PostMapping("/importData") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception + { + ExcelUtil util = new ExcelUtil(SysPeople.class); + List userList = util.importExcel(file.getInputStream()); + String operName = SecurityUtils.getUsername(); + String message = sysPeopleService.importPeople(userList, updateSupport, operName); + return success(message); + } + + @PostMapping("/importTemplate") + public void importTemplate(HttpServletResponse response) throws IOException + { + ExcelUtil util = new ExcelUtil(SysPeople.class); + util.importTemplateExcel(response, "人员信息数据"); + } + + /** + * 定时批量下发 + */ + @PostMapping("/batchDistribute") + public void batchDistribute() { + List ids = sysPeopleService.queryPeopleInfo(); + if(!CollectionUtils.isEmpty(ids)) { + Long[] array = (Long[]) ids.stream().map(SysPeople::getId).toArray(); + down(array); + } + } + + + /** + * 同步人员(锦江) + */ + @PostMapping("/saveUserInfo") + public void saveUserInfo(SysBranch space) { + HttpResponse response; + if(Constants.ZERO.equals(space.getType())) { + response = HttpUtil.createGet("http://192.168.255.135:5566/api/ulYcRBiE/dhr/getAccount") + .header("access_token", "f23c34a3200f1994d85de4daf1f15d") + .execute(); + } else { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + response = HttpUtil.createGet("http://192.168.255.135:5566/api/ulYcRBiE/dhr/getAccount?ts=" + sdf.format(new Date())) + .header("access_token", "f23c34a3200f1994d85de4daf1f15d") + .execute(); + } + String body = response.body(); + JSONObject object = JSONObject.parseObject(body); + if(!Constants.CODE.equals(object.get("code").toString())) { + throw new ServiceException("人员接口请求异常"); + } + List data = JSONObject.parseArray(object.get("data").toString(), JjserInfoVo.class); + if(CollectionUtils.isEmpty(data)) { + return; + } + List list = new ArrayList<>(); + for (JjserInfoVo datum : data) { + datum.setDelFlag(Constants.ZERO); + if(Constants.FIVE.equals(datum.getStatus())) { + JjserInfoVo infoVo = new JjserInfoVo(); + infoVo.setWorkcode(datum.getWorkcode()); + list.add(infoVo); + } + } + if(!CollectionUtils.isEmpty(list)) { + List collectStr = list.stream().map(JjserInfoVo::getWorkcode).collect(Collectors.toList()); + List ids = sysPeopleService.queryPeople(collectStr); + if(!CollectionUtils.isEmpty(ids)) { + Long[] collect = ids.stream().map(SysPeople::getId).toArray(Long[]::new); + remove(collect); + } + } + List collect = data.stream().filter(e -> !Constants.FIVE.equals(e.getStatus())).collect(Collectors.toList()); + sysBranchService.saveUserInfo(collect); + } + + + /** + * 定时批量下发 + */ + @PostMapping("/batchDown") + public void batchDown() { + startPage(); + SysPeopleRule sysPeopleRule= new SysPeopleRule(); + sysPeopleRule.setSync(0L); + List List=sysPeopleRuleService.selectSysPeopleRuleList(sysPeopleRule); + for(SysPeopleRule p:List){ + SysPeople people=sysPeopleService.selectSysPeopleById(p.getPeopleId()); + if(p.getEquipmentId()==null){ + SysRule rule=sysRuleService.selectSysRuleById(p.getRuleId()); + sdkService.authDeviceNews(rule,people);//规则授权 + }else{ + SysEquipment equipment=equipmentService.selectSysEquipmentById(p.getEquipmentId()); + sdkService.authDevices(people,equipment);//设备人员授权恢复 + } + p.setSync(1L); + people.setDown(1L); + sysPeopleService.updateSysPeople(people); + sysPeopleRuleService.updateSysPeopleRule(p); + } + } + + /** + * 删除离职人员(测试用得) + */ + @PostMapping("/getAccount") + public void getAccount() { + String body = HttpUtil.createGet("http://192.168.255.135:5566/api/ulYcRBiE/dhr/getAccount") + .header("access_token", "f23c34a3200f1994d85de4daf1f15d") + .execute().body(); + JSONObject object = JSONObject.parseObject(body); + List data = JSONObject.parseArray(object.get("data").toString(), JjserInfoVo.class); + List sysPeople = sysPeopleService.queryPeople(new ArrayList<>()); + List collect = data.stream().filter(e -> Constants.FIVE.equals(e.getStatus())).collect(Collectors.toList()); + for (JjserInfoVo datum : collect) { + for (SysPeople sysPerson : sysPeople) { + if(datum.getWorkcode().equals(sysPerson.getGh())) { + System.out.println(datum.getWorkcode()); + SysPeople people = new SysPeople(); + people.setGh(datum.getWorkcode()); + sysPeopleService.updatePeople(people); + } + } + } + + } + + /** + * 通过手机号查找姓名 + * @param phone + * @return + */ + @PostMapping("/queryPeopleName") + public AjaxResult queryPeopleName(String phone, String deptType) { + List branch = visitorService.querySysBranch(deptType); + List collect = branch.stream().map(SysBranch::getId).collect(Collectors.toList()); + SysPeople people = sysPeopleService.queryPeopleName(phone, collect); + if(people == null) { + return success(); + } + return success(people); + } + + /** + * 通过职位标签查询人员信息 + * @param position + * @return + */ + @PostMapping("/queryPeopleByPosition") + public AjaxResult queryPeopleByPosition(String position) { + List sysPeople = sysPeopleService.queryPeopleByPosition(position); + return success(sysPeople); + } + + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysPeopleLeaveController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysPeopleLeaveController.java new file mode 100644 index 0000000..0481968 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysPeopleLeaveController.java @@ -0,0 +1,330 @@ +package com.dcsoft.system.controller; + +import com.alibaba.fastjson.JSONObject; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.utils.uuid.IdUtils; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDataInfo; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.api.domain.SysUser; +import com.dcsoft.system.domain.*; +import com.dcsoft.system.service.*; +import com.dcsoft.system.uniubi.domain.Person; +import com.dcsoft.system.uniubi.service.ISysSdkService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 离职管理Controller + * + * @author nichun + * @date 2023-09-09 + */ +@RestController +@RequestMapping("/peopleLeave") +public class SysPeopleLeaveController extends BaseController +{ + @Autowired + private ISysPeopleLeaveService sysPeopleLeaveService; + + @Autowired + private ISysPeopleService sysPeoplService; + + @Autowired + protected ISysSdkService sdkService; + + @Autowired + private ISysEquipmentService equipmentService; + + @Autowired + private ISysEmpowerRecordService empowerRecordService; + + @Autowired + private ISysUserService userService; + + @Autowired + private ISysBranchService sysBranchService; + + @Autowired + private ISysRuleService sysRuleService; + + + /** + * 查询离职管理列表 + */ + @RequiresPermissions("system:peopleLeave:list") + @GetMapping("/list") + public TableDataInfo list(SysPeopleLeave sysPeopleLeave) + { + startPage(); + List list = sysPeopleLeaveService.selectSysPeopleLeaveList(sysPeopleLeave); + return getDataTable(list); + } + + /** + * 查询人员 + * @param sysPeopleLeave + * @return + */ + @GetMapping("/queryPeopleList") + public AjaxResult queryPeopleList(SysPeopleLeave sysPeopleLeave) { + List list = sysPeopleLeaveService.selectSysPeopleLeaveList(sysPeopleLeave); + return success(list); + } + + /** + * 导出离职管理列表 + */ + @RequiresPermissions("system:peopleLeave:export") + @Log(title = "离职管理", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysPeopleLeave sysPeopleLeave) + { + List list = sysPeopleLeaveService.selectSysPeopleLeaveList(sysPeopleLeave); + ExcelUtil util = new ExcelUtil(SysPeopleLeave.class); + util.exportExcel(response, list, "离职管理数据"); + } + + /** + * 获取离职管理详细信息 + */ + @RequiresPermissions("system:peopleLeave:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(sysPeopleLeaveService.selectSysPeopleLeaveById(id)); + } + + /** + * 新增离职管理 + */ + @RequiresPermissions("system:peopleLeave:add") + @Log(title = "离职管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SysPeopleLeave sysPeopleLeave) + { + if ("1".equals(sysPeopleLeave.getStatus())){ + if(sysPeopleLeave.getPeopleId()!=null){ + sysPeoplService.deleteSysPeopleById(sysPeopleLeave.getPeopleId()); + //删除设备人员 + SysPeople people = sysPeoplService.selectSysPeopleById(sysPeopleLeave.getPeopleId()); + if(StringUtils.isNotEmpty(people.getGuid())){ + SysEquipment equipment=new SysEquipment(); + equipment.setFlag("0"); + List list = equipmentService.selectSysEquipmentList(equipment); + for(SysEquipment e:list){ + sdkService.personDelete(people.getGuid(),e.getIp(),e.getPassword()); + } + } + } + } + return toAjax(sysPeopleLeaveService.insertSysPeopleLeave(sysPeopleLeave)); + } + + /** + * 修改离职管理 + */ + @RequiresPermissions("system:peopleLeave:edit") + @Log(title = "离职管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysPeopleLeave sysPeopleLeave) + { + if ("1".equals(sysPeopleLeave.getStatus())){ + if(sysPeopleLeave.getPeopleId()!=null){ + sysPeoplService.deleteSysPeopleById(sysPeopleLeave.getPeopleId()); + //删除设备人员 + SysPeople people = sysPeoplService.selectSysPeopleById(sysPeopleLeave.getPeopleId()); + if(StringUtils.isNotEmpty(people.getGuid())){ + SysEquipment equipment=new SysEquipment(); + equipment.setFlag("0"); + List list = equipmentService.selectSysEquipmentList(equipment); + for(SysEquipment e:list){ + sdkService.personDelete(people.getGuid(),e.getIp(),e.getPassword()); + } + } + } + } + return toAjax(sysPeopleLeaveService.updateSysPeopleLeave(sysPeopleLeave)); + } + + /** + * 删除离职管理 + */ + @RequiresPermissions("system:peopleLeave:remove") + @Log(title = "离职管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(sysPeopleLeaveService.deleteSysPeopleLeaveByIds(ids)); + } + + @PostMapping("/peopleLeave") + public void peopleLeave() + { +// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");//设置日期格式 + SysPeopleLeave sysPeopleLeave=new SysPeopleLeave(); + sysPeopleLeave.setType("0"); + sysPeopleLeave.setStatus("0"); + List leaveList=sysPeopleLeaveService.selectSysPeopleLeaveList(sysPeopleLeave); + for(SysPeopleLeave peopleLeave:leaveList){ + if(peopleLeave.getPeopleId()!=null){ + sysPeoplService.deleteSysPeopleById(peopleLeave.getPeopleId()); + //删除设备人员 + SysPeople people = sysPeoplService.selectSysPeopleById(peopleLeave.getPeopleId()); + empowerRecordService.deleteSysEmpowerRecordByPeopleId(people.getId()); + if(StringUtils.isNotEmpty(people.getGuid())){ + SysEquipment equipment=new SysEquipment(); + equipment.setFlag("0"); + List list = equipmentService.selectSysEquipmentList(equipment); + for(SysEquipment e:list){ + sdkService.personDelete(people.getGuid(),e.getIp(),e.getPassword()); + } + } + } + peopleLeave.setStatus("1"); + sysPeopleLeaveService.updateSysPeopleLeave(peopleLeave); + } + } + + /** + * 恢复人员 + * + * @return + */ + @PostMapping("/recoveryPeople") + public AjaxResult recoveryPeople(String id) { + SysPeople sysPeople = sysPeoplService.selectSysPeopleByUserId(Long.valueOf(id)); + //注册设备进行注册 + if(StringUtils.isNotEmpty(sysPeople.getAvatar())) {//是否上传头像,检测照片是否合格 + SysEquipment equipment=new SysEquipment(); + equipment.setIsCj("1"); + equipment.setFlag("0"); + List list=equipmentService.selectSysEquipmentList(equipment); + if(list.size()>0){ + //人员是否注册 + String ip=list.get(0).getIp(); + String pass=list.get(0).getPassword(); + if(org.apache.commons.lang3.StringUtils.isEmpty(sysPeople.getGuid())){ + Person person=new Person(); + person.setName(sysPeople.getName()); + person.setiDNumber(sysPeople.getIdcard()); + person.setPhone(sysPeople.getPhone()); + String data=sdkService.personCreate(person,ip,pass); + JSONObject json= JSONObject.parseObject(data); + if("1".equals(json.get("result")+"")) { + JSONObject obj= (JSONObject) json.get("data"); + String admitGuid=obj.get("id")+""; + sysPeople.setGuid(admitGuid); + }else{ + return error(json.get("msg")+""); + } + }else{//更新人员信息 + sdkService.personDelete(sysPeople.getGuid(),ip,pass); + Person person=new Person(); + person.setId(sysPeople.getGuid()); + person.setName(sysPeople.getName()); + person.setiDNumber(sysPeople.getIdcard()); + person.setPhone(sysPeople.getPhone()); + String data=sdkService.personCreate(person,ip,pass); + JSONObject json= JSONObject.parseObject(data); + if("1".equals(json.get("result")+"")) { + }else{ + return error(json.get("msg")+""); + } + } + //人像是否注册 + String datas = sdkService.imageCreateUrl(sysPeople.getGuid(), sysPeople.getAvatar(), ip, pass); + JSONObject jsons = JSONObject.parseObject(datas); + if ("1".equals(jsons.get("result")+"")) { + if(jsons.get("data")!=null){ + String faceGuid = jsons.get("data")+""; + sysPeople.setFaceGuid(faceGuid); + } + }else{ + return error(jsons.get("msg")+""); + } + //照片检测后删除注册设备人员 + sdkService.personDelete(sysPeople.getGuid(),ip,pass); + }else{ + Long userId= SecurityUtils.getUserId(); + SysUser user=userService.selectUserById(userId); + if(user.getEquipmentId()!=null){ + SysEquipment equipments = equipmentService.selectSysEquipmentById(user.getEquipmentId()); + String ip = equipments.getIp(); + String pass = equipments.getPassword(); + String flag = equipments.getFlag(); + if("0".equals(flag)){ + Person person=new Person(); + person.setName(sysPeople.getName()); + person.setiDNumber(sysPeople.getIdcard()); + person.setPhone(sysPeople.getPhone()); + String data=sdkService.personCreate(person,ip,pass); + JSONObject json= JSONObject.parseObject(data); + if("1".equals(json.get("result")+"")) { + JSONObject obj= (JSONObject) json.get("data"); + String admitGuid=obj.get("id")+""; + sysPeople.setGuid(admitGuid); + }else{ + return error(json.get("msg")+""); + } + String datas = sdkService.imageCreateUrl(sysPeople.getGuid(), sysPeople.getAvatar(), ip, pass); + JSONObject jsons = JSONObject.parseObject(datas); + if ("1".equals(jsons.get("result")+"")) { + if(jsons.get("data")!=null){ + String faceGuid = jsons.get("data")+""; + sysPeople.setFaceGuid(faceGuid); + } + }else{ + return error(jsons.get("msg")+""); + } + //照片检测后删除注册设备人员 + sdkService.personDelete(sysPeople.getGuid(),ip,pass); + }else { + return error("默认设备设备已离线"); + } + } + } + }else{ + sysPeople.setGuid(IdUtils.simpleUUID()); + } + + //下发设备 + if(sysPeople.getBranchId()!=null){ + SysBranch branch=sysBranchService.selectSysBranchById(sysPeople.getBranchId()); + if (branch.getRuleId()!= null) { + //添加人员授权信息 + SysRule rule=sysRuleService.selectSysRuleById(branch.getRuleId()); + String data=sdkService.authDeviceNew(rule,sysPeople); + if("".equals(data)){ + return AjaxResult.error("该规则未绑定设备!"); + } + sysPeople.setDown(1L); + } + } + sysPeople.setDelFlag(0L); + int i = sysPeoplService.updateSysPeople(sysPeople); + return toAjax(i); + } + + + @Log(title = "离职人员", businessType = BusinessType.IMPORT) + @PostMapping("/importData") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception + { + ExcelUtil util = new ExcelUtil<>(SysPeopleLeave.class); + List userList = util.importExcel(file.getInputStream()); + String operName = SecurityUtils.getUsername(); + String message = sysPeopleLeaveService.importPeople(userList, updateSupport, operName); + return success(message); + } + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysPeopleOtherController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysPeopleOtherController.java new file mode 100644 index 0000000..0770146 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysPeopleOtherController.java @@ -0,0 +1,328 @@ +package com.dcsoft.system.controller; + +import com.alibaba.fastjson.JSONObject; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.utils.uuid.IdUtils; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDataInfo; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.api.model.LoginUser; +import com.dcsoft.system.domain.*; +import com.dcsoft.system.service.*; +import com.dcsoft.system.uniubi.domain.Person; +import com.dcsoft.system.uniubi.service.ISysSdkService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.concurrent.ExecutionException; + +/** + * 人员管理Controller + * + * @author nichun + * @date 2023-03-08 + */ +@RestController +@RequestMapping("/sysPeopleOther") +public class SysPeopleOtherController extends BaseController +{ + @Autowired + private ISysPeopleOtherService sysPeopleOtherService; + + @Autowired + protected ISysSdkService sdkService; + + @Autowired + protected ISysPeopleEquipmentService peopleEquipmentService; + + @Autowired + private ISysBranchService sysBranchService; + + @Autowired + protected ISysEquipmentService equipmentService; + + @Autowired + private ISysPeopleService sysPeopleService; + + /** + * 查询人员管理列表 + */ + @GetMapping("/list") + public TableDataInfo list(SysPeopleOther sysPeople) + { + List list = sysPeopleOtherService.selectSysPeopleOtherList(sysPeople); + return getDataTable(list); + } + + @GetMapping("/queryPeopleList") + public AjaxResult queryPeopleList(SysPeopleOther sysPeople) { + List list = sysPeopleOtherService.queryPeopleList(sysPeople); + return success(list); + } + + /** + * 导出人员管理列表 + */ + @RequiresPermissions("system:sysPeopleOther:export") + @Log(title = "人员管理", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysPeopleOther sysPeople) + { + List list = sysPeopleOtherService.selectSysPeopleOtherLists(sysPeople); + ExcelUtil util = new ExcelUtil(SysPeopleOther.class); + util.exportExcel(response, list, "人员管理数据"); + } + + /** + * 获取人员管理详细信息 + */ + @RequiresPermissions("system:sysPeopleOther:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(sysPeopleOtherService.selectSysPeopleOtherById(id)); + } + + /** + * 新增人员管理 + */ + @RequiresPermissions("system:sysPeopleOther:add") + @Log(title = "人员管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SysPeopleOther sysPeople) throws ExecutionException, InterruptedException { + sysPeople.setGuid(IdUtils.simpleUUID()); + return toAjax(sysPeopleOtherService.insertSysPeopleOther(sysPeople)); + } + + + /** + * 修改人员管理 + */ + @RequiresPermissions("system:sysPeopleOther:edit") + @Log(title = "人员管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysPeopleOther sysPeople) + { + //照片未注册人员注册照片 + if(StringUtils.isNotEmpty(sysPeople.getAvatar())){ + if(StringUtils.isEmpty(sysPeople.getFaceGuid())){ + SysEquipment equipment=new SysEquipment(); + equipment.setIsCj("1"); + equipment.setFlag("0"); + List list=equipmentService.selectSysEquipmentList(equipment); + if(list.size()>0){ + //人员是否注册 + String ip=list.get(0).getIp(); + String pass=list.get(0).getPassword(); + Person person=new Person(); + person.setName(sysPeople.getName()); + person.setiDNumber(sysPeople.getIdcard()); + person.setPhone(sysPeople.getPhone()); + person.setId(sysPeople.getGuid()); + String data=sdkService.personCreate(person,ip,pass); + + //查看是否有底图,有底图就注册 + SysPeopleOther sysPeopleOther = sysPeopleOtherService.selectSysPeopleOtherById(sysPeople.getId()); + if(StringUtils.isNotEmpty(sysPeopleOther.getAvatar())){ + sdkService.imageCreateUrl(sysPeople.getGuid(), sysPeopleOther.getAvatar(), ip, pass); + } + + //人像是否注册 + String datas = sdkService.imageCreateUrl(sysPeople.getGuid(), sysPeople.getAvatar(), ip, pass); + JSONObject jsons = JSONObject.parseObject(datas); + if ("1".equals(jsons.get("result")+"")) { + if(jsons.get("data")!=null){ + String faceGuid = jsons.get("data")+""; + sysPeople.setFaceGuid(faceGuid); + //照片检测后删除注册设备人员 + sdkService.personDelete(sysPeople.getGuid(),ip,pass); + } + }else{ + //照片检测后删除注册设备人员 + sdkService.personDelete(sysPeople.getGuid(),ip,pass); + return error(jsons.get("msg")+""); + } + + } + } + } + return toAjax(sysPeopleOtherService.updateSysPeopleOther(sysPeople)); + } + + + + + /** + * 删除人员管理 + */ + @RequiresPermissions("system:sysPeopleOther:remove") + @Log(title = "人员管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + SysEquipment equipment=new SysEquipment(); + equipment.setFlag("0"); + equipment.setIsCj("0"); + equipment.setProductId(3L); + List list = equipmentService.selectSysEquipmentList(equipment); + if(list.size()>0){ + for(Long id:ids){//下发到设备上 + SysPeopleOther people=sysPeopleOtherService.selectSysPeopleOtherById(id); + for(SysEquipment e:list){ + String ip=e.getIp(); + String pass=e.getPassword(); + sdkService.personDelete(people.getGuid(),ip,pass); + //保存下发记录 + peopleEquipmentService.deleteSysPeopleEquipmentByOtherId(people.getId()); + } + } + } + //暂未处理离线设备人员数据删除 + return toAjax(sysPeopleOtherService.deleteSysPeopleOtherByIds(ids)); + } + + + @Log(title = "人员信息", businessType = BusinessType.IMPORT) + @RequiresPermissions("system:sysPeopleOther:import") + @PostMapping("/importData") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception + { + ExcelUtil util = new ExcelUtil(SysPeopleOther.class); + List userList = util.importExcel(file.getInputStream()); + String operName = SecurityUtils.getUsername(); + String message = sysPeopleOtherService.importPeople(userList, updateSupport, operName); + return success(message); + } + + @PostMapping("/importTemplate") + public void importTemplate(HttpServletResponse response) throws IOException + { + ExcelUtil util = new ExcelUtil(SysPeopleOther.class); + util.importTemplateExcel(response, "第三方人员信息数据"); + } + + @GetMapping("/branchTree") + public AjaxResult branchTree(SysBranch space) + { + //获取当前登录用户的所属部门 + // 获取当前的用户 + LoginUser loginUser = SecurityUtils.getLoginUser(); + SysBranch parent =sysBranchService.selectSysBranchByDeptId(loginUser.getSysUser().getDept().getDeptId()); + space.setParentId(parent.getId()); + return success(sysBranchService.selectSysBranchList(space)); + } + + + /** + * 新增人员管理 + */ + @Log(title = "第三方人员管理", businessType = BusinessType.INSERT) + @PostMapping("/addOther") + public AjaxResult addOther(@RequestBody SysPeopleOther sysPeople) throws ExecutionException, InterruptedException { + //注册设备进行注册 + if(org.apache.commons.lang3.StringUtils.isNotEmpty(sysPeople.getAvatar())) {//是否上传头像,检测照片是否合格 + SysEquipment equipment=new SysEquipment(); + equipment.setIsCj("1"); + equipment.setFlag("0"); + List list=equipmentService.selectSysEquipmentList(equipment); + if(list.size()>0){ + //人员是否注册 + String ip=list.get(0).getIp(); + String pass=list.get(0).getPassword(); + if(org.apache.commons.lang3.StringUtils.isEmpty(sysPeople.getGuid())){ + Person person=new Person(); + person.setName(sysPeople.getName()); + person.setiDNumber(sysPeople.getIdcard()); + person.setPhone(sysPeople.getPhone()); + String data=sdkService.personCreate(person,ip,pass); + JSONObject json= JSONObject.parseObject(data); + if("1".equals(json.get("result")+"")) { + JSONObject obj= (JSONObject) json.get("data"); + String admitGuid=obj.get("id")+""; + sysPeople.setGuid(admitGuid); + }else{ + return error(json.get("msg")+""); + } + } + //人像是否注册 + String datas = sdkService.imageCreateUrl(sysPeople.getGuid(), sysPeople.getAvatar(), ip, pass); + JSONObject jsons = JSONObject.parseObject(datas); + if ("1".equals(jsons.get("result")+"")) { + if(jsons.get("data")!=null){ + String faceGuid = jsons.get("data")+""; + sysPeople.setFaceGuid(faceGuid); + } + }else{ + return error(jsons.get("msg")+""); + } + //照片检测后删除注册设备人员 + sdkService.personDelete(sysPeople.getGuid(),ip,pass); + }else{ + sysPeople.setGuid(IdUtils.simpleUUID()); + } + }else{ + sysPeople.setGuid(IdUtils.simpleUUID()); + } + + return toAjax(sysPeopleOtherService.insertSysPeopleOther(sysPeople)); + } + + @GetMapping("/down/{ids}") + public AjaxResult down(@PathVariable Long[] ids) + { + + SysEquipment equipment=new SysEquipment(); + equipment.setFlag("0"); + equipment.setIsCj("0"); + equipment.setProductId(3L); + List list = equipmentService.selectSysEquipmentList(equipment); + if(list.size()>0){ + for(Long id:ids){//下发到设备上 + SysPeopleOther people=sysPeopleOtherService.selectSysPeopleOtherById(id); + Long down=0L; + try { + if(StringUtils.isNotEmpty(people.getGuid())){//人员 + Person person=new Person(); + person.setId(people.getGuid()); + person.setName(people.getName()); + person.setiDNumber(people.getIdcard()); + person.setPhone(people.getPhone()); + + for(SysEquipment e:list){ + String ip=e.getIp(); + String pass=e.getPassword(); + sdkService.personDelete(people.getGuid(),ip,pass); + sdkService.personCreate(person,ip,pass); + if(StringUtils.isNotEmpty(people.getFaceGuid())){//人脸 + sdkService.imageCreateUrl(people.getGuid(),people.getFaceGuid(),people.getAvatar(), e.getIp(), e.getPassword()); + } + down++; + //保存下发记录 + SysPeopleEquipment sysPeopleEquipment=new SysPeopleEquipment(); + sysPeopleEquipment.setOtherId(people.getId()); + sysPeopleEquipment.setEquipmentId(e.getId()); + sysPeopleEquipment.setGuid(people.getGuid()); + sysPeopleEquipment.setFaceGuid(people.getFaceGuid()); + peopleEquipmentService.insertSysPeopleEquipment(sysPeopleEquipment); + } + } + }catch (Exception e){ + e.printStackTrace(); + } + people.setDown(down); + sysPeopleOtherService.updateSysPeopleOther(people); + } + } + return toAjax(1); + } + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysPeopleRecordController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysPeopleRecordController.java new file mode 100644 index 0000000..f499048 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysPeopleRecordController.java @@ -0,0 +1,122 @@ +package com.dcsoft.system.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.system.domain.SysPeopleRecord; +import com.dcsoft.system.service.ISysPeopleRecordService; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.page.TableDataInfo; + +/** + * 人员识别记录Controller + * + * @author nichun + * @date 2023-03-08 + */ +@RestController +@RequestMapping("/peopleRecord") +public class SysPeopleRecordController extends BaseController +{ + @Autowired + private ISysPeopleRecordService sysPeopleRecordService; + + /** + * 查询人员识别记录列表 + */ + @RequiresPermissions("system:peopleRecord:list") + @GetMapping("/list") + public TableDataInfo list(SysPeopleRecord sysPeopleRecord) + { + startPage(); + List list = sysPeopleRecordService.selectSysPeopleRecordList(sysPeopleRecord); + return getDataTable(list); + } + + /** + * 导出人员识别记录列表 + */ + @RequiresPermissions("system:peopleRecord:export") + @Log(title = "人员识别记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysPeopleRecord sysPeopleRecord) + { + List list = sysPeopleRecordService.selectSysPeopleRecordList(sysPeopleRecord); + ExcelUtil util = new ExcelUtil(SysPeopleRecord.class); + util.exportExcel(response, list, "人员识别记录数据"); + } + + /** + * 获取人员识别记录详细信息 + */ + @RequiresPermissions("system:peopleRecord:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(sysPeopleRecordService.selectSysPeopleRecordById(id)); + } + + /** + * 新增人员识别记录 + */ + @RequiresPermissions("system:peopleRecord:add") + @Log(title = "人员识别记录", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SysPeopleRecord sysPeopleRecord) + { + return toAjax(sysPeopleRecordService.insertSysPeopleRecord(sysPeopleRecord)); + } + + /** + * 修改人员识别记录 + */ + @RequiresPermissions("system:peopleRecord:edit") + @Log(title = "人员识别记录", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysPeopleRecord sysPeopleRecord) + { + return toAjax(sysPeopleRecordService.updateSysPeopleRecord(sysPeopleRecord)); + } + + /** + * 删除人员识别记录 + */ + @RequiresPermissions("system:peopleRecord:remove") + @Log(title = "人员识别记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(sysPeopleRecordService.deleteSysPeopleRecordByIds(ids)); + } + + /** + * 获取头部信息 + */ + @GetMapping("/top") + public AjaxResult topApi() { + return sysPeopleRecordService.topApi(); + } + + /** + * 查询通行统计数量(昨天,今天) + * @return + */ + @PostMapping("/queryThroughCount") + public AjaxResult queryThroughCount() { + return success(sysPeopleRecordService.queryThroughCount()); + } + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysPointController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysPointController.java new file mode 100644 index 0000000..b8eb96b --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysPointController.java @@ -0,0 +1,104 @@ +package com.dcsoft.system.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.system.domain.SysPoint; +import com.dcsoft.system.service.ISysPointService; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.page.TableDataInfo; + +/** + * 点位管理Controller + * + * @author nichun + * @date 2023-03-08 + */ +@RestController +@RequestMapping("/point") +public class SysPointController extends BaseController +{ + @Autowired + private ISysPointService sysPointService; + + /** + * 查询点位管理列表 + */ + @RequiresPermissions("system:point:list") + @GetMapping("/list") + public TableDataInfo list(SysPoint sysPoint) + { + startPage(); + List list = sysPointService.selectSysPointList(sysPoint); + return getDataTable(list); + } + + /** + * 导出点位管理列表 + */ + @RequiresPermissions("system:point:export") + @Log(title = "点位管理", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysPoint sysPoint) + { + List list = sysPointService.selectSysPointList(sysPoint); + ExcelUtil util = new ExcelUtil(SysPoint.class); + util.exportExcel(response, list, "点位管理数据"); + } + + /** + * 获取点位管理详细信息 + */ + @RequiresPermissions("system:point:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(sysPointService.selectSysPointById(id)); + } + + /** + * 新增点位管理 + */ + @RequiresPermissions("system:point:add") + @Log(title = "点位管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SysPoint sysPoint) + { + return toAjax(sysPointService.insertSysPoint(sysPoint)); + } + + /** + * 修改点位管理 + */ + @RequiresPermissions("system:point:edit") + @Log(title = "点位管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysPoint sysPoint) + { + return toAjax(sysPointService.updateSysPoint(sysPoint)); + } + + /** + * 删除点位管理 + */ + @RequiresPermissions("system:point:remove") + @Log(title = "点位管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(sysPointService.deleteSysPointByIds(ids)); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysPostController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysPostController.java new file mode 100644 index 0000000..8a0c77d --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysPostController.java @@ -0,0 +1,130 @@ +package com.dcsoft.system.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDataInfo; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.domain.SysPost; +import com.dcsoft.system.service.ISysPostService; + +/** + * 岗位信息操作处理 + * + * @author dcsoft + */ +@RestController +@RequestMapping("/post") +public class SysPostController extends BaseController +{ + @Autowired + private ISysPostService postService; + + /** + * 获取岗位列表 + */ + @RequiresPermissions("system:post:list") + @GetMapping("/list") + public TableDataInfo list(SysPost post) + { + startPage(); + List list = postService.selectPostList(post); + return getDataTable(list); + } + + @Log(title = "岗位管理", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:post:export") + @PostMapping("/export") + public void export(HttpServletResponse response, SysPost post) + { + List list = postService.selectPostList(post); + ExcelUtil util = new ExcelUtil(SysPost.class); + util.exportExcel(response, list, "岗位数据"); + } + + /** + * 根据岗位编号获取详细信息 + */ + @RequiresPermissions("system:post:query") + @GetMapping(value = "/{postId}") + public AjaxResult getInfo(@PathVariable Long postId) + { + return success(postService.selectPostById(postId)); + } + + /** + * 新增岗位 + */ + @RequiresPermissions("system:post:add") + @Log(title = "岗位管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysPost post) + { + if (!postService.checkPostNameUnique(post)) + { + return error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在"); + } + else if (!postService.checkPostCodeUnique(post)) + { + return error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在"); + } + post.setCreateBy(SecurityUtils.getUsername()); + return toAjax(postService.insertPost(post)); + } + + /** + * 修改岗位 + */ + @RequiresPermissions("system:post:edit") + @Log(title = "岗位管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysPost post) + { + if (!postService.checkPostNameUnique(post)) + { + return error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在"); + } + else if (!postService.checkPostCodeUnique(post)) + { + return error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在"); + } + post.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(postService.updatePost(post)); + } + + /** + * 删除岗位 + */ + @RequiresPermissions("system:post:remove") + @Log(title = "岗位管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{postIds}") + public AjaxResult remove(@PathVariable Long[] postIds) + { + return toAjax(postService.deletePostByIds(postIds)); + } + + /** + * 获取岗位选择框列表 + */ + @GetMapping("/optionselect") + public AjaxResult optionselect() + { + List posts = postService.selectPostAll(); + return success(posts); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysProductController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysProductController.java new file mode 100644 index 0000000..6a45a72 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysProductController.java @@ -0,0 +1,104 @@ +package com.dcsoft.system.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.system.domain.SysProduct; +import com.dcsoft.system.service.ISysProductService; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.page.TableDataInfo; + +/** + * 产品信息Controller + * + * @author nichun + * @date 2023-03-08 + */ +@RestController +@RequestMapping("/product") +public class SysProductController extends BaseController +{ + @Autowired + private ISysProductService sysProductService; + + /** + * 查询产品信息列表 + */ + @RequiresPermissions("system:product:list") + @GetMapping("/list") + public TableDataInfo list(SysProduct sysProduct) + { + startPage(); + List list = sysProductService.selectSysProductList(sysProduct); + return getDataTable(list); + } + + /** + * 导出产品信息列表 + */ + @RequiresPermissions("system:product:export") + @Log(title = "产品信息", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysProduct sysProduct) + { + List list = sysProductService.selectSysProductList(sysProduct); + ExcelUtil util = new ExcelUtil(SysProduct.class); + util.exportExcel(response, list, "产品信息数据"); + } + + /** + * 获取产品信息详细信息 + */ + @RequiresPermissions("system:product:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(sysProductService.selectSysProductById(id)); + } + + /** + * 新增产品信息 + */ + @RequiresPermissions("system:product:add") + @Log(title = "产品信息", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SysProduct sysProduct) + { + return toAjax(sysProductService.insertSysProduct(sysProduct)); + } + + /** + * 修改产品信息 + */ + @RequiresPermissions("system:product:edit") + @Log(title = "产品信息", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysProduct sysProduct) + { + return toAjax(sysProductService.updateSysProduct(sysProduct)); + } + + /** + * 删除产品信息 + */ + @RequiresPermissions("system:product:remove") + @Log(title = "产品信息", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(sysProductService.deleteSysProductByIds(ids)); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysProfileController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysProfileController.java new file mode 100644 index 0000000..e7fa87e --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysProfileController.java @@ -0,0 +1,158 @@ +package com.dcsoft.system.controller; + +import java.util.Arrays; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; +import com.dcsoft.common.core.domain.R; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.utils.file.FileTypeUtils; +import com.dcsoft.common.core.utils.file.MimeTypeUtils; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.service.TokenService; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.api.RemoteFileService; +import com.dcsoft.system.api.domain.SysFile; +import com.dcsoft.system.api.domain.SysUser; +import com.dcsoft.system.api.model.LoginUser; +import com.dcsoft.system.service.ISysUserService; + +/** + * 个人信息 业务处理 + * + * @author dcsoft + */ +@RestController +@RequestMapping("/user/profile") +public class SysProfileController extends BaseController +{ + @Autowired + private ISysUserService userService; + + @Autowired + private TokenService tokenService; + + @Autowired + private RemoteFileService remoteFileService; + + /** + * 个人信息 + */ + @GetMapping + public AjaxResult profile() + { + String username = SecurityUtils.getUsername(); + SysUser user = userService.selectUserByUserName(username); + AjaxResult ajax = AjaxResult.success(user); + ajax.put("roleGroup", userService.selectUserRoleGroup(username)); + ajax.put("postGroup", userService.selectUserPostGroup(username)); + return ajax; + } + + /** + * 修改用户 + */ + @Log(title = "个人信息", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult updateProfile(@RequestBody SysUser user) + { + LoginUser loginUser = SecurityUtils.getLoginUser(); + SysUser sysUser = loginUser.getSysUser(); + user.setUserName(user.getUserName()); + if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) + { + return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); + } + else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) + { + return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); + } + user.setUserId(sysUser.getUserId()); + user.setPassword(null); + user.setAvatar(null); + user.setDeptId(null); + if (userService.updateUserProfile(user) > 0) + { + // 更新缓存用户信息 + loginUser.getSysUser().setNickName(user.getNickName()); + loginUser.getSysUser().setPhonenumber(user.getPhonenumber()); + loginUser.getSysUser().setEmail(user.getEmail()); + loginUser.getSysUser().setSex(user.getSex()); + tokenService.setLoginUser(loginUser); + return success(); + } + return error("修改个人信息异常,请联系管理员"); + } + + /** + * 重置密码 + */ + @Log(title = "个人信息", businessType = BusinessType.UPDATE) + @PutMapping("/updatePwd") + public AjaxResult updatePwd(String oldPassword, String newPassword) + { + String username = SecurityUtils.getUsername(); + SysUser user = userService.selectUserByUserName(username); + String password = user.getPassword(); + if (!SecurityUtils.matchesPassword(oldPassword, password)) + { + return error("修改密码失败,旧密码错误"); + } + if (SecurityUtils.matchesPassword(newPassword, password)) + { + return error("新密码不能与旧密码相同"); + } + if (userService.resetUserPwd(username, SecurityUtils.encryptPassword(newPassword)) > 0) + { + // 更新缓存用户密码 + LoginUser loginUser = SecurityUtils.getLoginUser(); + loginUser.getSysUser().setPassword(SecurityUtils.encryptPassword(newPassword)); + tokenService.setLoginUser(loginUser); + return success(); + } + return error("修改密码异常,请联系管理员"); + } + + /** + * 头像上传 + */ + @Log(title = "用户头像", businessType = BusinessType.UPDATE) + @PostMapping("/avatar") + public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) + { + if (!file.isEmpty()) + { + LoginUser loginUser = SecurityUtils.getLoginUser(); + String extension = FileTypeUtils.getExtension(file); + if (!StringUtils.equalsAnyIgnoreCase(extension, MimeTypeUtils.IMAGE_EXTENSION)) + { + return error("文件格式不正确,请上传" + Arrays.toString(MimeTypeUtils.IMAGE_EXTENSION) + "格式"); + } + R fileResult = remoteFileService.upload(file); + if (StringUtils.isNull(fileResult) || StringUtils.isNull(fileResult.getData())) + { + return error("文件服务异常,请联系管理员"); + } + String url = fileResult.getData().getUrl(); + if (userService.updateUserAvatar(loginUser.getUsername(), url)) + { + AjaxResult ajax = AjaxResult.success(); + ajax.put("imgUrl", url); + // 更新缓存用户头像 + loginUser.getSysUser().setAvatar(url); + tokenService.setLoginUser(loginUser); + return ajax; + } + } + return error("上传图片异常,请联系管理员"); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysRoleController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysRoleController.java new file mode 100644 index 0000000..b6136c5 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysRoleController.java @@ -0,0 +1,239 @@ +package com.dcsoft.system.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDataInfo; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.api.domain.SysDept; +import com.dcsoft.system.api.domain.SysRole; +import com.dcsoft.system.api.domain.SysUser; +import com.dcsoft.system.domain.SysUserRole; +import com.dcsoft.system.service.ISysDeptService; +import com.dcsoft.system.service.ISysRoleService; +import com.dcsoft.system.service.ISysUserService; + +/** + * 角色信息 + * + * @author dcsoft + */ +@RestController +@RequestMapping("/role") +public class SysRoleController extends BaseController +{ + @Autowired + private ISysRoleService roleService; + + @Autowired + private ISysUserService userService; + + @Autowired + private ISysDeptService deptService; + + @RequiresPermissions("system:role:list") + @GetMapping("/list") + public TableDataInfo list(SysRole role) + { + startPage(); + List list = roleService.selectRoleList(role); + return getDataTable(list); + } + + @Log(title = "角色管理", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:role:export") + @PostMapping("/export") + public void export(HttpServletResponse response, SysRole role) + { + List list = roleService.selectRoleList(role); + ExcelUtil util = new ExcelUtil(SysRole.class); + util.exportExcel(response, list, "角色数据"); + } + + /** + * 根据角色编号获取详细信息 + */ + @RequiresPermissions("system:role:query") + @GetMapping(value = "/{roleId}") + public AjaxResult getInfo(@PathVariable Long roleId) + { + roleService.checkRoleDataScope(roleId); + return success(roleService.selectRoleById(roleId)); + } + + /** + * 新增角色 + */ + @RequiresPermissions("system:role:add") + @Log(title = "角色管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysRole role) + { + if (!roleService.checkRoleNameUnique(role)) + { + return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在"); + } + else if (!roleService.checkRoleKeyUnique(role)) + { + return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在"); + } + role.setCreateBy(SecurityUtils.getUsername()); + return toAjax(roleService.insertRole(role)); + + } + + /** + * 修改保存角色 + */ + @RequiresPermissions("system:role:edit") + @Log(title = "角色管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysRole role) + { + roleService.checkRoleAllowed(role); + roleService.checkRoleDataScope(role.getRoleId()); + if (!roleService.checkRoleNameUnique(role)) + { + return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在"); + } + else if (!roleService.checkRoleKeyUnique(role)) + { + return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在"); + } + role.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(roleService.updateRole(role)); + } + + /** + * 修改保存数据权限 + */ + @RequiresPermissions("system:role:edit") + @Log(title = "角色管理", businessType = BusinessType.UPDATE) + @PutMapping("/dataScope") + public AjaxResult dataScope(@RequestBody SysRole role) + { + roleService.checkRoleAllowed(role); + roleService.checkRoleDataScope(role.getRoleId()); + return toAjax(roleService.authDataScope(role)); + } + + /** + * 状态修改 + */ + @RequiresPermissions("system:role:edit") + @Log(title = "角色管理", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public AjaxResult changeStatus(@RequestBody SysRole role) + { + roleService.checkRoleAllowed(role); + roleService.checkRoleDataScope(role.getRoleId()); + role.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(roleService.updateRoleStatus(role)); + } + + /** + * 删除角色 + */ + @RequiresPermissions("system:role:remove") + @Log(title = "角色管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{roleIds}") + public AjaxResult remove(@PathVariable Long[] roleIds) + { + return toAjax(roleService.deleteRoleByIds(roleIds)); + } + + /** + * 获取角色选择框列表 + */ + @RequiresPermissions("system:role:query") + @GetMapping("/optionselect") + public AjaxResult optionselect() + { + return success(roleService.selectRoleAll()); + } + /** + * 查询已分配用户角色列表 + */ + @RequiresPermissions("system:role:list") + @GetMapping("/authUser/allocatedList") + public TableDataInfo allocatedList(SysUser user) + { + startPage(); + List list = userService.selectAllocatedList(user); + return getDataTable(list); + } + + /** + * 查询未分配用户角色列表 + */ + @RequiresPermissions("system:role:list") + @GetMapping("/authUser/unallocatedList") + public TableDataInfo unallocatedList(SysUser user) + { + startPage(); + List list = userService.selectUnallocatedList(user); + return getDataTable(list); + } + + /** + * 取消授权用户 + */ + @RequiresPermissions("system:role:edit") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PutMapping("/authUser/cancel") + public AjaxResult cancelAuthUser(@RequestBody SysUserRole userRole) + { + return toAjax(roleService.deleteAuthUser(userRole)); + } + + /** + * 批量取消授权用户 + */ + @RequiresPermissions("system:role:edit") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PutMapping("/authUser/cancelAll") + public AjaxResult cancelAuthUserAll(Long roleId, Long[] userIds) + { + return toAjax(roleService.deleteAuthUsers(roleId, userIds)); + } + + /** + * 批量选择用户授权 + */ + @RequiresPermissions("system:role:edit") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PutMapping("/authUser/selectAll") + public AjaxResult selectAuthUserAll(Long roleId, Long[] userIds) + { + roleService.checkRoleDataScope(roleId); + return toAjax(roleService.insertAuthUsers(roleId, userIds)); + } + + /** + * 获取对应角色部门树列表 + */ + @RequiresPermissions("system:role:query") + @GetMapping(value = "/deptTree/{roleId}") + public AjaxResult deptTree(@PathVariable("roleId") Long roleId) + { + AjaxResult ajax = AjaxResult.success(); + ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId)); + ajax.put("depts", deptService.selectDeptTreeList(new SysDept())); + return ajax; + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysRuleController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysRuleController.java new file mode 100644 index 0000000..abd849e --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysRuleController.java @@ -0,0 +1,175 @@ +package com.dcsoft.system.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.system.domain.SysRule; +import com.dcsoft.system.service.ISysRuleService; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.page.TableDataInfo; + +/** + * 通行规则Controller + * + * @author nichun + * @date 2023-03-08 + */ +@RestController +@RequestMapping("/rule") +public class SysRuleController extends BaseController +{ + @Autowired + private ISysRuleService sysRuleService; + + /** + * 查询通行规则列表 + */ +// @RequiresPermissions("system:rule:list") + @GetMapping("/list") + public TableDataInfo list(SysRule sysRule) + { + startPage(); + List list = sysRuleService.selectSysRuleList(sysRule); + return getDataTable(list); + } + + @GetMapping("/lists") + public AjaxResult lists(SysRule sysRule) + { + List list = sysRuleService.selectSysRuleList(sysRule); + return AjaxResult.success(list); + } + + /** + * 导出通行规则列表 + */ + @RequiresPermissions("system:rule:export") + @Log(title = "通行规则", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysRule sysRule) + { + List list = sysRuleService.selectSysRuleList(sysRule); + ExcelUtil util = new ExcelUtil(SysRule.class); + util.exportExcel(response, list, "通行规则数据"); + } + + /** + * 获取通行规则详细信息 + */ + @RequiresPermissions("system:rule:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + SysRule rule=sysRuleService.selectSysRuleById(id); + if(StringUtils.isNotEmpty(rule.getPermission())){ + String[] checkList=rule.getPermission().split(","); + rule.setCheckList(checkList); + } + return success(rule); + } + + /** + * 新增通行规则 + */ + @RequiresPermissions("system:rule:add") + @Log(title = "通行规则", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SysRule rule) + { + String permission=""; + for(String s:rule.getCheckList()){ + permission+=s+","; + } + if(!"".equals(permission)){ + permission=permission.substring(0,permission.length()-1); + } + rule.setPermission(permission); + if(rule.getPointIds()!=null){ + String pointIds=""; + for(String s:rule.getPointIds()){ + pointIds+=s+","; + } + if(!"".equals(pointIds)){ + pointIds=pointIds.substring(0,pointIds.length()-1); + } + rule.setPointId(pointIds); + } + return toAjax(sysRuleService.insertSysRule(rule)); + } + + /** + * 修改通行规则 + */ + @RequiresPermissions("system:rule:edit") + @Log(title = "通行规则", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysRule rule) + { + String permission=""; + for(String s:rule.getCheckList()){ + permission+=s+","; + } + if(!"".equals(permission)){ + permission=permission.substring(0,permission.length()-1); + } + rule.setPermission(permission); + if(rule.getPointIds()!=null){ + String pointIds=""; + + for(String s:rule.getPointIds()){ + pointIds+=s+","; + } + if(!"".equals(pointIds)){ + pointIds=pointIds.substring(0,pointIds.length()-1); + } + rule.setPointId(pointIds); + } + return toAjax(sysRuleService.updateSysRule(rule)); + } + + /** + * 删除通行规则 + */ + @RequiresPermissions("system:rule:remove") + @Log(title = "通行规则", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(sysRuleService.deleteSysRuleByIds(ids)); + } + + /** + * 获取企业模块|菜单权限树 + */ + @GetMapping(value = "/ruleAuth") + public AjaxResult selectRuleAuthScope() { + AjaxResult ajax = AjaxResult.success(); + ajax.put("depts", sysRuleService.selectRuleAuthScope()); + return ajax; + } + + /** + * 获取企业模块|菜单权限树 + */ + @GetMapping(value = "/queryRuleAuth") + public AjaxResult queryRuleAuth() { + AjaxResult ajax = AjaxResult.success(); + ajax.put("depts", sysRuleService.queryRuleAuth()); + return ajax; + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysSpaceController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysSpaceController.java new file mode 100644 index 0000000..5f669f8 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysSpaceController.java @@ -0,0 +1,124 @@ +package com.dcsoft.system.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.dcsoft.common.core.utils.StringUtils; +import org.apache.commons.lang3.ArrayUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.system.domain.SysSpace; +import com.dcsoft.system.service.ISysSpaceService; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.utils.poi.ExcelUtil; + +/** + * 空间管理Controller + * + * @author nichun + * @date 2023-03-08 + */ +@RestController +@RequestMapping("/space") +public class SysSpaceController extends BaseController +{ + @Autowired + private ISysSpaceService sysSpaceService; + + /** + * 查询空间管理列表 + */ + @RequiresPermissions("system:space:list") + @GetMapping("/list") + public AjaxResult list(SysSpace sysSpace) + { + List list = sysSpaceService.selectSysSpaceList(sysSpace); + return success(list); + } + + /** + * 查询部门列表(排除节点) + */ + @RequiresPermissions("system:space:list") + @GetMapping("/list/exclude/{id}") + public AjaxResult excludeChild(@PathVariable(value = "id", required = false) Long id) + { + List depts = sysSpaceService.selectSysSpaceList(new SysSpace()); + depts.removeIf(d -> d.getId().intValue() == id || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), id + "")); + return success(depts); + } + + + /** + * 导出空间管理列表 + */ + @RequiresPermissions("system:space:export") + @Log(title = "空间管理", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysSpace sysSpace) + { + List list = sysSpaceService.selectSysSpaceList(sysSpace); + ExcelUtil util = new ExcelUtil(SysSpace.class); + util.exportExcel(response, list, "空间管理数据"); + } + + /** + * 获取空间管理详细信息 + */ + @RequiresPermissions("system:space:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(sysSpaceService.selectSysSpaceById(id)); + } + + /** + * 新增空间管理 + */ + @RequiresPermissions("system:space:add") + @Log(title = "空间管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SysSpace sysSpace) + { + return toAjax(sysSpaceService.insertSysSpace(sysSpace)); + } + + /** + * 修改空间管理 + */ + @RequiresPermissions("system:space:edit") + @Log(title = "空间管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysSpace sysSpace) + { + + return toAjax(sysSpaceService.updateSysSpace(sysSpace)); + } + + /** + * 获取空间树列表 + */ +// @RequiresPermissions("system:space:list") + @GetMapping("/spaceTree") + public AjaxResult spaceTree(SysSpace space) + { + return success(sysSpaceService.selectSpaceTreeList(space)); + } + + /** + * 删除空间 + */ + @RequiresPermissions("system:space:remove") + @Log(title = "空间管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(sysSpaceService.deleteSysSpaceByIds(ids)); + } + + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysSyncRuleController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysSyncRuleController.java new file mode 100644 index 0000000..88e4302 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysSyncRuleController.java @@ -0,0 +1,148 @@ +package com.dcsoft.system.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.fastjson.JSONObject; +import com.dcsoft.system.domain.SysSyncItem; +import com.dcsoft.system.utils.HttpUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.system.domain.SysSyncRule; +import com.dcsoft.system.service.ISysSyncRuleService; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.page.TableDataInfo; + +/** + * 同步规则Controller + * + * @author nichun + * @date 2024-01-11 + */ +@RestController +@RequestMapping("/syncRule") +public class SysSyncRuleController extends BaseController +{ + @Autowired + private ISysSyncRuleService sysSyncRuleService; + + /** + * 查询同步规则列表 + */ + @RequiresPermissions("system:syncRule:list") + @GetMapping("/list") + public TableDataInfo list(SysSyncRule sysSyncRule) + { + startPage(); + List list = sysSyncRuleService.selectSysSyncRuleList(sysSyncRule); + return getDataTable(list); + } + + /** + * 导出同步规则列表 + */ + @RequiresPermissions("system:syncRule:export") + @Log(title = "同步规则", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysSyncRule sysSyncRule) + { + List list = sysSyncRuleService.selectSysSyncRuleList(sysSyncRule); + ExcelUtil util = new ExcelUtil(SysSyncRule.class); + util.exportExcel(response, list, "同步规则数据"); + } + + /** + * 获取同步规则详细信息 + */ + @RequiresPermissions("system:syncRule:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + SysSyncRule rule=sysSyncRuleService.selectSysSyncRuleById(id); + List list= sysSyncRuleService.selectSysSyncRuleItem(id); + if(list.size()>0){ + String[] branchIds=new String[list.size()]; + for(int i=0;i list = userService.selectUserList(user); + return getDataTable(list); + } + + @Log(title = "用户管理", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:user:export") + @PostMapping("/export") + public void export(HttpServletResponse response, SysUser user) + { + List list = userService.selectUserList(user); + ExcelUtil util = new ExcelUtil(SysUser.class); + util.exportExcel(response, list, "用户数据"); + } + + @Log(title = "用户管理", businessType = BusinessType.IMPORT) + @RequiresPermissions("system:user:import") + @PostMapping("/importData") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception + { + ExcelUtil util = new ExcelUtil(SysUser.class); + List userList = util.importExcel(file.getInputStream()); + String operName = SecurityUtils.getUsername(); + String message = userService.importUser(userList, updateSupport, operName); + return success(message); + } + + @PostMapping("/importTemplate") + public void importTemplate(HttpServletResponse response) throws IOException + { + ExcelUtil util = new ExcelUtil(SysUser.class); + util.importTemplateExcel(response, "用户数据"); + } + + /** + * 获取当前用户信息 + */ + @InnerAuth + @GetMapping("/info/{username}") + public R info(@PathVariable("username") String username) + { + SysUser sysUser = userService.selectUserByUserName(username); + if (StringUtils.isNull(sysUser)) + { + return R.fail("用户名或密码错误"); + } + // 角色集合 + Set roles = permissionService.getRolePermission(sysUser); + // 权限集合 + Set permissions = permissionService.getMenuPermission(sysUser); + LoginUser sysUserVo = new LoginUser(); + sysUserVo.setUserid(sysUser.getUserId()); + sysUserVo.setSysUser(sysUser); + sysUserVo.setRoles(roles); + sysUserVo.setPermissions(permissions); + return R.ok(sysUserVo); + } + + /** + * 获取当前用户信息 + */ + @InnerAuth + @GetMapping("/wxinfo/{openid}") + public R getWxUserInfo(@PathVariable("openid") String openid) + { + SysUser sysUser = userService.selectUserByOpenId(openid); + if (StringUtils.isNull(sysUser)) + { + return R.fail(10001, "用户名或密码错误"); + } + // 角色集合 + Set roles = permissionService.getRolePermission(sysUser); + // 权限集合 + Set permissions = permissionService.getMenuPermission(sysUser); + LoginUser sysUserVo = new LoginUser(); + sysUserVo.setSysUser(sysUser); + sysUserVo.setRoles(roles); + sysUserVo.setPermissions(permissions); + return R.ok(sysUserVo); + } + + /** + * 注册用户信息 + */ + @InnerAuth + @PostMapping("/updateOpenId") + public R updateOpenId(@RequestBody SysUser sysUser) + { + System.out.println("SysUser==========="+sysUser.toString()); + if (userService.updateOpenId(sysUser)==0) + { + return R.fail("保存用户openid" + sysUser.getUserName() + "'失败,账号不存在"); + } + return R.ok(true); + } + + /** + * 注册用户信息 + */ + @InnerAuth + @PostMapping("/register") + public R register(@RequestBody SysUser sysUser) + { + String username = sysUser.getUserName(); + if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser")))) + { + return R.fail("当前系统没有开启注册功能!"); + } + if (!userService.checkUserNameUnique(sysUser)) + { + return R.fail("保存用户'" + username + "'失败,注册账号已存在"); + } + return R.ok(userService.registerUser(sysUser)); + } + + /** + * 获取用户信息 + * + * @return 用户信息 + */ + @GetMapping("getInfo") + public AjaxResult getInfo() + { + SysUser user = userService.selectUserById(SecurityUtils.getUserId()); + // 角色集合 + Set roles = permissionService.getRolePermission(user); + // 权限集合 + Set permissions = permissionService.getMenuPermission(user); + AjaxResult ajax = AjaxResult.success(); + ajax.put("user", user); + ajax.put("roles", roles); + ajax.put("permissions", permissions); + return ajax; + } + + /** + * 根据用户编号获取详细信息 + */ + @RequiresPermissions("system:user:query") + @GetMapping(value = { "/", "/{userId}" }) + public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId) + { + userService.checkUserDataScope(userId); + AjaxResult ajax = AjaxResult.success(); + List roles = roleService.selectRoleAll(); + ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); + ajax.put("posts", postService.selectPostAll()); + if (StringUtils.isNotNull(userId)) + { + SysUser sysUser = userService.selectUserById(userId); + ajax.put(AjaxResult.DATA_TAG, sysUser); + ajax.put("postIds", postService.selectPostListByUserId(userId)); + ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList())); + } + return ajax; + } + + /** + * 新增用户 + */ + @RequiresPermissions("system:user:add") + @Log(title = "用户管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysUser user) + { + if (!userService.checkUserNameUnique(user)) + { + return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在"); + } + else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) + { + return error("新增用户'" + user.getUserName() + "'失败,手机号码已存在"); + } + else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) + { + return error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在"); + } + user.setCreateBy(SecurityUtils.getUsername()); + user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); + int i=userService.insertUser(user); + /*try { + SysBranch sysBranch =sysBranchService.selectSysBranchByDeptId(user.getDeptId()); + if(sysBranch!=null){//查询到部门绑定的人员时 + SysPeople people=new SysPeople(); + people.setUserId(user.getUserId()); + people.setName(user.getUserName()); + people.setPhone(user.getPhonenumber()); + people.setSex(user.getSex()); + people.setBranchId(sysBranch.getId()); + String data=sysApiService.admitCreate(people); + JSONObject json= JSONObject.parseObject(data); + if("1".equals(json.get("result")+"")){ + JSONObject obj= (JSONObject) json.get("data"); + String admitGuid=obj.get("admitGuid")+""; + people.setGuid(admitGuid); + } + peopleService.insertSysPeople(people); + } + }catch (Exception e){ + e.printStackTrace(); + }*/ + return toAjax(i); + } + + /** + * 修改用户 + */ + @RequiresPermissions("system:user:edit") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysUser user) + { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + if (!userService.checkUserNameUnique(user)) + { + return error("修改用户'" + user.getUserName() + "'失败,登录账号已存在"); + } + else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) + { + return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); + } + else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) + { + return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); + } + user.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(userService.updateUser(user)); + } + + /** + * 删除用户 + */ + @RequiresPermissions("system:user:remove") + @Log(title = "用户管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{userIds}") + public AjaxResult remove(@PathVariable Long[] userIds) + { + if (ArrayUtils.contains(userIds, SecurityUtils.getUserId())) + { + return error("当前用户不能删除"); + } + return toAjax(userService.deleteUserByIds(userIds)); + } + + /** + * 重置密码 + */ + @RequiresPermissions("system:user:edit") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PutMapping("/resetPwd") + public AjaxResult resetPwd(@RequestBody SysUser user) + { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); + user.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(userService.resetPwd(user)); + } + + /** + * 状态修改 + */ + @RequiresPermissions("system:user:edit") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public AjaxResult changeStatus(@RequestBody SysUser user) + { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + user.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(userService.updateUserStatus(user)); + } + + /** + * 根据用户编号获取授权角色 + */ + @RequiresPermissions("system:user:query") + @GetMapping("/authRole/{userId}") + public AjaxResult authRole(@PathVariable("userId") Long userId) + { + AjaxResult ajax = AjaxResult.success(); + SysUser user = userService.selectUserById(userId); + List roles = roleService.selectRolesByUserId(userId); + ajax.put("user", user); + ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); + return ajax; + } + + /** + * 用户授权角色 + */ + @RequiresPermissions("system:user:edit") + @Log(title = "用户管理", businessType = BusinessType.GRANT) + @PutMapping("/authRole") + public AjaxResult insertAuthRole(Long userId, Long[] roleIds) + { + userService.checkUserDataScope(userId); + userService.insertUserAuth(userId, roleIds); + return success(); + } + + /** + * 获取部门树列表 + */ +// @RequiresPermissions("system:user:list") + @GetMapping("/deptTree") + public AjaxResult deptTree(SysDept dept) + { + return success(deptService.selectDeptTreeList(dept)); + } + + /** + * 获取小程序openid和session_key + * @param code + * @return + */ + @GetMapping("/jscode2session") + public AjaxResult jscode2session(String code) { + String url = "https://api.weixin.qq.com/sns/jscode2session?appid="+ appid +"&secret="+ secret +"&js_code="+ code +"&grant_type=authorization_code"; + String body = HttpUtil.createGet(url).execute().body(); + if(body.contains("errcode")){ + return AjaxResult.error(body); + } + JSONObject jsonObject = JSON.parseObject(body); + return AjaxResult.success(jsonObject); + } + + /** + * 小程序获取token + * @param appletInfoVo + * @return + */ + @PostMapping("/queryAppletToken") + public AjaxResult queryAppletToken(AppletInfoVo appletInfoVo) { + return success(userService.queryAppletToken(appletInfoVo)); + } + + /** + * 小程序修改用户头像 + * @return + */ + @PostMapping("/updateAppletAvatar") + public AjaxResult updateAppletAvatar(@RequestParam("avatarfile") MultipartFile file, @RequestParam("userName") String userName) { + return success(userService.updateAppletAvatar(file, userName)); + } + + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysUserOnlineController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysUserOnlineController.java new file mode 100644 index 0000000..cf8081c --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/SysUserOnlineController.java @@ -0,0 +1,87 @@ +package com.dcsoft.system.controller; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.core.constant.CacheConstants; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDataInfo; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.redis.service.RedisService; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.system.api.model.LoginUser; +import com.dcsoft.system.domain.SysUserOnline; +import com.dcsoft.system.service.ISysUserOnlineService; + +/** + * 在线用户监控 + * + * @author dcsoft + */ +@RestController +@RequestMapping("/online") +public class SysUserOnlineController extends BaseController +{ + @Autowired + private ISysUserOnlineService userOnlineService; + + @Autowired + private RedisService redisService; + + @RequiresPermissions("monitor:online:list") + @GetMapping("/list") + public TableDataInfo list(String ipaddr, String userName) + { + Collection keys = redisService.keys(CacheConstants.LOGIN_TOKEN_KEY + "*"); + List userOnlineList = new ArrayList(); + for (String key : keys) + { + try{ + LoginUser user = redisService.getCacheObject(key); + if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) + { + userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user)); + } + else if (StringUtils.isNotEmpty(ipaddr)) + { + userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user)); + } + else if (StringUtils.isNotEmpty(userName)) + { + userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user)); + } + else + { + userOnlineList.add(userOnlineService.loginUserToUserOnline(user)); + } + }catch (Exception e){ + e.printStackTrace(); + } + } + Collections.reverse(userOnlineList); + userOnlineList.removeAll(Collections.singleton(null)); + return getDataTable(userOnlineList); + } + + /** + * 强退用户 + */ + @RequiresPermissions("monitor:online:forceLogout") + @Log(title = "在线用户", businessType = BusinessType.FORCE) + @DeleteMapping("/{tokenId}") + public AjaxResult forceLogout(@PathVariable String tokenId) + { + redisService.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId); + return success(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/ThreadTest1.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/ThreadTest1.java new file mode 100644 index 0000000..5101a0d --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/controller/ThreadTest1.java @@ -0,0 +1,21 @@ +package com.dcsoft.system.controller; + +import cn.hutool.core.thread.ThreadUtil; + +import java.util.concurrent.*; + +public class ThreadTest1 { + public static void main(String[] args) throws ExecutionException, InterruptedException { + for (int i = 0; i < 3; i++) { + ThreadUtil.execAsync(() -> { + ThreadLocalRandom threadLocalRandom = ThreadLocalRandom.current(); + int number = threadLocalRandom.nextInt(20) + 1; + System.out.println(number); + }); +// System.out.println("当前第:" + i + "个线程"); + } +// System.out.println("task finish!"); + + + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysBackGroup.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysBackGroup.java new file mode 100644 index 0000000..774f5d5 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysBackGroup.java @@ -0,0 +1,76 @@ +package com.dcsoft.system.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 背景配置对象 sys_back_group + * + * @author dcsoft + * @date 2024-03-01 + */ +public class SysBackGroup extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 参数主键 */ + private Long id; + + /** 题目 */ + @Excel(name = "题目") + private String name; + + /** 头像 */ + @Excel(name = "头像") + private String avatar; + + @Excel(name = "logo") + private String logo; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setAvatar(String avatar) + { + this.avatar = avatar; + } + + public String getAvatar() + { + return avatar; + } + + public String getLogo() { + return logo; + } + + public void setLogo(String logo) { + this.logo = logo; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("avatar", getAvatar()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysBlackList.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysBlackList.java new file mode 100644 index 0000000..80378f7 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysBlackList.java @@ -0,0 +1,112 @@ +package com.dcsoft.system.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 黑名单管理对象 sys_black_list + * + * @author nichun + * @date 2023-07-03 + */ +public class SysBlackList extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 人员Id */ + private Long id; + + /** 姓名 */ + @Excel(name = "姓名") + private String name; + + /** 联系电话 */ + @Excel(name = "联系电话") + private String phone; + + /** 用户性别(0男 1女 2保密) */ + @Excel(name = "用户性别", readConverterExp = "1=男,2=女") + private String sex; + + /** 身份证号码 */ + @Excel(name = "身份证号码") + private String idcard; + + /** 车牌号码 */ + @Excel(name = "车牌号码") + private String carNo; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setPhone(String phone) + { + this.phone = phone; + } + + public String getPhone() + { + return phone; + } + public void setSex(String sex) + { + this.sex = sex; + } + + public String getSex() + { + return sex; + } + public void setIdcard(String idcard) + { + this.idcard = idcard; + } + + public String getIdcard() + { + return idcard; + } + public void setCarNo(String carNo) + { + this.carNo = carNo; + } + + public String getCarNo() + { + return carNo; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("phone", getPhone()) + .append("sex", getSex()) + .append("idcard", getIdcard()) + .append("carNo", getCarNo()) + .append("remark", getRemark()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysBranch.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysBranch.java new file mode 100644 index 0000000..d39b64e --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysBranch.java @@ -0,0 +1,79 @@ +package com.dcsoft.system.domain; + +import com.dcsoft.system.api.domain.SysDept; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; + +import java.util.ArrayList; +import java.util.List; + +/** + * 部门管理对象 sys_branch + * + * @author dcsoft + * @date 2023-03-07 + */ +@Data +public class SysBranch extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 部门Id */ + private String id; + + /** 部门名称 */ + @Excel(name = "部门名称") + private String name; + + /** 部门负责人 */ + @Excel(name = "部门负责人") + private String leader; + + /** 联系电话 */ + @Excel(name = "联系电话") + private String phone; + + /** 父级Id */ + @Excel(name = "父级Id") + private String parentId; + + /** 祖级列表 */ + @Excel(name = "祖级列表") + private String ancestors; + + /** 所属空间 */ + @Excel(name = "所属空间") + private Long spaceId; + + private Long deptId; + + private String type; + + /** + * 规则id + */ + private Long ruleId; + + /** + * 梯控规则id + */ + private String ladderRuleId; + + /** + * 访客审核 0否 1是 + */ + private String isExamine; + + private Boolean examine; + + + + /** 子部门 */ + private List children = new ArrayList(); + + + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysConfig.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysConfig.java new file mode 100644 index 0000000..1c9d87b --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysConfig.java @@ -0,0 +1,111 @@ +package com.dcsoft.system.domain; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.annotation.Excel.ColumnType; +import com.dcsoft.common.core.web.domain.BaseEntity; + +/** + * 参数配置表 sys_config + * + * @author dcsoft + */ +public class SysConfig extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 参数主键 */ + @Excel(name = "参数主键", cellType = ColumnType.NUMERIC) + private Long configId; + + /** 参数名称 */ + @Excel(name = "参数名称") + private String configName; + + /** 参数键名 */ + @Excel(name = "参数键名") + private String configKey; + + /** 参数键值 */ + @Excel(name = "参数键值") + private String configValue; + + /** 系统内置(Y是 N否) */ + @Excel(name = "系统内置", readConverterExp = "Y=是,N=否") + private String configType; + + public Long getConfigId() + { + return configId; + } + + public void setConfigId(Long configId) + { + this.configId = configId; + } + + @NotBlank(message = "参数名称不能为空") + @Size(min = 0, max = 100, message = "参数名称不能超过100个字符") + public String getConfigName() + { + return configName; + } + + public void setConfigName(String configName) + { + this.configName = configName; + } + + @NotBlank(message = "参数键名长度不能为空") + @Size(min = 0, max = 100, message = "参数键名长度不能超过100个字符") + public String getConfigKey() + { + return configKey; + } + + public void setConfigKey(String configKey) + { + this.configKey = configKey; + } + + @NotBlank(message = "参数键值不能为空") + @Size(min = 0, max = 500, message = "参数键值长度不能超过500个字符") + public String getConfigValue() + { + return configValue; + } + + public void setConfigValue(String configValue) + { + this.configValue = configValue; + } + + public String getConfigType() + { + return configType; + } + + public void setConfigType(String configType) + { + this.configType = configType; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("configId", getConfigId()) + .append("configName", getConfigName()) + .append("configKey", getConfigKey()) + .append("configValue", getConfigValue()) + .append("configType", getConfigType()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysEmpowerRecord.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysEmpowerRecord.java new file mode 100644 index 0000000..cbcef93 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysEmpowerRecord.java @@ -0,0 +1,67 @@ +package com.dcsoft.system.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 授权记录对象 sys_empower_record + * + * @author nichun + * @date 2023-03-08 + */ +@Data +public class SysEmpowerRecord extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 记录Id */ + private Long id; + + /** 姓名 */ + @Excel(name = "姓名") + private String name; + + private String peopleName; + + /** 人员id */ + @Excel(name = "人员id") + private String peopleId; + + /** 信息下发(0成功 1失败) */ + @Excel(name = "信息下发", readConverterExp = "0=成功,1=失败") + private String infoDown; + + /** 授权方式(0本地 1云盘) */ + @Excel(name = "授权方式", readConverterExp = "0=本地,1=云盘") + private String empower; + + /** 设备Id */ + @Excel(name = "设备Id") + private Long equipmentId; + + /** 操作(0启用 1禁用) */ + @Excel(name = "操作", readConverterExp = "0=启用,1=禁用") + private String status; + + /** 规则Id */ + @Excel(name = "规则Id") + private Long ruleId; + + + private SysPeople people; + + private SysEquipment equipment; + + private SysRule rule; + + private String gh; + + /** + * 门禁设备位置 1进 2出 + */ + private String entryExitType; + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysEquipment.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysEquipment.java new file mode 100644 index 0000000..003ad57 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysEquipment.java @@ -0,0 +1,1140 @@ +package com.dcsoft.system.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import com.dcsoft.system.api.domain.SysDept; +import com.dcsoft.system.domain.vo.SysFileVo; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.List; + +/** + * 设备信息对象 sys_equipment + * + * @author nichun + * @date 2023-03-08 + */ +public class SysEquipment extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 设备Id */ + private Long id; + + /** 所属产品Id */ + @Excel(name = "所属产品Id") + private Long productId; + + /** 设备名称 */ + @Excel(name = "设备名称") + private String name; + + /** 设备序列号 */ + @Excel(name = "设备序列号") + private String sequence; + + /** 设备Ip */ + @Excel(name = "设备Ip") + private String ip; + + /** 设备密码 */ + @Excel(name = "设备密码") + private String password; + + /** 设备区域 */ + @Excel(name = "设备区域") + private Long spaceId; + + /** 设备位置 */ + @Excel(name = "设备位置") + private Long pointId; + + /** 对接状态(0未对接 1对接成功) */ + private Long state; + + /** 设备状态(0在线 1离线) */ + private String flag; + + /***设备回调地址***/ + private String backUrl; + + /***设备回调地址***/ + private String isCj; + + + /** 操作标识 */ + private String handle; + + /** 识别通用参数.时间窗 60 秒(默认) */ + private String comRecTimeWindow; + + /** 识别通用参数.识别等级 1:非活体 速度优先2:活体 安全优先(默认) */ + private String comRecRank; + + /** 识别通用参数.识别距离 *1:无限制 *2:0.5 米以内 *3:1 米以内(Uface C 默认) *4:1.5 米以内 *5:2 米以内 *6:3 米以内 *7:4 米以内 若识别等级选择 2 活体,则 1、4、5、6、7 不可选;若识别等级选择 1 非活体,则 1-7 均可选。} */ + private String comRecDistModeType; + + /** 中英文语言类型 zh_CN: 简体中文 en: 英文 */ + private String languageType; + + /** 识别通用参数.继电器控制时间 500ms(默认) 继电器控制开门到关门之间的时间间隔,默认 500ms。请输入 100-25500 之间的整数,向下取整百。如:输入 101-199 之间的整数,实际生效的是 100ms。 */ + private String comRelayTime; + + /** 时区 */ + private String timeZone; + + /** 刷脸识别参数.刷脸模式开关 1:打开(默认) 2:关闭} */ + private String faceEnable; + + /** 刷脸识别参数.人像识别阈值 80(默认) 实际允许 0-100 之间的所有整数。提示:请输入 50-100 之间的整数。分数越高,识别准确率越高,但识别速度会变慢 */ + private String faceScore; + + /** 刷脸识别参数.人像检测类型 1:多人识别(默认) 2:单人识别 */ + private String faceDetectionType; + + /** 是否连续识别 1: 关(默认) 2: 开 */ + private String repeatRegEnable; + + /** 连续识别间隔时间 */ + private String regInterval; + + /** 刷卡识别参数.刷卡模式开关 1:打开(默认) 2:关闭 */ + private String cardEnable; + + /** 识别成功参数.语音播类型 1:播报名字(默认) 2:不播放 100:自定义 */ + private String recSucTtsModeType; + + /** 识别成功参数.语音播报自定义内容 允许{name}、{tag}。字段格式固定,其他内容只允许数字、英文和汉字,长度限制 255 个字符。如:{name}欢迎光临 */ + private String recSucTtsModeContent; + + /** 识别成功参数.屏幕显示文字 1 类型 1:姓名(默认) 100:自定义 */ + private String recSucDisplayText1Type; + + /** 识别成功参数.屏幕显示文字 2 自定义内容 */ + private String recSucDisplayText1Content; + + /** 识别成功参数.屏幕显示文字 2 类型 1:识别成功(默认) 100:自定义 */ + private String recSucDisplayText2Type; + + /** 识别成功参数.屏幕显示文字 2 自定义内容 */ + private String recSucDisplayText2Content; + + /** 识别成功参数.串口输出类型 1:开门(默认) 2:不输出 3:输出 phone 4:输出 cardNo 100:自定义 */ + private String recSucComModeType; + + /** 识别成功参数.串口输出自定义内容 */ + private String recSucComModeContent; + + /** 识别成功参数.韦根输出类型 1:不输出(默认) 2:韦根 26 3:韦根 34 */ + private String recSucWiegandType; + + /** 识别成功参数.韦根输出自定义内容 允许{phone}、{cardNo}。字段格式固定且只能为数字或字母,其他内容只允许数字、英文和英文符号,长度限制 255 个字符。串口支持输出韦根信号,设备需要外接串口 → 韦根信号转换小板,小板由本公司定制。自定义内容传入格式:韦根 26:#26WG{cardNo}#,韦根 34:#34WG{cardNo}#注意:{cardNo}+数字组合后,韦根 26 范围为 1-65535(待定),有效范围为 5 位;韦根 34 范围为 1-4294967295(待定),有效范围为 10 位。若超出范围,则输出的信号会进行转换,输出无效信号。 */ + private String recSucWiegandContent; + + /** 识别成功参数.继电器输出类型 1:输出(默认) 2:不输出 */ + private String recSucRelayType; + + /** 识别失败参数.识别失败开关 1:打开(默认) 2:关闭 */ + private String recFailEnable; + + /** 识别失败参数.判定次数 3(默认) 打开识别失败开关后,该选项有效;连续比对 N 次都未达到分数阈值,则判定为识别失败,默认 3 次;传入值请选择 1-20 之间的整数,1 表示快速判定但精确率最低,随着数值增加,判定时间增加,精确度提高 */ + private String recFailTimesThreshold; + + /** 识别失败参数.语音播类型 1:识别失败(默认) 2:不播放 100:自定义 */ + private String recFailTtsModeType; + + /** 识别失败参数.语音播报自定义内容 内容只允许数字、英文和汉字,长度限制 255 个字符。如:注意陌生人 */ + private String recFailTtsModeContent; + + /** 识别失败参数.屏幕显示文字类型 1:识别失败(默认) 100:自定义 */ + private String recFailDisplayTextType; + + /** 识别失败参数.屏幕显示文字自定义内容 内容只允许数字、中英文和中英文符号,长度限制 255 个字符。如:注意陌生人! */ + private String recFailDisplayTextContent; + + /** 识别失败参数.串口输出类型 1:开门 2:不输出(默认) 100:自定义 */ + private String recFailComModeType; + + /** 识别失败参数.串口输出自定义内容 */ + private String recFailComModeContent; + + /** 识别失败参数.韦根输出类型 1:不输出(默认) 2:韦根 26 3:韦根 34 */ + private String recFailWiegandType; + + /** 识别失败参数.韦根输出自定义内容 */ + private String recFailWiegandContent; + + /** 识别失败参数.继电器输出类型 1:输出 2:不输出(默认) */ + private String recFailRelayType; + + /** 权限不足参数.语音播类型 1:播报姓名权限不足(默认) 2:不播放 100:自定义 */ + private String recNoPerTtsModeType; + + /** 权限不足参数.语音播报自定义内容 允许{name}、{tag}。字段格式固定,其他内容只允许数字、英文和汉字,长度限制 255 个字符。如:{name}无权通行 */ + private String recNoPerTtsModeContent; + + /** 权限不足参数.屏幕显示文字 1 类型 1:姓名(默认) 100:自定义 */ + private String recNoPerDisplayText1Type; + + /** 权限不足参数.屏幕显示文字 1 类型 1:姓名(默认) 100:自定义 */ + private String recNoPerDisplayText1Content; + + /** 权限不足参数.屏幕显示文字 1 类型 1:姓名(默认) 100:自定义 */ + private String recNoPerDisplayText2Type; + + /** 权限不足参数.屏幕显示文字 2 自定义内容 */ + private String recNoPerDisplayText2Content; + + /** 权限不足参数.串口输出类型 1:开门 2:不输出(默认) 3:输出 phone 4:输出 cardNo 100:自定义 */ + private String recNoPerComModeType; + + /** 权限不足参数.串口输出类型 1:开门 2:不输出(默认) 3:输出 phone 4:输出 cardNo 100:自定义 */ + private String recNoPerComModeContent; + + /** 权限不足参数.韦根输出类型 1:不输出(默认) 2:韦根 26 3:韦根 34 */ + private String recNoPerWiegandType; + + /** 权限不足参数.韦根输出自定义内容 */ + private String recNoPerWiegandContent; + + /** 权限不足参数.继电器输出类型 1:输出 2:不输出(默认) */ + private String recNoPerRelayType; + + /** 固定显示参数.显示文字内容 1 类型 1:不显示(默认) 2:应用名称 100:自定义 */ + private String scrDisplayText1Type; + + /** 固定显示参数.显示文字内容 1 自定义内容 长度限制 255 */ + private String scrDisplayText1Content; + + /** 固定显示参数.显示文字内容 2 类型 1:不显示 2:设备名称(默认) 100:自定义 */ + private String scrDisplayText2Type; + + /** 固定显示参数.显示文字内容 2 自定义内容 长度限制 255 */ + private String scrDisplayText2Content; + + /** 固定显示参数.是否显示设备序列号 true(默认) false */ + private String isShowDeviceKey; + + /** 固定显示参数.是否显示 IP true(默认) false */ + private String isShowIp; + + /** 固定显示参数.是否显示人数 true(默认) false */ + private String isShowPersonCount; + + /** 固定显示参数.显示图片 1 默认使用设备自带图片(jpg,jpeg,png,mp4) */ + private String scrImage1Url; + + /** 固定显示参数.显示图片 2 默认无图片(jpg,jpeg,png,mp4) */ + private String scrImage2Url; + + /** 测温开关,1 开,2 关 */ + private String isTemperatureOpen; + + /** 低温补偿开关,1 开,2 关 */ + private String temperatureCompensation; + + /** 有效温度最高值 */ + private String temperatureMeasureMax; + + /** 有效温度最低值 */ + private String temperatureMeasureMin; + + /** 高温补偿开关,1 开,2 关 */ + private String tempMapSwitch; + + /** 测温单位 */ + private String tempUnit; + + /** 口罩模式开关:1 开,2 关 */ + private String isMaskOpen; + + /** 异常温度判断值 */ + private String errorTemperature; + + private SysProduct product; + + private SysPoint point; + + private String bigtype; + + private String doorNo; + + private String empowerRecordId; + + private String peopleId; + + private String entryExitType; + + private String deviceKey; + + private String deviceIp; + + private String port; + + private String fileName; + + private String fileType; + + public String getFileType() { + return fileType; + } + + public void setFileType(String fileType) { + this.fileType = fileType; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + private List fileList; + + public List getFileList() { + return fileList; + } + + public void setFileList(List fileList) { + this.fileList = fileList; + } + + public String getPort() { + return port; + } + + public void setPort(String port) { + this.port = port; + } + + public String getDeviceIp() { + return deviceIp; + } + + public void setDeviceIp(String deviceIp) { + this.deviceIp = deviceIp; + } + + public String getDeviceKey() { + return deviceKey; + } + + public void setDeviceKey(String deviceKey) { + this.deviceKey = deviceKey; + } + + public String getEntryExitType() { + return entryExitType; + } + + public void setEntryExitType(String entryExitType) { + this.entryExitType = entryExitType; + } + + public String getPeopleId() { + return peopleId; + } + + public void setPeopleId(String peopleId) { + this.peopleId = peopleId; + } + + public String getEmpowerRecordId() { + return empowerRecordId; + } + + public void setEmpowerRecordId(String empowerRecordId) { + this.empowerRecordId = empowerRecordId; + } + + public String getDoorNo() { + return doorNo; + } + + public void setDoorNo(String doorNo) { + this.doorNo = doorNo; + } + + public String getBigtype() { + return bigtype; + } + + public void setBigtype(String bigtype) { + this.bigtype = bigtype; + } + + public SysPoint getPoint() { + return point; + } + + public void setPoint(SysPoint point) { + this.point = point; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setProductId(Long productId) + { + this.productId = productId; + } + + public Long getProductId() + { + return productId; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setSequence(String sequence) + { + this.sequence = sequence; + } + + public String getSequence() + { + return sequence; + } + public void setIp(String ip) + { + this.ip = ip; + } + + public String getIp() + { + return ip; + } + public void setPassword(String password) + { + this.password = password; + } + + public String getPassword() + { + return password; + } + public void setSpaceId(Long spaceId) + { + this.spaceId = spaceId; + } + + public Long getSpaceId() + { + return spaceId; + } + public void setPointId(Long pointId) + { + this.pointId = pointId; + } + + public Long getPointId() + { + return pointId; + } + public void setState(Long state) + { + this.state = state; + } + + public Long getState() + { + return state; + } + public void setFlag(String flag) + { + this.flag = flag; + } + + public String getFlag() + { + return flag; + } + public void setComRecTimeWindow(String comRecTimeWindow) + { + this.comRecTimeWindow = comRecTimeWindow; + } + + public String getComRecTimeWindow() + { + return comRecTimeWindow; + } + public void setComRecRank(String comRecRank) + { + this.comRecRank = comRecRank; + } + + public String getComRecRank() + { + return comRecRank; + } + public void setComRecDistModeType(String comRecDistModeType) + { + this.comRecDistModeType = comRecDistModeType; + } + + public String getComRecDistModeType() + { + return comRecDistModeType; + } + public void setLanguageType(String languageType) + { + this.languageType = languageType; + } + + public String getLanguageType() + { + return languageType; + } + public void setComRelayTime(String comRelayTime) + { + this.comRelayTime = comRelayTime; + } + + public String getComRelayTime() + { + return comRelayTime; + } + public void setTimeZone(String timeZone) + { + this.timeZone = timeZone; + } + + public String getTimeZone() + { + return timeZone; + } + public void setFaceEnable(String faceEnable) + { + this.faceEnable = faceEnable; + } + + public String getFaceEnable() + { + return faceEnable; + } + public void setFaceScore(String faceScore) + { + this.faceScore = faceScore; + } + + public String getFaceScore() + { + return faceScore; + } + public void setFaceDetectionType(String faceDetectionType) + { + this.faceDetectionType = faceDetectionType; + } + + public String getFaceDetectionType() + { + return faceDetectionType; + } + public void setRepeatRegEnable(String repeatRegEnable) + { + this.repeatRegEnable = repeatRegEnable; + } + + public String getRepeatRegEnable() + { + return repeatRegEnable; + } + public void setRegInterval(String regInterval) + { + this.regInterval = regInterval; + } + + public String getRegInterval() + { + return regInterval; + } + public void setCardEnable(String cardEnable) + { + this.cardEnable = cardEnable; + } + + public String getCardEnable() + { + return cardEnable; + } + public void setRecSucTtsModeType(String recSucTtsModeType) + { + this.recSucTtsModeType = recSucTtsModeType; + } + + public String getRecSucTtsModeType() + { + return recSucTtsModeType; + } + public void setRecSucTtsModeContent(String recSucTtsModeContent) + { + this.recSucTtsModeContent = recSucTtsModeContent; + } + + public String getRecSucTtsModeContent() + { + return recSucTtsModeContent; + } + public void setRecSucDisplayText1Type(String recSucDisplayText1Type) + { + this.recSucDisplayText1Type = recSucDisplayText1Type; + } + + public String getRecSucDisplayText1Type() + { + return recSucDisplayText1Type; + } + public void setRecSucDisplayText1Content(String recSucDisplayText1Content) + { + this.recSucDisplayText1Content = recSucDisplayText1Content; + } + + public String getRecSucDisplayText1Content() + { + return recSucDisplayText1Content; + } + public void setRecSucDisplayText2Type(String recSucDisplayText2Type) + { + this.recSucDisplayText2Type = recSucDisplayText2Type; + } + + public String getRecSucDisplayText2Type() + { + return recSucDisplayText2Type; + } + public void setRecSucDisplayText2Content(String recSucDisplayText2Content) + { + this.recSucDisplayText2Content = recSucDisplayText2Content; + } + + public String getRecSucDisplayText2Content() + { + return recSucDisplayText2Content; + } + public void setRecSucComModeType(String recSucComModeType) + { + this.recSucComModeType = recSucComModeType; + } + + public String getRecSucComModeType() + { + return recSucComModeType; + } + public void setRecSucComModeContent(String recSucComModeContent) + { + this.recSucComModeContent = recSucComModeContent; + } + + public String getRecSucComModeContent() + { + return recSucComModeContent; + } + public void setRecSucWiegandType(String recSucWiegandType) + { + this.recSucWiegandType = recSucWiegandType; + } + + public String getRecSucWiegandType() + { + return recSucWiegandType; + } + public void setRecSucWiegandContent(String recSucWiegandContent) + { + this.recSucWiegandContent = recSucWiegandContent; + } + + public String getRecSucWiegandContent() + { + return recSucWiegandContent; + } + public void setRecSucRelayType(String recSucRelayType) + { + this.recSucRelayType = recSucRelayType; + } + + public String getRecSucRelayType() + { + return recSucRelayType; + } + public void setRecFailEnable(String recFailEnable) + { + this.recFailEnable = recFailEnable; + } + + public String getRecFailEnable() + { + return recFailEnable; + } + public void setRecFailTimesThreshold(String recFailTimesThreshold) + { + this.recFailTimesThreshold = recFailTimesThreshold; + } + + public String getRecFailTimesThreshold() + { + return recFailTimesThreshold; + } + public void setRecFailTtsModeType(String recFailTtsModeType) + { + this.recFailTtsModeType = recFailTtsModeType; + } + + public String getRecFailTtsModeType() + { + return recFailTtsModeType; + } + public void setRecFailTtsModeContent(String recFailTtsModeContent) + { + this.recFailTtsModeContent = recFailTtsModeContent; + } + + public String getRecFailTtsModeContent() + { + return recFailTtsModeContent; + } + public void setRecFailDisplayTextType(String recFailDisplayTextType) + { + this.recFailDisplayTextType = recFailDisplayTextType; + } + + public String getRecFailDisplayTextType() + { + return recFailDisplayTextType; + } + public void setRecFailDisplayTextContent(String recFailDisplayTextContent) + { + this.recFailDisplayTextContent = recFailDisplayTextContent; + } + + public String getRecFailDisplayTextContent() + { + return recFailDisplayTextContent; + } + public void setRecFailComModeType(String recFailComModeType) + { + this.recFailComModeType = recFailComModeType; + } + + public String getRecFailComModeType() + { + return recFailComModeType; + } + public void setRecFailComModeContent(String recFailComModeContent) + { + this.recFailComModeContent = recFailComModeContent; + } + + public String getRecFailComModeContent() + { + return recFailComModeContent; + } + public void setRecFailWiegandType(String recFailWiegandType) + { + this.recFailWiegandType = recFailWiegandType; + } + + public String getRecFailWiegandType() + { + return recFailWiegandType; + } + public void setRecFailWiegandContent(String recFailWiegandContent) + { + this.recFailWiegandContent = recFailWiegandContent; + } + + public String getRecFailWiegandContent() + { + return recFailWiegandContent; + } + public void setRecFailRelayType(String recFailRelayType) + { + this.recFailRelayType = recFailRelayType; + } + + public String getRecFailRelayType() + { + return recFailRelayType; + } + public void setRecNoPerTtsModeType(String recNoPerTtsModeType) + { + this.recNoPerTtsModeType = recNoPerTtsModeType; + } + + public String getRecNoPerTtsModeType() + { + return recNoPerTtsModeType; + } + public void setRecNoPerTtsModeContent(String recNoPerTtsModeContent) + { + this.recNoPerTtsModeContent = recNoPerTtsModeContent; + } + + public String getRecNoPerTtsModeContent() + { + return recNoPerTtsModeContent; + } + public void setRecNoPerDisplayText1Type(String recNoPerDisplayText1Type) + { + this.recNoPerDisplayText1Type = recNoPerDisplayText1Type; + } + + public String getRecNoPerDisplayText1Type() + { + return recNoPerDisplayText1Type; + } + public void setRecNoPerDisplayText1Content(String recNoPerDisplayText1Content) + { + this.recNoPerDisplayText1Content = recNoPerDisplayText1Content; + } + + public String getRecNoPerDisplayText1Content() + { + return recNoPerDisplayText1Content; + } + public void setRecNoPerDisplayText2Type(String recNoPerDisplayText2Type) + { + this.recNoPerDisplayText2Type = recNoPerDisplayText2Type; + } + + public String getRecNoPerDisplayText2Type() + { + return recNoPerDisplayText2Type; + } + public void setRecNoPerDisplayText2Content(String recNoPerDisplayText2Content) + { + this.recNoPerDisplayText2Content = recNoPerDisplayText2Content; + } + + public String getRecNoPerDisplayText2Content() + { + return recNoPerDisplayText2Content; + } + public void setRecNoPerComModeType(String recNoPerComModeType) + { + this.recNoPerComModeType = recNoPerComModeType; + } + + public String getRecNoPerComModeType() + { + return recNoPerComModeType; + } + public void setRecNoPerComModeContent(String recNoPerComModeContent) + { + this.recNoPerComModeContent = recNoPerComModeContent; + } + + public String getRecNoPerComModeContent() + { + return recNoPerComModeContent; + } + public void setRecNoPerWiegandType(String recNoPerWiegandType) + { + this.recNoPerWiegandType = recNoPerWiegandType; + } + + public String getRecNoPerWiegandType() + { + return recNoPerWiegandType; + } + public void setRecNoPerWiegandContent(String recNoPerWiegandContent) + { + this.recNoPerWiegandContent = recNoPerWiegandContent; + } + + public String getRecNoPerWiegandContent() + { + return recNoPerWiegandContent; + } + public void setRecNoPerRelayType(String recNoPerRelayType) + { + this.recNoPerRelayType = recNoPerRelayType; + } + + public String getRecNoPerRelayType() + { + return recNoPerRelayType; + } + public void setScrDisplayText1Type(String scrDisplayText1Type) + { + this.scrDisplayText1Type = scrDisplayText1Type; + } + + public String getScrDisplayText1Type() + { + return scrDisplayText1Type; + } + public void setScrDisplayText1Content(String scrDisplayText1Content) + { + this.scrDisplayText1Content = scrDisplayText1Content; + } + + public String getScrDisplayText1Content() + { + return scrDisplayText1Content; + } + public void setScrDisplayText2Type(String scrDisplayText2Type) + { + this.scrDisplayText2Type = scrDisplayText2Type; + } + + public String getScrDisplayText2Type() + { + return scrDisplayText2Type; + } + public void setScrDisplayText2Content(String scrDisplayText2Content) + { + this.scrDisplayText2Content = scrDisplayText2Content; + } + + public String getScrDisplayText2Content() + { + return scrDisplayText2Content; + } + public void setIsShowDeviceKey(String isShowDeviceKey) + { + this.isShowDeviceKey = isShowDeviceKey; + } + + public String getIsShowDeviceKey() + { + return isShowDeviceKey; + } + public void setIsShowIp(String isShowIp) + { + this.isShowIp = isShowIp; + } + + public String getIsShowIp() + { + return isShowIp; + } + public void setIsShowPersonCount(String isShowPersonCount) + { + this.isShowPersonCount = isShowPersonCount; + } + + public String getIsShowPersonCount() + { + return isShowPersonCount; + } + public void setScrImage1Url(String scrImage1Url) + { + this.scrImage1Url = scrImage1Url; + } + + public String getScrImage1Url() + { + return scrImage1Url; + } + public void setScrImage2Url(String scrImage2Url) + { + this.scrImage2Url = scrImage2Url; + } + + public String getScrImage2Url() + { + return scrImage2Url; + } + public void setIsTemperatureOpen(String isTemperatureOpen) + { + this.isTemperatureOpen = isTemperatureOpen; + } + + public String getIsTemperatureOpen() + { + return isTemperatureOpen; + } + public void setTemperatureCompensation(String temperatureCompensation) + { + this.temperatureCompensation = temperatureCompensation; + } + + public String getTemperatureCompensation() + { + return temperatureCompensation; + } + public void setTemperatureMeasureMax(String temperatureMeasureMax) + { + this.temperatureMeasureMax = temperatureMeasureMax; + } + + public String getTemperatureMeasureMax() + { + return temperatureMeasureMax; + } + public void setTemperatureMeasureMin(String temperatureMeasureMin) + { + this.temperatureMeasureMin = temperatureMeasureMin; + } + + public String getTemperatureMeasureMin() + { + return temperatureMeasureMin; + } + public void setTempMapSwitch(String tempMapSwitch) + { + this.tempMapSwitch = tempMapSwitch; + } + + public String getTempMapSwitch() + { + return tempMapSwitch; + } + public void setTempUnit(String tempUnit) + { + this.tempUnit = tempUnit; + } + + public String getTempUnit() + { + return tempUnit; + } + public void setIsMaskOpen(String isMaskOpen) + { + this.isMaskOpen = isMaskOpen; + } + + public String getIsMaskOpen() + { + return isMaskOpen; + } + public void setErrorTemperature(String errorTemperature) + { + this.errorTemperature = errorTemperature; + } + + public String getErrorTemperature() + { + return errorTemperature; + } + + public String getHandle() { + return handle; + } + + public void setHandle(String handle) { + this.handle = handle; + } + + public SysProduct getProduct() { + return product; + } + + public void setProduct(SysProduct product) { + this.product = product; + } + + public String getBackUrl() { + return backUrl; + } + + public void setBackUrl(String backUrl) { + this.backUrl = backUrl; + } + + public String getIsCj() { + return isCj; + } + + public void setIsCj(String isCj) { + this.isCj = isCj; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("productId", getProductId()) + .append("name", getName()) + .append("sequence", getSequence()) + .append("ip", getIp()) + .append("password", getPassword()) + .append("spaceId", getSpaceId()) + .append("pointId", getPointId()) + .append("remark", getRemark()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("state", getState()) + .append("flag", getFlag()) + .append("comRecTimeWindow", getComRecTimeWindow()) + .append("comRecRank", getComRecRank()) + .append("comRecDistModeType", getComRecDistModeType()) + .append("languageType", getLanguageType()) + .append("comRelayTime", getComRelayTime()) + .append("timeZone", getTimeZone()) + .append("faceEnable", getFaceEnable()) + .append("faceScore", getFaceScore()) + .append("faceDetectionType", getFaceDetectionType()) + .append("repeatRegEnable", getRepeatRegEnable()) + .append("regInterval", getRegInterval()) + .append("cardEnable", getCardEnable()) + .append("recSucTtsModeType", getRecSucTtsModeType()) + .append("recSucTtsModeContent", getRecSucTtsModeContent()) + .append("recSucDisplayText1Type", getRecSucDisplayText1Type()) + .append("recSucDisplayText1Content", getRecSucDisplayText1Content()) + .append("recSucDisplayText2Type", getRecSucDisplayText2Type()) + .append("recSucDisplayText2Content", getRecSucDisplayText2Content()) + .append("recSucComModeType", getRecSucComModeType()) + .append("recSucComModeContent", getRecSucComModeContent()) + .append("recSucWiegandType", getRecSucWiegandType()) + .append("recSucWiegandContent", getRecSucWiegandContent()) + .append("recSucRelayType", getRecSucRelayType()) + .append("recFailEnable", getRecFailEnable()) + .append("recFailTimesThreshold", getRecFailTimesThreshold()) + .append("recFailTtsModeType", getRecFailTtsModeType()) + .append("recFailTtsModeContent", getRecFailTtsModeContent()) + .append("recFailDisplayTextType", getRecFailDisplayTextType()) + .append("recFailDisplayTextContent", getRecFailDisplayTextContent()) + .append("recFailComModeType", getRecFailComModeType()) + .append("recFailComModeContent", getRecFailComModeContent()) + .append("recFailWiegandType", getRecFailWiegandType()) + .append("recFailWiegandContent", getRecFailWiegandContent()) + .append("recFailRelayType", getRecFailRelayType()) + .append("recNoPerTtsModeType", getRecNoPerTtsModeType()) + .append("recNoPerTtsModeContent", getRecNoPerTtsModeContent()) + .append("recNoPerDisplayText1Type", getRecNoPerDisplayText1Type()) + .append("recNoPerDisplayText1Content", getRecNoPerDisplayText1Content()) + .append("recNoPerDisplayText2Type", getRecNoPerDisplayText2Type()) + .append("recNoPerDisplayText2Content", getRecNoPerDisplayText2Content()) + .append("recNoPerComModeType", getRecNoPerComModeType()) + .append("recNoPerComModeContent", getRecNoPerComModeContent()) + .append("recNoPerWiegandType", getRecNoPerWiegandType()) + .append("recNoPerWiegandContent", getRecNoPerWiegandContent()) + .append("recNoPerRelayType", getRecNoPerRelayType()) + .append("scrDisplayText1Type", getScrDisplayText1Type()) + .append("scrDisplayText1Content", getScrDisplayText1Content()) + .append("scrDisplayText2Type", getScrDisplayText2Type()) + .append("scrDisplayText2Content", getScrDisplayText2Content()) + .append("isShowDeviceKey", getIsShowDeviceKey()) + .append("isShowIp", getIsShowIp()) + .append("isShowPersonCount", getIsShowPersonCount()) + .append("scrImage1Url", getScrImage1Url()) + .append("scrImage2Url", getScrImage2Url()) + .append("isTemperatureOpen", getIsTemperatureOpen()) + .append("temperatureCompensation", getTemperatureCompensation()) + .append("temperatureMeasureMax", getTemperatureMeasureMax()) + .append("temperatureMeasureMin", getTemperatureMeasureMin()) + .append("tempMapSwitch", getTempMapSwitch()) + .append("tempUnit", getTempUnit()) + .append("isMaskOpen", getIsMaskOpen()) + .append("errorTemperature", getErrorTemperature()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysManageRecord.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysManageRecord.java new file mode 100644 index 0000000..a1cb890 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysManageRecord.java @@ -0,0 +1,148 @@ +package com.dcsoft.system.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 授权管理记录对象 sys_manage_record + * + * @author dcsoft + * @date 2023-03-08 + */ +public class SysManageRecord extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 记录Id */ + private Long id; + + /** 关联类型(1部门 2人员) */ + @Excel(name = "关联类型(1部门 2人员)") + private Long type; + + /** 人员id */ + @Excel(name = "人员id") + private Long peopleId; + + /** 部门id */ + @Excel(name = "部门id") + private Long branchId; + + /** 规则id */ + @Excel(name = "规则id") + private Long ruleId; + + private SysPeople people; + + private SysBranch branch; + + private SysRule rule; + + protected String[] peopleIds; + + protected String[] branchIds; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setType(Long type) + { + this.type = type; + } + + public Long getType() + { + return type; + } + public void setPeopleId(Long peopleId) + { + this.peopleId = peopleId; + } + + public Long getPeopleId() + { + return peopleId; + } + public void setBranchId(Long branchId) + { + this.branchId = branchId; + } + + public Long getBranchId() + { + return branchId; + } + public void setRuleId(Long ruleId) + { + this.ruleId = ruleId; + } + + public Long getRuleId() + { + return ruleId; + } + + public String[] getPeopleIds() { + return peopleIds; + } + + public void setPeopleIds(String[] peopleIds) { + this.peopleIds = peopleIds; + } + + public String[] getBranchIds() { + return branchIds; + } + + public void setBranchIds(String[] branchIds) { + this.branchIds = branchIds; + } + + public SysPeople getPeople() { + return people; + } + + public void setPeople(SysPeople people) { + this.people = people; + } + + public SysBranch getBranch() { + return branch; + } + + public void setBranch(SysBranch branch) { + this.branch = branch; + } + + public SysRule getRule() { + return rule; + } + + public void setRule(SysRule rule) { + this.rule = rule; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("type", getType()) + .append("peopleId", getPeopleId()) + .append("branchId", getBranchId()) + .append("ruleId", getRuleId()) + .append("remark", getRemark()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysMenu.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysMenu.java new file mode 100644 index 0000000..a6e7abb --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysMenu.java @@ -0,0 +1,259 @@ +package com.dcsoft.system.domain; + +import java.util.ArrayList; +import java.util.List; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.dcsoft.common.core.web.domain.BaseEntity; + +/** + * 菜单权限表 sys_menu + * + * @author dcsoft + */ +public class SysMenu extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 菜单ID */ + private Long menuId; + + /** 菜单名称 */ + private String menuName; + + /** 父菜单名称 */ + private String parentName; + + /** 父菜单ID */ + private Long parentId; + + /** 显示顺序 */ + private Integer orderNum; + + /** 路由地址 */ + private String path; + + /** 组件路径 */ + private String component; + + /** 路由参数 */ + private String query; + + /** 是否为外链(0是 1否) */ + private String isFrame; + + /** 是否缓存(0缓存 1不缓存) */ + private String isCache; + + /** 类型(M目录 C菜单 F按钮) */ + private String menuType; + + /** 显示状态(0显示 1隐藏) */ + private String visible; + + /** 菜单状态(0正常 1停用) */ + private String status; + + /** 权限字符串 */ + private String perms; + + /** 菜单图标 */ + private String icon; + + /** 子菜单 */ + private List children = new ArrayList(); + + public Long getMenuId() + { + return menuId; + } + + public void setMenuId(Long menuId) + { + this.menuId = menuId; + } + + @NotBlank(message = "菜单名称不能为空") + @Size(min = 0, max = 50, message = "菜单名称长度不能超过50个字符") + public String getMenuName() + { + return menuName; + } + + public void setMenuName(String menuName) + { + this.menuName = menuName; + } + + public String getParentName() + { + return parentName; + } + + public void setParentName(String parentName) + { + this.parentName = parentName; + } + + public Long getParentId() + { + return parentId; + } + + public void setParentId(Long parentId) + { + this.parentId = parentId; + } + + @NotNull(message = "显示顺序不能为空") + public Integer getOrderNum() + { + return orderNum; + } + + public void setOrderNum(Integer orderNum) + { + this.orderNum = orderNum; + } + + @Size(min = 0, max = 200, message = "路由地址不能超过200个字符") + public String getPath() + { + return path; + } + + public void setPath(String path) + { + this.path = path; + } + + @Size(min = 0, max = 200, message = "组件路径不能超过255个字符") + public String getComponent() + { + return component; + } + + public void setComponent(String component) + { + this.component = component; + } + + public String getQuery() + { + return query; + } + + public void setQuery(String query) + { + this.query = query; + } + + public String getIsFrame() + { + return isFrame; + } + + public void setIsFrame(String isFrame) + { + this.isFrame = isFrame; + } + + public String getIsCache() + { + return isCache; + } + + public void setIsCache(String isCache) + { + this.isCache = isCache; + } + + @NotBlank(message = "菜单类型不能为空") + public String getMenuType() + { + return menuType; + } + + public void setMenuType(String menuType) + { + this.menuType = menuType; + } + + public String getVisible() + { + return visible; + } + + public void setVisible(String visible) + { + this.visible = visible; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + @Size(min = 0, max = 100, message = "权限标识长度不能超过100个字符") + public String getPerms() + { + return perms; + } + + public void setPerms(String perms) + { + this.perms = perms; + } + + 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; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("menuId", getMenuId()) + .append("menuName", getMenuName()) + .append("parentId", getParentId()) + .append("orderNum", getOrderNum()) + .append("path", getPath()) + .append("component", getComponent()) + .append("isFrame", getIsFrame()) + .append("IsCache", getIsCache()) + .append("menuType", getMenuType()) + .append("visible", getVisible()) + .append("status ", getStatus()) + .append("perms", getPerms()) + .append("icon", getIcon()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysNotice.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysNotice.java new file mode 100644 index 0000000..4a30c8b --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysNotice.java @@ -0,0 +1,102 @@ +package com.dcsoft.system.domain; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.dcsoft.common.core.web.domain.BaseEntity; +import com.dcsoft.common.core.xss.Xss; + +/** + * 通知公告表 sys_notice + * + * @author dcsoft + */ +public class SysNotice extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 公告ID */ + private Long noticeId; + + /** 公告标题 */ + private String noticeTitle; + + /** 公告类型(1通知 2公告) */ + private String noticeType; + + /** 公告内容 */ + private String noticeContent; + + /** 公告状态(0正常 1关闭) */ + private String status; + + public Long getNoticeId() + { + return noticeId; + } + + public void setNoticeId(Long noticeId) + { + this.noticeId = noticeId; + } + + public void setNoticeTitle(String noticeTitle) + { + this.noticeTitle = noticeTitle; + } + + @Xss(message = "公告标题不能包含脚本字符") + @NotBlank(message = "公告标题不能为空") + @Size(min = 0, max = 50, message = "公告标题不能超过50个字符") + public String getNoticeTitle() + { + return noticeTitle; + } + + public void setNoticeType(String noticeType) + { + this.noticeType = noticeType; + } + + public String getNoticeType() + { + return noticeType; + } + + public void setNoticeContent(String noticeContent) + { + this.noticeContent = noticeContent; + } + + public String getNoticeContent() + { + return noticeContent; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getStatus() + { + return status; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("noticeId", getNoticeId()) + .append("noticeTitle", getNoticeTitle()) + .append("noticeType", getNoticeType()) + .append("noticeContent", getNoticeContent()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPeople.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPeople.java new file mode 100644 index 0000000..0e8ec7c --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPeople.java @@ -0,0 +1,433 @@ +package com.dcsoft.system.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.Date; + +/** + * 人员管理对象 sys_people + * + * @author nichun + * @date 2023-03-08 + */ +public class SysPeople extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** + * 微信openid + * **/ + private String openid; + + /** 人员Id */ + private Long id; + + /** 人员名称 */ + @Excel(name = "人员名称",sort = 2) + private String name; + + /** 联系电话 */ + @Excel(name = "联系电话",sort = 3) + private String phone; + + /** 用户性别(0男 1女 2保密) */ + @Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=保密",sort = 4) + private String sex; + + /** 头像地址 */ + private String avatar; + + /** 所在部门 */ + private String branchId; + + @Excel(name = "所在部门",sort = 5) + private String branchName; + + /** 职位标签 */ + @Excel(name = "职位标签",sort = 6) + private String position; + + /** 身份证号码 */ + @Excel(name = "身份证号码",sort = 7) + private String idcard; + + /** 车牌号码 */ + private String carNo; + + /** 门卡号码 */ + @Excel(name = "卡号",sort = 8) + private String doorNo; + + /** 人员编号对接 */ + private String guid; + + /** 人像对接 */ + private String faceGuid; + + /** 关联用户 */ + private Long userId; + + /** 删除标志(0正常 1删除) */ + private Long delFlag; + + private SysBranch branch; + + /** 工号 */ + @Excel(name = "工号",sort = 1) + String gh; + + /**指纹特征值**/ + private String fingerprint; + + /**入职时间**/ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "入职时间", width = 30, dateFormat = "yyyy-MM-dd",sort = 9) + private Date joinTime; + + private Long down; + + private String downFlag; + + private String guidFlag; + + private String faceFlag; + + private String pageNum; + + private String sequence; + + private String cardFlag; + + private Long ruleId; + + private Long branchParent; + + private String serialNumber; + + private String wxFlag; + + /** + * 梯控规则id + */ + private String ladderRuleId; + + private String isExamine; + + private String visitorRegisterId; + + public String getVisitorRegisterId() { + return visitorRegisterId; + } + + public void setVisitorRegisterId(String visitorRegisterId) { + this.visitorRegisterId = visitorRegisterId; + } + + public String getIsExamine() { + return isExamine; + } + + public void setIsExamine(String isExamine) { + this.isExamine = isExamine; + } + + public String getLadderRuleId() { + return ladderRuleId; + } + + public void setLadderRuleId(String ladderRuleId) { + this.ladderRuleId = ladderRuleId; + } + + public String getWxFlag() { + return wxFlag; + } + + public void setWxFlag(String wxFlag) { + this.wxFlag = wxFlag; + } + + public String getOpenid() { + return openid; + } + + public void setOpenid(String openid) { + this.openid = openid; + } + + public String getSerialNumber() { + return serialNumber; + } + + public void setSerialNumber(String serialNumber) { + this.serialNumber = serialNumber; + } + + public Long getRuleId() { + return ruleId; + } + + public void setRuleId(Long ruleId) { + this.ruleId = ruleId; + } + + public String getCardFlag() { + return cardFlag; + } + + public void setCardFlag(String cardFlag) { + this.cardFlag = cardFlag; + } + + public String getSequence() { + return sequence; + } + + public void setSequence(String sequence) { + this.sequence = sequence; + } + + public String getPageNum() { + return pageNum; + } + + public void setPageNum(String pageNum) { + this.pageNum = pageNum; + } + + public SysBranch getBranch() { + return branch; + } + + public void setBranch(SysBranch branch) { + this.branch = branch; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setPhone(String phone) + { + this.phone = phone; + } + + public String getPhone() + { + return phone; + } + public void setSex(String sex) + { + this.sex = sex; + } + + public String getSex() + { + return sex; + } + public void setAvatar(String avatar) + { + this.avatar = avatar; + } + + public String getAvatar() + { + return avatar; + } + public void setBranchId(String branchId) + { + this.branchId = branchId; + } + + public String getBranchId() + { + return branchId; + } + public void setPosition(String position) + { + this.position = position; + } + + public String getPosition() + { + return position; + } + public void setIdcard(String idcard) + { + this.idcard = idcard; + } + + public String getIdcard() + { + return idcard; + } + public void setCarNo(String carNo) + { + this.carNo = carNo; + } + + public String getCarNo() + { + return carNo; + } + public void setDoorNo(String doorNo) + { + this.doorNo = doorNo; + } + + public String getDoorNo() + { + return doorNo; + } + public void setGuid(String guid) + { + this.guid = guid; + } + + public String getGuid() + { + return guid; + } + public void setFaceGuid(String faceGuid) + { + this.faceGuid = faceGuid; + } + + public String getFaceGuid() + { + return faceGuid; + } + public void setUserId(Long userId) + { + this.userId = userId; + } + + public Long getUserId() + { + return userId; + } + public void setDelFlag(Long delFlag) + { + this.delFlag = delFlag; + } + + public Long getDelFlag() + { + return delFlag; + } + + public String getGh() { + return gh; + } + + public void setGh(String gh) { + this.gh = gh; + } + + public String getFingerprint() { + return fingerprint; + } + + public void setFingerprint(String fingerprint) { + this.fingerprint = fingerprint; + } + + public Date getJoinTime() { + return joinTime; + } + + public void setJoinTime(Date joinTime) { + this.joinTime = joinTime; + } + + public Long getDown() { + return down; + } + + public void setDown(Long down) { + this.down = down; + } + + public String getBranchName() { + return branchName; + } + + public void setBranchName(String branchName) { + this.branchName = branchName; + } + + public String getDownFlag() { + return downFlag; + } + + public void setDownFlag(String downFlag) { + this.downFlag = downFlag; + } + + public String getGuidFlag() { + return guidFlag; + } + + public void setGuidFlag(String guidFlag) { + this.guidFlag = guidFlag; + } + + public String getFaceFlag() { + return faceFlag; + } + + public void setFaceFlag(String faceFlag) { + this.faceFlag = faceFlag; + } + + public Long getBranchParent() { + return branchParent; + } + + public void setBranchParent(Long branchParent) { + this.branchParent = branchParent; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("phone", getPhone()) + .append("sex", getSex()) + .append("avatar", getAvatar()) + .append("branchId", getBranchId()) + .append("position", getPosition()) + .append("idcard", getIdcard()) + .append("carNo", getCarNo()) + .append("doorNo", getDoorNo()) + .append("guid", getGuid()) + .append("faceGuid", getFaceGuid()) + .append("userId", getUserId()) + .append("remark", getRemark()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("delFlag", getDelFlag()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPeopleEquipment.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPeopleEquipment.java new file mode 100644 index 0000000..70f5497 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPeopleEquipment.java @@ -0,0 +1,116 @@ +package com.dcsoft.system.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 人员设备下发信息对象 sys_people_equipment + * + * @author dcsoft + * @date 2023-06-12 + */ +public class SysPeopleEquipment extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** Id */ + private Long id; + + /** 人员Id */ + @Excel(name = "人员Id") + private Long peopleId; + + /** 设备Id */ + @Excel(name = "设备Id") + private Long equipmentId; + + /** 人员编号对接 */ + @Excel(name = "人员编号对接") + private String guid; + + /** 人像对接 */ + @Excel(name = "人像对接") + private String faceGuid; + + /** 访客Id */ + @Excel(name = "访客Id") + private Long visitorId; + + private Long otherId; + + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setPeopleId(Long peopleId) + { + this.peopleId = peopleId; + } + + public Long getPeopleId() + { + return peopleId; + } + public void setEquipmentId(Long equipmentId) + { + this.equipmentId = equipmentId; + } + + public Long getEquipmentId() + { + return equipmentId; + } + public void setGuid(String guid) + { + this.guid = guid; + } + + public String getGuid() + { + return guid; + } + public void setFaceGuid(String faceGuid) + { + this.faceGuid = faceGuid; + } + + public String getFaceGuid() + { + return faceGuid; + } + + public Long getVisitorId() { + return visitorId; + } + + public void setVisitorId(Long visitorId) { + this.visitorId = visitorId; + } + + public Long getOtherId() { + return otherId; + } + + public void setOtherId(Long otherId) { + this.otherId = otherId; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("peopleId", getPeopleId()) + .append("equipmentId", getEquipmentId()) + .append("guid", getGuid()) + .append("faceGuid", getFaceGuid()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPeopleLeave.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPeopleLeave.java new file mode 100644 index 0000000..582b3ab --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPeopleLeave.java @@ -0,0 +1,187 @@ +package com.dcsoft.system.domain; + +import java.util.Date; + +import com.dcsoft.common.core.web.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.dcsoft.common.core.annotation.Excel; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 离职管理对象 sys_people_leave + * + * @author nichun + * @date 2023-09-09 + */ +public class SysPeopleLeave extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 人员Id */ + private Long id; + + /** 工号 */ + @Excel(name = "工号") + private String gh; + + /** 姓名 */ + @Excel(name = "姓名") + private String name; + + /** 用户性别(0男 1女 2保密) */ + @Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=保密") + private String sex; + + /** 所在部门 */ + private String branchId; + + /** 身份证号码 */ + private String idcard; + + /** 离职时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "离职时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date leaveTime; + + /** 关联人员 */ + private Long peopleId; + + /** 离职原因 */ + @Excel(name = "离职原因") + private String leaveReason; + + @Excel(name = "所在部门") + private String branchName; + + private String type; + + @Excel(name = "离职状态", readConverterExp = "0=未离职,1=已离职") + private String status; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setGh(String gh) + { + this.gh = gh; + } + + public String getGh() + { + return gh; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setSex(String sex) + { + this.sex = sex; + } + + public String getSex() + { + return sex; + } + + public String getBranchId() { + return branchId; + } + + public void setBranchId(String branchId) { + this.branchId = branchId; + } + + public void setIdcard(String idcard) + { + this.idcard = idcard; + } + + public String getIdcard() + { + return idcard; + } + public void setLeaveTime(Date leaveTime) + { + this.leaveTime = leaveTime; + } + + public Date getLeaveTime() + { + return leaveTime; + } + public void setPeopleId(Long peopleId) + { + this.peopleId = peopleId; + } + + public Long getPeopleId() + { + return peopleId; + } + public void setLeaveReason(String leaveReason) + { + this.leaveReason = leaveReason; + } + + public String getLeaveReason() + { + return leaveReason; + } + + public String getBranchName() { + return branchName; + } + + public void setBranchName(String branchName) { + this.branchName = branchName; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("gh", getGh()) + .append("name", getName()) + .append("sex", getSex()) + .append("branchId", getBranchId()) + .append("idcard", getIdcard()) + .append("leaveTime", getLeaveTime()) + .append("peopleId", getPeopleId()) + .append("leaveReason", getLeaveReason()) + .append("remark", getRemark()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPeopleOther.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPeopleOther.java new file mode 100644 index 0000000..128d778 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPeopleOther.java @@ -0,0 +1,400 @@ +package com.dcsoft.system.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.Date; + +/** + * 第三方人员管理对象 sys_people + * + * @author nichun + * @date 2023-03-08 + */ +public class SysPeopleOther extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** + * 微信openid + * **/ + private String openid; + + /** 人员Id */ + private Long id; + + /** 人员名称 */ + @Excel(name = "人员名称",sort = 2) + private String name; + + /** 联系电话 */ + @Excel(name = "联系电话",sort = 3) + private String phone; + + /** 用户性别(0男 1女 2保密) */ + @Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=保密",sort = 4) + private String sex; + + /** 头像地址 */ + private String avatar; + + /** 所在部门 */ + private String branchId; + + @Excel(name = "所在部门",sort = 5) + private String branchName; + + /** 职位标签 */ + @Excel(name = "职位标签",sort = 6) + private String position; + + /** 身份证号码 */ + @Excel(name = "身份证号码",sort = 7) + private String idcard; + + /** 车牌号码 */ + private String carNo; + + + /** 人员编号对接 */ + private String guid; + + /** 人像对接 */ + private String faceGuid; + + + + /** 删除标志(0正常 1删除) */ + private Long delFlag; + + private SysBranch branch; + + + private Long down; + + private String downFlag; + + private String guidFlag; + + private String faceFlag; + + private String pageNum; + + private String sequence; + + private String cardFlag; + + private Long ruleId; + + private Long branchParent; + + private String serialNumber; + + private String wxFlag; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date validTimeStart; + + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date validTimeEnd; + + + private String file1; + + private String file2; + + private String file3; + + + + public String getWxFlag() { + return wxFlag; + } + + public void setWxFlag(String wxFlag) { + this.wxFlag = wxFlag; + } + + public String getOpenid() { + return openid; + } + + public void setOpenid(String openid) { + this.openid = openid; + } + + public String getSerialNumber() { + return serialNumber; + } + + public void setSerialNumber(String serialNumber) { + this.serialNumber = serialNumber; + } + + public Long getRuleId() { + return ruleId; + } + + public void setRuleId(Long ruleId) { + this.ruleId = ruleId; + } + + public String getCardFlag() { + return cardFlag; + } + + public void setCardFlag(String cardFlag) { + this.cardFlag = cardFlag; + } + + public String getSequence() { + return sequence; + } + + public void setSequence(String sequence) { + this.sequence = sequence; + } + + public String getPageNum() { + return pageNum; + } + + public void setPageNum(String pageNum) { + this.pageNum = pageNum; + } + + public SysBranch getBranch() { + return branch; + } + + public void setBranch(SysBranch branch) { + this.branch = branch; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setPhone(String phone) + { + this.phone = phone; + } + + public String getPhone() + { + return phone; + } + public void setSex(String sex) + { + this.sex = sex; + } + + public String getSex() + { + return sex; + } + public void setAvatar(String avatar) + { + this.avatar = avatar; + } + + public String getAvatar() + { + return avatar; + } + public void setBranchId(String branchId) + { + this.branchId = branchId; + } + + public String getBranchId() + { + return branchId; + } + public void setPosition(String position) + { + this.position = position; + } + + public String getPosition() + { + return position; + } + public void setIdcard(String idcard) + { + this.idcard = idcard; + } + + public String getIdcard() + { + return idcard; + } + public void setCarNo(String carNo) + { + this.carNo = carNo; + } + + public String getCarNo() + { + return carNo; + } + + public void setGuid(String guid) + { + this.guid = guid; + } + + public String getGuid() + { + return guid; + } + public void setFaceGuid(String faceGuid) + { + this.faceGuid = faceGuid; + } + + public String getFaceGuid() + { + return faceGuid; + } + + public void setDelFlag(Long delFlag) + { + this.delFlag = delFlag; + } + + public Long getDelFlag() + { + return delFlag; + } + + + public Long getDown() { + return down; + } + + public void setDown(Long down) { + this.down = down; + } + + public String getBranchName() { + return branchName; + } + + public void setBranchName(String branchName) { + this.branchName = branchName; + } + + public String getDownFlag() { + return downFlag; + } + + public void setDownFlag(String downFlag) { + this.downFlag = downFlag; + } + + public String getGuidFlag() { + return guidFlag; + } + + public void setGuidFlag(String guidFlag) { + this.guidFlag = guidFlag; + } + + public String getFaceFlag() { + return faceFlag; + } + + public void setFaceFlag(String faceFlag) { + this.faceFlag = faceFlag; + } + + public Long getBranchParent() { + return branchParent; + } + + public void setBranchParent(Long branchParent) { + this.branchParent = branchParent; + } + + public Date getValidTimeStart() { + return validTimeStart; + } + + public void setValidTimeStart(Date validTimeStart) { + this.validTimeStart = validTimeStart; + } + + public Date getValidTimeEnd() { + return validTimeEnd; + } + + public void setValidTimeEnd(Date validTimeEnd) { + this.validTimeEnd = validTimeEnd; + } + + public String getFile1() { + return file1; + } + + public void setFile1(String file1) { + this.file1 = file1; + } + + public String getFile2() { + return file2; + } + + public void setFile2(String file2) { + this.file2 = file2; + } + + public String getFile3() { + return file3; + } + + public void setFile3(String file3) { + this.file3 = file3; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("phone", getPhone()) + .append("sex", getSex()) + .append("avatar", getAvatar()) + .append("branchId", getBranchId()) + .append("position", getPosition()) + .append("idcard", getIdcard()) + .append("carNo", getCarNo()) + .append("guid", getGuid()) + .append("faceGuid", getFaceGuid()) + .append("remark", getRemark()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("delFlag", getDelFlag()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPeopleRecord.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPeopleRecord.java new file mode 100644 index 0000000..9d88163 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPeopleRecord.java @@ -0,0 +1,481 @@ +package com.dcsoft.system.domain; + +import java.util.Date; + +import com.dcsoft.common.core.web.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.dcsoft.common.core.annotation.Excel; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 人员识别记录对象 sys_people_record + * + * @author nichun + * @date 2023-03-08 + */ +public class SysPeopleRecord extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 记录Id */ + @JsonSerialize(using= ToStringSerializer.class) + private Long id; + + /** 人员id */ + private String peopleId; + + /** 设备id */ + private String equipmentId; + + /** 设备内网ip */ + private String deviceIp; + + /** 人员guid 或者STRANGERBABY */ + private String admitGuid; + + /** 识别模式,1:人像识别, 2:刷卡识别 ,3:人卡合一 4,人证比对 7:密码识别 8 二维码识别 */ + @Excel(name = "识别模式",sort = 6 , readConverterExp = "0=人像验证,3= 刷卡验证,9= 指纹比对,12= 身份证验证") + private String recMode; + + /** 现场照url */ + private String filePath; + + /** 识别记录时间戳 */ + private Long showTime; + + /** 识别记录时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "识别记录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss",sort = 1) + private Date showDate; + + /** 活体结果 1:活体判断成功 2:活体判断失败 3:未进行活体判断 */ + @Excel(name = "活体结果", readConverterExp = "1=活体判断成功,2=活体判断失败,3=活体判断失败") + private String aliveType; + + /** 识别分数 */ + private String recScore; + + /** 设备序列号 */ + @Excel(name = "设备序列号",sort = 5) + private String deviceNo; + + /** 软件版本号 */ + private String deviceVersion; + + /** 设备来源 */ + private String source; + + /** 人员比对结果,1:比对成功 2:比对失败 */ + @Excel(name = "人员比对结果" , readConverterExp = "1=比对成功,2=比对失败") + private String type; + + /** 识别卡号 */ + @Excel(name = "识别卡号",sort = 7) + private String cardNo; + + /** 设备名称 */ + private String deviceName; + + /** 比对模式,1:本地识别 2:云端识别 */ + private String recType; + + /** 结果 */ + private String result; + + /** 有效日期判断 1:有效期内 2:有效期外 3:未进行有效期判断 */ + private String permissionTimeType; + + /** 有效时间段判断 1:时间段内 2:时间段外 3:未进行时间段判断 */ + private String passTimeType; + + /** 识别模式判断 1. 模式正确 2.模式不正确 */ + private String recModeType; + + /** 保留字段 */ + private String storageId; + + /** 当前时间戳 */ + private Long timestamp; + + /** 识别主体姓名 */ + private String admitName; + + private String flag; + + private String sign; + + + private SysEquipment equipment; + + @Excel(name = "人员姓名",sort = 4) + private String peopleName; + + @Excel(name = "设备名称",sort = 2) + private String equipmentName; + + @Excel(name = "工号",sort = 3) + private String gh; + + private Long groupId;//考勤用---考勤组 + + /** + * 小时 + */ + private String hour; + + /** + * 今天 + */ + private String today; + + /** + * 昨天 + */ + private String yesterday; + + public String getHour() { + return hour; + } + + public void setHour(String hour) { + this.hour = hour; + } + + public String getToday() { + return today; + } + + public void setToday(String today) { + this.today = today; + } + + public String getYesterday() { + return yesterday; + } + + public void setYesterday(String yesterday) { + this.yesterday = yesterday; + } + + public Long getGroupId() { + return groupId; + } + + public void setGroupId(Long groupId) { + this.groupId = groupId; + } + + + public SysEquipment getEquipment() { + return equipment; + } + + public void setEquipment(SysEquipment equipment) { + this.equipment = equipment; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setPeopleId(String peopleId) + { + this.peopleId = peopleId; + } + + public String getPeopleId() + { + return peopleId; + } + public void setEquipmentId(String equipmentId) + { + this.equipmentId = equipmentId; + } + + public String getEquipmentId() + { + return equipmentId; + } + public void setDeviceIp(String deviceIp) + { + this.deviceIp = deviceIp; + } + + public String getDeviceIp() + { + return deviceIp; + } + public void setAdmitGuid(String admitGuid) + { + this.admitGuid = admitGuid; + } + + public String getAdmitGuid() + { + return admitGuid; + } + public void setRecMode(String recMode) + { + this.recMode = recMode; + } + + public String getRecMode() + { + return recMode; + } + public void setFilePath(String filePath) + { + this.filePath = filePath; + } + + public String getFilePath() + { + return filePath; + } + public void setShowTime(Long showTime) + { + this.showTime = showTime; + } + + public Long getShowTime() + { + return showTime; + } + public void setShowDate(Date showDate) + { + this.showDate = showDate; + } + + public Date getShowDate() + { + return showDate; + } + public void setAliveType(String aliveType) + { + this.aliveType = aliveType; + } + + public String getAliveType() + { + return aliveType; + } + public void setRecScore(String recScore) + { + this.recScore = recScore; + } + + public String getRecScore() + { + return recScore; + } + public void setDeviceNo(String deviceNo) + { + this.deviceNo = deviceNo; + } + + public String getDeviceNo() + { + return deviceNo; + } + public void setDeviceVersion(String deviceVersion) + { + this.deviceVersion = deviceVersion; + } + + public String getDeviceVersion() + { + return deviceVersion; + } + public void setSource(String source) + { + this.source = source; + } + + public String getSource() + { + return source; + } + public void setType(String type) + { + this.type = type; + } + + public String getType() + { + return type; + } + public void setCardNo(String cardNo) + { + this.cardNo = cardNo; + } + + public String getCardNo() + { + return cardNo; + } + public void setDeviceName(String deviceName) + { + this.deviceName = deviceName; + } + + public String getDeviceName() + { + return deviceName; + } + public void setRecType(String recType) + { + this.recType = recType; + } + + public String getRecType() + { + return recType; + } + public void setResult(String result) + { + this.result = result; + } + + public String getResult() + { + return result; + } + public void setPermissionTimeType(String permissionTimeType) + { + this.permissionTimeType = permissionTimeType; + } + + public String getPermissionTimeType() + { + return permissionTimeType; + } + public void setPassTimeType(String passTimeType) + { + this.passTimeType = passTimeType; + } + + public String getPassTimeType() + { + return passTimeType; + } + public void setRecModeType(String recModeType) + { + this.recModeType = recModeType; + } + + public String getRecModeType() + { + return recModeType; + } + public void setStorageId(String storageId) + { + this.storageId = storageId; + } + + public String getStorageId() + { + return storageId; + } + public void setTimestamp(Long timestamp) + { + this.timestamp = timestamp; + } + + public Long getTimestamp() + { + return timestamp; + } + public void setAdmitName(String admitName) + { + this.admitName = admitName; + } + + public String getAdmitName() + { + return admitName; + } + + public String getFlag() { + return flag; + } + + public void setFlag(String flag) { + this.flag = flag; + } + + public String getPeopleName() { + return peopleName; + } + + public void setPeopleName(String peopleName) { + this.peopleName = peopleName; + } + + public String getEquipmentName() { + return equipmentName; + } + + public void setEquipmentName(String equipmentName) { + this.equipmentName = equipmentName; + } + + public String getGh() { + return gh; + } + + public void setGh(String gh) { + this.gh = gh; + } + + public String getSign() { + return sign; + } + + public void setSign(String sign) { + this.sign = sign; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("peopleId", getPeopleId()) + .append("equipmentId", getEquipmentId()) + .append("deviceIp", getDeviceIp()) + .append("admitGuid", getAdmitGuid()) + .append("recMode", getRecMode()) + .append("filePath", getFilePath()) + .append("showTime", getShowTime()) + .append("showDate", getShowDate()) + .append("aliveType", getAliveType()) + .append("recScore", getRecScore()) + .append("deviceNo", getDeviceNo()) + .append("deviceVersion", getDeviceVersion()) + .append("source", getSource()) + .append("type", getType()) + .append("cardNo", getCardNo()) + .append("deviceName", getDeviceName()) + .append("recType", getRecType()) + .append("result", getResult()) + .append("permissionTimeType", getPermissionTimeType()) + .append("passTimeType", getPassTimeType()) + .append("recModeType", getRecModeType()) + .append("storageId", getStorageId()) + .append("timestamp", getTimestamp()) + .append("admitName", getAdmitName()) + .append("remark", getRemark()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPeopleRule.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPeopleRule.java new file mode 100644 index 0000000..30d1091 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPeopleRule.java @@ -0,0 +1,97 @@ +package com.dcsoft.system.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 人员规则关联对象 sys_people_rule + * + * @author dcsoft + * @date 2023-12-22 + */ +public class SysPeopleRule extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键Id */ + private Long id; + + /** 关联人员 */ + @Excel(name = "关联人员") + private Long peopleId; + + /** 关联规则 */ + @Excel(name = "关联规则") + private Long ruleId; + + + private Long equipmentId; + + + /** 是否同步 */ + @Excel(name = "是否同步") + private Long sync; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setPeopleId(Long peopleId) + { + this.peopleId = peopleId; + } + + public Long getPeopleId() + { + return peopleId; + } + public void setRuleId(Long ruleId) + { + this.ruleId = ruleId; + } + + public Long getRuleId() + { + return ruleId; + } + + public Long getEquipmentId() { + return equipmentId; + } + + public void setEquipmentId(Long equipmentId) { + this.equipmentId = equipmentId; + } + + public void setSync(Long sync) + { + this.sync = sync; + } + + public Long getSync() + { + return sync; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("peopleId", getPeopleId()) + .append("ruleId", getRuleId()) + .append("sync", getSync()) + .append("remark", getRemark()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPoint.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPoint.java new file mode 100644 index 0000000..a564858 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPoint.java @@ -0,0 +1,90 @@ +package com.dcsoft.system.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 点位管理对象 sys_point + * + * @author nichun + * @date 2023-03-08 + */ +public class SysPoint extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 点位Id */ + private Long id; + + /** 点位名称 */ + @Excel(name = "点位名称") + private String name; + + /** 所属空间 */ + @Excel(name = "所属空间") + private Long spaceId; + + private SysSpace space; + + private Long sort; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setSpaceId(Long spaceId) + { + this.spaceId = spaceId; + } + + public Long getSpaceId() + { + return spaceId; + } + + public SysSpace getSpace() { + return space; + } + + public void setSpace(SysSpace space) { + this.space = space; + } + + public Long getSort() { + return sort; + } + + public void setSort(Long sort) { + this.sort = sort; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("spaceId", getSpaceId()) + .append("remark", getRemark()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPost.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPost.java new file mode 100644 index 0000000..aae1183 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysPost.java @@ -0,0 +1,124 @@ +package com.dcsoft.system.domain; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.annotation.Excel.ColumnType; +import com.dcsoft.common.core.web.domain.BaseEntity; + +/** + * 岗位表 sys_post + * + * @author dcsoft + */ +public class SysPost extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 岗位序号 */ + @Excel(name = "岗位序号", cellType = ColumnType.NUMERIC) + private Long postId; + + /** 岗位编码 */ + @Excel(name = "岗位编码") + private String postCode; + + /** 岗位名称 */ + @Excel(name = "岗位名称") + private String postName; + + /** 岗位排序 */ + @Excel(name = "岗位排序") + private Integer postSort; + + /** 状态(0正常 1停用) */ + @Excel(name = "状态", readConverterExp = "0=正常,1=停用") + private String status; + + /** 用户是否存在此岗位标识 默认不存在 */ + private boolean flag = false; + + public Long getPostId() + { + return postId; + } + + public void setPostId(Long postId) + { + this.postId = postId; + } + + @NotBlank(message = "岗位编码不能为空") + @Size(min = 0, max = 64, message = "岗位编码长度不能超过64个字符") + public String getPostCode() + { + return postCode; + } + + public void setPostCode(String postCode) + { + this.postCode = postCode; + } + + @NotBlank(message = "岗位名称不能为空") + @Size(min = 0, max = 50, message = "岗位名称长度不能超过50个字符") + public String getPostName() + { + return postName; + } + + public void setPostName(String postName) + { + this.postName = postName; + } + + @NotNull(message = "显示顺序不能为空") + public Integer getPostSort() + { + return postSort; + } + + public void setPostSort(Integer postSort) + { + this.postSort = postSort; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public boolean isFlag() + { + return flag; + } + + public void setFlag(boolean flag) + { + this.flag = flag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("postId", getPostId()) + .append("postCode", getPostCode()) + .append("postName", getPostName()) + .append("postSort", getPostSort()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysProduct.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysProduct.java new file mode 100644 index 0000000..792ef5e --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysProduct.java @@ -0,0 +1,195 @@ +package com.dcsoft.system.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 产品信息对象 sys_product + * + * @author nichun + * @date 2023-03-08 + */ +public class SysProduct extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 产品Id */ + private Long id; + + /** 产品图片地址 */ + @Excel(name = "产品图片地址") + private String avatar; + + /** 产品名称 */ + @Excel(name = "产品名称") + private String name; + + /** 产品型号 */ + @Excel(name = "产品型号") + private String version; + + /** 产品品类(大类) */ + @Excel(name = "产品品类", readConverterExp = "大=类") + private String bigtype; + + /** 产品品类(小类) */ + @Excel(name = "产品品类", readConverterExp = "小=类") + private String subtype; + + /** 节点类型 */ + @Excel(name = "节点类型") + private String genre; + + /** 产品描述 */ + @Excel(name = "产品描述") + private String describes; + + /** 联网方式 */ + @Excel(name = "联网方式") + private String network; + + /** 数据格式 */ + @Excel(name = "数据格式") + private String dataFormat; + + /** 数据校验级别 */ + @Excel(name = "数据校验级别") + private String scale; + + /** 认证方式 */ + @Excel(name = "认证方式") + private String attestation; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setAvatar(String avatar) + { + this.avatar = avatar; + } + + public String getAvatar() + { + return avatar; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setVersion(String version) + { + this.version = version; + } + + public String getVersion() + { + return version; + } + public void setBigtype(String bigtype) + { + this.bigtype = bigtype; + } + + public String getBigtype() + { + return bigtype; + } + public void setSubtype(String subtype) + { + this.subtype = subtype; + } + + public String getSubtype() + { + return subtype; + } + public void setGenre(String genre) + { + this.genre = genre; + } + + public String getGenre() + { + return genre; + } + public void setDescribes(String describes) + { + this.describes = describes; + } + + public String getDescribes() + { + return describes; + } + public void setNetwork(String network) + { + this.network = network; + } + + public String getNetwork() + { + return network; + } + public void setDataFormat(String dataFormat) + { + this.dataFormat = dataFormat; + } + + public String getDataFormat() + { + return dataFormat; + } + public void setScale(String scale) + { + this.scale = scale; + } + + public String getScale() + { + return scale; + } + public void setAttestation(String attestation) + { + this.attestation = attestation; + } + + public String getAttestation() + { + return attestation; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("avatar", getAvatar()) + .append("name", getName()) + .append("version", getVersion()) + .append("bigtype", getBigtype()) + .append("subtype", getSubtype()) + .append("genre", getGenre()) + .append("describes", getDescribes()) + .append("network", getNetwork()) + .append("dataFormat", getDataFormat()) + .append("scale", getScale()) + .append("attestation", getAttestation()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysRoleDept.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysRoleDept.java new file mode 100644 index 0000000..2818b79 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysRoleDept.java @@ -0,0 +1,46 @@ +package com.dcsoft.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 角色和部门关联 sys_role_dept + * + * @author dcsoft + */ +public class SysRoleDept +{ + /** 角色ID */ + private Long roleId; + + /** 部门ID */ + private Long deptId; + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + public Long getDeptId() + { + return deptId; + } + + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("roleId", getRoleId()) + .append("deptId", getDeptId()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysRoleMenu.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysRoleMenu.java new file mode 100644 index 0000000..e0316f3 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysRoleMenu.java @@ -0,0 +1,46 @@ +package com.dcsoft.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 角色和菜单关联 sys_role_menu + * + * @author dcsoft + */ +public class SysRoleMenu +{ + /** 角色ID */ + private Long roleId; + + /** 菜单ID */ + private Long menuId; + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + public Long getMenuId() + { + return menuId; + } + + public void setMenuId(Long menuId) + { + this.menuId = menuId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("roleId", getRoleId()) + .append("menuId", getMenuId()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysRule.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysRule.java new file mode 100644 index 0000000..03c9490 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysRule.java @@ -0,0 +1,204 @@ +package com.dcsoft.system.domain; + +import java.util.Date; + +import com.dcsoft.common.core.web.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.dcsoft.common.core.annotation.Excel; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 通行规则对象 sys_rule + * + * @author nichun + * @date 2023-03-08 + */ +public class SysRule extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 规则Id */ + private Long id; + + /** 规则名称 */ + @Excel(name = "规则名称") + private String name; + + /** 有效期开始 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "有效期开始", width = 30, dateFormat = "yyyy-MM-dd") + private Date startTime; + + /** 有效期结束 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "有效期结束", width = 30, dateFormat = "yyyy-MM-dd") + private Date endTime; + + /** 准入时间起 */ + @Excel(name = "准入时间起") + private String admittanceStart; + + /** 准入时间止 */ + @Excel(name = "准入时间止") + private String admittanceEnd; + + /** 设备空间 */ + private Long spaceId; + + @Excel(name = "设备空间") + private String spaceName; + + /** 设备位置 */ + @Excel(name = "设备位置") + private String pointId; + + /** 1:本地库 2:云端库 默认本地 */ + @Excel(name = "1:本地库 2:云端库 默认本地") + private String type; + + /** facePermission 刷脸权限 idCardPermission 刷卡权限 faceAndCardPermission 人卡合一权限 idCardFacePermission 人证比对权限 +passwordPermission 密码权限 */ + @Excel(name = "权限") + private String permission; + + protected String[] checkList; + + protected String[] pointIds; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setStartTime(Date startTime) + { + this.startTime = startTime; + } + + public Date getStartTime() + { + return startTime; + } + public void setEndTime(Date endTime) + { + this.endTime = endTime; + } + + public Date getEndTime() + { + return endTime; + } + public void setAdmittanceStart(String admittanceStart) + { + this.admittanceStart = admittanceStart; + } + + public String getAdmittanceStart() + { + return admittanceStart; + } + public void setAdmittanceEnd(String admittanceEnd) + { + this.admittanceEnd = admittanceEnd; + } + + public String getAdmittanceEnd() + { + return admittanceEnd; + } + public void setSpaceId(Long spaceId) + { + this.spaceId = spaceId; + } + + public Long getSpaceId() + { + return spaceId; + } + public void setPointId(String pointId) + { + this.pointId = pointId; + } + + public String getPointId() + { + return pointId; + } + public void setType(String type) + { + this.type = type; + } + + public String getType() + { + return type; + } + public void setPermission(String permission) + { + this.permission = permission; + } + + public String getPermission() + { + return permission; + } + + public String[] getCheckList() { + return checkList; + } + + public void setCheckList(String[] checkList) { + this.checkList = checkList; + } + + public String[] getPointIds() { + return pointIds; + } + + public void setPointIds(String[] pointIds) { + this.pointIds = pointIds; + } + + public String getSpaceName() { + return spaceName; + } + + public void setSpaceName(String spaceName) { + this.spaceName = spaceName; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("startTime", getStartTime()) + .append("endTime", getEndTime()) + .append("admittanceStart", getAdmittanceStart()) + .append("admittanceEnd", getAdmittanceEnd()) + .append("spaceId", getSpaceId()) + .append("pointId", getPointId()) + .append("remark", getRemark()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("type", getType()) + .append("permission", getPermission()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysSpace.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysSpace.java new file mode 100644 index 0000000..8a6c2ef --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysSpace.java @@ -0,0 +1,128 @@ +package com.dcsoft.system.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import com.dcsoft.system.api.domain.SysDept; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * 空间管理对象 sys_space + * + * @author nichun + * @date 2023-03-08 + */ +public class SysSpace extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 空间Id */ + private Long id; + + /** 空间名称 */ + @Excel(name = "空间名称") + private String name; + + /** 父部门id */ + @Excel(name = "父部门id") + private Long parentId; + + /** 祖级列表 */ + private String ancestors; + + /** 空间类型(0父级 1子级) */ + @Excel(name = "空间类型", readConverterExp = "0=父级,1=子级") + private String type; + + /** 子空间 */ + private List children = new ArrayList(); + + /** 子空间 */ + private List children1 = new ArrayList(); + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setParentId(Long parentId) + { + this.parentId = parentId; + } + + public Long getParentId() + { + return parentId; + } + public void setAncestors(String ancestors) + { + this.ancestors = ancestors; + } + + public String getAncestors() + { + return ancestors; + } + public void setType(String type) + { + this.type = type; + } + + public String getType() + { + return type; + } + + public List getChildren() { + return children; + } + + + public void setChildren(List children) { + this.children = children; + } + + public List getChildren1() { + return children1; + } + + public void setChildren1(List children1) { + this.children1 = children1; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("parentId", getParentId()) + .append("ancestors", getAncestors()) + .append("type", getType()) + .append("remark", getRemark()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } + + + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysSyncItem.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysSyncItem.java new file mode 100644 index 0000000..75475cf --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysSyncItem.java @@ -0,0 +1,65 @@ +package com.dcsoft.system.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 同步部门关联对象 sys_sync_item + * + * @author dcsoft + * @date 2024-01-11 + */ +public class SysSyncItem extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** Id */ + private Long id; + + /** 部门 */ + @Excel(name = "部门") + private String dept; + + /** 规则 */ + @Excel(name = "规则") + private Long ruleId; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + + public void setRuleId(Long ruleId) + { + this.ruleId = ruleId; + } + + public Long getRuleId() + { + return ruleId; + } + + public String getDept() { + return dept; + } + + public void setDept(String dept) { + this.dept = dept; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("dept", getDept()) + .append("ruleId", getRuleId()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysSyncRule.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysSyncRule.java new file mode 100644 index 0000000..295e7b5 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysSyncRule.java @@ -0,0 +1,148 @@ +package com.dcsoft.system.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 同步规则对象 sys_sync_rule + * + * @author nichun + * @date 2024-01-11 + */ +public class SysSyncRule extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 规则Id */ + private Long id; + + /** 规则名称 */ + @Excel(name = "规则名称") + private String name; + + /** 唯一标志 */ + @Excel(name = "唯一标志") + private String guid; + + /** 全量部门地址 */ + @Excel(name = "全量部门地址") + private String allDeptUrl; + + /** 增量部门地址 */ + @Excel(name = "增量部门地址") + private String addDeptUrl; + + /** 全量人员地址 */ + @Excel(name = "全量人员地址") + private String allPeopleUrl; + + /** 增量人员地址 */ + @Excel(name = "增量人员地址") + private String addPeopleUrl; + + + private String[] branchIds; + + private String branchId; + + public String getBranchId() { + return branchId; + } + + public void setBranchId(String branchId) { + this.branchId = branchId; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setGuid(String guid) + { + this.guid = guid; + } + + public String getGuid() + { + return guid; + } + public void setAllDeptUrl(String allDeptUrl) + { + this.allDeptUrl = allDeptUrl; + } + + public String getAllDeptUrl() + { + return allDeptUrl; + } + public void setAddDeptUrl(String addDeptUrl) + { + this.addDeptUrl = addDeptUrl; + } + + public String getAddDeptUrl() + { + return addDeptUrl; + } + public void setAllPeopleUrl(String allPeopleUrl) + { + this.allPeopleUrl = allPeopleUrl; + } + + public String getAllPeopleUrl() + { + return allPeopleUrl; + } + public void setAddPeopleUrl(String addPeopleUrl) + { + this.addPeopleUrl = addPeopleUrl; + } + + public String getAddPeopleUrl() + { + return addPeopleUrl; + } + + + public String[] getBranchIds() { + return branchIds; + } + + public void setBranchIds(String[] branchIds) { + this.branchIds = branchIds; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("guid", getGuid()) + .append("allDeptUrl", getAllDeptUrl()) + .append("addDeptUrl", getAddDeptUrl()) + .append("allPeopleUrl", getAllPeopleUrl()) + .append("addPeopleUrl", getAddPeopleUrl()) + .append("remark", getRemark()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysUserOnline.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysUserOnline.java new file mode 100644 index 0000000..ccc4bd8 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysUserOnline.java @@ -0,0 +1,100 @@ +package com.dcsoft.system.domain; + +/** + * 当前在线会话 + * + * @author dcsoft + */ +public class SysUserOnline +{ + /** 会话编号 */ + private String tokenId; + + /** 用户名称 */ + private String userName; + + /** 登录IP地址 */ + private String ipaddr; + + /** 登录地址 */ + private String loginLocation; + + /** 浏览器类型 */ + private String browser; + + /** 操作系统 */ + private String os; + + /** 登录时间 */ + private Long loginTime; + + public String getTokenId() + { + return tokenId; + } + + public void setTokenId(String tokenId) + { + this.tokenId = tokenId; + } + + public String getUserName() + { + return userName; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + public String getIpaddr() + { + return ipaddr; + } + + public void setIpaddr(String ipaddr) + { + this.ipaddr = ipaddr; + } + + public String getLoginLocation() + { + return loginLocation; + } + + public void setLoginLocation(String loginLocation) + { + this.loginLocation = loginLocation; + } + + public String getBrowser() + { + return browser; + } + + public void setBrowser(String browser) + { + this.browser = browser; + } + + public String getOs() + { + return os; + } + + public void setOs(String os) + { + this.os = os; + } + + public Long getLoginTime() + { + return loginTime; + } + + public void setLoginTime(Long loginTime) + { + this.loginTime = loginTime; + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysUserPost.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysUserPost.java new file mode 100644 index 0000000..4ca223c --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysUserPost.java @@ -0,0 +1,46 @@ +package com.dcsoft.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 用户和岗位关联 sys_user_post + * + * @author dcsoft + */ +public class SysUserPost +{ + /** 用户ID */ + private Long userId; + + /** 岗位ID */ + private Long postId; + + public Long getUserId() + { + return userId; + } + + public void setUserId(Long userId) + { + this.userId = userId; + } + + public Long getPostId() + { + return postId; + } + + public void setPostId(Long postId) + { + this.postId = postId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("userId", getUserId()) + .append("postId", getPostId()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysUserRole.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysUserRole.java new file mode 100644 index 0000000..1d6015b --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/SysUserRole.java @@ -0,0 +1,46 @@ +package com.dcsoft.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 用户和角色关联 sys_user_role + * + * @author dcsoft + */ +public class SysUserRole +{ + /** 用户ID */ + private Long userId; + + /** 角色ID */ + private Long roleId; + + public Long getUserId() + { + return userId; + } + + public void setUserId(Long userId) + { + this.userId = userId; + } + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("userId", getUserId()) + .append("roleId", getRoleId()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/AppletInfoVo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/AppletInfoVo.java new file mode 100644 index 0000000..c5cdb84 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/AppletInfoVo.java @@ -0,0 +1,26 @@ +package com.dcsoft.system.domain.vo; + +import lombok.Data; + +@Data +public class AppletInfoVo { + /** + * 用户名 + */ + private String userName; + + /** + * 小程序唯一标识openid + */ + private String openId; + + /** + * 用户头像 + */ + private String avatar; + + /** + * token + */ + private String token; +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/BranchSelectVo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/BranchSelectVo.java new file mode 100644 index 0000000..e69de29 diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/JjDivisionVo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/JjDivisionVo.java new file mode 100644 index 0000000..7a6e59d --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/JjDivisionVo.java @@ -0,0 +1,97 @@ +package com.dcsoft.system.domain.vo; + +import lombok.Data; + +@Data +public class JjDivisionVo { + + /** + * nc成本中心 + */ + private String cbzx; + + /** + * 部门类型1是公司,2是子公司,3是分公司,4是部门 + */ + private String kind; + + /** + * 名称 + */ + private String name; + + /** + * 部门负责人id + */ + private String bmfzr; + + /** + * 部门分管领导id + */ + private String bmfgld; + + /** + * 层级 + */ + private String level; + + /** + * 部门id,主键唯一 + */ + private String deptid; + + /** + * 是否虚拟部门0否1是 + */ + private String sfxnbm; + + /** + * 0有效1无效 + */ + private String status; + + /** + * 税号 + */ + private String orgcode; + + /** + * 组织code + */ + private String deptcode; + + /** + * 简称 + */ + private String shortname; + + /** + * 上级部门code + */ + private String parentcode; + + /** + * 生效日期 + */ + private String effectivedate; + + /** + * 机构成立时间 + */ + private String establisheddate; + + /** + * 钉钉部门id + */ + private String dingdingdepartmentid; + + /** + * 组级id + */ + private String ancestors; + + private String id; + + private String parentId; + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/JjStationVo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/JjStationVo.java new file mode 100644 index 0000000..fc0b511 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/JjStationVo.java @@ -0,0 +1,39 @@ +package com.dcsoft.system.domain.vo; + +import lombok.Data; + +import java.util.Date; + +@Data +public class JjStationVo { + + /** 主键id */ + private String id ; + + /** 岗位id,主键 */ + private String postid ; + + /** 岗位所属组织code */ + private String deptcode ; + + /** 岗位名称 */ + private String postname ; + + /** 岗位code */ + private String postcode ; + + /** 开始设置日期 */ + private String begindate ; + + /** 创建人 */ + private String createdBy ; + + /** 创建时间 */ + private Date createdTime ; + + /** 更新人 */ + private String updatedBy ; + + /** 更新时间 */ + private Date updatedTime ; +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/JjserInfoVo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/JjserInfoVo.java new file mode 100644 index 0000000..eec32ba --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/JjserInfoVo.java @@ -0,0 +1,90 @@ +package com.dcsoft.system.domain.vo; + +import lombok.Data; + +import java.util.Date; + +@Data +public class JjserInfoVo { + + /** 主键id */ + private String id ; + + /** 性别0女1男 */ + private String sex ; + + /** 所属部门 */ + private String ssbm ; + + /** 是否建立邮箱0否1是 */ + private String sfjlyx ; + + /** 邮箱 */ + private String email ; + + /** 岗位 */ + private String posts ; + + /** 职级 */ + private String ranks ; + + /** 是否董监高 */ + private String sfdjg ; + + /** 民族 */ + private String nation ; + + /** 是否建立oa账户0否1是 */ + private String sfjloa ; + + /** oa账户 */ + private String oalogin ; + + /** 1在职5离职 */ + private String status ; + + /** 是否有亲属在本集团工作 */ + private String sfyzxqs ; + + /** 生日 */ + private String birthday ; + + /** 姓名 */ + private String lastname ; + + /** 手机号码 */ + private String telphone ; + + /** 工号 */ + private String workcode ; + + /** 人员id,主键 */ + private String accountid ; + + /** 直接上级id */ + private String managerid ; + + /** 入职日期 */ + private String joineddate ; + + /** 创建人 */ + private String createdBy ; + + /** 创建时间 */ + private Date createdTime ; + + /** 更新人 */ + private String updatedBy ; + + /** 删除状态 0.否;1.是 */ + private String deleteState ; + + /** 更新时间 */ + private Date updatedTime ; + + private String delFlag; + + + + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/MetaVo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/MetaVo.java new file mode 100644 index 0000000..1110cca --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/MetaVo.java @@ -0,0 +1,106 @@ +package com.dcsoft.system.domain.vo; + +import com.dcsoft.common.core.utils.StringUtils; + +/** + * 路由显示信息 + * + * @author dcsoft + */ +public class MetaVo +{ + /** + * 设置该路由在侧边栏和面包屑中展示的名字 + */ + private String title; + + /** + * 设置该路由的图标,对应路径src/assets/icons/svg + */ + private String icon; + + /** + * 设置为true,则不会被 缓存 + */ + private boolean noCache; + + /** + * 内链地址(http(s)://开头) + */ + private String link; + + public MetaVo() + { + } + + public MetaVo(String title, String icon) + { + this.title = title; + this.icon = icon; + } + + public MetaVo(String title, String icon, boolean noCache) + { + this.title = title; + this.icon = icon; + this.noCache = noCache; + } + + public MetaVo(String title, String icon, String link) + { + this.title = title; + this.icon = icon; + this.link = link; + } + + public MetaVo(String title, String icon, boolean noCache, String link) + { + this.title = title; + this.icon = icon; + this.noCache = noCache; + if (StringUtils.ishttp(link)) + { + this.link = link; + } + } + + public boolean isNoCache() + { + return noCache; + } + + public void setNoCache(boolean noCache) + { + this.noCache = noCache; + } + + public String getTitle() + { + return title; + } + + public void setTitle(String title) + { + this.title = title; + } + + public String getIcon() + { + return icon; + } + + public void setIcon(String icon) + { + this.icon = icon; + } + + public String getLink() + { + return link; + } + + public void setLink(String link) + { + this.link = link; + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/OfficialAccountVo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/OfficialAccountVo.java new file mode 100644 index 0000000..9556f7c --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/OfficialAccountVo.java @@ -0,0 +1,21 @@ +package com.dcsoft.system.domain.vo; + +import lombok.Data; + +import java.util.Date; + +@Data +public class OfficialAccountVo { + + private String name; + + private String phone; + + private String id; + + private String createTime; + + private String avatar; + + private String position; +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/RouterVo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/RouterVo.java new file mode 100644 index 0000000..af3abc5 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/RouterVo.java @@ -0,0 +1,148 @@ +package com.dcsoft.system.domain.vo; + +import com.fasterxml.jackson.annotation.JsonInclude; +import java.util.List; + +/** + * 路由配置信息 + * + * @author dcsoft + */ +@JsonInclude(JsonInclude.Include.NON_EMPTY) +public class RouterVo +{ + /** + * 路由名字 + */ + private String name; + + /** + * 路由地址 + */ + private String path; + + /** + * 是否隐藏路由,当设置 true 的时候该路由不会再侧边栏出现 + */ + private boolean hidden; + + /** + * 重定向地址,当设置 noRedirect 的时候该路由在面包屑导航中不可被点击 + */ + private String redirect; + + /** + * 组件地址 + */ + private String component; + + /** + * 路由参数:如 {"id": 1, "name": "ry"} + */ + private String query; + + /** + * 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面 + */ + private Boolean alwaysShow; + + /** + * 其他元素 + */ + private MetaVo meta; + + /** + * 子路由 + */ + private List children; + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getPath() + { + return path; + } + + public void setPath(String path) + { + this.path = path; + } + + public boolean getHidden() + { + return hidden; + } + + public void setHidden(boolean hidden) + { + this.hidden = hidden; + } + + public String getRedirect() + { + return redirect; + } + + public void setRedirect(String redirect) + { + this.redirect = redirect; + } + + public String getComponent() + { + return component; + } + + public void setComponent(String component) + { + this.component = component; + } + + public String getQuery() + { + return query; + } + + public void setQuery(String query) + { + this.query = query; + } + + public Boolean getAlwaysShow() + { + return alwaysShow; + } + + public void setAlwaysShow(Boolean alwaysShow) + { + this.alwaysShow = alwaysShow; + } + + public MetaVo getMeta() + { + return meta; + } + + public void setMeta(MetaVo meta) + { + this.meta = meta; + } + + public List getChildren() + { + return children; + } + + public void setChildren(List children) + { + this.children = children; + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/SysAuthTree.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/SysAuthTree.java new file mode 100644 index 0000000..4f2ebe3 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/SysAuthTree.java @@ -0,0 +1,130 @@ +package com.dcsoft.system.domain.vo; + +import com.dcsoft.system.domain.SysPoint; +import com.dcsoft.system.domain.SysSpace; +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; +import java.util.stream.Collectors; + + +/** + * 权限对象 通用结构 + * + * @author xueyi + */ +@Data +@NoArgsConstructor +public class SysAuthTree { + + + /** Id */ + private Long id; + + /** 父级Id */ + private Long parentId; + + /** 名称 */ + private String label; + + /** 状态 */ + private String status; + + /** 子节点 */ + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private List children; + + /** 类型(0 模块 1 菜单) */ + private String type; + + private String deviceId; + + private String channelId; + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getChannelId() { + return channelId; + } + + public void setChannelId(String channelId) { + this.channelId = channelId; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getParentId() { + return parentId; + } + + public void setParentId(Long parentId) { + this.parentId = parentId; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + this.children = children; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + /** + * 模块转换 + */ + public SysAuthTree(SysSpace module) { + this.id = module.getId(); + this.label = module.getName(); + this.type = "0"; + this.children = module.getChildren().stream().map(SysAuthTree::new).collect(Collectors.toList()); + this.children.addAll(module.getChildren1().stream().map(SysAuthTree::new).collect(Collectors.toList())); + } + + /** + * 菜单转换 + */ + public SysAuthTree(SysPoint point) { + this.id = point.getId(); + this.label = point.getName(); + this.type = "1"; + + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/SysFileVo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/SysFileVo.java new file mode 100644 index 0000000..708ecb2 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/SysFileVo.java @@ -0,0 +1,40 @@ +package com.dcsoft.system.domain.vo; + +import lombok.Data; +import lombok.Getter; +import lombok.Setter; + +import java.util.Date; + +@Getter +@Setter +public class SysFileVo { + private String id ; + + /** 业务id */ + private String businessId ; + + /** 业务type */ + private String businessType ; + + /** 文件名称 */ + private String fileName ; + + /** 文件地址 */ + private String url ; + + /** 删除状态 0.否;1.是 */ + private String deleteState ; + + /** 创建人 */ + private String createdBy ; + + /** 创建时间 */ + private Date createdTime ; + + /** 更新人 */ + private String updatedBy ; + + /** 更新时间 */ + private Date updatedTime ; +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/TreeSelect.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/TreeSelect.java new file mode 100644 index 0000000..96c5eec --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/TreeSelect.java @@ -0,0 +1,119 @@ +package com.dcsoft.system.domain.vo; + +import java.io.Serializable; +import java.util.List; +import java.util.stream.Collectors; + +import com.dcsoft.system.domain.SysBranch; +import com.dcsoft.system.domain.SysPoint; +import com.dcsoft.system.domain.SysSpace; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.dcsoft.system.api.domain.SysDept; +import com.dcsoft.system.domain.SysMenu; + +/** + * Treeselect树结构实体类 + * + * @author dcsoft + */ +public class TreeSelect implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 节点ID */ + private Long id; + + /** 节点名称 */ + private String label; + + /** 子节点 */ + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private List children; + + /** 父级Id */ + private Long parentId; + + + public TreeSelect() + { + + } + + public TreeSelect(SysDept dept) + { + this.id = dept.getDeptId(); + this.label = dept.getDeptName(); + this.children = dept.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + public TreeSelect(SysMenu menu) + { + this.id = menu.getMenuId(); + this.label = menu.getMenuName(); + this.children = menu.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + /** + * 模块转换 + */ + public TreeSelect(SysSpace space) { + this.id = space.getId(); + this.label = space.getName(); + this.children = space.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList()); + + } + + /** + * 菜单转换 + */ + public TreeSelect(SysPoint point) { + this.id = point.getId(); + this.parentId = point.getSpaceId()==0L ? point.getId(): point.getSpaceId(); + this.label = point.getName(); + } + + public TreeSelect(SysBranch branch) { +// this.id = branch.getId(); + this.label = branch.getName(); + this.children = branch.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList()); + + } + + public Long getId() + { + return id; + } + + public void setId(Long id) + { + this.id = id; + } + + public String getLabel() + { + return label; + } + + public void setLabel(String label) + { + this.label = label; + } + + public List getChildren() + { + return children; + } + + public void setChildren(List children) + { + this.children = children; + } + + public Long getParentId() { + return parentId; + } + + public void setParentId(Long parentId) { + this.parentId = parentId; + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/TreeSelectVo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/TreeSelectVo.java new file mode 100644 index 0000000..3a1389b --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/domain/vo/TreeSelectVo.java @@ -0,0 +1,36 @@ +package com.dcsoft.system.domain.vo; + +import com.dcsoft.system.domain.SysBranch; +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Data; + +import java.util.List; +import java.util.stream.Collectors; + +@Data +public class TreeSelectVo { + /** 节点ID */ + private String id; + + /** 节点名称 */ + private String label; + + /** 子节点 */ + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private List children; + + /** 父级Id */ + private String parentId; + + + public TreeSelectVo() + { + + } + + public TreeSelectVo(SysBranch branch) { + this.id = branch.getId(); + this.label = branch.getName(); + this.children = branch.getChildren().stream().map(TreeSelectVo::new).collect(Collectors.toList()); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysBackGroupMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysBackGroupMapper.java new file mode 100644 index 0000000..dc30143 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysBackGroupMapper.java @@ -0,0 +1,63 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import com.dcsoft.system.domain.SysBackGroup; + +/** + * 背景配置Mapper接口 + * + * @author dcsoft + * @date 2024-03-01 + */ +public interface SysBackGroupMapper +{ + /** + * 查询背景配置 + * + * @param id 背景配置主键 + * @return 背景配置 + */ + public SysBackGroup selectSysBackGroupById(Long id); + + /** + * 查询背景配置列表 + * + * @param sysBackGroup 背景配置 + * @return 背景配置集合 + */ + public List selectSysBackGroupList(SysBackGroup sysBackGroup); + + /** + * 新增背景配置 + * + * @param sysBackGroup 背景配置 + * @return 结果 + */ + public int insertSysBackGroup(SysBackGroup sysBackGroup); + + /** + * 修改背景配置 + * + * @param sysBackGroup 背景配置 + * @return 结果 + */ + public int updateSysBackGroup(SysBackGroup sysBackGroup); + + /** + * 删除背景配置 + * + * @param id 背景配置主键 + * @return 结果 + */ + public int deleteSysBackGroupById(Long id); + + /** + * 批量删除背景配置 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteSysBackGroupByIds(Long[] ids); + + public int deleteSysBackGroup(); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysBlackListMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysBlackListMapper.java new file mode 100644 index 0000000..8f766d6 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysBlackListMapper.java @@ -0,0 +1,103 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import com.dcsoft.system.domain.SysBlackList; +import com.dcsoft.system.visitor.domain.PersonnelInfoVo; +import com.dcsoft.system.visitor.domain.Visitor; +import com.dcsoft.system.visitor.domain.VisitorInfoVo; +import com.dcsoft.system.visitor.domain.VisitorParamVo; +import org.apache.ibatis.annotations.Param; + +/** + * 黑名单管理Mapper接口 + * + * @author nichun + * @date 2023-07-03 + */ +public interface SysBlackListMapper +{ + /** + * 查询黑名单管理 + * + * @param id 黑名单管理主键 + * @return 黑名单管理 + */ + public SysBlackList selectSysBlackListById(Long id); + + /** + * 查询黑名单管理列表 + * + * @param sysBlackList 黑名单管理 + * @return 黑名单管理集合 + */ + public List selectSysBlackListList(SysBlackList sysBlackList); + + /** + * 新增黑名单管理 + * + * @param sysBlackList 黑名单管理 + * @return 结果 + */ + public int insertSysBlackList(SysBlackList sysBlackList); + + /** + * 修改黑名单管理 + * + * @param sysBlackList 黑名单管理 + * @return 结果 + */ + public int updateSysBlackList(SysBlackList sysBlackList); + + /** + * 删除黑名单管理 + * + * @param id 黑名单管理主键 + * @return 结果 + */ + public int deleteSysBlackListById(Long id); + + /** + * 批量删除黑名单管理 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteSysBlackListByIds(Long[] ids); + + /** + * 查询访客人员信息 + */ + PersonnelInfoVo queryPersonnelInfo(@Param("list") List list); + + /** + * 查询通行人员信息 + */ + List queryGeneralInfo(String id); + + /** + * 查询被访人 + */ + List queryPeople(Visitor paramVo); + + /** + * 查询已审核状态信息 + */ + VisitorParamVo queryAuditedVisitor(Visitor paramVo); + + /** + * 查询详情 + */ + VisitorInfoVo queryVisitorInfo(Visitor paramVo); + + /** + * 查询随访人 + */ + List queryFollowUp(Visitor infoVo); + + /** + * 查询黑名单 + */ + SysBlackList queryBlackById(Visitor visitor); + + VisitorInfoVo queryVisitorType(Visitor paramVo); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysBranchMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysBranchMapper.java new file mode 100644 index 0000000..a3bc317 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysBranchMapper.java @@ -0,0 +1,100 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import com.dcsoft.system.domain.SysBranch; +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.domain.SysPeopleOther; +import com.dcsoft.system.domain.vo.JjDivisionVo; +import com.dcsoft.system.domain.vo.JjStationVo; +import com.dcsoft.system.domain.vo.JjserInfoVo; +import org.apache.ibatis.annotations.Param; + +/** + * 部门管理Mapper接口 + * + * @author dcsoft + * @date 2023-03-07 + */ +public interface SysBranchMapper +{ + /** + * 查询部门管理 + * + * @param id 部门管理主键 + * @return 部门管理 + */ + public SysBranch selectSysBranchById(String id); + + /** + * 查询部门管理列表 + * + * @param sysBranch 部门管理 + * @return 部门管理集合 + */ + public List selectSysBranchList(SysBranch sysBranch); + + /** + * 新增部门管理 + * + * @param sysBranch 部门管理 + * @return 结果 + */ + public int insertSysBranch(SysBranch sysBranch); + + /** + * 修改部门管理 + * + * @param sysBranch 部门管理 + * @return 结果 + */ + public int updateSysBranch(SysBranch sysBranch); + + /** + * 删除部门管理 + * + * @param id 部门管理主键 + * @return 结果 + */ + public int deleteSysBranchById(Long id); + + /** + * 批量删除部门管理 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteSysBranchByIds(String[] ids); + + public int deleteSysBranchByBranchId(String id); + + public SysBranch selectSysBranchByDeptId(Long deptId); + + List queryBranchTree(); + + void saveBranchTree(List list); + + /** + * 同步人员(锦江) + */ + void saveUserInfo(List data); + + /** + * 同步岗位(锦江) + */ + void saveStation(List data); + + List selectBranchTree(@Param("sysPeople") SysPeople sysPeople); + + List selectBranchTreeOther(@Param("sysPeople") SysPeopleOther sysPeople); + + /** + * + */ + void updateBranchTree(List list); + + /** + * 查询物业子部门 + * @return + */ + List queryPropertyDept(String parentId); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysConfigMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysConfigMapper.java new file mode 100644 index 0000000..cbcfa03 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysConfigMapper.java @@ -0,0 +1,76 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import com.dcsoft.system.domain.SysConfig; + +/** + * 参数配置 数据层 + * + * @author dcsoft + */ +public interface SysConfigMapper +{ + /** + * 查询参数配置信息 + * + * @param config 参数配置信息 + * @return 参数配置信息 + */ + public SysConfig selectConfig(SysConfig config); + + /** + * 通过ID查询配置 + * + * @param configId 参数ID + * @return 参数配置信息 + */ + public SysConfig selectConfigById(Long configId); + + /** + * 查询参数配置列表 + * + * @param config 参数配置信息 + * @return 参数配置集合 + */ + public List selectConfigList(SysConfig config); + + /** + * 根据键名查询参数配置信息 + * + * @param configKey 参数键名 + * @return 参数配置信息 + */ + public SysConfig checkConfigKeyUnique(String configKey); + + /** + * 新增参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + public int insertConfig(SysConfig config); + + /** + * 修改参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + public int updateConfig(SysConfig config); + + /** + * 删除参数配置 + * + * @param configId 参数ID + * @return 结果 + */ + public int deleteConfigById(Long configId); + + /** + * 批量删除参数信息 + * + * @param configIds 需要删除的参数ID + * @return 结果 + */ + public int deleteConfigByIds(Long[] configIds); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysDeptMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysDeptMapper.java new file mode 100644 index 0000000..ba51d70 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysDeptMapper.java @@ -0,0 +1,120 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.dcsoft.system.api.domain.SysDept; + +/** + * 部门管理 数据层 + * + * @author dcsoft + */ +public interface SysDeptMapper +{ + /** + * 查询部门管理数据 + * + * @param dept 部门信息 + * @return 部门信息集合 + */ + public List selectDeptList(SysDept dept); + + /** + * 根据角色ID查询部门树信息 + * + * @param roleId 角色ID + * @param deptCheckStrictly 部门树选择项是否关联显示 + * @return 选中部门列表 + */ + public List selectDeptListByRoleId(@Param("roleId") Long roleId, @Param("deptCheckStrictly") boolean deptCheckStrictly); + + /** + * 根据部门ID查询信息 + * + * @param deptId 部门ID + * @return 部门信息 + */ + public SysDept selectDeptById(Long deptId); + + /** + * 根据ID查询所有子部门 + * + * @param deptId 部门ID + * @return 部门列表 + */ + public List selectChildrenDeptById(Long deptId); + + /** + * 根据ID查询所有子部门(正常状态) + * + * @param deptId 部门ID + * @return 子部门数 + */ + public int selectNormalChildrenDeptById(Long deptId); + + /** + * 是否存在子节点 + * + * @param deptId 部门ID + * @return 结果 + */ + public int hasChildByDeptId(Long deptId); + + /** + * 查询部门是否存在用户 + * + * @param deptId 部门ID + * @return 结果 + */ + public int checkDeptExistUser(Long deptId); + + /** + * 校验部门名称是否唯一 + * + * @param deptName 部门名称 + * @param parentId 父部门ID + * @return 结果 + */ + public SysDept checkDeptNameUnique(@Param("deptName") String deptName, @Param("parentId") Long parentId); + + /** + * 新增部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + public int insertDept(SysDept dept); + + /** + * 修改部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + public int updateDept(SysDept dept); + + /** + * 修改所在部门正常状态 + * + * @param deptIds 部门ID组 + */ + public void updateDeptStatusNormal(Long[] deptIds); + + /** + * 修改子元素关系 + * + * @param depts 子元素 + * @return 结果 + */ + public int updateDeptChildren(@Param("depts") List depts); + + /** + * 删除部门管理信息 + * + * @param deptId 部门ID + * @return 结果 + */ + public int deleteDeptById(Long deptId); + + public SysDept findByParentExternalId(String externalId); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysDictDataMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysDictDataMapper.java new file mode 100644 index 0000000..dee4f00 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysDictDataMapper.java @@ -0,0 +1,95 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.dcsoft.system.api.domain.SysDictData; + +/** + * 字典表 数据层 + * + * @author dcsoft + */ +public interface SysDictDataMapper +{ + /** + * 根据条件分页查询字典数据 + * + * @param dictData 字典数据信息 + * @return 字典数据集合信息 + */ + public List selectDictDataList(SysDictData dictData); + + /** + * 根据字典类型查询字典数据 + * + * @param dictType 字典类型 + * @return 字典数据集合信息 + */ + public List selectDictDataByType(String dictType); + + /** + * 根据字典类型和字典键值查询字典数据信息 + * + * @param dictType 字典类型 + * @param dictValue 字典键值 + * @return 字典标签 + */ + public String selectDictLabel(@Param("dictType") String dictType, @Param("dictValue") String dictValue); + + /** + * 根据字典数据ID查询信息 + * + * @param dictCode 字典数据ID + * @return 字典数据 + */ + public SysDictData selectDictDataById(Long dictCode); + + /** + * 查询字典数据 + * + * @param dictType 字典类型 + * @return 字典数据 + */ + public int countDictDataByType(String dictType); + + /** + * 通过字典ID删除字典数据信息 + * + * @param dictCode 字典数据ID + * @return 结果 + */ + public int deleteDictDataById(Long dictCode); + + /** + * 批量删除字典数据信息 + * + * @param dictCodes 需要删除的字典数据ID + * @return 结果 + */ + public int deleteDictDataByIds(Long[] dictCodes); + + /** + * 新增字典数据信息 + * + * @param dictData 字典数据信息 + * @return 结果 + */ + public int insertDictData(SysDictData dictData); + + /** + * 修改字典数据信息 + * + * @param dictData 字典数据信息 + * @return 结果 + */ + public int updateDictData(SysDictData dictData); + + /** + * 同步修改字典类型 + * + * @param oldDictType 旧字典类型 + * @param newDictType 新旧字典类型 + * @return 结果 + */ + public int updateDictDataType(@Param("oldDictType") String oldDictType, @Param("newDictType") String newDictType); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysDictTypeMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysDictTypeMapper.java new file mode 100644 index 0000000..b429a64 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysDictTypeMapper.java @@ -0,0 +1,83 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import com.dcsoft.system.api.domain.SysDictType; + +/** + * 字典表 数据层 + * + * @author dcsoft + */ +public interface SysDictTypeMapper +{ + /** + * 根据条件分页查询字典类型 + * + * @param dictType 字典类型信息 + * @return 字典类型集合信息 + */ + public List selectDictTypeList(SysDictType dictType); + + /** + * 根据所有字典类型 + * + * @return 字典类型集合信息 + */ + public List selectDictTypeAll(); + + /** + * 根据字典类型ID查询信息 + * + * @param dictId 字典类型ID + * @return 字典类型 + */ + public SysDictType selectDictTypeById(Long dictId); + + /** + * 根据字典类型查询信息 + * + * @param dictType 字典类型 + * @return 字典类型 + */ + public SysDictType selectDictTypeByType(String dictType); + + /** + * 通过字典ID删除字典信息 + * + * @param dictId 字典ID + * @return 结果 + */ + public int deleteDictTypeById(Long dictId); + + /** + * 批量删除字典类型信息 + * + * @param dictIds 需要删除的字典ID + * @return 结果 + */ + public int deleteDictTypeByIds(Long[] dictIds); + + /** + * 新增字典类型信息 + * + * @param dictType 字典类型信息 + * @return 结果 + */ + public int insertDictType(SysDictType dictType); + + /** + * 修改字典类型信息 + * + * @param dictType 字典类型信息 + * @return 结果 + */ + public int updateDictType(SysDictType dictType); + + /** + * 校验字典类型称是否唯一 + * + * @param dictType 字典类型 + * @return 结果 + */ + public SysDictType checkDictTypeUnique(String dictType); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysEmpowerRecordMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysEmpowerRecordMapper.java new file mode 100644 index 0000000..e5f8040 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysEmpowerRecordMapper.java @@ -0,0 +1,63 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import com.dcsoft.system.domain.SysEmpowerRecord; + +/** + * 授权记录Mapper接口 + * + * @author nichun + * @date 2023-03-08 + */ +public interface SysEmpowerRecordMapper +{ + /** + * 查询授权记录 + * + * @param id 授权记录主键 + * @return 授权记录 + */ + public SysEmpowerRecord selectSysEmpowerRecordById(Long id); + + /** + * 查询授权记录列表 + * + * @param sysEmpowerRecord 授权记录 + * @return 授权记录集合 + */ + public List selectSysEmpowerRecordList(SysEmpowerRecord sysEmpowerRecord); + + /** + * 新增授权记录 + * + * @param sysEmpowerRecord 授权记录 + * @return 结果 + */ + public int insertSysEmpowerRecord(SysEmpowerRecord sysEmpowerRecord); + + /** + * 修改授权记录 + * + * @param sysEmpowerRecord 授权记录 + * @return 结果 + */ + public int updateSysEmpowerRecord(SysEmpowerRecord sysEmpowerRecord); + + /** + * 删除授权记录 + * + * @param id 授权记录主键 + * @return 结果 + */ + public int deleteSysEmpowerRecordById(Long id); + + /** + * 批量删除授权记录 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteSysEmpowerRecordByIds(Long[] ids); + + public int deleteSysEmpowerRecordByPeopleId(Long peopleId); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysEquipmentMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysEquipmentMapper.java new file mode 100644 index 0000000..bf07487 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysEquipmentMapper.java @@ -0,0 +1,124 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import java.util.Map; + +import com.dcsoft.system.domain.SysEmpowerRecord; +import com.dcsoft.system.domain.SysEquipment; +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.domain.vo.SysFileVo; + +/** + * 设备信息Mapper接口 + * + * @author nichun + * @date 2023-03-08 + */ +public interface SysEquipmentMapper +{ + /** + * 查询设备信息 + * + * @param id 设备信息主键 + * @return 设备信息 + */ + public SysEquipment selectSysEquipmentById(Long id); + + /** + * 查询设备信息列表 + * + * @param sysEquipment 设备信息 + * @return 设备信息集合 + */ + public List selectSysEquipmentList(SysEquipment sysEquipment); + + /** + * 新增设备信息 + * + * @param sysEquipment 设备信息 + * @return 结果 + */ + public int insertSysEquipment(SysEquipment sysEquipment); + + /** + * 修改设备信息 + * + * @param sysEquipment 设备信息 + * @return 结果 + */ + public int updateSysEquipment(SysEquipment sysEquipment); + + /** + * 删除设备信息 + * + * @param id 设备信息主键 + * @return 结果 + */ + public int deleteSysEquipmentById(Long id); + + /** + * 批量删除设备信息 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteSysEquipmentByIds(Long[] ids); + + SysEquipment selectEquipmentBySequence(String deviceNo); + + /** + * 查询设备信息 + */ + List queryEquipmentInfo(List pointIds); + + /** + * 查询人员信息 + */ + SysPeople queryPeopleInfo(SysPeople people); + + List> selectSysEquipmentPeopleById(Long id); + + /** + * 根据设备序列号查询产品类型 + * @param deviceKey + * @return + */ + String queryDeviceSequence(String deviceKey); + + /** + * 查询授权记录规则id + * @param people + * @return + */ + List queryEmpowerRecord(SysPeople people); + + /** + * 查询人员信息 + * @param sysPeople + * @return + */ + SysPeople queryPeople(SysPeople sysPeople); + + SysEquipment queryEmpower(String sequence); + + /** + * 根据设备序列好查询设备信息 + * @param sysEquipment + * @return + */ + SysEquipment queryEquipmentByDeviceKey(SysEquipment sysEquipment); + + List queryEquipmentByIp(List listIp); + + /** + * 根据设备序列号修改设备密码 + * @param sysEquipment + */ + void updateEquipmentByDeviceKey(SysEquipment sysEquipment); + + void saveFile(List sysFiles); + + void deleteFile(SysFileVo sysFile); + + List queryFile(SysFileVo sysFile); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysLogininforMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysLogininforMapper.java new file mode 100644 index 0000000..217d812 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysLogininforMapper.java @@ -0,0 +1,42 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import com.dcsoft.system.api.domain.SysLogininfor; + +/** + * 系统访问日志情况信息 数据层 + * + * @author dcsoft + */ +public interface SysLogininforMapper +{ + /** + * 新增系统登录日志 + * + * @param logininfor 访问日志对象 + */ + public int insertLogininfor(SysLogininfor logininfor); + + /** + * 查询系统登录日志集合 + * + * @param logininfor 访问日志对象 + * @return 登录记录集合 + */ + public List selectLogininforList(SysLogininfor logininfor); + + /** + * 批量删除系统登录日志 + * + * @param infoIds 需要删除的登录日志ID + * @return 结果 + */ + public int deleteLogininforByIds(Long[] infoIds); + + /** + * 清空系统登录日志 + * + * @return 结果 + */ + public int cleanLogininfor(); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysManageRecordMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysManageRecordMapper.java new file mode 100644 index 0000000..89c5060 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysManageRecordMapper.java @@ -0,0 +1,61 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import com.dcsoft.system.domain.SysManageRecord; + +/** + * 授权管理记录Mapper接口 + * + * @author dcsoft + * @date 2023-03-08 + */ +public interface SysManageRecordMapper +{ + /** + * 查询授权管理记录 + * + * @param id 授权管理记录主键 + * @return 授权管理记录 + */ + public SysManageRecord selectSysManageRecordById(Long id); + + /** + * 查询授权管理记录列表 + * + * @param sysManageRecord 授权管理记录 + * @return 授权管理记录集合 + */ + public List selectSysManageRecordList(SysManageRecord sysManageRecord); + + /** + * 新增授权管理记录 + * + * @param sysManageRecord 授权管理记录 + * @return 结果 + */ + public int insertSysManageRecord(SysManageRecord sysManageRecord); + + /** + * 修改授权管理记录 + * + * @param sysManageRecord 授权管理记录 + * @return 结果 + */ + public int updateSysManageRecord(SysManageRecord sysManageRecord); + + /** + * 删除授权管理记录 + * + * @param id 授权管理记录主键 + * @return 结果 + */ + public int deleteSysManageRecordById(Long id); + + /** + * 批量删除授权管理记录 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteSysManageRecordByIds(Long[] ids); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysMenuMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysMenuMapper.java new file mode 100644 index 0000000..cf78312 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysMenuMapper.java @@ -0,0 +1,125 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.dcsoft.system.domain.SysMenu; + +/** + * 菜单表 数据层 + * + * @author dcsoft + */ +public interface SysMenuMapper +{ + /** + * 查询系统菜单列表 + * + * @param menu 菜单信息 + * @return 菜单列表 + */ + public List selectMenuList(SysMenu menu); + + /** + * 根据用户所有权限 + * + * @return 权限列表 + */ + public List selectMenuPerms(); + + /** + * 根据用户查询系统菜单列表 + * + * @param menu 菜单信息 + * @return 菜单列表 + */ + public List selectMenuListByUserId(SysMenu menu); + + /** + * 根据角色ID查询权限 + * + * @param roleId 角色ID + * @return 权限列表 + */ + public List selectMenuPermsByRoleId(Long roleId); + + /** + * 根据用户ID查询权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + public List selectMenuPermsByUserId(Long userId); + + /** + * 根据用户ID查询菜单 + * + * @return 菜单列表 + */ + public List selectMenuTreeAll(); + + /** + * 根据用户ID查询菜单 + * + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuTreeByUserId(Long userId); + + /** + * 根据角色ID查询菜单树信息 + * + * @param roleId 角色ID + * @param menuCheckStrictly 菜单树选择项是否关联显示 + * @return 选中菜单列表 + */ + public List selectMenuListByRoleId(@Param("roleId") Long roleId, @Param("menuCheckStrictly") boolean menuCheckStrictly); + + /** + * 根据菜单ID查询信息 + * + * @param menuId 菜单ID + * @return 菜单信息 + */ + public SysMenu selectMenuById(Long menuId); + + /** + * 是否存在菜单子节点 + * + * @param menuId 菜单ID + * @return 结果 + */ + public int hasChildByMenuId(Long menuId); + + /** + * 新增菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + public int insertMenu(SysMenu menu); + + /** + * 修改菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + public int updateMenu(SysMenu menu); + + /** + * 删除菜单管理信息 + * + * @param menuId 菜单ID + * @return 结果 + */ + public int deleteMenuById(Long menuId); + + /** + * 校验菜单名称是否唯一 + * + * @param menuName 菜单名称 + * @param parentId 父菜单ID + * @return 结果 + */ + public SysMenu checkMenuNameUnique(@Param("menuName") String menuName, @Param("parentId") Long parentId); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysNoticeMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysNoticeMapper.java new file mode 100644 index 0000000..1776d13 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysNoticeMapper.java @@ -0,0 +1,60 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import com.dcsoft.system.domain.SysNotice; + +/** + * 通知公告表 数据层 + * + * @author dcsoft + */ +public interface SysNoticeMapper +{ + /** + * 查询公告信息 + * + * @param noticeId 公告ID + * @return 公告信息 + */ + public SysNotice selectNoticeById(Long noticeId); + + /** + * 查询公告列表 + * + * @param notice 公告信息 + * @return 公告集合 + */ + public List selectNoticeList(SysNotice notice); + + /** + * 新增公告 + * + * @param notice 公告信息 + * @return 结果 + */ + public int insertNotice(SysNotice notice); + + /** + * 修改公告 + * + * @param notice 公告信息 + * @return 结果 + */ + public int updateNotice(SysNotice notice); + + /** + * 批量删除公告 + * + * @param noticeId 公告ID + * @return 结果 + */ + public int deleteNoticeById(Long noticeId); + + /** + * 批量删除公告信息 + * + * @param noticeIds 需要删除的公告ID + * @return 结果 + */ + public int deleteNoticeByIds(Long[] noticeIds); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysOperLogMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysOperLogMapper.java new file mode 100644 index 0000000..6a28190 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysOperLogMapper.java @@ -0,0 +1,48 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import com.dcsoft.system.api.domain.SysOperLog; + +/** + * 操作日志 数据层 + * + * @author dcsoft + */ +public interface SysOperLogMapper +{ + /** + * 新增操作日志 + * + * @param operLog 操作日志对象 + */ + public int insertOperlog(SysOperLog operLog); + + /** + * 查询系统操作日志集合 + * + * @param operLog 操作日志对象 + * @return 操作日志集合 + */ + public List selectOperLogList(SysOperLog operLog); + + /** + * 批量删除系统操作日志 + * + * @param operIds 需要删除的操作日志ID + * @return 结果 + */ + public int deleteOperLogByIds(Long[] operIds); + + /** + * 查询操作日志详细 + * + * @param operId 操作ID + * @return 操作日志对象 + */ + public SysOperLog selectOperLogById(Long operId); + + /** + * 清空操作日志 + */ + public void cleanOperLog(); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPeopleEquipmentMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPeopleEquipmentMapper.java new file mode 100644 index 0000000..0db7c74 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPeopleEquipmentMapper.java @@ -0,0 +1,70 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import com.dcsoft.system.domain.SysPeopleEquipment; + +/** + * 人员设备下发信息Mapper接口 + * + * @author dcsoft + * @date 2023-06-12 + */ +public interface SysPeopleEquipmentMapper +{ + /** + * 查询人员设备下发信息 + * + * @param id 人员设备下发信息主键 + * @return 人员设备下发信息 + */ + public SysPeopleEquipment selectSysPeopleEquipmentById(Long id); + + /** + * 查询人员设备下发信息列表 + * + * @param sysPeopleEquipment 人员设备下发信息 + * @return 人员设备下发信息集合 + */ + public List selectSysPeopleEquipmentList(SysPeopleEquipment sysPeopleEquipment); + + /** + * 新增人员设备下发信息 + * + * @param sysPeopleEquipment 人员设备下发信息 + * @return 结果 + */ + public int insertSysPeopleEquipment(SysPeopleEquipment sysPeopleEquipment); + + /** + * 修改人员设备下发信息 + * + * @param sysPeopleEquipment 人员设备下发信息 + * @return 结果 + */ + public int updateSysPeopleEquipment(SysPeopleEquipment sysPeopleEquipment); + + /** + * 删除人员设备下发信息 + * + * @param id 人员设备下发信息主键 + * @return 结果 + */ + public int deleteSysPeopleEquipmentById(Long id); + + /** + * 批量删除人员设备下发信息 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteSysPeopleEquipmentByIds(Long[] ids); + + public SysPeopleEquipment selectSysPeopleEquipmentByGuId(String guid); + + public List selectSysPeopleEquipmentByPeopleId(String peopleId); + + public List selectSysPeopleEquipmentByVisitorId(Long visitorId); + + + public int deleteSysPeopleEquipmentByOtherId(Long otherId); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPeopleLeaveMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPeopleLeaveMapper.java new file mode 100644 index 0000000..0c74a76 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPeopleLeaveMapper.java @@ -0,0 +1,67 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import com.dcsoft.system.domain.SysPeopleLeave; + +/** + * 离职管理Mapper接口 + * + * @author nichun + * @date 2023-09-09 + */ +public interface SysPeopleLeaveMapper +{ + /** + * 查询离职管理 + * + * @param id 离职管理主键 + * @return 离职管理 + */ + public SysPeopleLeave selectSysPeopleLeaveById(Long id); + + /** + * 查询离职管理列表 + * + * @param sysPeopleLeave 离职管理 + * @return 离职管理集合 + */ + public List selectSysPeopleLeaveList(SysPeopleLeave sysPeopleLeave); + + /** + * 新增离职管理 + * + * @param sysPeopleLeave 离职管理 + * @return 结果 + */ + public int insertSysPeopleLeave(SysPeopleLeave sysPeopleLeave); + + /** + * 修改离职管理 + * + * @param sysPeopleLeave 离职管理 + * @return 结果 + */ + public int updateSysPeopleLeave(SysPeopleLeave sysPeopleLeave); + + /** + * 删除离职管理 + * + * @param id 离职管理主键 + * @return 结果 + */ + public int deleteSysPeopleLeaveById(Long id); + + /** + * 批量删除离职管理 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteSysPeopleLeaveByIds(Long[] ids); + + void savePeopleLeaveList(List list); + + List queryPeopleLeaveList(List list); + + void updatePeopleLeaveList(List peopleLeaveList); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPeopleMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPeopleMapper.java new file mode 100644 index 0000000..a69b5fe --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPeopleMapper.java @@ -0,0 +1,111 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.domain.SysPeopleLeave; +import com.dcsoft.system.domain.vo.OfficialAccountVo; +import org.apache.ibatis.annotations.Param; + +/** + * 人员管理Mapper接口 + * + * @author nichun + * @date 2023-03-08 + */ +public interface SysPeopleMapper +{ + /** + * 查询人员管理 + * + * @param id 人员管理主键 + * @return 人员管理 + */ + public SysPeople selectSysPeopleById(Long id); + + /** + * 查询人员管理列表 + * + * @param sysPeople 人员管理 + * @return 人员管理集合 + */ + public List selectSysPeopleList(@Param("sysPeople") SysPeople sysPeople, @Param("list") List list); + + /** + * 新增人员管理 + * + * @param sysPeople 人员管理 + * @return 结果 + */ + public int insertSysPeople(SysPeople sysPeople); + + /** + * 修改人员管理 + * + * @param sysPeople 人员管理 + * @return 结果 + */ + public int updateSysPeople(SysPeople sysPeople); + + /** + * 删除人员管理 + * + * @param id 人员管理主键 + * @return 结果 + */ + public int deleteSysPeopleById(Long id); + + /** + * 批量删除人员管理 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteSysPeopleByIds(Long[] ids); + + SysPeople selectByGuid(SysPeople sysPeople); + + + SysPeople selectSysPeopleByUserId(Long userId); + + SysPeople selectSysPeopleByBranchUser(@Param("branchName") String branchName,@Param("userName") String userName); + + SysPeople selectSysPeopleByGh(String gh); + + SysPeople selectSysPeopleByPhoneUser(SysPeople sysPeople); + + List queryPeopleInfo(); + + List queryPeople(List collectStr); + + SysPeople queryPeopleDetails(String details); + + SysPeople selectSysPeopleByUserName(String userName); + + public int deleteSysPeopleByGuid(String guid); + + void updatePeople(SysPeople people); + + String selectDoorNo(Long id); + + String selectPeopleById(String card); + + void updatePeopleInfo(SysPeople sysPeople); + + OfficialAccountVo queryPeopleById(String id); + + SysPeople selectSysPeopleByOpenId(String openid); + + SysPeople selectSysPeopleGh(@Param("phone")String phone,@Param("userName") String userName); + + SysPeople queryPeopleName(@Param("phone") String phone, @Param("list") List collect); + + SysPeople selectSysPeopleByDoorNo(String doorNo); + + SysPeople queryEmpowerRecord(String phone); + + SysPeople queryPeopleByOpenid(String openid); + + List queryPeopleByPosition(String position); + + List querySysPeopleInfo(Long userId); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPeopleOtherMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPeopleOtherMapper.java new file mode 100644 index 0000000..967887f --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPeopleOtherMapper.java @@ -0,0 +1,101 @@ +package com.dcsoft.system.mapper; + +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.domain.SysPeopleOther; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 人员管理Mapper接口 + * + * @author nichun + * @date 2023-03-08 + */ +public interface SysPeopleOtherMapper +{ + /** + * 查询人员管理 + * + * @param id 人员管理主键 + * @return 人员管理 + */ + public SysPeopleOther selectSysPeopleOtherById(Long id); + + /** + * 查询人员管理列表 + * + * @param sysPeople 人员管理 + * @return 人员管理集合 + */ + public List selectSysPeopleOtherList(@Param("sysPeopleOther") SysPeopleOther sysPeople, @Param("list") List list); + + /** + * 新增人员管理 + * + * @param sysPeople 人员管理 + * @return 结果 + */ + public int insertSysPeopleOther(SysPeopleOther sysPeople); + + /** + * 修改人员管理 + * + * @param sysPeople 人员管理 + * @return 结果 + */ + public int updateSysPeopleOther(SysPeopleOther sysPeople); + + /** + * 删除人员管理 + * + * @param id 人员管理主键 + * @return 结果 + */ + public int deleteSysPeopleOtherById(Long id); + + /** + * 批量删除人员管理 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteSysPeopleOtherByIds(Long[] ids); + + SysPeopleOther selectByGuid(SysPeopleOther sysPeople); + + + SysPeopleOther selectSysPeopleOtherByUserId(Long userId); + + SysPeopleOther selectSysPeopleOtherByBranchUser(@Param("branchName") String branchName,@Param("userName") String userName); + + SysPeopleOther selectSysPeopleOtherByGh(String gh); + + SysPeopleOther selectSysPeopleOtherByPhoneUser(SysPeopleOther sysPeople); + + List queryPeopleInfo(); + + List queryPeople(List collectStr); + + SysPeopleOther queryPeopleDetails(String details); + + SysPeopleOther selectSysPeopleOtherByUserName(String userName); + + public int deleteSysPeopleOtherByGuid(String guid); + + void updatePeople(SysPeopleOther people); + + String selectDoorNo(Long id); + + String selectPeopleById(String card); + + void updatePeopleInfo(SysPeopleOther sysPeople); + + SysPeopleOther queryPeopleById(String id); + + SysPeopleOther selectSysPeopleOtherByOpenId(String openid); + + SysPeopleOther selectSysPeopleOtherGh(@Param("phone")String phone,@Param("userName") String userName); + + SysPeopleOther queryPeopleName(String phone); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPeopleRecordMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPeopleRecordMapper.java new file mode 100644 index 0000000..0d7dbdf --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPeopleRecordMapper.java @@ -0,0 +1,81 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import java.util.Map; + +import com.dcsoft.system.domain.SysPeopleRecord; + +/** + * 人员识别记录Mapper接口 + * + * @author nichun + * @date 2023-03-08 + */ +public interface SysPeopleRecordMapper +{ + /** + * 查询人员识别记录 + * + * @param id 人员识别记录主键 + * @return 人员识别记录 + */ + public SysPeopleRecord selectSysPeopleRecordById(Long id); + + /** + * 查询人员识别记录列表 + * + * @param sysPeopleRecord 人员识别记录 + * @return 人员识别记录集合 + */ + public List selectSysPeopleRecordList(SysPeopleRecord sysPeopleRecord); + + /** + * 查询人员识别记录列表 + * + * @param sysPeopleRecord 人员识别记录 + * @return 人员识别记录集合 + */ + public List selectSysPeopleRecordLists(SysPeopleRecord sysPeopleRecord); + + /** + * 新增人员识别记录 + * + * @param sysPeopleRecord 人员识别记录 + * @return 结果 + */ + public int insertSysPeopleRecord(SysPeopleRecord sysPeopleRecord); + + /** + * 修改人员识别记录 + * + * @param sysPeopleRecord 人员识别记录 + * @return 结果 + */ + public int updateSysPeopleRecord(SysPeopleRecord sysPeopleRecord); + + /** + * 删除人员识别记录 + * + * @param id 人员识别记录主键 + * @return 结果 + */ + public int deleteSysPeopleRecordById(Long id); + + /** + * 批量删除人员识别记录 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteSysPeopleRecordByIds(Long[] ids); + + public List> topApi(); + + String selectPeopleRecordById(String deviceKey); + + /** + * 查询通行统计数量(昨天,今天) + * @return + */ + List queryThroughCount(); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPeopleRuleMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPeopleRuleMapper.java new file mode 100644 index 0000000..468d451 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPeopleRuleMapper.java @@ -0,0 +1,61 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import com.dcsoft.system.domain.SysPeopleRule; + +/** + * 人员规则关联Mapper接口 + * + * @author dcsoft + * @date 2023-12-22 + */ +public interface SysPeopleRuleMapper +{ + /** + * 查询人员规则关联 + * + * @param id 人员规则关联主键 + * @return 人员规则关联 + */ + public SysPeopleRule selectSysPeopleRuleById(Long id); + + /** + * 查询人员规则关联列表 + * + * @param sysPeopleRule 人员规则关联 + * @return 人员规则关联集合 + */ + public List selectSysPeopleRuleList(SysPeopleRule sysPeopleRule); + + /** + * 新增人员规则关联 + * + * @param sysPeopleRule 人员规则关联 + * @return 结果 + */ + public int insertSysPeopleRule(SysPeopleRule sysPeopleRule); + + /** + * 修改人员规则关联 + * + * @param sysPeopleRule 人员规则关联 + * @return 结果 + */ + public int updateSysPeopleRule(SysPeopleRule sysPeopleRule); + + /** + * 删除人员规则关联 + * + * @param id 人员规则关联主键 + * @return 结果 + */ + public int deleteSysPeopleRuleById(Long id); + + /** + * 批量删除人员规则关联 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteSysPeopleRuleByIds(Long[] ids); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPointMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPointMapper.java new file mode 100644 index 0000000..2f4fc83 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPointMapper.java @@ -0,0 +1,62 @@ +package com.dcsoft.system.mapper; + +import java.util.List; + +import com.dcsoft.system.domain.SysPoint; + +/** + * 点位管理Mapper接口 + * + * @author nichun + * @date 2023-03-08 + */ +public interface SysPointMapper +{ + /** + * 查询点位管理 + * + * @param id 点位管理主键 + * @return 点位管理 + */ + public SysPoint selectSysPointById(Long id); + + /** + * 查询点位管理列表 + * + * @param sysPoint 点位管理 + * @return 点位管理集合 + */ + public List selectSysPointList(SysPoint sysPoint); + + /** + * 新增点位管理 + * + * @param sysPoint 点位管理 + * @return 结果 + */ + public int insertSysPoint(SysPoint sysPoint); + + /** + * 修改点位管理 + * + * @param sysPoint 点位管理 + * @return 结果 + */ + public int updateSysPoint(SysPoint sysPoint); + + /** + * 删除点位管理 + * + * @param id 点位管理主键 + * @return 结果 + */ + public int deleteSysPointById(Long id); + + /** + * 批量删除点位管理 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteSysPointByIds(Long[] ids); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPostMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPostMapper.java new file mode 100644 index 0000000..c187c31 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysPostMapper.java @@ -0,0 +1,99 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import com.dcsoft.system.domain.SysPost; + +/** + * 岗位信息 数据层 + * + * @author dcsoft + */ +public interface SysPostMapper +{ + /** + * 查询岗位数据集合 + * + * @param post 岗位信息 + * @return 岗位数据集合 + */ + public List selectPostList(SysPost post); + + /** + * 查询所有岗位 + * + * @return 岗位列表 + */ + public List selectPostAll(); + + /** + * 通过岗位ID查询岗位信息 + * + * @param postId 岗位ID + * @return 角色对象信息 + */ + public SysPost selectPostById(Long postId); + + /** + * 根据用户ID获取岗位选择框列表 + * + * @param userId 用户ID + * @return 选中岗位ID列表 + */ + public List selectPostListByUserId(Long userId); + + /** + * 查询用户所属岗位组 + * + * @param userName 用户名 + * @return 结果 + */ + public List selectPostsByUserName(String userName); + + /** + * 删除岗位信息 + * + * @param postId 岗位ID + * @return 结果 + */ + public int deletePostById(Long postId); + + /** + * 批量删除岗位信息 + * + * @param postIds 需要删除的岗位ID + * @return 结果 + */ + public int deletePostByIds(Long[] postIds); + + /** + * 修改岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + public int updatePost(SysPost post); + + /** + * 新增岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + public int insertPost(SysPost post); + + /** + * 校验岗位名称 + * + * @param postName 岗位名称 + * @return 结果 + */ + public SysPost checkPostNameUnique(String postName); + + /** + * 校验岗位编码 + * + * @param postCode 岗位编码 + * @return 结果 + */ + public SysPost checkPostCodeUnique(String postCode); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysProductMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysProductMapper.java new file mode 100644 index 0000000..971399d --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysProductMapper.java @@ -0,0 +1,61 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import com.dcsoft.system.domain.SysProduct; + +/** + * 产品信息Mapper接口 + * + * @author nichun + * @date 2023-03-08 + */ +public interface SysProductMapper +{ + /** + * 查询产品信息 + * + * @param id 产品信息主键 + * @return 产品信息 + */ + public SysProduct selectSysProductById(Long id); + + /** + * 查询产品信息列表 + * + * @param sysProduct 产品信息 + * @return 产品信息集合 + */ + public List selectSysProductList(SysProduct sysProduct); + + /** + * 新增产品信息 + * + * @param sysProduct 产品信息 + * @return 结果 + */ + public int insertSysProduct(SysProduct sysProduct); + + /** + * 修改产品信息 + * + * @param sysProduct 产品信息 + * @return 结果 + */ + public int updateSysProduct(SysProduct sysProduct); + + /** + * 删除产品信息 + * + * @param id 产品信息主键 + * @return 结果 + */ + public int deleteSysProductById(Long id); + + /** + * 批量删除产品信息 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteSysProductByIds(Long[] ids); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysRoleDeptMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysRoleDeptMapper.java new file mode 100644 index 0000000..a85af2c --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysRoleDeptMapper.java @@ -0,0 +1,44 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import com.dcsoft.system.domain.SysRoleDept; + +/** + * 角色与部门关联表 数据层 + * + * @author dcsoft + */ +public interface SysRoleDeptMapper +{ + /** + * 通过角色ID删除角色和部门关联 + * + * @param roleId 角色ID + * @return 结果 + */ + public int deleteRoleDeptByRoleId(Long roleId); + + /** + * 批量删除角色部门关联信息 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteRoleDept(Long[] ids); + + /** + * 查询部门使用数量 + * + * @param deptId 部门ID + * @return 结果 + */ + public int selectCountRoleDeptByDeptId(Long deptId); + + /** + * 批量新增角色部门信息 + * + * @param roleDeptList 角色部门列表 + * @return 结果 + */ + public int batchRoleDept(List roleDeptList); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysRoleMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysRoleMapper.java new file mode 100644 index 0000000..ab46b03 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysRoleMapper.java @@ -0,0 +1,107 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import com.dcsoft.system.api.domain.SysRole; + +/** + * 角色表 数据层 + * + * @author dcsoft + */ +public interface SysRoleMapper +{ + /** + * 根据条件分页查询角色数据 + * + * @param role 角色信息 + * @return 角色数据集合信息 + */ + public List selectRoleList(SysRole role); + + /** + * 根据用户ID查询角色 + * + * @param userId 用户ID + * @return 角色列表 + */ + public List selectRolePermissionByUserId(Long userId); + + /** + * 查询所有角色 + * + * @return 角色列表 + */ + public List selectRoleAll(); + + /** + * 根据用户ID获取角色选择框列表 + * + * @param userId 用户ID + * @return 选中角色ID列表 + */ + public List selectRoleListByUserId(Long userId); + + /** + * 通过角色ID查询角色 + * + * @param roleId 角色ID + * @return 角色对象信息 + */ + public SysRole selectRoleById(Long roleId); + + /** + * 根据用户ID查询角色 + * + * @param userName 用户名 + * @return 角色列表 + */ + public List selectRolesByUserName(String userName); + + /** + * 校验角色名称是否唯一 + * + * @param roleName 角色名称 + * @return 角色信息 + */ + public SysRole checkRoleNameUnique(String roleName); + + /** + * 校验角色权限是否唯一 + * + * @param roleKey 角色权限 + * @return 角色信息 + */ + public SysRole checkRoleKeyUnique(String roleKey); + + /** + * 修改角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + public int updateRole(SysRole role); + + /** + * 新增角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + public int insertRole(SysRole role); + + /** + * 通过角色ID删除角色 + * + * @param roleId 角色ID + * @return 结果 + */ + public int deleteRoleById(Long roleId); + + /** + * 批量删除角色信息 + * + * @param roleIds 需要删除的角色ID + * @return 结果 + */ + public int deleteRoleByIds(Long[] roleIds); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysRoleMenuMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysRoleMenuMapper.java new file mode 100644 index 0000000..58fb74e --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysRoleMenuMapper.java @@ -0,0 +1,44 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import com.dcsoft.system.domain.SysRoleMenu; + +/** + * 角色与菜单关联表 数据层 + * + * @author dcsoft + */ +public interface SysRoleMenuMapper +{ + /** + * 查询菜单使用数量 + * + * @param menuId 菜单ID + * @return 结果 + */ + public int checkMenuExistRole(Long menuId); + + /** + * 通过角色ID删除角色和菜单关联 + * + * @param roleId 角色ID + * @return 结果 + */ + public int deleteRoleMenuByRoleId(Long roleId); + + /** + * 批量删除角色菜单关联信息 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteRoleMenu(Long[] ids); + + /** + * 批量新增角色菜单信息 + * + * @param roleMenuList 角色菜单列表 + * @return 结果 + */ + public int batchRoleMenu(List roleMenuList); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysRuleMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysRuleMapper.java new file mode 100644 index 0000000..7125cb4 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysRuleMapper.java @@ -0,0 +1,61 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import com.dcsoft.system.domain.SysRule; + +/** + * 通行规则Mapper接口 + * + * @author nichun + * @date 2023-03-08 + */ +public interface SysRuleMapper +{ + /** + * 查询通行规则 + * + * @param id 通行规则主键 + * @return 通行规则 + */ + public SysRule selectSysRuleById(Long id); + + /** + * 查询通行规则列表 + * + * @param sysRule 通行规则 + * @return 通行规则集合 + */ + public List selectSysRuleList(SysRule sysRule); + + /** + * 新增通行规则 + * + * @param sysRule 通行规则 + * @return 结果 + */ + public int insertSysRule(SysRule sysRule); + + /** + * 修改通行规则 + * + * @param sysRule 通行规则 + * @return 结果 + */ + public int updateSysRule(SysRule sysRule); + + /** + * 删除通行规则 + * + * @param id 通行规则主键 + * @return 结果 + */ + public int deleteSysRuleById(Long id); + + /** + * 批量删除通行规则 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteSysRuleByIds(Long[] ids); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysSpaceMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysSpaceMapper.java new file mode 100644 index 0000000..623c4a7 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysSpaceMapper.java @@ -0,0 +1,64 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import com.dcsoft.system.domain.SysSpace; +import com.dcsoft.system.domain.vo.SysAuthTree; + +/** + * 空间管理Mapper接口 + * + * @author nichun + * @date 2023-03-08 + */ +public interface SysSpaceMapper +{ + /** + * 查询空间管理 + * + * @param id 空间管理主键 + * @return 空间管理 + */ + public SysSpace selectSysSpaceById(Long id); + + /** + * 查询空间管理列表 + * + * @param sysSpace 空间管理 + * @return 空间管理集合 + */ + public List selectSysSpaceList(SysSpace sysSpace); + + /** + * 新增空间管理 + * + * @param sysSpace 空间管理 + * @return 结果 + */ + public int insertSysSpace(SysSpace sysSpace); + + /** + * 修改空间管理 + * + * @param sysSpace 空间管理 + * @return 结果 + */ + public int updateSysSpace(SysSpace sysSpace); + + /** + * 删除空间管理 + * + * @param id 空间管理主键 + * @return 结果 + */ + public int deleteSysSpaceById(Long id); + + /** + * 批量删除空间管理 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteSysSpaceByIds(Long[] ids); + + List selectTree(); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysSyncRuleMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysSyncRuleMapper.java new file mode 100644 index 0000000..d3231b5 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysSyncRuleMapper.java @@ -0,0 +1,80 @@ +package com.dcsoft.system.mapper; + +import java.util.List; + +import com.dcsoft.system.domain.SysSyncItem; +import com.dcsoft.system.domain.SysSyncRule; +import org.apache.ibatis.annotations.Param; + +/** + * 同步规则Mapper接口 + * + * @author nichun + * @date 2024-01-11 + */ +public interface SysSyncRuleMapper +{ + /** + * 查询同步规则 + * + * @param id 同步规则主键 + * @return 同步规则 + */ + public SysSyncRule selectSysSyncRuleById(Long id); + + /** + * 查询同步规则列表 + * + * @param sysSyncRule 同步规则 + * @return 同步规则集合 + */ + public List selectSysSyncRuleList(SysSyncRule sysSyncRule); + + /** + * 新增同步规则 + * + * @param sysSyncRule 同步规则 + * @return 结果 + */ + public int insertSysSyncRule(SysSyncRule sysSyncRule); + + /** + * 修改同步规则 + * + * @param sysSyncRule 同步规则 + * @return 结果 + */ + public int updateSysSyncRule(SysSyncRule sysSyncRule); + + /** + * 删除同步规则 + * + * @param id 同步规则主键 + * @return 结果 + */ + public int deleteSysSyncRuleById(Long id); + + /** + * 批量删除同步规则 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteSysSyncRuleByIds(Long[] ids); + + public int insetSysSyncRuleItem(SysSyncItem item); + + + public int deleteSysSyncRuleItem(Long id); + + List selectSysSyncRuleItem(Long id); + + List selectSysSyncItemRuleList(SysSyncRule rule); + + /** + * 查询园区对映的部门 + * @param tdGuid + * @return + */ + List queryParkDept(String tdGuid); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysUserMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysUserMapper.java new file mode 100644 index 0000000..ca7719b --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysUserMapper.java @@ -0,0 +1,160 @@ +package com.dcsoft.system.mapper; + +import java.util.List; + +import com.dcsoft.system.domain.vo.AppletInfoVo; +import org.apache.ibatis.annotations.Param; +import com.dcsoft.system.api.domain.SysUser; + +/** + * 用户表 数据层 + * + * @author dcsoft + */ +public interface SysUserMapper +{ + /** + * 根据条件分页查询用户列表 + * + * @param sysUser 用户信息 + * @return 用户信息集合信息 + */ + public List selectUserList(SysUser sysUser); + + /** + * 根据条件分页查询已配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectAllocatedList(SysUser user); + + /** + * 根据条件分页查询未分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectUnallocatedList(SysUser user); + + /** + * 通过用户名查询用户 + * + * @param userName 用户名 + * @return 用户对象信息 + */ + public SysUser selectUserByUserName(String userName); + + /** + * 通过用户ID查询用户 + * + * @param userId 用户ID + * @return 用户对象信息 + */ + public SysUser selectUserById(Long userId); + + /** + * 新增用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int insertUser(SysUser user); + + /** + * 修改用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int updateUser(SysUser user); + + /** + * 修改用户头像 + * + * @param userName 用户名 + * @param avatar 头像地址 + * @return 结果 + */ + public int updateUserAvatar(@Param("userName") String userName, @Param("avatar") String avatar); + + /** + * 重置用户密码 + * + * @param userName 用户名 + * @param password 密码 + * @return 结果 + */ + public int resetUserPwd(@Param("userName") String userName, @Param("password") String password); + + /** + * 通过用户ID删除用户 + * + * @param userId 用户ID + * @return 结果 + */ + public int deleteUserById(Long userId); + + /** + * 批量删除用户信息 + * + * @param userIds 需要删除的用户ID + * @return 结果 + */ + public int deleteUserByIds(Long[] userIds); + + /** + * 校验用户名称是否唯一 + * + * @param userName 用户名称 + * @return 结果 + */ + public SysUser checkUserNameUnique(String userName); + + /** + * 校验手机号码是否唯一 + * + * @param phonenumber 手机号码 + * @return 结果 + */ + public SysUser checkPhoneUnique(String phonenumber); + + /** + * 校验email是否唯一 + * + * @param email 用户邮箱 + * @return 结果 + */ + public SysUser checkEmailUnique(String email); + + /** + * 通过用户名查询用户 + * + * @param openid 微信openid + * @return 用户对象信息 + */ + public SysUser selectUserByOpenId(String openid); + + public int updateOpenId(SysUser sysUser); + + /** + * 通过用户名查询用户 + * + * @param externalId IDaas externalId + * @return 用户对象信息 + */ + public SysUser selectUserByExternalId(String externalId); + + /** + * 查询用户信息 + * @param appletInfoVo + * @return + */ + SysUser queryUserInfo(AppletInfoVo appletInfoVo); + + /** + * 小程序更新头像 + * @param appletInfoVo + */ + void updateAppletAvatar(AppletInfoVo appletInfoVo); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysUserPostMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysUserPostMapper.java new file mode 100644 index 0000000..80c6043 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysUserPostMapper.java @@ -0,0 +1,44 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import com.dcsoft.system.domain.SysUserPost; + +/** + * 用户与岗位关联表 数据层 + * + * @author dcsoft + */ +public interface SysUserPostMapper +{ + /** + * 通过用户ID删除用户和岗位关联 + * + * @param userId 用户ID + * @return 结果 + */ + public int deleteUserPostByUserId(Long userId); + + /** + * 通过岗位ID查询岗位使用数量 + * + * @param postId 岗位ID + * @return 结果 + */ + public int countUserPostById(Long postId); + + /** + * 批量删除用户和岗位关联 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteUserPost(Long[] ids); + + /** + * 批量新增用户岗位信息 + * + * @param userPostList 用户角色列表 + * @return 结果 + */ + public int batchUserPost(List userPostList); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysUserRoleMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysUserRoleMapper.java new file mode 100644 index 0000000..ddcd6af --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/mapper/SysUserRoleMapper.java @@ -0,0 +1,62 @@ +package com.dcsoft.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.dcsoft.system.domain.SysUserRole; + +/** + * 用户与角色关联表 数据层 + * + * @author dcsoft + */ +public interface SysUserRoleMapper +{ + /** + * 通过用户ID删除用户和角色关联 + * + * @param userId 用户ID + * @return 结果 + */ + public int deleteUserRoleByUserId(Long userId); + + /** + * 批量删除用户和角色关联 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteUserRole(Long[] ids); + + /** + * 通过角色ID查询角色使用数量 + * + * @param roleId 角色ID + * @return 结果 + */ + public int countUserRoleByRoleId(Long roleId); + + /** + * 批量新增用户角色信息 + * + * @param userRoleList 用户角色列表 + * @return 结果 + */ + public int batchUserRole(List userRoleList); + + /** + * 删除用户和角色关联信息 + * + * @param userRole 用户和角色关联信息 + * @return 结果 + */ + public int deleteUserRoleInfo(SysUserRole userRole); + + /** + * 批量取消授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要删除的用户数据ID + * @return 结果 + */ + public int deleteUserRoleInfos(@Param("roleId") Long roleId, @Param("userIds") Long[] userIds); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysBackGroupService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysBackGroupService.java new file mode 100644 index 0000000..e3d6455 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysBackGroupService.java @@ -0,0 +1,63 @@ +package com.dcsoft.system.service; + +import java.util.List; +import com.dcsoft.system.domain.SysBackGroup; + +/** + * 背景配置Service接口 + * + * @author dcsoft + * @date 2024-03-01 + */ +public interface ISysBackGroupService +{ + /** + * 查询背景配置 + * + * @param id 背景配置主键 + * @return 背景配置 + */ + public SysBackGroup selectSysBackGroupById(Long id); + + /** + * 查询背景配置列表 + * + * @param sysBackGroup 背景配置 + * @return 背景配置集合 + */ + public List selectSysBackGroupList(SysBackGroup sysBackGroup); + + /** + * 新增背景配置 + * + * @param sysBackGroup 背景配置 + * @return 结果 + */ + public int insertSysBackGroup(SysBackGroup sysBackGroup); + + /** + * 修改背景配置 + * + * @param sysBackGroup 背景配置 + * @return 结果 + */ + public int updateSysBackGroup(SysBackGroup sysBackGroup); + + /** + * 批量删除背景配置 + * + * @param ids 需要删除的背景配置主键集合 + * @return 结果 + */ + public int deleteSysBackGroupByIds(Long[] ids); + + /** + * 删除背景配置信息 + * + * @param id 背景配置主键 + * @return 结果 + */ + public int deleteSysBackGroupById(Long id); + + public int deleteSysBackGroup(); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysBlackListService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysBlackListService.java new file mode 100644 index 0000000..606509f --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysBlackListService.java @@ -0,0 +1,64 @@ +package com.dcsoft.system.service; + +import java.util.List; +import com.dcsoft.system.domain.SysBlackList; +import com.dcsoft.system.visitor.domain.Visitor; + +/** + * 黑名单管理Service接口 + * + * @author nichun + * @date 2023-07-03 + */ +public interface ISysBlackListService +{ + /** + * 查询黑名单管理 + * + * @param id 黑名单管理主键 + * @return 黑名单管理 + */ + public SysBlackList selectSysBlackListById(Long id); + + /** + * 查询黑名单管理列表 + * + * @param sysBlackList 黑名单管理 + * @return 黑名单管理集合 + */ + public List selectSysBlackListList(SysBlackList sysBlackList); + + /** + * 新增黑名单管理 + * + * @param sysBlackList 黑名单管理 + * @return 结果 + */ + public int insertSysBlackList(SysBlackList sysBlackList); + + /** + * 修改黑名单管理 + * + * @param sysBlackList 黑名单管理 + * @return 结果 + */ + public int updateSysBlackList(SysBlackList sysBlackList); + + /** + * 批量删除黑名单管理 + * + * @param ids 需要删除的黑名单管理主键集合 + * @return 结果 + */ + public int deleteSysBlackListByIds(Long[] ids); + + /** + * 删除黑名单管理信息 + * + * @param id 黑名单管理主键 + * @return 结果 + */ + public int deleteSysBlackListById(Long id); + + SysBlackList queryBlackById(Visitor visitor); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysBranchService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysBranchService.java new file mode 100644 index 0000000..c735659 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysBranchService.java @@ -0,0 +1,128 @@ +package com.dcsoft.system.service; + +import java.util.List; + +import com.dcsoft.system.api.domain.SysDept; +import com.dcsoft.system.domain.SysBranch; +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.domain.vo.JjserInfoVo; +import com.dcsoft.system.domain.vo.TreeSelect; +import com.dcsoft.system.domain.vo.TreeSelectVo; + +/** + * 部门管理Service接口 + * + * @author dcsoft + * @date 2023-03-07 + */ +public interface ISysBranchService +{ + /** + * 查询部门管理 + * + * @param id 部门管理主键 + * @return 部门管理 + */ + public SysBranch selectSysBranchById(String id); + + /** + * 查询部门管理列表 + * + * @param sysBranch 部门管理 + * @return 部门管理集合 + */ + public List selectSysBranchList(SysBranch sysBranch); + + /** + * 新增部门管理 + * + * @param sysBranch 部门管理 + * @return 结果 + */ + public int insertSysBranch(SysBranch sysBranch); + + /** + * 修改部门管理 + * + * @param sysBranch 部门管理 + * @return 结果 + */ + public int updateSysBranch(SysBranch sysBranch); + + /** + * 批量删除部门管理 + * + * @param ids 需要删除的部门管理主键集合 + * @return 结果 + */ + public int deleteSysBranchByIds(String[] ids); + + /** + * 删除部门管理信息 + * + * @param id 部门管理主键 + * @return 结果 + */ + public int deleteSysBranchById(Long id); + + /** + * 查询部门树结构信息 + * + * @param branch 部门信息 + * @return 部门树信息集合 + */ + public List selectBranchTreeList(SysBranch branch); + + /** + * 构建前端所需要树结构 + * + * @param branchs 部门列表 + * @return 树结构列表 + */ + public List buildBranchTree(List branchs); + + /** + * 构建前端所需要下拉树结构 + * + * @param branchs 部门列表 + * @return 下拉树结构列表 + */ + public List buildBranchTreeSelect(List branchs); + + public SysBranch selectSysBranchByDeptId(Long parentId); + + List queryBranchTree(SysBranch space); + + /** + * 同步部门(锦江) + */ + void saveBranchTree(SysBranch space); + + /** + * 同步人员(锦江) + */ + void saveUserInfo(List data); + + /** + * 同步岗位(锦江) + */ + void saveStation(SysBranch space); + + + public int deleteSysBranchByBranchId(String id); + + public int updateSysBranchs(SysBranch sysBranch); + + public int insertSysBranchs(SysBranch sysBranch); + + /** + * 查询部门树 + */ + List queryDeptInfo(SysBranch paramVo); + + /** + * 查询物业子部门 + * @return + */ + List queryPropertyDept(String parentId); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysConfigService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysConfigService.java new file mode 100644 index 0000000..05eacf1 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysConfigService.java @@ -0,0 +1,93 @@ +package com.dcsoft.system.service; + +import java.util.List; +import com.dcsoft.system.domain.SysConfig; + +/** + * 参数配置 服务层 + * + * @author dcsoft + */ +public interface ISysConfigService +{ + /** + * 查询参数配置信息 + * + * @param configId 参数配置ID + * @return 参数配置信息 + */ + public SysConfig selectConfigById(Long configId); + + /** + * 根据键名查询参数配置信息 + * + * @param configKey 参数键名 + * @return 参数键值 + */ + public String selectConfigByKey(String configKey); + + /** + * 查询参数配置列表 + * + * @param config 参数配置信息 + * @return 参数配置集合 + */ + public List selectConfigList(SysConfig config); + + /** + * 新增参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + public int insertConfig(SysConfig config); + + /** + * 修改参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + public int updateConfig(SysConfig config); + + /** + * 批量删除参数信息 + * + * @param configIds 需要删除的参数ID + */ + public void deleteConfigByIds(Long[] configIds); + + /** + * 加载参数缓存数据 + */ + public void loadingConfigCache(); + + /** + * 清空参数缓存数据 + */ + public void clearConfigCache(); + + /** + * 重置参数缓存数据 + */ + public void resetConfigCache(); + + /** + * 校验参数键名是否唯一 + * + * @param config 参数信息 + * @return 结果 + */ + public boolean checkConfigKeyUnique(SysConfig config); + + + /** + * 备份数据库数据 + */ + public void backUp(); + + + public List listFile(); + + public boolean recover(String id); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysDeptService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysDeptService.java new file mode 100644 index 0000000..ae45eda --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysDeptService.java @@ -0,0 +1,126 @@ +package com.dcsoft.system.service; + +import java.util.List; +import com.dcsoft.system.api.domain.SysDept; +import com.dcsoft.system.domain.vo.TreeSelect; + +/** + * 部门管理 服务层 + * + * @author dcsoft + */ +public interface ISysDeptService +{ + /** + * 查询部门管理数据 + * + * @param dept 部门信息 + * @return 部门信息集合 + */ + public List selectDeptList(SysDept dept); + + /** + * 查询部门树结构信息 + * + * @param dept 部门信息 + * @return 部门树信息集合 + */ + public List selectDeptTreeList(SysDept dept); + + /** + * 构建前端所需要树结构 + * + * @param depts 部门列表 + * @return 树结构列表 + */ + public List buildDeptTree(List depts); + + /** + * 构建前端所需要下拉树结构 + * + * @param depts 部门列表 + * @return 下拉树结构列表 + */ + public List buildDeptTreeSelect(List depts); + + /** + * 根据角色ID查询部门树信息 + * + * @param roleId 角色ID + * @return 选中部门列表 + */ + public List selectDeptListByRoleId(Long roleId); + + /** + * 根据部门ID查询信息 + * + * @param deptId 部门ID + * @return 部门信息 + */ + public SysDept selectDeptById(Long deptId); + + /** + * 根据ID查询所有子部门(正常状态) + * + * @param deptId 部门ID + * @return 子部门数 + */ + public int selectNormalChildrenDeptById(Long deptId); + + /** + * 是否存在部门子节点 + * + * @param deptId 部门ID + * @return 结果 + */ + public boolean hasChildByDeptId(Long deptId); + + /** + * 查询部门是否存在用户 + * + * @param deptId 部门ID + * @return 结果 true 存在 false 不存在 + */ + public boolean checkDeptExistUser(Long deptId); + + /** + * 校验部门名称是否唯一 + * + * @param dept 部门信息 + * @return 结果 + */ + public boolean checkDeptNameUnique(SysDept dept); + + /** + * 校验部门是否有数据权限 + * + * @param deptId 部门id + */ + public void checkDeptDataScope(Long deptId); + + /** + * 新增保存部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + public int insertDept(SysDept dept); + + /** + * 修改保存部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + public int updateDept(SysDept dept); + + /** + * 删除部门管理信息 + * + * @param deptId 部门ID + * @return 结果 + */ + public int deleteDeptById(Long deptId); + + public SysDept findByParentExternalId(String parentExternalId); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysDictDataService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysDictDataService.java new file mode 100644 index 0000000..c1df40f --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysDictDataService.java @@ -0,0 +1,64 @@ +package com.dcsoft.system.service; + +import java.util.List; +import java.util.Map; + +import com.dcsoft.system.api.domain.SysDictData; + +/** + * 字典 业务层 + * + * @author dcsoft + */ +public interface ISysDictDataService +{ + /** + * 根据条件分页查询字典数据 + * + * @param dictData 字典数据信息 + * @return 字典数据集合信息 + */ + public List selectDictDataList(SysDictData dictData); + + /** + * 根据字典类型和字典键值查询字典数据信息 + * + * @param dictType 字典类型 + * @param dictValue 字典键值 + * @return 字典标签 + */ + public String selectDictLabel(String dictType, String dictValue); + + /** + * 根据字典数据ID查询信息 + * + * @param dictCode 字典数据ID + * @return 字典数据 + */ + public SysDictData selectDictDataById(Long dictCode); + + /** + * 批量删除字典数据信息 + * + * @param dictCodes 需要删除的字典数据ID + */ + public void deleteDictDataByIds(Long[] dictCodes); + + /** + * 新增保存字典数据信息 + * + * @param dictData 字典数据信息 + * @return 结果 + */ + public int insertDictData(SysDictData dictData); + + /** + * 修改保存字典数据信息 + * + * @param dictData 字典数据信息 + * @return 结果 + */ + public int updateDictData(SysDictData dictData); + + Map queryDictData(String dictType); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysDictTypeService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysDictTypeService.java new file mode 100644 index 0000000..a3eaf52 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysDictTypeService.java @@ -0,0 +1,98 @@ +package com.dcsoft.system.service; + +import java.util.List; +import com.dcsoft.system.api.domain.SysDictData; +import com.dcsoft.system.api.domain.SysDictType; + +/** + * 字典 业务层 + * + * @author dcsoft + */ +public interface ISysDictTypeService +{ + /** + * 根据条件分页查询字典类型 + * + * @param dictType 字典类型信息 + * @return 字典类型集合信息 + */ + public List selectDictTypeList(SysDictType dictType); + + /** + * 根据所有字典类型 + * + * @return 字典类型集合信息 + */ + public List selectDictTypeAll(); + + /** + * 根据字典类型查询字典数据 + * + * @param dictType 字典类型 + * @return 字典数据集合信息 + */ + public List selectDictDataByType(String dictType); + + /** + * 根据字典类型ID查询信息 + * + * @param dictId 字典类型ID + * @return 字典类型 + */ + public SysDictType selectDictTypeById(Long dictId); + + /** + * 根据字典类型查询信息 + * + * @param dictType 字典类型 + * @return 字典类型 + */ + public SysDictType selectDictTypeByType(String dictType); + + /** + * 批量删除字典信息 + * + * @param dictIds 需要删除的字典ID + */ + public void deleteDictTypeByIds(Long[] dictIds); + + /** + * 加载字典缓存数据 + */ + public void loadingDictCache(); + + /** + * 清空字典缓存数据 + */ + public void clearDictCache(); + + /** + * 重置字典缓存数据 + */ + public void resetDictCache(); + + /** + * 新增保存字典类型信息 + * + * @param dictType 字典类型信息 + * @return 结果 + */ + public int insertDictType(SysDictType dictType); + + /** + * 修改保存字典类型信息 + * + * @param dictType 字典类型信息 + * @return 结果 + */ + public int updateDictType(SysDictType dictType); + + /** + * 校验字典类型称是否唯一 + * + * @param dictType 字典类型 + * @return 结果 + */ + public boolean checkDictTypeUnique(SysDictType dictType); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysEmpowerRecordService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysEmpowerRecordService.java new file mode 100644 index 0000000..b133a18 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysEmpowerRecordService.java @@ -0,0 +1,63 @@ +package com.dcsoft.system.service; + +import java.util.List; +import com.dcsoft.system.domain.SysEmpowerRecord; + +/** + * 授权记录Service接口 + * + * @author nichun + * @date 2023-03-08 + */ +public interface ISysEmpowerRecordService +{ + /** + * 查询授权记录 + * + * @param id 授权记录主键 + * @return 授权记录 + */ + public SysEmpowerRecord selectSysEmpowerRecordById(Long id); + + /** + * 查询授权记录列表 + * + * @param sysEmpowerRecord 授权记录 + * @return 授权记录集合 + */ + public List selectSysEmpowerRecordList(SysEmpowerRecord sysEmpowerRecord); + + /** + * 新增授权记录 + * + * @param sysEmpowerRecord 授权记录 + * @return 结果 + */ + public int insertSysEmpowerRecord(SysEmpowerRecord sysEmpowerRecord); + + /** + * 修改授权记录 + * + * @param sysEmpowerRecord 授权记录 + * @return 结果 + */ + public int updateSysEmpowerRecord(SysEmpowerRecord sysEmpowerRecord); + + /** + * 批量删除授权记录 + * + * @param ids 需要删除的授权记录主键集合 + * @return 结果 + */ + public int deleteSysEmpowerRecordByIds(Long[] ids); + + /** + * 删除授权记录信息 + * + * @param id 授权记录主键 + * @return 结果 + */ + public int deleteSysEmpowerRecordById(Long id); + + public int deleteSysEmpowerRecordByPeopleId(Long peopleId); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysEquipmentService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysEquipmentService.java new file mode 100644 index 0000000..8b4d5bd --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysEquipmentService.java @@ -0,0 +1,126 @@ +package com.dcsoft.system.service; + +import java.util.List; +import java.util.Map; + +import com.dcsoft.system.domain.SysEmpowerRecord; +import com.dcsoft.system.domain.SysEquipment; +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.uniubi.domain.EwmInfo; +import com.dcsoft.system.uniubi.domain.LadderControlVo; + +/** + * 设备信息Service接口 + * + * @author nichun + * @date 2023-03-08 + */ +public interface ISysEquipmentService +{ + /** + * 查询设备信息 + * + * @param id 设备信息主键 + * @return 设备信息 + */ + public SysEquipment selectSysEquipmentById(Long id); + + /** + * 查询设备信息列表 + * + * @param sysEquipment 设备信息 + * @return 设备信息集合 + */ + public List selectSysEquipmentList(SysEquipment sysEquipment); + + /** + * 新增设备信息 + * + * @param sysEquipment 设备信息 + * @return 结果 + */ + public int insertSysEquipment(SysEquipment sysEquipment); + + /** + * 修改设备信息 + * + * @param sysEquipment 设备信息 + * @return 结果 + */ + public int updateSysEquipment(SysEquipment sysEquipment); + + /** + * 批量删除设备信息 + * + * @param ids 需要删除的设备信息主键集合 + * @return 结果 + */ + public int deleteSysEquipmentByIds(Long[] ids); + + /** + * 删除设备信息信息 + * + * @param id 设备信息主键 + * @return 结果 + */ + public int deleteSysEquipmentById(Long id); + + SysEquipment selectEquipmentBySequence(String deviceNo); + + /** + * 查询设备信息 + */ + List queryEquipmentInfo(List pointIds); + + /** + * 查询人员信息 + */ + SysPeople queryPeopleInfo(SysPeople people); + + List> selectSysEquipmentPeopleById(Long id); + + /** + * 根据设备序列号查询产品类型 + * @param deviceKey + * @return + */ + String queryDeviceSequence(String deviceKey); + + + /** + * 查询授权记录规则id + * @param people + * @return + */ + List queryEmpowerRecord(SysPeople people); + + /** + * 查询人员信息 + * @param sysPeople + * @return + */ + SysPeople queryPeople(SysPeople sysPeople); + + SysEquipment queryEmpower(String sequence); + + /** + * 根据设备序列好查询设备信息 + * @param sysEquipment + * @return + */ + SysEquipment queryEquipmentByDeviceKey(SysEquipment sysEquipment); + + /** + * 根据设备序列号修改设备密码 + * @param sysEquipment + */ + void updateEquipmentByDeviceKey(SysEquipment sysEquipment); + + void saveFile(SysEquipment sysEquipment); + + /** + * 根据设备序列号修改设备轮播文件 + * @param sysEquipment + */ + void updateEquipmentFile(SysEquipment sysEquipment); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysLogininforService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysLogininforService.java new file mode 100644 index 0000000..3562982 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysLogininforService.java @@ -0,0 +1,40 @@ +package com.dcsoft.system.service; + +import java.util.List; +import com.dcsoft.system.api.domain.SysLogininfor; + +/** + * 系统访问日志情况信息 服务层 + * + * @author dcsoft + */ +public interface ISysLogininforService +{ + /** + * 新增系统登录日志 + * + * @param logininfor 访问日志对象 + */ + public int insertLogininfor(SysLogininfor logininfor); + + /** + * 查询系统登录日志集合 + * + * @param logininfor 访问日志对象 + * @return 登录记录集合 + */ + public List selectLogininforList(SysLogininfor logininfor); + + /** + * 批量删除系统登录日志 + * + * @param infoIds 需要删除的登录日志ID + * @return 结果 + */ + public int deleteLogininforByIds(Long[] infoIds); + + /** + * 清空系统登录日志 + */ + public void cleanLogininfor(); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysManageRecordService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysManageRecordService.java new file mode 100644 index 0000000..b17a93b --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysManageRecordService.java @@ -0,0 +1,61 @@ +package com.dcsoft.system.service; + +import java.util.List; +import com.dcsoft.system.domain.SysManageRecord; + +/** + * 授权管理记录Service接口 + * + * @author dcsoft + * @date 2023-03-08 + */ +public interface ISysManageRecordService +{ + /** + * 查询授权管理记录 + * + * @param id 授权管理记录主键 + * @return 授权管理记录 + */ + public SysManageRecord selectSysManageRecordById(Long id); + + /** + * 查询授权管理记录列表 + * + * @param sysManageRecord 授权管理记录 + * @return 授权管理记录集合 + */ + public List selectSysManageRecordList(SysManageRecord sysManageRecord); + + /** + * 新增授权管理记录 + * + * @param sysManageRecord 授权管理记录 + * @return 结果 + */ + public int insertSysManageRecord(SysManageRecord sysManageRecord); + + /** + * 修改授权管理记录 + * + * @param sysManageRecord 授权管理记录 + * @return 结果 + */ + public int updateSysManageRecord(SysManageRecord sysManageRecord); + + /** + * 批量删除授权管理记录 + * + * @param ids 需要删除的授权管理记录主键集合 + * @return 结果 + */ + public int deleteSysManageRecordByIds(Long[] ids); + + /** + * 删除授权管理记录信息 + * + * @param id 授权管理记录主键 + * @return 结果 + */ + public int deleteSysManageRecordById(Long id); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysMenuService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysMenuService.java new file mode 100644 index 0000000..2e5a915 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysMenuService.java @@ -0,0 +1,144 @@ +package com.dcsoft.system.service; + +import java.util.List; +import java.util.Set; +import com.dcsoft.system.domain.SysMenu; +import com.dcsoft.system.domain.vo.RouterVo; +import com.dcsoft.system.domain.vo.TreeSelect; + +/** + * 菜单 业务层 + * + * @author dcsoft + */ +public interface ISysMenuService +{ + /** + * 根据用户查询系统菜单列表 + * + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuList(Long userId); + + /** + * 根据用户查询系统菜单列表 + * + * @param menu 菜单信息 + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuList(SysMenu menu, Long userId); + + /** + * 根据用户ID查询权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + public Set selectMenuPermsByUserId(Long userId); + + /** + * 根据角色ID查询权限 + * + * @param roleId 角色ID + * @return 权限列表 + */ + public Set selectMenuPermsByRoleId(Long roleId); + + /** + * 根据用户ID查询菜单树信息 + * + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuTreeByUserId(Long userId); + + /** + * 根据角色ID查询菜单树信息 + * + * @param roleId 角色ID + * @return 选中菜单列表 + */ + public List selectMenuListByRoleId(Long roleId); + + /** + * 构建前端路由所需要的菜单 + * + * @param menus 菜单列表 + * @return 路由列表 + */ + public List buildMenus(List menus); + + /** + * 构建前端所需要树结构 + * + * @param menus 菜单列表 + * @return 树结构列表 + */ + public List buildMenuTree(List menus); + + /** + * 构建前端所需要下拉树结构 + * + * @param menus 菜单列表 + * @return 下拉树结构列表 + */ + public List buildMenuTreeSelect(List menus); + + /** + * 根据菜单ID查询信息 + * + * @param menuId 菜单ID + * @return 菜单信息 + */ + public SysMenu selectMenuById(Long menuId); + + /** + * 是否存在菜单子节点 + * + * @param menuId 菜单ID + * @return 结果 true 存在 false 不存在 + */ + public boolean hasChildByMenuId(Long menuId); + + /** + * 查询菜单是否存在角色 + * + * @param menuId 菜单ID + * @return 结果 true 存在 false 不存在 + */ + public boolean checkMenuExistRole(Long menuId); + + /** + * 新增保存菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + public int insertMenu(SysMenu menu); + + /** + * 修改保存菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + public int updateMenu(SysMenu menu); + + /** + * 删除菜单管理信息 + * + * @param menuId 菜单ID + * @return 结果 + */ + public int deleteMenuById(Long menuId); + + /** + * 校验菜单名称是否唯一 + * + * @param menu 菜单信息 + * @return 结果 + */ + public boolean checkMenuNameUnique(SysMenu menu); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysNoticeService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysNoticeService.java new file mode 100644 index 0000000..8629208 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysNoticeService.java @@ -0,0 +1,60 @@ +package com.dcsoft.system.service; + +import java.util.List; +import com.dcsoft.system.domain.SysNotice; + +/** + * 公告 服务层 + * + * @author dcsoft + */ +public interface ISysNoticeService +{ + /** + * 查询公告信息 + * + * @param noticeId 公告ID + * @return 公告信息 + */ + public SysNotice selectNoticeById(Long noticeId); + + /** + * 查询公告列表 + * + * @param notice 公告信息 + * @return 公告集合 + */ + public List selectNoticeList(SysNotice notice); + + /** + * 新增公告 + * + * @param notice 公告信息 + * @return 结果 + */ + public int insertNotice(SysNotice notice); + + /** + * 修改公告 + * + * @param notice 公告信息 + * @return 结果 + */ + public int updateNotice(SysNotice notice); + + /** + * 删除公告信息 + * + * @param noticeId 公告ID + * @return 结果 + */ + public int deleteNoticeById(Long noticeId); + + /** + * 批量删除公告信息 + * + * @param noticeIds 需要删除的公告ID + * @return 结果 + */ + public int deleteNoticeByIds(Long[] noticeIds); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysOperLogService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysOperLogService.java new file mode 100644 index 0000000..cd13ede --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysOperLogService.java @@ -0,0 +1,49 @@ +package com.dcsoft.system.service; + +import java.util.List; +import com.dcsoft.system.api.domain.SysOperLog; + +/** + * 操作日志 服务层 + * + * @author dcsoft + */ +public interface ISysOperLogService +{ + /** + * 新增操作日志 + * + * @param operLog 操作日志对象 + * @return 结果 + */ + public int insertOperlog(SysOperLog operLog); + + /** + * 查询系统操作日志集合 + * + * @param operLog 操作日志对象 + * @return 操作日志集合 + */ + public List selectOperLogList(SysOperLog operLog); + + /** + * 批量删除系统操作日志 + * + * @param operIds 需要删除的操作日志ID + * @return 结果 + */ + public int deleteOperLogByIds(Long[] operIds); + + /** + * 查询操作日志详细 + * + * @param operId 操作ID + * @return 操作日志对象 + */ + public SysOperLog selectOperLogById(Long operId); + + /** + * 清空操作日志 + */ + public void cleanOperLog(); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPeopleEquipmentService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPeopleEquipmentService.java new file mode 100644 index 0000000..64c6af3 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPeopleEquipmentService.java @@ -0,0 +1,81 @@ +package com.dcsoft.system.service; + +import java.util.List; +import com.dcsoft.system.domain.SysPeopleEquipment; + +/** + * 人员设备下发信息Service接口 + * + * @author dcsoft + * @date 2023-06-12 + */ +public interface ISysPeopleEquipmentService +{ + /** + * 查询人员设备下发信息 + * + * @param id 人员设备下发信息主键 + * @return 人员设备下发信息 + */ + public SysPeopleEquipment selectSysPeopleEquipmentById(Long id); + + /** + * 查询人员设备下发信息列表 + * + * @param sysPeopleEquipment 人员设备下发信息 + * @return 人员设备下发信息集合 + */ + public List selectSysPeopleEquipmentList(SysPeopleEquipment sysPeopleEquipment); + + /** + * 新增人员设备下发信息 + * + * @param sysPeopleEquipment 人员设备下发信息 + * @return 结果 + */ + public int insertSysPeopleEquipment(SysPeopleEquipment sysPeopleEquipment); + + /** + * 修改人员设备下发信息 + * + * @param sysPeopleEquipment 人员设备下发信息 + * @return 结果 + */ + public int updateSysPeopleEquipment(SysPeopleEquipment sysPeopleEquipment); + + /** + * 批量删除人员设备下发信息 + * + * @param ids 需要删除的人员设备下发信息主键集合 + * @return 结果 + */ + public int deleteSysPeopleEquipmentByIds(Long[] ids); + + /** + * 删除人员设备下发信息信息 + * + * @param id 人员设备下发信息主键 + * @return 结果 + */ + public int deleteSysPeopleEquipmentById(Long id); + + /** + * 查询人员设备下发信息 + * + * @param id 人员设备下发信息主键 + * @return 人员设备下发信息 + */ + public SysPeopleEquipment selectSysPeopleEquipmentByGuId(String guId); + + /** + * 查询人员设备下发信息 + * + * @param id 人员设备下发信息主键 + * @return 人员设备下发信息 + */ + public List selectSysPeopleEquipmentByPeopleId(String peopleId); + + public List selectSysPeopleEquipmentByVisitorId(Long visitorId); + + public int deleteSysPeopleEquipmentByOtherId(Long otherId); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPeopleLeaveService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPeopleLeaveService.java new file mode 100644 index 0000000..56da95f --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPeopleLeaveService.java @@ -0,0 +1,70 @@ +package com.dcsoft.system.service; + +import java.util.List; +import com.dcsoft.system.domain.SysPeopleLeave; + +/** + * 离职管理Service接口 + * + * @author nichun + * @date 2023-09-09 + */ +public interface ISysPeopleLeaveService +{ + /** + * 查询离职管理 + * + * @param id 离职管理主键 + * @return 离职管理 + */ + public SysPeopleLeave selectSysPeopleLeaveById(Long id); + + /** + * 查询离职管理列表 + * + * @param sysPeopleLeave 离职管理 + * @return 离职管理集合 + */ + public List selectSysPeopleLeaveList(SysPeopleLeave sysPeopleLeave); + + /** + * 新增离职管理 + * + * @param sysPeopleLeave 离职管理 + * @return 结果 + */ + public int insertSysPeopleLeave(SysPeopleLeave sysPeopleLeave); + + /** + * 修改离职管理 + * + * @param sysPeopleLeave 离职管理 + * @return 结果 + */ + public int updateSysPeopleLeave(SysPeopleLeave sysPeopleLeave); + + /** + * 批量删除离职管理 + * + * @param ids 需要删除的离职管理主键集合 + * @return 结果 + */ + public int deleteSysPeopleLeaveByIds(Long[] ids); + + /** + * 删除离职管理信息 + * + * @param id 离职管理主键 + * @return 结果 + */ + public int deleteSysPeopleLeaveById(Long id); + + /** + * 离职人员导入 + * @param userList + * @param updateSupport + * @param operName + * @return + */ + String importPeople(List userList, boolean updateSupport, String operName); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPeopleOtherService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPeopleOtherService.java new file mode 100644 index 0000000..ba66189 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPeopleOtherService.java @@ -0,0 +1,107 @@ +package com.dcsoft.system.service; + + +import com.dcsoft.system.domain.SysPeopleOther; + +import java.util.List; + +/** + * 人员管理Service接口 + * + * @author nichun + * @date 2023-03-08 + */ +public interface ISysPeopleOtherService +{ + /** + * 查询人员管理 + * + * @param id 人员管理主键 + * @return 人员管理 + */ + public SysPeopleOther selectSysPeopleOtherById(Long id); + + /** + * 查询人员管理列表 + * + * @param sysPeople 人员管理 + * @return 人员管理集合 + */ + public List selectSysPeopleOtherList(SysPeopleOther sysPeople); + + public List selectSysPeopleOtherLists(SysPeopleOther sysPeople); + + /** + * 新增人员管理 + * + * @param sysPeople 人员管理 + * @return 结果 + */ + public int insertSysPeopleOther(SysPeopleOther sysPeople); + + /** + * 修改人员管理 + * + * @param sysPeople 人员管理 + * @return 结果 + */ + public int updateSysPeopleOther(SysPeopleOther sysPeople); + + /** + * 批量删除人员管理 + * + * @param ids 需要删除的人员管理主键集合 + * @return 结果 + */ + public int deleteSysPeopleOtherByIds(Long[] ids); + + /** + * 删除人员管理信息 + * + * @param id 人员管理主键 + * @return 结果 + */ + public int deleteSysPeopleOtherById(Long id); + + SysPeopleOther selectByGuid(SysPeopleOther sysPeople); + + SysPeopleOther selectSysPeopleByUserId(Long userId); + + SysPeopleOther selectSysPeopleByBranchUser(String branchName, String userName); + + public String importPeople(List userList, boolean updateSupport, String operName); + + + + SysPeopleOther selectSysPeopleByPhoneUser(SysPeopleOther people); + + List queryPeopleInfo(); + + List queryPeople(List collectStr); + + SysPeopleOther queryPeopleDetails(String details); + + public int updateSysPeoples(SysPeopleOther sysPeople); + + public int insertSysPeoples(SysPeopleOther sysPeople); + + public int deleteSysPeopleOtherByGuid(String guid); + + void updatePeople(SysPeopleOther people); + + String selectDoorNo(Long id); + + String selectPeopleById(String card); + + void updatePeopleInfo(SysPeopleOther sysPeople); + + SysPeopleOther queryPeopleById(String id); + + SysPeopleOther selectSysPeopleByOpenId(String openid); + + SysPeopleOther selectSysPeopleByGh(String phone, String name); + + SysPeopleOther queryPeopleName(String phone); + + List queryPeopleList(SysPeopleOther sysPeople); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPeopleRecordService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPeopleRecordService.java new file mode 100644 index 0000000..adf2d6f --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPeopleRecordService.java @@ -0,0 +1,82 @@ +package com.dcsoft.system.service; + +import java.util.List; + +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.system.domain.SysPeopleRecord; + +/** + * 人员识别记录Service接口 + * + * @author nichun + * @date 2023-03-08 + */ +public interface ISysPeopleRecordService +{ + /** + * 查询人员识别记录 + * + * @param id 人员识别记录主键 + * @return 人员识别记录 + */ + public SysPeopleRecord selectSysPeopleRecordById(Long id); + + /** + * 查询人员识别记录列表 + * + * @param sysPeopleRecord 人员识别记录 + * @return 人员识别记录集合 + */ + public List selectSysPeopleRecordList(SysPeopleRecord sysPeopleRecord); + + /** + * 查询人员识别记录列表 + * + * @param sysPeopleRecord 人员识别记录 + * @return 人员识别记录集合 + */ + public List selectSysPeopleRecordLists(SysPeopleRecord sysPeopleRecord); + + + /** + * 新增人员识别记录 + * + * @param sysPeopleRecord 人员识别记录 + * @return 结果 + */ + public int insertSysPeopleRecord(SysPeopleRecord sysPeopleRecord); + + /** + * 修改人员识别记录 + * + * @param sysPeopleRecord 人员识别记录 + * @return 结果 + */ + public int updateSysPeopleRecord(SysPeopleRecord sysPeopleRecord); + + /** + * 批量删除人员识别记录 + * + * @param ids 需要删除的人员识别记录主键集合 + * @return 结果 + */ + public int deleteSysPeopleRecordByIds(Long[] ids); + + /** + * 删除人员识别记录信息 + * + * @param id 人员识别记录主键 + * @return 结果 + */ + public int deleteSysPeopleRecordById(Long id); + + AjaxResult topApi(); + + String selectPeopleRecordById(String deviceKey); + + /** + * 查询通行统计数量(昨天,今天) + * @return + */ + List queryThroughCount(); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPeopleRuleService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPeopleRuleService.java new file mode 100644 index 0000000..dc13189 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPeopleRuleService.java @@ -0,0 +1,61 @@ +package com.dcsoft.system.service; + +import java.util.List; +import com.dcsoft.system.domain.SysPeopleRule; + +/** + * 人员规则关联Service接口 + * + * @author dcsoft + * @date 2023-12-22 + */ +public interface ISysPeopleRuleService +{ + /** + * 查询人员规则关联 + * + * @param id 人员规则关联主键 + * @return 人员规则关联 + */ + public SysPeopleRule selectSysPeopleRuleById(Long id); + + /** + * 查询人员规则关联列表 + * + * @param sysPeopleRule 人员规则关联 + * @return 人员规则关联集合 + */ + public List selectSysPeopleRuleList(SysPeopleRule sysPeopleRule); + + /** + * 新增人员规则关联 + * + * @param sysPeopleRule 人员规则关联 + * @return 结果 + */ + public int insertSysPeopleRule(SysPeopleRule sysPeopleRule); + + /** + * 修改人员规则关联 + * + * @param sysPeopleRule 人员规则关联 + * @return 结果 + */ + public int updateSysPeopleRule(SysPeopleRule sysPeopleRule); + + /** + * 批量删除人员规则关联 + * + * @param ids 需要删除的人员规则关联主键集合 + * @return 结果 + */ + public int deleteSysPeopleRuleByIds(Long[] ids); + + /** + * 删除人员规则关联信息 + * + * @param id 人员规则关联主键 + * @return 结果 + */ + public int deleteSysPeopleRuleById(Long id); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPeopleService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPeopleService.java new file mode 100644 index 0000000..bb0449d --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPeopleService.java @@ -0,0 +1,116 @@ +package com.dcsoft.system.service; + +import java.util.List; +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.domain.vo.OfficialAccountVo; + +/** + * 人员管理Service接口 + * + * @author nichun + * @date 2023-03-08 + */ +public interface ISysPeopleService +{ + /** + * 查询人员管理 + * + * @param id 人员管理主键 + * @return 人员管理 + */ + public SysPeople selectSysPeopleById(Long id); + + /** + * 查询人员管理列表 + * + * @param sysPeople 人员管理 + * @return 人员管理集合 + */ + public List selectSysPeopleList(SysPeople sysPeople); + + public List selectSysPeopleLists(SysPeople sysPeople); + + /** + * 新增人员管理 + * + * @param sysPeople 人员管理 + * @return 结果 + */ + public int insertSysPeople(SysPeople sysPeople); + + /** + * 修改人员管理 + * + * @param sysPeople 人员管理 + * @return 结果 + */ + public int updateSysPeople(SysPeople sysPeople); + + /** + * 批量删除人员管理 + * + * @param ids 需要删除的人员管理主键集合 + * @return 结果 + */ + public int deleteSysPeopleByIds(Long[] ids); + + /** + * 删除人员管理信息 + * + * @param id 人员管理主键 + * @return 结果 + */ + public int deleteSysPeopleById(Long id); + + SysPeople selectByGuid(SysPeople sysPeople); + + SysPeople selectSysPeopleByUserId(Long userId); + + SysPeople selectSysPeopleByBranchUser(String branchName, String userName); + + public String importPeople(List userList, boolean updateSupport, String operName); + + SysPeople selectSysPeopleByPhoneUser(SysPeople people); + + List queryPeopleInfo(); + + List queryPeople(List collectStr); + + SysPeople queryPeopleDetails(String details); + + public int updateSysPeoples(SysPeople sysPeople); + + public int insertSysPeoples(SysPeople sysPeople); + + public int deleteSysPeopleByGuid(String guid); + + void updatePeople(SysPeople people); + + String selectDoorNo(Long id); + + String selectPeopleById(String card); + + void updatePeopleInfo(SysPeople sysPeople); + + OfficialAccountVo queryPeopleById(String id); + + SysPeople selectSysPeopleByOpenId(String openid); + + SysPeople selectSysPeopleByGh(String phone, String name); + + SysPeople queryPeopleName(String phone, List collect); + + List queryPeopleList(SysPeople sysPeople); + + SysPeople selectSysPeopleByGh(String gh); + + SysPeople selectSysPeopleByDoorNo(String doorNo); + + SysPeople queryEmpowerRecord(String phone); + + SysPeople queryPeopleByOpenid(String openid); + + List queryPeopleByPosition(String position); + + List querySysPeopleInfo(Long userId); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPermissionService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPermissionService.java new file mode 100644 index 0000000..719ea5e --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPermissionService.java @@ -0,0 +1,29 @@ +package com.dcsoft.system.service; + +import java.util.Set; + +import com.dcsoft.system.api.domain.SysUser; + +/** + * 权限信息 服务层 + * + * @author dcsoft + */ +public interface ISysPermissionService +{ + /** + * 获取角色数据权限 + * + * @param userId 用户Id + * @return 角色权限信息 + */ + public Set getRolePermission(SysUser user); + + /** + * 获取菜单数据权限 + * + * @param userId 用户Id + * @return 菜单权限信息 + */ + public Set getMenuPermission(SysUser user); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPointService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPointService.java new file mode 100644 index 0000000..8aaecc9 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPointService.java @@ -0,0 +1,61 @@ +package com.dcsoft.system.service; + +import java.util.List; +import com.dcsoft.system.domain.SysPoint; + +/** + * 点位管理Service接口 + * + * @author nichun + * @date 2023-03-08 + */ +public interface ISysPointService +{ + /** + * 查询点位管理 + * + * @param id 点位管理主键 + * @return 点位管理 + */ + public SysPoint selectSysPointById(Long id); + + /** + * 查询点位管理列表 + * + * @param sysPoint 点位管理 + * @return 点位管理集合 + */ + public List selectSysPointList(SysPoint sysPoint); + + /** + * 新增点位管理 + * + * @param sysPoint 点位管理 + * @return 结果 + */ + public int insertSysPoint(SysPoint sysPoint); + + /** + * 修改点位管理 + * + * @param sysPoint 点位管理 + * @return 结果 + */ + public int updateSysPoint(SysPoint sysPoint); + + /** + * 批量删除点位管理 + * + * @param ids 需要删除的点位管理主键集合 + * @return 结果 + */ + public int deleteSysPointByIds(Long[] ids); + + /** + * 删除点位管理信息 + * + * @param id 点位管理主键 + * @return 结果 + */ + public int deleteSysPointById(Long id); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPostService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPostService.java new file mode 100644 index 0000000..7a26da3 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysPostService.java @@ -0,0 +1,99 @@ +package com.dcsoft.system.service; + +import java.util.List; +import com.dcsoft.system.domain.SysPost; + +/** + * 岗位信息 服务层 + * + * @author dcsoft + */ +public interface ISysPostService +{ + /** + * 查询岗位信息集合 + * + * @param post 岗位信息 + * @return 岗位列表 + */ + public List selectPostList(SysPost post); + + /** + * 查询所有岗位 + * + * @return 岗位列表 + */ + public List selectPostAll(); + + /** + * 通过岗位ID查询岗位信息 + * + * @param postId 岗位ID + * @return 角色对象信息 + */ + public SysPost selectPostById(Long postId); + + /** + * 根据用户ID获取岗位选择框列表 + * + * @param userId 用户ID + * @return 选中岗位ID列表 + */ + public List selectPostListByUserId(Long userId); + + /** + * 校验岗位名称 + * + * @param post 岗位信息 + * @return 结果 + */ + public boolean checkPostNameUnique(SysPost post); + + /** + * 校验岗位编码 + * + * @param post 岗位信息 + * @return 结果 + */ + public boolean checkPostCodeUnique(SysPost post); + + /** + * 通过岗位ID查询岗位使用数量 + * + * @param postId 岗位ID + * @return 结果 + */ + public int countUserPostById(Long postId); + + /** + * 删除岗位信息 + * + * @param postId 岗位ID + * @return 结果 + */ + public int deletePostById(Long postId); + + /** + * 批量删除岗位信息 + * + * @param postIds 需要删除的岗位ID + * @return 结果 + */ + public int deletePostByIds(Long[] postIds); + + /** + * 新增保存岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + public int insertPost(SysPost post); + + /** + * 修改保存岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + public int updatePost(SysPost post); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysProductService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysProductService.java new file mode 100644 index 0000000..94d8437 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysProductService.java @@ -0,0 +1,61 @@ +package com.dcsoft.system.service; + +import java.util.List; +import com.dcsoft.system.domain.SysProduct; + +/** + * 产品信息Service接口 + * + * @author nichun + * @date 2023-03-08 + */ +public interface ISysProductService +{ + /** + * 查询产品信息 + * + * @param id 产品信息主键 + * @return 产品信息 + */ + public SysProduct selectSysProductById(Long id); + + /** + * 查询产品信息列表 + * + * @param sysProduct 产品信息 + * @return 产品信息集合 + */ + public List selectSysProductList(SysProduct sysProduct); + + /** + * 新增产品信息 + * + * @param sysProduct 产品信息 + * @return 结果 + */ + public int insertSysProduct(SysProduct sysProduct); + + /** + * 修改产品信息 + * + * @param sysProduct 产品信息 + * @return 结果 + */ + public int updateSysProduct(SysProduct sysProduct); + + /** + * 批量删除产品信息 + * + * @param ids 需要删除的产品信息主键集合 + * @return 结果 + */ + public int deleteSysProductByIds(Long[] ids); + + /** + * 删除产品信息信息 + * + * @param id 产品信息主键 + * @return 结果 + */ + public int deleteSysProductById(Long id); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysRoleService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysRoleService.java new file mode 100644 index 0000000..36f716d --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysRoleService.java @@ -0,0 +1,173 @@ +package com.dcsoft.system.service; + +import java.util.List; +import java.util.Set; +import com.dcsoft.system.api.domain.SysRole; +import com.dcsoft.system.domain.SysUserRole; + +/** + * 角色业务层 + * + * @author dcsoft + */ +public interface ISysRoleService +{ + /** + * 根据条件分页查询角色数据 + * + * @param role 角色信息 + * @return 角色数据集合信息 + */ + public List selectRoleList(SysRole role); + + /** + * 根据用户ID查询角色列表 + * + * @param userId 用户ID + * @return 角色列表 + */ + public List selectRolesByUserId(Long userId); + + /** + * 根据用户ID查询角色权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + public Set selectRolePermissionByUserId(Long userId); + + /** + * 查询所有角色 + * + * @return 角色列表 + */ + public List selectRoleAll(); + + /** + * 根据用户ID获取角色选择框列表 + * + * @param userId 用户ID + * @return 选中角色ID列表 + */ + public List selectRoleListByUserId(Long userId); + + /** + * 通过角色ID查询角色 + * + * @param roleId 角色ID + * @return 角色对象信息 + */ + public SysRole selectRoleById(Long roleId); + + /** + * 校验角色名称是否唯一 + * + * @param role 角色信息 + * @return 结果 + */ + public boolean checkRoleNameUnique(SysRole role); + + /** + * 校验角色权限是否唯一 + * + * @param role 角色信息 + * @return 结果 + */ + public boolean checkRoleKeyUnique(SysRole role); + + /** + * 校验角色是否允许操作 + * + * @param role 角色信息 + */ + public void checkRoleAllowed(SysRole role); + + /** + * 校验角色是否有数据权限 + * + * @param roleId 角色id + */ + public void checkRoleDataScope(Long roleId); + + /** + * 通过角色ID查询角色使用数量 + * + * @param roleId 角色ID + * @return 结果 + */ + public int countUserRoleByRoleId(Long roleId); + + /** + * 新增保存角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + public int insertRole(SysRole role); + + /** + * 修改保存角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + public int updateRole(SysRole role); + + /** + * 修改角色状态 + * + * @param role 角色信息 + * @return 结果 + */ + public int updateRoleStatus(SysRole role); + + /** + * 修改数据权限信息 + * + * @param role 角色信息 + * @return 结果 + */ + public int authDataScope(SysRole role); + + /** + * 通过角色ID删除角色 + * + * @param roleId 角色ID + * @return 结果 + */ + public int deleteRoleById(Long roleId); + + /** + * 批量删除角色信息 + * + * @param roleIds 需要删除的角色ID + * @return 结果 + */ + public int deleteRoleByIds(Long[] roleIds); + + /** + * 取消授权用户角色 + * + * @param userRole 用户和角色关联信息 + * @return 结果 + */ + public int deleteAuthUser(SysUserRole userRole); + + /** + * 批量取消授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要取消授权的用户数据ID + * @return 结果 + */ + public int deleteAuthUsers(Long roleId, Long[] userIds); + + /** + * 批量选择授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要删除的用户数据ID + * @return 结果 + */ + public int insertAuthUsers(Long roleId, Long[] userIds); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysRuleService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysRuleService.java new file mode 100644 index 0000000..d9e8b11 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysRuleService.java @@ -0,0 +1,67 @@ +package com.dcsoft.system.service; + +import java.util.List; +import com.dcsoft.system.domain.SysRule; +import com.dcsoft.system.domain.vo.SysAuthTree; +import com.dcsoft.system.domain.vo.TreeSelect; + +/** + * 通行规则Service接口 + * + * @author nichun + * @date 2023-03-08 + */ +public interface ISysRuleService +{ + /** + * 查询通行规则 + * + * @param id 通行规则主键 + * @return 通行规则 + */ + public SysRule selectSysRuleById(Long id); + + /** + * 查询通行规则列表 + * + * @param sysRule 通行规则 + * @return 通行规则集合 + */ + public List selectSysRuleList(SysRule sysRule); + + /** + * 新增通行规则 + * + * @param sysRule 通行规则 + * @return 结果 + */ + public int insertSysRule(SysRule sysRule); + + /** + * 修改通行规则 + * + * @param sysRule 通行规则 + * @return 结果 + */ + public int updateSysRule(SysRule sysRule); + + /** + * 批量删除通行规则 + * + * @param ids 需要删除的通行规则主键集合 + * @return 结果 + */ + public int deleteSysRuleByIds(Long[] ids); + + /** + * 删除通行规则信息 + * + * @param id 通行规则主键 + * @return 结果 + */ + public int deleteSysRuleById(Long id); + + List selectRuleAuthScope(); + + List queryRuleAuth(); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysSpaceService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysSpaceService.java new file mode 100644 index 0000000..81dc635 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysSpaceService.java @@ -0,0 +1,81 @@ +package com.dcsoft.system.service; + +import java.util.List; + +import com.dcsoft.system.domain.SysSpace; +import com.dcsoft.system.domain.vo.TreeSelect; + +/** + * 空间管理Service接口 + * + * @author nichun + * @date 2023-03-08 + */ +public interface ISysSpaceService +{ + /** + * 查询空间管理 + * + * @param id 空间管理主键 + * @return 空间管理 + */ + public SysSpace selectSysSpaceById(Long id); + + /** + * 查询空间管理列表 + * + * @param sysSpace 空间管理 + * @return 空间管理集合 + */ + public List selectSysSpaceList(SysSpace sysSpace); + + /** + * 新增空间管理 + * + * @param sysSpace 空间管理 + * @return 结果 + */ + public int insertSysSpace(SysSpace sysSpace); + + /** + * 修改空间管理 + * + * @param sysSpace 空间管理 + * @return 结果 + */ + public int updateSysSpace(SysSpace sysSpace); + + /** + * 批量删除空间管理 + * + * @param ids 需要删除的空间管理主键集合 + * @return 结果 + */ + public int deleteSysSpaceByIds(Long[] ids); + + /** + * 删除空间管理信息 + * + * @param id 空间管理主键 + * @return 结果 + */ + public int deleteSysSpaceById(Long id); + + public List selectSpaceTreeList(SysSpace space); + + /** + * 构建前端所需要树结构 + * + * @param spaces 部门列表 + * @return 树结构列表 + */ + public List buildSpaceTree(List spaces); + + /** + * 构建前端所需要下拉树结构 + * + * @param spaces 部门列表 + * @return 下拉树结构列表 + */ + public List buildSpaceTreeSelect(List spaces); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysSyncRuleService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysSyncRuleService.java new file mode 100644 index 0000000..49faf84 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysSyncRuleService.java @@ -0,0 +1,82 @@ +package com.dcsoft.system.service; + +import java.util.List; + +import com.dcsoft.system.domain.SysBranch; +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.domain.SysSyncItem; +import com.dcsoft.system.domain.SysSyncRule; + +/** + * 同步规则Service接口 + * + * @author nichun + * @date 2024-01-11 + */ +public interface ISysSyncRuleService +{ + /** + * 查询同步规则 + * + * @param id 同步规则主键 + * @return 同步规则 + */ + public SysSyncRule selectSysSyncRuleById(Long id); + + /** + * 查询同步规则列表 + * + * @param sysSyncRule 同步规则 + * @return 同步规则集合 + */ + public List selectSysSyncRuleList(SysSyncRule sysSyncRule); + + /** + * 新增同步规则 + * + * @param sysSyncRule 同步规则 + * @return 结果 + */ + public int insertSysSyncRule(SysSyncRule sysSyncRule); + + /** + * 修改同步规则 + * + * @param sysSyncRule 同步规则 + * @return 结果 + */ + public int updateSysSyncRule(SysSyncRule sysSyncRule); + + /** + * 批量删除同步规则 + * + * @param ids 需要删除的同步规则主键集合 + * @return 结果 + */ + public int deleteSysSyncRuleByIds(Long[] ids); + + /** + * 删除同步规则信息 + * + * @param id 同步规则主键 + * @return 结果 + */ + public int deleteSysSyncRuleById(Long id); + + public int insetSysSyncRuleItem(SysSyncItem item); + + public int deleteSysSyncRuleItem(Long id); + + List selectSysSyncRuleItem(Long id); + + public String addDept(SysBranch branch, String delete); + + public String addPeople(SysPeople sysPeople, String update); + + /** + * 查询园区对映的部门 + * @param tdGuid + * @return + */ + List queryParkDept(String tdGuid); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysUserOnlineService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysUserOnlineService.java new file mode 100644 index 0000000..7ebf0cd --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysUserOnlineService.java @@ -0,0 +1,48 @@ +package com.dcsoft.system.service; + +import com.dcsoft.system.api.model.LoginUser; +import com.dcsoft.system.domain.SysUserOnline; + +/** + * 在线用户 服务层 + * + * @author dcsoft + */ +public interface ISysUserOnlineService +{ + /** + * 通过登录地址查询信息 + * + * @param ipaddr 登录地址 + * @param user 用户信息 + * @return 在线用户信息 + */ + public SysUserOnline selectOnlineByIpaddr(String ipaddr, LoginUser user); + + /** + * 通过用户名称查询信息 + * + * @param userName 用户名称 + * @param user 用户信息 + * @return 在线用户信息 + */ + public SysUserOnline selectOnlineByUserName(String userName, LoginUser user); + + /** + * 通过登录地址/用户名称查询信息 + * + * @param ipaddr 登录地址 + * @param userName 用户名称 + * @param user 用户信息 + * @return 在线用户信息 + */ + public SysUserOnline selectOnlineByInfo(String ipaddr, String userName, LoginUser user); + + /** + * 设置在线用户信息 + * + * @param user 用户信息 + * @return 在线用户 + */ + public SysUserOnline loginUserToUserOnline(LoginUser user); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysUserService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysUserService.java new file mode 100644 index 0000000..f82e027 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/ISysUserService.java @@ -0,0 +1,230 @@ +package com.dcsoft.system.service; + +import java.util.List; + +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.system.api.domain.SysUser; +import com.dcsoft.system.domain.vo.AppletInfoVo; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.multipart.MultipartFile; + +/** + * 用户 业务层 + * + * @author dcsoft + */ +public interface ISysUserService +{ + /** + * 根据条件分页查询用户列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectUserList(SysUser user); + + /** + * 根据条件分页查询已分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectAllocatedList(SysUser user); + + /** + * 根据条件分页查询未分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectUnallocatedList(SysUser user); + + /** + * 通过用户名查询用户 + * + * @param userName 用户名 + * @return 用户对象信息 + */ + public SysUser selectUserByUserName(String userName); + + /** + * 通过用户ID查询用户 + * + * @param userId 用户ID + * @return 用户对象信息 + */ + public SysUser selectUserById(Long userId); + + /** + * 根据用户ID查询用户所属角色组 + * + * @param userName 用户名 + * @return 结果 + */ + public String selectUserRoleGroup(String userName); + + /** + * 根据用户ID查询用户所属岗位组 + * + * @param userName 用户名 + * @return 结果 + */ + public String selectUserPostGroup(String userName); + + /** + * 校验用户名称是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + public boolean checkUserNameUnique(SysUser user); + + /** + * 校验手机号码是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + public boolean checkPhoneUnique(SysUser user); + + /** + * 校验email是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + public boolean checkEmailUnique(SysUser user); + + /** + * 校验用户是否允许操作 + * + * @param user 用户信息 + */ + public void checkUserAllowed(SysUser user); + + /** + * 校验用户是否有数据权限 + * + * @param userId 用户id + */ + public void checkUserDataScope(Long userId); + + /** + * 新增用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int insertUser(SysUser user); + + /** + * 注册用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public boolean registerUser(SysUser user); + + /** + * 修改用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int updateUser(SysUser user); + + /** + * 用户授权角色 + * + * @param userId 用户ID + * @param roleIds 角色组 + */ + public void insertUserAuth(Long userId, Long[] roleIds); + + /** + * 修改用户状态 + * + * @param user 用户信息 + * @return 结果 + */ + public int updateUserStatus(SysUser user); + + /** + * 修改用户基本信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int updateUserProfile(SysUser user); + + /** + * 修改用户头像 + * + * @param userName 用户名 + * @param avatar 头像地址 + * @return 结果 + */ + public boolean updateUserAvatar(String userName, String avatar); + + /** + * 重置用户密码 + * + * @param user 用户信息 + * @return 结果 + */ + public int resetPwd(SysUser user); + + /** + * 重置用户密码 + * + * @param userName 用户名 + * @param password 密码 + * @return 结果 + */ + public int resetUserPwd(String userName, String password); + + /** + * 通过用户ID删除用户 + * + * @param userId 用户ID + * @return 结果 + */ + public int deleteUserById(Long userId); + + /** + * 批量删除用户信息 + * + * @param userIds 需要删除的用户ID + * @return 结果 + */ + public int deleteUserByIds(Long[] userIds); + + /** + * 导入用户数据 + * + * @param userList 用户数据列表 + * @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据 + * @param operName 操作用户 + * @return 结果 + */ + public String importUser(List userList, Boolean isUpdateSupport, String operName); + + public SysUser selectUserByOpenId(String openid); + + public SysUser selectUserByExternalId(String externalId); + + public int updateOpenId(SysUser sysUser); + + /** + * 小程序获取token + * @param appletInfoVo + * @return + */ + AppletInfoVo queryAppletToken(AppletInfoVo appletInfoVo); + + /** + * 小程序更新头像 + * @return + */ + String updateAppletAvatar(MultipartFile file, String userName); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysBackGroupServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysBackGroupServiceImpl.java new file mode 100644 index 0000000..1ededfb --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysBackGroupServiceImpl.java @@ -0,0 +1,100 @@ +package com.dcsoft.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.dcsoft.system.mapper.SysBackGroupMapper; +import com.dcsoft.system.domain.SysBackGroup; +import com.dcsoft.system.service.ISysBackGroupService; + +/** + * 背景配置Service业务层处理 + * + * @author dcsoft + * @date 2024-03-01 + */ +@Service +public class SysBackGroupServiceImpl implements ISysBackGroupService +{ + @Autowired + private SysBackGroupMapper sysBackGroupMapper; + + /** + * 查询背景配置 + * + * @param id 背景配置主键 + * @return 背景配置 + */ + @Override + public SysBackGroup selectSysBackGroupById(Long id) + { + return sysBackGroupMapper.selectSysBackGroupById(id); + } + + /** + * 查询背景配置列表 + * + * @param sysBackGroup 背景配置 + * @return 背景配置 + */ + @Override + public List selectSysBackGroupList(SysBackGroup sysBackGroup) + { + return sysBackGroupMapper.selectSysBackGroupList(sysBackGroup); + } + + /** + * 新增背景配置 + * + * @param sysBackGroup 背景配置 + * @return 结果 + */ + @Override + public int insertSysBackGroup(SysBackGroup sysBackGroup) + { + return sysBackGroupMapper.insertSysBackGroup(sysBackGroup); + } + + /** + * 修改背景配置 + * + * @param sysBackGroup 背景配置 + * @return 结果 + */ + @Override + public int updateSysBackGroup(SysBackGroup sysBackGroup) + { + return sysBackGroupMapper.updateSysBackGroup(sysBackGroup); + } + + /** + * 批量删除背景配置 + * + * @param ids 需要删除的背景配置主键 + * @return 结果 + */ + @Override + public int deleteSysBackGroupByIds(Long[] ids) + { + return sysBackGroupMapper.deleteSysBackGroupByIds(ids); + } + + /** + * 删除背景配置信息 + * + * @param id 背景配置主键 + * @return 结果 + */ + @Override + public int deleteSysBackGroupById(Long id) + { + return sysBackGroupMapper.deleteSysBackGroupById(id); + } + + @Override + public int deleteSysBackGroup() { + return sysBackGroupMapper.deleteSysBackGroup(); + } + + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysBlackListServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysBlackListServiceImpl.java new file mode 100644 index 0000000..caf0507 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysBlackListServiceImpl.java @@ -0,0 +1,102 @@ +package com.dcsoft.system.service.impl; + +import java.util.List; +import com.dcsoft.common.core.utils.DateUtils; +import com.dcsoft.system.visitor.domain.Visitor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.dcsoft.system.mapper.SysBlackListMapper; +import com.dcsoft.system.domain.SysBlackList; +import com.dcsoft.system.service.ISysBlackListService; + +/** + * 黑名单管理Service业务层处理 + * + * @author nichun + * @date 2023-07-03 + */ +@Service +public class SysBlackListServiceImpl implements ISysBlackListService +{ + @Autowired + private SysBlackListMapper sysBlackListMapper; + + /** + * 查询黑名单管理 + * + * @param id 黑名单管理主键 + * @return 黑名单管理 + */ + @Override + public SysBlackList selectSysBlackListById(Long id) + { + return sysBlackListMapper.selectSysBlackListById(id); + } + + /** + * 查询黑名单管理列表 + * + * @param sysBlackList 黑名单管理 + * @return 黑名单管理 + */ + @Override + public List selectSysBlackListList(SysBlackList sysBlackList) + { + return sysBlackListMapper.selectSysBlackListList(sysBlackList); + } + + /** + * 新增黑名单管理 + * + * @param sysBlackList 黑名单管理 + * @return 结果 + */ + @Override + public int insertSysBlackList(SysBlackList sysBlackList) + { + sysBlackList.setCreateTime(DateUtils.getNowDate()); + return sysBlackListMapper.insertSysBlackList(sysBlackList); + } + + /** + * 修改黑名单管理 + * + * @param sysBlackList 黑名单管理 + * @return 结果 + */ + @Override + public int updateSysBlackList(SysBlackList sysBlackList) + { + sysBlackList.setUpdateTime(DateUtils.getNowDate()); + return sysBlackListMapper.updateSysBlackList(sysBlackList); + } + + /** + * 批量删除黑名单管理 + * + * @param ids 需要删除的黑名单管理主键 + * @return 结果 + */ + @Override + public int deleteSysBlackListByIds(Long[] ids) + { + return sysBlackListMapper.deleteSysBlackListByIds(ids); + } + + /** + * 删除黑名单管理信息 + * + * @param id 黑名单管理主键 + * @return 结果 + */ + @Override + public int deleteSysBlackListById(Long id) + { + return sysBlackListMapper.deleteSysBlackListById(id); + } + + @Override + public SysBlackList queryBlackById(Visitor visitor) { + return sysBlackListMapper.queryBlackById(visitor); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysBranchServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysBranchServiceImpl.java new file mode 100644 index 0000000..744afbd --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysBranchServiceImpl.java @@ -0,0 +1,343 @@ +package com.dcsoft.system.service.impl; + +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.stream.Collectors; + +import cn.hutool.http.HttpResponse; +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson.JSONObject; +import com.dcsoft.common.core.constant.Constants; +import com.dcsoft.common.core.exception.ServiceException; +import com.dcsoft.common.core.utils.DateUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.domain.vo.JjDivisionVo; +import com.dcsoft.system.domain.vo.JjStationVo; +import com.dcsoft.system.domain.vo.JjserInfoVo; +import com.dcsoft.system.domain.vo.TreeSelect; +import com.dcsoft.system.domain.vo.TreeSelectVo; +import com.dcsoft.system.service.ISysSyncRuleService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.dcsoft.system.mapper.SysBranchMapper; +import com.dcsoft.system.domain.SysBranch; +import com.dcsoft.system.service.ISysBranchService; +import com.dcsoft.common.datascope.annotation.DataScope; + +/** + * 部门管理Service业务层处理 + * + * @author dcsoft + * @date 2023-03-07 + */ +@Slf4j +@Service +public class SysBranchServiceImpl implements ISysBranchService +{ + @Autowired + private SysBranchMapper sysBranchMapper; + + @Autowired + private ISysSyncRuleService syncRuleService; + + /** + * 查询部门管理 + * + * @param id 部门管理主键 + * @return 部门管理 + */ + @Override + public SysBranch selectSysBranchById(String id) + { + return sysBranchMapper.selectSysBranchById(id); + } + + /** + * 查询部门管理列表 + * + * @param sysBranch 部门管理 + * @return 部门管理 + */ + @Override + @DataScope(deptAlias = "d") + public List selectSysBranchList(SysBranch sysBranch) + { + return sysBranchMapper.selectSysBranchList(sysBranch); + } + + /** + * 新增部门管理 + * + * @param sysBranch 部门管理 + * @return 结果 + */ + @Override + public int insertSysBranch(SysBranch sysBranch) + { + sysBranch.setCreateTime(DateUtils.getNowDate()); + //部门增量同步 + syncRuleService.addDept(sysBranch,"add"); + return sysBranchMapper.insertSysBranch(sysBranch); + } + + /** + * 修改部门管理 + * + * @param sysBranch 部门管理 + * @return 结果 + */ + @Override + public int updateSysBranch(SysBranch sysBranch) + { + sysBranch.setUpdateTime(DateUtils.getNowDate()); + //部门增量同步 + syncRuleService.addDept(sysBranch,"update"); + return sysBranchMapper.updateSysBranch(sysBranch); + } + + /** + * 批量删除部门管理 + * + * @param ids 需要删除的部门管理主键 + * @return 结果 + */ + @Override + public int deleteSysBranchByIds(String[] ids) + { + for(String id:ids){ + SysBranch branch=new SysBranch(); + branch.setId(id); + syncRuleService.addDept(branch,"delete"); + } + return sysBranchMapper.deleteSysBranchByIds(ids); + } + + /** + * 删除部门管理信息 + * + * @param id 部门管理主键 + * @return 结果 + */ + @Override + public int deleteSysBranchById(Long id) + { + return sysBranchMapper.deleteSysBranchById(id); + } + + + /** + * 查询部门树结构信息 + * + * @param sysBranch 部门信息 + * @return 部门树信息集合 + */ + @Override + @DataScope(deptAlias = "d") + public List selectBranchTreeList(SysBranch sysBranch) + { + List branchs = sysBranchMapper.selectSysBranchList(sysBranch); + return buildBranchTreeSelect(branchs); + } + + @Override + public List queryBranchTree(SysBranch space) { + List branchs = sysBranchMapper.queryBranchTree(); + return buildBranchTreeSelect(branchs); + } + + /** + * 同步部门 + */ + @Override + public void saveBranchTree(SysBranch space) { + HttpResponse response; + if(Constants.ZERO.equals(space.getType())) { + response = HttpUtil.createGet("http://192.168.255.135:5566/api/ulYcRBiE/dhr/getOrganization") + .header("access_token", "f23c34a3200f1994d85de4daf1f15d") + .execute(); + } else { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + response = HttpUtil.createGet("http://192.168.255.135:5566/api/ulYcRBiE/dhr/getOrganization?ts=" + sdf.format(new Date())) + .header("access_token", "f23c34a3200f1994d85de4daf1f15d") + .execute(); + } + String body = response.body(); + JSONObject object = JSONObject.parseObject(body); + List data = JSONObject.parseArray(object.get("data").toString(), JjDivisionVo.class); + log.info("部门接口返回数据:" + object); + if(!"200".equals(object.get("code").toString())) { + throw new ServiceException("部门接口请求异常"); + } + for (JjDivisionVo datum : data) { + if("ROOT".equals(datum.getParentcode())) { + datum.setParentcode("0"); + } + } + sysBranchMapper.saveBranchTree(data); + } + + /** + * 同步人员(锦江) + */ + @Override + public void saveUserInfo(List data) { + sysBranchMapper.saveUserInfo(data); + } + + /** + * 同步岗位(锦江) + */ + @Override + public void saveStation(SysBranch space) { + HttpResponse response; + if(Constants.ZERO.equals(space.getType())) { + response = HttpUtil.createGet("http://192.168.255.135:5566/api/ulYcRBiE/dhr/getPosts") + .header("access_token", "f23c34a3200f1994d85de4daf1f15d") + .execute(); + } else { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + response = HttpUtil.createGet("http://192.168.255.135:5566/api/ulYcRBiE/dhr/getPosts?ts=" + sdf.format(new Date())) + .header("access_token", "f23c34a3200f1994d85de4daf1f15d") + .execute(); + } + String body = response.body(); + JSONObject object = JSONObject.parseObject(body); + if(!"200".equals(object.get("code").toString())) { + throw new ServiceException("岗位接口请求异常"); + } + List data = JSONObject.parseArray(object.get("data").toString(), JjStationVo.class); + sysBranchMapper.saveStation(data); + + } + + @Override + public int deleteSysBranchByBranchId(String id) { + return sysBranchMapper.deleteSysBranchByBranchId(id); + } + + @Override + public int updateSysBranchs(SysBranch sysBranch) { + return sysBranchMapper.updateSysBranch(sysBranch); + } + + @Override + public int insertSysBranchs(SysBranch sysBranch) { + return sysBranchMapper.insertSysBranch(sysBranch); + } + + /** + * 查询部门树 + */ + @Override + public List queryDeptInfo(SysBranch paramVo) { + List branchs = sysBranchMapper.selectSysBranchList(new SysBranch()); + return buildBranchTreeSelect(branchs); + } + + /** + * 查询物业子部门 + * @return + */ + @Override + public List queryPropertyDept(String parentId) { + return sysBranchMapper.queryPropertyDept(parentId); + } + + + /** + * 构建前端所需要树结构 + * + * @param branchs 部门列表 + * @return 树结构列表 + */ + @Override + public List buildBranchTree(List branchs) + { + List returnList = new ArrayList(); + List tempList = branchs.stream().map(SysBranch::getId).collect(Collectors.toList()); + for (SysBranch branch : branchs) + { + // 如果是顶级节点, 遍历该父节点的所有子节点 + if (!tempList.contains(branch.getParentId())) + { + recursionFn(branchs, branch); + returnList.add(branch); + } + } + if (returnList.isEmpty()) + { + returnList = branchs; + } + return returnList; + } + + /** + * 构建前端所需要下拉树结构 + * + * @param branchs 部门列表 + * @return 下拉树结构列表 + */ + @Override + public List buildBranchTreeSelect(List branchs) + { + List branchTrees = buildBranchTree(branchs); + return branchTrees.stream().map(TreeSelectVo::new).collect(Collectors.toList()); + } + + + + /** + * 递归列表 + */ + private void recursionFn(List list, SysBranch t) + { + // 得到子节点列表 + List childList = getChildList(list, t); + t.setChildren(childList); + for (SysBranch tChild : childList) + { + if (hasChild(list, tChild)) + { + recursionFn(list, tChild); + } + } + } + + /** + * 得到子节点列表 + */ + private List getChildList(List list, SysBranch t) + { + List tlist = new ArrayList(); + Iterator it = list.iterator(); + while (it.hasNext()) + { + SysBranch n = (SysBranch) it.next(); + if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().equals(t.getId())) + { + tlist.add(n); + } + } + return tlist; + } + + /** + * 判断是否有子节点 + */ + private boolean hasChild(List list, SysBranch t) + { + return getChildList(list, t).size() > 0 ? true : false; + } + + + @Override + public SysBranch selectSysBranchByDeptId(Long deptId) { + return sysBranchMapper.selectSysBranchByDeptId(deptId); + } + + + + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysConfigServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysConfigServiceImpl.java new file mode 100644 index 0000000..ea06001 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysConfigServiceImpl.java @@ -0,0 +1,332 @@ +package com.dcsoft.system.service.impl; + +import java.awt.*; +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import javax.annotation.PostConstruct; + +import com.dcsoft.system.utils.BackupConfig; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.dcsoft.common.core.constant.CacheConstants; +import com.dcsoft.common.core.constant.UserConstants; +import com.dcsoft.common.core.exception.ServiceException; +import com.dcsoft.common.core.text.Convert; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.redis.service.RedisService; +import com.dcsoft.system.domain.SysConfig; +import com.dcsoft.system.mapper.SysConfigMapper; +import com.dcsoft.system.service.ISysConfigService; + +/** + * 参数配置 服务层实现 + * + * @author dcsoft + */ +@Service +public class SysConfigServiceImpl implements ISysConfigService +{ + @Autowired + private SysConfigMapper configMapper; + + @Autowired + private RedisService redisService; + + @Autowired + private BackupConfig backupConfig; + + /** + * 项目启动时,初始化参数到缓存 + */ + @PostConstruct + public void init() + { + loadingConfigCache(); + } + + /** + * 查询参数配置信息 + * + * @param configId 参数配置ID + * @return 参数配置信息 + */ + @Override + public SysConfig selectConfigById(Long configId) + { + SysConfig config = new SysConfig(); + config.setConfigId(configId); + return configMapper.selectConfig(config); + } + + /** + * 根据键名查询参数配置信息 + * + * @param configKey 参数key + * @return 参数键值 + */ + @Override + public String selectConfigByKey(String configKey) + { + String configValue = Convert.toStr(redisService.getCacheObject(getCacheKey(configKey))); + if (StringUtils.isNotEmpty(configValue)) + { + return configValue; + } + SysConfig config = new SysConfig(); + config.setConfigKey(configKey); + SysConfig retConfig = configMapper.selectConfig(config); + if (StringUtils.isNotNull(retConfig)) + { + redisService.setCacheObject(getCacheKey(configKey), retConfig.getConfigValue()); + return retConfig.getConfigValue(); + } + return StringUtils.EMPTY; + } + + /** + * 查询参数配置列表 + * + * @param config 参数配置信息 + * @return 参数配置集合 + */ + @Override + public List selectConfigList(SysConfig config) + { + return configMapper.selectConfigList(config); + } + + /** + * 新增参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + @Override + public int insertConfig(SysConfig config) + { + int row = configMapper.insertConfig(config); + if (row > 0) + { + redisService.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue()); + } + return row; + } + + /** + * 修改参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + @Override + public int updateConfig(SysConfig config) + { + SysConfig temp = configMapper.selectConfigById(config.getConfigId()); + if (!StringUtils.equals(temp.getConfigKey(), config.getConfigKey())) + { + redisService.deleteObject(getCacheKey(temp.getConfigKey())); + } + + int row = configMapper.updateConfig(config); + if (row > 0) + { + redisService.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue()); + } + return row; + } + + /** + * 批量删除参数信息 + * + * @param configIds 需要删除的参数ID + */ + @Override + public void deleteConfigByIds(Long[] configIds) + { + for (Long configId : configIds) + { + SysConfig config = selectConfigById(configId); + if (StringUtils.equals(UserConstants.YES, config.getConfigType())) + { + throw new ServiceException(String.format("内置参数【%1$s】不能删除 ", config.getConfigKey())); + } + configMapper.deleteConfigById(configId); + redisService.deleteObject(getCacheKey(config.getConfigKey())); + } + } + + /** + * 加载参数缓存数据 + */ + @Override + public void loadingConfigCache() + { + List configsList = configMapper.selectConfigList(new SysConfig()); + for (SysConfig config : configsList) + { + redisService.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue()); + } + } + + /** + * 清空参数缓存数据 + */ + @Override + public void clearConfigCache() + { + Collection keys = redisService.keys(CacheConstants.SYS_CONFIG_KEY + "*"); + redisService.deleteObject(keys); + } + + /** + * 重置参数缓存数据 + */ + @Override + public void resetConfigCache() + { + clearConfigCache(); + loadingConfigCache(); + } + + /** + * 校验参数键名是否唯一 + * + * @param config 参数配置信息 + * @return 结果 + */ + @Override + public boolean checkConfigKeyUnique(SysConfig config) + { + Long configId = StringUtils.isNull(config.getConfigId()) ? -1L : config.getConfigId(); + SysConfig info = configMapper.checkConfigKeyUnique(config.getConfigKey()); + if (StringUtils.isNotNull(info) && info.getConfigId().longValue() != configId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 设置cache key + * + * @param configKey 参数键 + * @return 缓存键key + */ + private String getCacheKey(String configKey) + { + return CacheConstants.SYS_CONFIG_KEY + configKey; + } + + /** + * 备份数据库数据数据 + */ + @Override + public void backUp() + { + File file = new File(backupConfig.getBackupPath()); + if (!file.exists()) { + file.mkdirs(); + } + SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss"); + String fileName = backupConfig.getBackupPath() + "/" + sdf.format(new Date()) + ".sql"; + /** 默认使用linux*/ + String c1 = "/bin/sh"; + String c2 = "-c"; + String os_name = System.getProperty("os.name"); + // 判断是否是windows系统 + if (os_name.toLowerCase().startsWith("win")){ + c1 = "cmd"; + c2 = "/c"; + } + //参考示例:# /usr/local/mysql/bin/mysqldump -uroot -p123456 -P3306 shuju > shuju.sql + String cmd = backupConfig.getMysqldumpPath() // mysqldump的绝对路径,配置环境变量,直接写mysqldump即可 + + " -u" + backupConfig.getUsername() // 数据库用户名 + + " -p" + backupConfig.getPassword() // 数据库密码 + + " -P" + backupConfig.getPort() // 数据库端口号 + + " " + backupConfig.getDbName() // 数据库名 + + " > " + fileName; // 最终写入的文件路径 + try { + System.out.println("第一个参数 " + c1); + System.out.println("第二个参数 " + c2); + System.out.println("具体命令 " + cmd); + + System.out.println("数据库备份START" + LocalDateTime.now()); + /** + * exec重载方法有一个参数的,window下执行正常,linux下无法完成备份。 + * 使用多参数重载方法都可以正常备份 + */ + Process process = Runtime.getRuntime().exec(new String[]{c1, c2, cmd}); + process.waitFor(); + System.out.println("数据库备份END" + LocalDateTime.now()); + } catch (Exception e) { + e.printStackTrace(); + System.out.println("数据库备份失败:{}"+ e.getMessage()); + } + + } + + /** + * @param filepath 数据库备份的脚本路径 + * @return + */ + public boolean recover(String filepath) { + + /** 默认使用linux*/ + String c1 = "/bin/sh"; + String c2 = "-c"; + String os_name = System.getProperty("os.name"); + // 判断是否是windows系统 + if (os_name.toLowerCase().startsWith("win")){ + c1 = "cmd"; + c2 = "/c"; + } + + String fileName = backupConfig.getBackupPath() + "/" + filepath; + String stmt2 = + backupConfig.getMysqlPath() + +" -u "+backupConfig.getUsername() + +" -p" + backupConfig.getPassword() // 数据库密码 + +" -P" + backupConfig.getPort() // 数据库端口号 + +" "+backupConfig.getDbName() + +" < " + fileName; + String[] cmd = { c1, c2, stmt2 }; + System.out.println("具体命令 " + stmt2); + System.out.println("数据库还原START" + LocalDateTime.now()); + try { + Process process = Runtime.getRuntime().exec(cmd); + process.waitFor(); + System.out.println("数据已从 " + filepath + " 导入到数据库中"); + System.out.println("数据库还原END" + LocalDateTime.now()); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + return true; + + } + + @Override + public List listFile() { + List list=new ArrayList<>(); + String path=backupConfig.getBackupPath(); + File file1 = new File(path); + if (file1.exists()) { + File[] files = file1.listFiles(); + for (File file2:files){ + String sql= String.valueOf(file2.toPath()); + String resultImage =sql.substring(sql.length()-18,sql.length()); + list.add(resultImage); + } + } + return list; + } + + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysDeptServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysDeptServiceImpl.java new file mode 100644 index 0000000..fc3ecab --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysDeptServiceImpl.java @@ -0,0 +1,345 @@ +package com.dcsoft.system.service.impl; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.dcsoft.common.core.constant.UserConstants; +import com.dcsoft.common.core.exception.ServiceException; +import com.dcsoft.common.core.text.Convert; +import com.dcsoft.common.core.utils.SpringUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.datascope.annotation.DataScope; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.api.domain.SysDept; +import com.dcsoft.system.api.domain.SysRole; +import com.dcsoft.system.api.domain.SysUser; +import com.dcsoft.system.domain.vo.TreeSelect; +import com.dcsoft.system.mapper.SysDeptMapper; +import com.dcsoft.system.mapper.SysRoleMapper; +import com.dcsoft.system.service.ISysDeptService; + +/** + * 部门管理 服务实现 + * + * @author dcsoft + */ +@Service +public class SysDeptServiceImpl implements ISysDeptService +{ + @Autowired + private SysDeptMapper deptMapper; + + @Autowired + private SysRoleMapper roleMapper; + + /** + * 查询部门管理数据 + * + * @param dept 部门信息 + * @return 部门信息集合 + */ + @Override + @DataScope(deptAlias = "d") + public List selectDeptList(SysDept dept) + { + return deptMapper.selectDeptList(dept); + } + + /** + * 查询部门树结构信息 + * + * @param dept 部门信息 + * @return 部门树信息集合 + */ + @Override + public List selectDeptTreeList(SysDept dept) + { + List depts = SpringUtils.getAopProxy(this).selectDeptList(dept); + return buildDeptTreeSelect(depts); + } + + /** + * 构建前端所需要树结构 + * + * @param depts 部门列表 + * @return 树结构列表 + */ + @Override + public List buildDeptTree(List depts) + { + List returnList = new ArrayList(); + List tempList = depts.stream().map(SysDept::getDeptId).collect(Collectors.toList()); + for (SysDept dept : depts) + { + // 如果是顶级节点, 遍历该父节点的所有子节点 + if (!tempList.contains(dept.getParentId())) + { + recursionFn(depts, dept); + returnList.add(dept); + } + } + if (returnList.isEmpty()) + { + returnList = depts; + } + return returnList; + } + + /** + * 构建前端所需要下拉树结构 + * + * @param depts 部门列表 + * @return 下拉树结构列表 + */ + @Override + public List buildDeptTreeSelect(List depts) + { + List deptTrees = buildDeptTree(depts); + return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + /** + * 根据角色ID查询部门树信息 + * + * @param roleId 角色ID + * @return 选中部门列表 + */ + @Override + public List selectDeptListByRoleId(Long roleId) + { + SysRole role = roleMapper.selectRoleById(roleId); + return deptMapper.selectDeptListByRoleId(roleId, role.isDeptCheckStrictly()); + } + + /** + * 根据部门ID查询信息 + * + * @param deptId 部门ID + * @return 部门信息 + */ + @Override + public SysDept selectDeptById(Long deptId) + { + return deptMapper.selectDeptById(deptId); + } + + /** + * 根据ID查询所有子部门(正常状态) + * + * @param deptId 部门ID + * @return 子部门数 + */ + @Override + public int selectNormalChildrenDeptById(Long deptId) + { + return deptMapper.selectNormalChildrenDeptById(deptId); + } + + /** + * 是否存在子节点 + * + * @param deptId 部门ID + * @return 结果 + */ + @Override + public boolean hasChildByDeptId(Long deptId) + { + int result = deptMapper.hasChildByDeptId(deptId); + return result > 0; + } + + /** + * 查询部门是否存在用户 + * + * @param deptId 部门ID + * @return 结果 true 存在 false 不存在 + */ + @Override + public boolean checkDeptExistUser(Long deptId) + { + int result = deptMapper.checkDeptExistUser(deptId); + return result > 0; + } + + /** + * 校验部门名称是否唯一 + * + * @param dept 部门信息 + * @return 结果 + */ + @Override + public boolean checkDeptNameUnique(SysDept dept) + { + Long deptId = StringUtils.isNull(dept.getDeptId()) ? -1L : dept.getDeptId(); + SysDept info = deptMapper.checkDeptNameUnique(dept.getDeptName(), dept.getParentId()); + if (StringUtils.isNotNull(info) && info.getDeptId().longValue() != deptId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验部门是否有数据权限 + * + * @param deptId 部门id + */ + @Override + public void checkDeptDataScope(Long deptId) + { + if (!SysUser.isAdmin(SecurityUtils.getUserId())) + { + SysDept dept = new SysDept(); + dept.setDeptId(deptId); + List depts = SpringUtils.getAopProxy(this).selectDeptList(dept); + if (StringUtils.isEmpty(depts)) + { + throw new ServiceException("没有权限访问部门数据!"); + } + } + } + + /** + * 新增保存部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + @Override + public int insertDept(SysDept dept) + { + SysDept info = deptMapper.selectDeptById(dept.getParentId()); + // 如果父节点不为正常状态,则不允许新增子节点 + if (!UserConstants.DEPT_NORMAL.equals(info.getStatus())) + { + throw new ServiceException("部门停用,不允许新增"); + } + dept.setAncestors(info.getAncestors() + "," + dept.getParentId()); + return deptMapper.insertDept(dept); + } + + /** + * 修改保存部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + @Override + public int updateDept(SysDept dept) + { + SysDept newParentDept = deptMapper.selectDeptById(dept.getParentId()); + SysDept oldDept = deptMapper.selectDeptById(dept.getDeptId()); + if (StringUtils.isNotNull(newParentDept) && StringUtils.isNotNull(oldDept)) + { + String newAncestors = newParentDept.getAncestors() + "," + newParentDept.getDeptId(); + String oldAncestors = oldDept.getAncestors(); + dept.setAncestors(newAncestors); + updateDeptChildren(dept.getDeptId(), newAncestors, oldAncestors); + } + int result = deptMapper.updateDept(dept); + if (UserConstants.DEPT_NORMAL.equals(dept.getStatus()) && StringUtils.isNotEmpty(dept.getAncestors()) + && !StringUtils.equals("0", dept.getAncestors())) + { + // 如果该部门是启用状态,则启用该部门的所有上级部门 + updateParentDeptStatusNormal(dept); + } + return result; + } + + /** + * 修改该部门的父级部门状态 + * + * @param dept 当前部门 + */ + private void updateParentDeptStatusNormal(SysDept dept) + { + String ancestors = dept.getAncestors(); + Long[] deptIds = Convert.toLongArray(ancestors); + deptMapper.updateDeptStatusNormal(deptIds); + } + + /** + * 修改子元素关系 + * + * @param deptId 被修改的部门ID + * @param newAncestors 新的父ID集合 + * @param oldAncestors 旧的父ID集合 + */ + public void updateDeptChildren(Long deptId, String newAncestors, String oldAncestors) + { + List children = deptMapper.selectChildrenDeptById(deptId); + for (SysDept child : children) + { + child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors)); + } + if (children.size() > 0) + { + deptMapper.updateDeptChildren(children); + } + } + + /** + * 删除部门管理信息 + * + * @param deptId 部门ID + * @return 结果 + */ + @Override + public int deleteDeptById(Long deptId) + { + return deptMapper.deleteDeptById(deptId); + } + + /** + * 递归列表 + */ + private void recursionFn(List list, SysDept t) + { + // 得到子节点列表 + List childList = getChildList(list, t); + t.setChildren(childList); + for (SysDept tChild : childList) + { + if (hasChild(list, tChild)) + { + recursionFn(list, tChild); + } + } + } + + /** + * 得到子节点列表 + */ + private List getChildList(List list, SysDept t) + { + List tlist = new ArrayList(); + Iterator it = list.iterator(); + while (it.hasNext()) + { + SysDept n = (SysDept) it.next(); + if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getDeptId().longValue()) + { + tlist.add(n); + } + } + return tlist; + } + + /** + * 判断是否有子节点 + */ + private boolean hasChild(List list, SysDept t) + { + return getChildList(list, t).size() > 0 ? true : false; + } + + + @Override + public SysDept findByParentExternalId(String externalId) + { + return deptMapper.findByParentExternalId(externalId); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysDictDataServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysDictDataServiceImpl.java new file mode 100644 index 0000000..a0d202b --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysDictDataServiceImpl.java @@ -0,0 +1,122 @@ +package com.dcsoft.system.service.impl; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.dcsoft.common.security.utils.DictUtils; +import com.dcsoft.system.api.domain.SysDictData; +import com.dcsoft.system.mapper.SysDictDataMapper; +import com.dcsoft.system.service.ISysDictDataService; + +/** + * 字典 业务层处理 + * + * @author dcsoft + */ +@Service +public class SysDictDataServiceImpl implements ISysDictDataService +{ + @Autowired + private SysDictDataMapper dictDataMapper; + + /** + * 根据条件分页查询字典数据 + * + * @param dictData 字典数据信息 + * @return 字典数据集合信息 + */ + @Override + public List selectDictDataList(SysDictData dictData) + { + return dictDataMapper.selectDictDataList(dictData); + } + + /** + * 根据字典类型和字典键值查询字典数据信息 + * + * @param dictType 字典类型 + * @param dictValue 字典键值 + * @return 字典标签 + */ + @Override + public String selectDictLabel(String dictType, String dictValue) + { + return dictDataMapper.selectDictLabel(dictType, dictValue); + } + + /** + * 根据字典数据ID查询信息 + * + * @param dictCode 字典数据ID + * @return 字典数据 + */ + @Override + public SysDictData selectDictDataById(Long dictCode) + { + return dictDataMapper.selectDictDataById(dictCode); + } + + /** + * 批量删除字典数据信息 + * + * @param dictCodes 需要删除的字典数据ID + */ + @Override + public void deleteDictDataByIds(Long[] dictCodes) + { + for (Long dictCode : dictCodes) + { + SysDictData data = selectDictDataById(dictCode); + dictDataMapper.deleteDictDataById(dictCode); + List dictDatas = dictDataMapper.selectDictDataByType(data.getDictType()); + DictUtils.setDictCache(data.getDictType(), dictDatas); + } + } + + /** + * 新增保存字典数据信息 + * + * @param data 字典数据信息 + * @return 结果 + */ + @Override + public int insertDictData(SysDictData data) + { + int row = dictDataMapper.insertDictData(data); + if (row > 0) + { + List dictDatas = dictDataMapper.selectDictDataByType(data.getDictType()); + DictUtils.setDictCache(data.getDictType(), dictDatas); + } + return row; + } + + /** + * 修改保存字典数据信息 + * + * @param data 字典数据信息 + * @return 结果 + */ + @Override + public int updateDictData(SysDictData data) + { + int row = dictDataMapper.updateDictData(data); + if (row > 0) + { + List dictDatas = dictDataMapper.selectDictDataByType(data.getDictType()); + DictUtils.setDictCache(data.getDictType(), dictDatas); + } + return row; + } + + @Override + public Map queryDictData(String dictType) { + SysDictData dictData = new SysDictData(); + dictData.setDictType(dictType); + List sysDictData = dictDataMapper.selectDictDataList(dictData); + return sysDictData.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel)); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysDictTypeServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysDictTypeServiceImpl.java new file mode 100644 index 0000000..d1e0a00 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysDictTypeServiceImpl.java @@ -0,0 +1,223 @@ +package com.dcsoft.system.service.impl; + +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import javax.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.dcsoft.common.core.constant.UserConstants; +import com.dcsoft.common.core.exception.ServiceException; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.security.utils.DictUtils; +import com.dcsoft.system.api.domain.SysDictData; +import com.dcsoft.system.api.domain.SysDictType; +import com.dcsoft.system.mapper.SysDictDataMapper; +import com.dcsoft.system.mapper.SysDictTypeMapper; +import com.dcsoft.system.service.ISysDictTypeService; + +/** + * 字典 业务层处理 + * + * @author dcsoft + */ +@Service +public class SysDictTypeServiceImpl implements ISysDictTypeService +{ + @Autowired + private SysDictTypeMapper dictTypeMapper; + + @Autowired + private SysDictDataMapper dictDataMapper; + + /** + * 项目启动时,初始化字典到缓存 + */ + @PostConstruct + public void init() + { + loadingDictCache(); + } + + /** + * 根据条件分页查询字典类型 + * + * @param dictType 字典类型信息 + * @return 字典类型集合信息 + */ + @Override + public List selectDictTypeList(SysDictType dictType) + { + return dictTypeMapper.selectDictTypeList(dictType); + } + + /** + * 根据所有字典类型 + * + * @return 字典类型集合信息 + */ + @Override + public List selectDictTypeAll() + { + return dictTypeMapper.selectDictTypeAll(); + } + + /** + * 根据字典类型查询字典数据 + * + * @param dictType 字典类型 + * @return 字典数据集合信息 + */ + @Override + public List selectDictDataByType(String dictType) + { + List dictDatas = DictUtils.getDictCache(dictType); + if (StringUtils.isNotEmpty(dictDatas)) + { + return dictDatas; + } + dictDatas = dictDataMapper.selectDictDataByType(dictType); + if (StringUtils.isNotEmpty(dictDatas)) + { + DictUtils.setDictCache(dictType, dictDatas); + return dictDatas; + } + return null; + } + + /** + * 根据字典类型ID查询信息 + * + * @param dictId 字典类型ID + * @return 字典类型 + */ + @Override + public SysDictType selectDictTypeById(Long dictId) + { + return dictTypeMapper.selectDictTypeById(dictId); + } + + /** + * 根据字典类型查询信息 + * + * @param dictType 字典类型 + * @return 字典类型 + */ + @Override + public SysDictType selectDictTypeByType(String dictType) + { + return dictTypeMapper.selectDictTypeByType(dictType); + } + + /** + * 批量删除字典类型信息 + * + * @param dictIds 需要删除的字典ID + */ + @Override + public void deleteDictTypeByIds(Long[] dictIds) + { + for (Long dictId : dictIds) + { + SysDictType dictType = selectDictTypeById(dictId); + if (dictDataMapper.countDictDataByType(dictType.getDictType()) > 0) + { + throw new ServiceException(String.format("%1$s已分配,不能删除", dictType.getDictName())); + } + dictTypeMapper.deleteDictTypeById(dictId); + DictUtils.removeDictCache(dictType.getDictType()); + } + } + + /** + * 加载字典缓存数据 + */ + @Override + public void loadingDictCache() + { + SysDictData dictData = new SysDictData(); + dictData.setStatus("0"); + Map> dictDataMap = dictDataMapper.selectDictDataList(dictData).stream().collect(Collectors.groupingBy(SysDictData::getDictType)); + for (Map.Entry> entry : dictDataMap.entrySet()) + { + DictUtils.setDictCache(entry.getKey(), entry.getValue().stream().sorted(Comparator.comparing(SysDictData::getDictSort)).collect(Collectors.toList())); + } + } + + /** + * 清空字典缓存数据 + */ + @Override + public void clearDictCache() + { + DictUtils.clearDictCache(); + } + + /** + * 重置字典缓存数据 + */ + @Override + public void resetDictCache() + { + clearDictCache(); + loadingDictCache(); + } + + /** + * 新增保存字典类型信息 + * + * @param dict 字典类型信息 + * @return 结果 + */ + @Override + public int insertDictType(SysDictType dict) + { + int row = dictTypeMapper.insertDictType(dict); + if (row > 0) + { + DictUtils.setDictCache(dict.getDictType(), null); + } + return row; + } + + /** + * 修改保存字典类型信息 + * + * @param dict 字典类型信息 + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int updateDictType(SysDictType dict) + { + SysDictType oldDict = dictTypeMapper.selectDictTypeById(dict.getDictId()); + dictDataMapper.updateDictDataType(oldDict.getDictType(), dict.getDictType()); + int row = dictTypeMapper.updateDictType(dict); + if (row > 0) + { + List dictDatas = dictDataMapper.selectDictDataByType(dict.getDictType()); + DictUtils.setDictCache(dict.getDictType(), dictDatas); + } + return row; + } + + /** + * 校验字典类型称是否唯一 + * + * @param dict 字典类型 + * @return 结果 + */ + @Override + public boolean checkDictTypeUnique(SysDictType dict) + { + Long dictId = StringUtils.isNull(dict.getDictId()) ? -1L : dict.getDictId(); + SysDictType dictType = dictTypeMapper.checkDictTypeUnique(dict.getDictType()); + if (StringUtils.isNotNull(dictType) && dictType.getDictId().longValue() != dictId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysEmpowerRecordServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysEmpowerRecordServiceImpl.java new file mode 100644 index 0000000..88fb8f1 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysEmpowerRecordServiceImpl.java @@ -0,0 +1,101 @@ +package com.dcsoft.system.service.impl; + +import java.util.List; +import com.dcsoft.common.core.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.dcsoft.system.mapper.SysEmpowerRecordMapper; +import com.dcsoft.system.domain.SysEmpowerRecord; +import com.dcsoft.system.service.ISysEmpowerRecordService; + +/** + * 授权记录Service业务层处理 + * + * @author nichun + * @date 2023-03-08 + */ +@Service +public class SysEmpowerRecordServiceImpl implements ISysEmpowerRecordService +{ + @Autowired + private SysEmpowerRecordMapper sysEmpowerRecordMapper; + + /** + * 查询授权记录 + * + * @param id 授权记录主键 + * @return 授权记录 + */ + @Override + public SysEmpowerRecord selectSysEmpowerRecordById(Long id) + { + return sysEmpowerRecordMapper.selectSysEmpowerRecordById(id); + } + + /** + * 查询授权记录列表 + * + * @param sysEmpowerRecord 授权记录 + * @return 授权记录 + */ + @Override + public List selectSysEmpowerRecordList(SysEmpowerRecord sysEmpowerRecord) + { + return sysEmpowerRecordMapper.selectSysEmpowerRecordList(sysEmpowerRecord); + } + + /** + * 新增授权记录 + * + * @param sysEmpowerRecord 授权记录 + * @return 结果 + */ + @Override + public int insertSysEmpowerRecord(SysEmpowerRecord sysEmpowerRecord) + { + sysEmpowerRecord.setCreateTime(DateUtils.getNowDate()); + return sysEmpowerRecordMapper.insertSysEmpowerRecord(sysEmpowerRecord); + } + + /** + * 修改授权记录 + * + * @param sysEmpowerRecord 授权记录 + * @return 结果 + */ + @Override + public int updateSysEmpowerRecord(SysEmpowerRecord sysEmpowerRecord) + { + sysEmpowerRecord.setUpdateTime(DateUtils.getNowDate()); + return sysEmpowerRecordMapper.updateSysEmpowerRecord(sysEmpowerRecord); + } + + /** + * 批量删除授权记录 + * + * @param ids 需要删除的授权记录主键 + * @return 结果 + */ + @Override + public int deleteSysEmpowerRecordByIds(Long[] ids) + { + return sysEmpowerRecordMapper.deleteSysEmpowerRecordByIds(ids); + } + + /** + * 删除授权记录信息 + * + * @param id 授权记录主键 + * @return 结果 + */ + @Override + public int deleteSysEmpowerRecordById(Long id) + { + return sysEmpowerRecordMapper.deleteSysEmpowerRecordById(id); + } + + @Override + public int deleteSysEmpowerRecordByPeopleId(Long peopleId) { + return sysEmpowerRecordMapper.deleteSysEmpowerRecordByPeopleId(peopleId); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysEquipmentServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysEquipmentServiceImpl.java new file mode 100644 index 0000000..f99b8b5 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysEquipmentServiceImpl.java @@ -0,0 +1,251 @@ +package com.dcsoft.system.service.impl; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import com.dcsoft.common.core.utils.DateUtils; +import com.dcsoft.system.domain.SysEmpowerRecord; +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.domain.vo.SysFileVo; +import com.dcsoft.system.uniubi.domain.EwmInfo; +import com.dcsoft.system.uniubi.domain.LadderControlVo; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.dcsoft.system.mapper.SysEquipmentMapper; +import com.dcsoft.system.domain.SysEquipment; +import com.dcsoft.system.service.ISysEquipmentService; +import org.springframework.util.CollectionUtils; + +/** + * 设备信息Service业务层处理 + * + * @author nichun + * @date 2023-03-08 + */ +@Service +public class SysEquipmentServiceImpl implements ISysEquipmentService +{ + @Autowired + private SysEquipmentMapper sysEquipmentMapper; + + /** + * 查询设备信息 + * + * @param id 设备信息主键 + * @return 设备信息 + */ + @Override + public SysEquipment selectSysEquipmentById(Long id) + { + SysEquipment equipment = sysEquipmentMapper.selectSysEquipmentById(id); + // 查询访客机图片或视频 + SysFileVo sysFile = new SysFileVo(); + sysFile.setBusinessType("sys_fkj"); + sysFile.setBusinessId(String.valueOf(id)); + List list = sysEquipmentMapper.queryFile(sysFile); + if(!CollectionUtils.isEmpty(list)) { + equipment.setFileList(list); + } + return equipment; + } + + /** + * 查询设备信息列表 + * + * @param sysEquipment 设备信息 + * @return 设备信息 + */ + @Override + public List selectSysEquipmentList(SysEquipment sysEquipment) + { + return sysEquipmentMapper.selectSysEquipmentList(sysEquipment); + } + + /** + * 新增设备信息 + * + * @param sysEquipment 设备信息 + * @return 结果 + */ + @Override + public int insertSysEquipment(SysEquipment sysEquipment) + { + sysEquipment.setCreateTime(DateUtils.getNowDate()); + return sysEquipmentMapper.insertSysEquipment(sysEquipment); + } + + /** + * 修改设备信息 + * + * @param sysEquipment 设备信息 + * @return 结果 + */ + @Override + public int updateSysEquipment(SysEquipment sysEquipment) + { + sysEquipment.setUpdateTime(DateUtils.getNowDate()); + return sysEquipmentMapper.updateSysEquipment(sysEquipment); + } + + /** + * 批量删除设备信息 + * + * @param ids 需要删除的设备信息主键 + * @return 结果 + */ + @Override + public int deleteSysEquipmentByIds(Long[] ids) + { + return sysEquipmentMapper.deleteSysEquipmentByIds(ids); + } + + /** + * 删除设备信息信息 + * + * @param id 设备信息主键 + * @return 结果 + */ + @Override + public int deleteSysEquipmentById(Long id) + { + return sysEquipmentMapper.deleteSysEquipmentById(id); + } + + @Override + public SysEquipment selectEquipmentBySequence(String deviceNo) { + return sysEquipmentMapper.selectEquipmentBySequence(deviceNo); + } + + /** + * 查询设备信息 + */ + @Override + public List queryEquipmentInfo(List pointIds) { + return sysEquipmentMapper.queryEquipmentInfo(pointIds); + } + + /** + * 查询人员信息 + */ + @Override + public SysPeople queryPeopleInfo(SysPeople people) { + return sysEquipmentMapper.queryPeopleInfo(people); + } + + @Override + public List> selectSysEquipmentPeopleById(Long id) { + return sysEquipmentMapper.selectSysEquipmentPeopleById(id); + } + + /** + * 根据设备序列号查询产品类型 + * @param deviceKey + * @return + */ + @Override + public String queryDeviceSequence(String deviceKey) { + return sysEquipmentMapper.queryDeviceSequence(deviceKey); + } + + + /** + * 查询授权记录规则id + * @param people + * @return + */ + @Override + public List queryEmpowerRecord(SysPeople people) { + return sysEquipmentMapper.queryEmpowerRecord(people); + } + + /** + * 查询人员信息 + * @param sysPeople + * @return + */ + @Override + public SysPeople queryPeople(SysPeople sysPeople) { + return sysEquipmentMapper.queryPeople(sysPeople); + } + + + @Override + public SysEquipment queryEmpower(String sequence) { + return sysEquipmentMapper.queryEmpower(sequence); + } + + /** + * 根据设备序列好查询设备信息 + * @param sysEquipment + * @return + */ + @Override + public SysEquipment queryEquipmentByDeviceKey(SysEquipment sysEquipment) { + SysEquipment equipment = sysEquipmentMapper.queryEquipmentByDeviceKey(sysEquipment); + // 查询访客机图片或视频 + SysFileVo sysFile = new SysFileVo(); + sysFile.setBusinessType("sys_fkj"); + sysFile.setBusinessId(String.valueOf(equipment.getId())); + List list = sysEquipmentMapper.queryFile(sysFile); + if(!CollectionUtils.isEmpty(list)) { + equipment.setFileList(list); + } + return equipment; + } + + /** + * 根据设备序列号修改设备密码 + * @param sysEquipment + */ + @Override + public void updateEquipmentByDeviceKey(SysEquipment sysEquipment) { + if(StringUtils.isNotEmpty(sysEquipment.getIp())) { + sysEquipment.setDeviceIp(sysEquipment.getIp() + ":" + sysEquipment.getPort()); + } + SysEquipment equipment = sysEquipmentMapper.selectEquipmentBySequence(sysEquipment.getDeviceKey()); + if(equipment != null) { + sysEquipment.setId(equipment.getId()); + saveFile(sysEquipment); + } + sysEquipmentMapper.updateEquipmentByDeviceKey(sysEquipment); + } + + @Override + public void saveFile(SysEquipment sysEquipment) { + SysFileVo sysFile = new SysFileVo(); + sysFile.setBusinessId(String.valueOf(sysEquipment.getId())); + sysFile.setBusinessType("sys_fkj"); + sysEquipmentMapper.deleteFile(sysFile); + List fileList = sysEquipment.getFileList(); + if(!CollectionUtils.isEmpty(fileList)) { + List sysFiles = new ArrayList<>(); + for (SysFileVo fileVo : fileList) { + SysFileVo file = new SysFileVo(); + file.setBusinessId(String.valueOf(sysEquipment.getId())); + file.setFileName(fileVo.getFileName()); + file.setUrl(fileVo.getUrl()); + file.setBusinessType("sys_fkj"); + file.setId(UUID.randomUUID().toString().replace("-", "")); + sysFiles.add(file); + } + sysEquipmentMapper.saveFile(sysFiles); + } + + } + + /** + * 根据设备序列号修改设备轮播文件 + * @param sysEquipment + */ + @Override + public void updateEquipmentFile(SysEquipment sysEquipment) { + SysEquipment equipment = sysEquipmentMapper.queryEquipmentByDeviceKey(sysEquipment); + equipment.setFileList(sysEquipment.getFileList()); + saveFile(equipment); + } + + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysLogininforServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysLogininforServiceImpl.java new file mode 100644 index 0000000..eb473a4 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysLogininforServiceImpl.java @@ -0,0 +1,65 @@ +package com.dcsoft.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.dcsoft.system.api.domain.SysLogininfor; +import com.dcsoft.system.mapper.SysLogininforMapper; +import com.dcsoft.system.service.ISysLogininforService; + +/** + * 系统访问日志情况信息 服务层处理 + * + * @author dcsoft + */ +@Service +public class SysLogininforServiceImpl implements ISysLogininforService +{ + + @Autowired + private SysLogininforMapper logininforMapper; + + /** + * 新增系统登录日志 + * + * @param logininfor 访问日志对象 + */ + @Override + public int insertLogininfor(SysLogininfor logininfor) + { + return logininforMapper.insertLogininfor(logininfor); + } + + /** + * 查询系统登录日志集合 + * + * @param logininfor 访问日志对象 + * @return 登录记录集合 + */ + @Override + public List selectLogininforList(SysLogininfor logininfor) + { + return logininforMapper.selectLogininforList(logininfor); + } + + /** + * 批量删除系统登录日志 + * + * @param infoIds 需要删除的登录日志ID + * @return 结果 + */ + @Override + public int deleteLogininforByIds(Long[] infoIds) + { + return logininforMapper.deleteLogininforByIds(infoIds); + } + + /** + * 清空系统登录日志 + */ + @Override + public void cleanLogininfor() + { + logininforMapper.cleanLogininfor(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysManageRecordServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysManageRecordServiceImpl.java new file mode 100644 index 0000000..2090755 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysManageRecordServiceImpl.java @@ -0,0 +1,96 @@ +package com.dcsoft.system.service.impl; + +import java.util.List; +import com.dcsoft.common.core.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.dcsoft.system.mapper.SysManageRecordMapper; +import com.dcsoft.system.domain.SysManageRecord; +import com.dcsoft.system.service.ISysManageRecordService; + +/** + * 授权管理记录Service业务层处理 + * + * @author dcsoft + * @date 2023-03-08 + */ +@Service +public class SysManageRecordServiceImpl implements ISysManageRecordService +{ + @Autowired + private SysManageRecordMapper sysManageRecordMapper; + + /** + * 查询授权管理记录 + * + * @param id 授权管理记录主键 + * @return 授权管理记录 + */ + @Override + public SysManageRecord selectSysManageRecordById(Long id) + { + return sysManageRecordMapper.selectSysManageRecordById(id); + } + + /** + * 查询授权管理记录列表 + * + * @param sysManageRecord 授权管理记录 + * @return 授权管理记录 + */ + @Override + public List selectSysManageRecordList(SysManageRecord sysManageRecord) + { + return sysManageRecordMapper.selectSysManageRecordList(sysManageRecord); + } + + /** + * 新增授权管理记录 + * + * @param sysManageRecord 授权管理记录 + * @return 结果 + */ + @Override + public int insertSysManageRecord(SysManageRecord sysManageRecord) + { + sysManageRecord.setCreateTime(DateUtils.getNowDate()); + return sysManageRecordMapper.insertSysManageRecord(sysManageRecord); + } + + /** + * 修改授权管理记录 + * + * @param sysManageRecord 授权管理记录 + * @return 结果 + */ + @Override + public int updateSysManageRecord(SysManageRecord sysManageRecord) + { + sysManageRecord.setUpdateTime(DateUtils.getNowDate()); + return sysManageRecordMapper.updateSysManageRecord(sysManageRecord); + } + + /** + * 批量删除授权管理记录 + * + * @param ids 需要删除的授权管理记录主键 + * @return 结果 + */ + @Override + public int deleteSysManageRecordByIds(Long[] ids) + { + return sysManageRecordMapper.deleteSysManageRecordByIds(ids); + } + + /** + * 删除授权管理记录信息 + * + * @param id 授权管理记录主键 + * @return 结果 + */ + @Override + public int deleteSysManageRecordById(Long id) + { + return sysManageRecordMapper.deleteSysManageRecordById(id); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysMenuServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysMenuServiceImpl.java new file mode 100644 index 0000000..ae852ce --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysMenuServiceImpl.java @@ -0,0 +1,531 @@ +package com.dcsoft.system.service.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.dcsoft.common.core.constant.Constants; +import com.dcsoft.common.core.constant.UserConstants; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.api.domain.SysRole; +import com.dcsoft.system.api.domain.SysUser; +import com.dcsoft.system.domain.SysMenu; +import com.dcsoft.system.domain.vo.MetaVo; +import com.dcsoft.system.domain.vo.RouterVo; +import com.dcsoft.system.domain.vo.TreeSelect; +import com.dcsoft.system.mapper.SysMenuMapper; +import com.dcsoft.system.mapper.SysRoleMapper; +import com.dcsoft.system.mapper.SysRoleMenuMapper; +import com.dcsoft.system.service.ISysMenuService; + +/** + * 菜单 业务层处理 + * + * @author dcsoft + */ +@Service +public class SysMenuServiceImpl implements ISysMenuService +{ + public static final String PREMISSION_STRING = "perms[\"{0}\"]"; + + @Autowired + private SysMenuMapper menuMapper; + + @Autowired + private SysRoleMapper roleMapper; + + @Autowired + private SysRoleMenuMapper roleMenuMapper; + + /** + * 根据用户查询系统菜单列表 + * + * @param userId 用户ID + * @return 菜单列表 + */ + @Override + public List selectMenuList(Long userId) + { + return selectMenuList(new SysMenu(), userId); + } + + /** + * 查询系统菜单列表 + * + * @param menu 菜单信息 + * @return 菜单列表 + */ + @Override + public List selectMenuList(SysMenu menu, Long userId) + { + List menuList = null; + // 管理员显示所有菜单信息 + if (SysUser.isAdmin(userId)) + { + menuList = menuMapper.selectMenuList(menu); + } + else + { + menu.getParams().put("userId", userId); + menuList = menuMapper.selectMenuListByUserId(menu); + } + return menuList; + } + + /** + * 根据用户ID查询权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + @Override + public Set selectMenuPermsByUserId(Long userId) + { + List perms = menuMapper.selectMenuPermsByUserId(userId); + Set permsSet = new HashSet<>(); + for (String perm : perms) + { + if (StringUtils.isNotEmpty(perm)) + { + permsSet.addAll(Arrays.asList(perm.trim().split(","))); + } + } + return permsSet; + } + + /** + * 根据角色ID查询权限 + * + * @param roleId 角色ID + * @return 权限列表 + */ + @Override + public Set selectMenuPermsByRoleId(Long roleId) + { + List perms = menuMapper.selectMenuPermsByRoleId(roleId); + Set permsSet = new HashSet<>(); + for (String perm : perms) + { + if (StringUtils.isNotEmpty(perm)) + { + permsSet.addAll(Arrays.asList(perm.trim().split(","))); + } + } + return permsSet; + } + + /** + * 根据用户ID查询菜单 + * + * @param userId 用户名称 + * @return 菜单列表 + */ + @Override + public List selectMenuTreeByUserId(Long userId) + { + List menus = null; + if (SecurityUtils.isAdmin(userId)) + { + menus = menuMapper.selectMenuTreeAll(); + } + else + { + menus = menuMapper.selectMenuTreeByUserId(userId); + } + return getChildPerms(menus, 0); + } + + /** + * 根据角色ID查询菜单树信息 + * + * @param roleId 角色ID + * @return 选中菜单列表 + */ + @Override + public List selectMenuListByRoleId(Long roleId) + { + SysRole role = roleMapper.selectRoleById(roleId); + return menuMapper.selectMenuListByRoleId(roleId, role.isMenuCheckStrictly()); + } + + /** + * 构建前端路由所需要的菜单 + * + * @param menus 菜单列表 + * @return 路由列表 + */ + @Override + public List buildMenus(List menus) + { + List routers = new LinkedList(); + for (SysMenu menu : menus) + { + RouterVo router = new RouterVo(); + router.setHidden("1".equals(menu.getVisible())); + router.setName(getRouteName(menu)); + router.setPath(getRouterPath(menu)); + router.setComponent(getComponent(menu)); + router.setQuery(menu.getQuery()); + router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath())); + List cMenus = menu.getChildren(); + if (!cMenus.isEmpty() && cMenus.size() > 0 && UserConstants.TYPE_DIR.equals(menu.getMenuType())) + { + router.setAlwaysShow(true); + router.setRedirect("noRedirect"); + router.setChildren(buildMenus(cMenus)); + } + else if (isMenuFrame(menu)) + { + router.setMeta(null); + List childrenList = new ArrayList(); + RouterVo children = new RouterVo(); + children.setPath(menu.getPath()); + children.setComponent(menu.getComponent()); + children.setName(StringUtils.capitalize(menu.getPath())); + children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath())); + children.setQuery(menu.getQuery()); + childrenList.add(children); + router.setChildren(childrenList); + } + else if (menu.getParentId().intValue() == 0 && isInnerLink(menu)) + { + router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon())); + router.setPath("/"); + List childrenList = new ArrayList(); + RouterVo children = new RouterVo(); + String routerPath = innerLinkReplaceEach(menu.getPath()); + children.setPath(routerPath); + children.setComponent(UserConstants.INNER_LINK); + children.setName(StringUtils.capitalize(routerPath)); + children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), menu.getPath())); + childrenList.add(children); + router.setChildren(childrenList); + } + routers.add(router); + } + return routers; + } + + /** + * 构建前端所需要树结构 + * + * @param menus 菜单列表 + * @return 树结构列表 + */ + @Override + public List buildMenuTree(List menus) + { + List returnList = new ArrayList(); + List tempList = menus.stream().map(SysMenu::getMenuId).collect(Collectors.toList()); + for (Iterator iterator = menus.iterator(); iterator.hasNext();) + { + SysMenu menu = (SysMenu) iterator.next(); + // 如果是顶级节点, 遍历该父节点的所有子节点 + if (!tempList.contains(menu.getParentId())) + { + recursionFn(menus, menu); + returnList.add(menu); + } + } + if (returnList.isEmpty()) + { + returnList = menus; + } + return returnList; + } + + /** + * 构建前端所需要下拉树结构 + * + * @param menus 菜单列表 + * @return 下拉树结构列表 + */ + @Override + public List buildMenuTreeSelect(List menus) + { + List menuTrees = buildMenuTree(menus); + return menuTrees.stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + /** + * 根据菜单ID查询信息 + * + * @param menuId 菜单ID + * @return 菜单信息 + */ + @Override + public SysMenu selectMenuById(Long menuId) + { + return menuMapper.selectMenuById(menuId); + } + + /** + * 是否存在菜单子节点 + * + * @param menuId 菜单ID + * @return 结果 + */ + @Override + public boolean hasChildByMenuId(Long menuId) + { + int result = menuMapper.hasChildByMenuId(menuId); + return result > 0; + } + + /** + * 查询菜单使用数量 + * + * @param menuId 菜单ID + * @return 结果 + */ + @Override + public boolean checkMenuExistRole(Long menuId) + { + int result = roleMenuMapper.checkMenuExistRole(menuId); + return result > 0; + } + + /** + * 新增保存菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + @Override + public int insertMenu(SysMenu menu) + { + return menuMapper.insertMenu(menu); + } + + /** + * 修改保存菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + @Override + public int updateMenu(SysMenu menu) + { + return menuMapper.updateMenu(menu); + } + + /** + * 删除菜单管理信息 + * + * @param menuId 菜单ID + * @return 结果 + */ + @Override + public int deleteMenuById(Long menuId) + { + return menuMapper.deleteMenuById(menuId); + } + + /** + * 校验菜单名称是否唯一 + * + * @param menu 菜单信息 + * @return 结果 + */ + @Override + public boolean checkMenuNameUnique(SysMenu menu) + { + Long menuId = StringUtils.isNull(menu.getMenuId()) ? -1L : menu.getMenuId(); + SysMenu info = menuMapper.checkMenuNameUnique(menu.getMenuName(), menu.getParentId()); + if (StringUtils.isNotNull(info) && info.getMenuId().longValue() != menuId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 获取路由名称 + * + * @param menu 菜单信息 + * @return 路由名称 + */ + public String getRouteName(SysMenu menu) + { + String routerName = StringUtils.capitalize(menu.getPath()); + // 非外链并且是一级目录(类型为目录) + if (isMenuFrame(menu)) + { + routerName = StringUtils.EMPTY; + } + return routerName; + } + + /** + * 获取路由地址 + * + * @param menu 菜单信息 + * @return 路由地址 + */ + public String getRouterPath(SysMenu menu) + { + String routerPath = menu.getPath(); + // 内链打开外网方式 + if (menu.getParentId().intValue() != 0 && isInnerLink(menu)) + { + routerPath = innerLinkReplaceEach(routerPath); + } + // 非外链并且是一级目录(类型为目录) + if (0 == menu.getParentId().intValue() && UserConstants.TYPE_DIR.equals(menu.getMenuType()) + && UserConstants.NO_FRAME.equals(menu.getIsFrame())) + { + routerPath = "/" + menu.getPath(); + } + // 非外链并且是一级目录(类型为菜单) + else if (isMenuFrame(menu)) + { + routerPath = "/"; + } + return routerPath; + } + + /** + * 获取组件信息 + * + * @param menu 菜单信息 + * @return 组件信息 + */ + public String getComponent(SysMenu menu) + { + String component = UserConstants.LAYOUT; + if (StringUtils.isNotEmpty(menu.getComponent()) && !isMenuFrame(menu)) + { + component = menu.getComponent(); + } + else if (StringUtils.isEmpty(menu.getComponent()) && menu.getParentId().intValue() != 0 && isInnerLink(menu)) + { + component = UserConstants.INNER_LINK; + } + else if (StringUtils.isEmpty(menu.getComponent()) && isParentView(menu)) + { + component = UserConstants.PARENT_VIEW; + } + return component; + } + + /** + * 是否为菜单内部跳转 + * + * @param menu 菜单信息 + * @return 结果 + */ + public boolean isMenuFrame(SysMenu menu) + { + return menu.getParentId().intValue() == 0 && UserConstants.TYPE_MENU.equals(menu.getMenuType()) + && menu.getIsFrame().equals(UserConstants.NO_FRAME); + } + + /** + * 是否为内链组件 + * + * @param menu 菜单信息 + * @return 结果 + */ + public boolean isInnerLink(SysMenu menu) + { + return menu.getIsFrame().equals(UserConstants.NO_FRAME) && StringUtils.ishttp(menu.getPath()); + } + + /** + * 是否为parent_view组件 + * + * @param menu 菜单信息 + * @return 结果 + */ + public boolean isParentView(SysMenu menu) + { + return menu.getParentId().intValue() != 0 && UserConstants.TYPE_DIR.equals(menu.getMenuType()); + } + + /** + * 根据父节点的ID获取所有子节点 + * + * @param list 分类表 + * @param parentId 传入的父节点ID + * @return String + */ + public List getChildPerms(List list, int parentId) + { + List returnList = new ArrayList(); + for (Iterator iterator = list.iterator(); iterator.hasNext();) + { + SysMenu t = (SysMenu) iterator.next(); + // 一、根据传入的某个父节点ID,遍历该父节点的所有子节点 + if (t.getParentId() == parentId) + { + recursionFn(list, t); + returnList.add(t); + } + } + return returnList; + } + + /** + * 递归列表 + * + * @param list + * @param t + */ + private void recursionFn(List list, SysMenu t) + { + // 得到子节点列表 + List childList = getChildList(list, t); + t.setChildren(childList); + for (SysMenu tChild : childList) + { + if (hasChild(list, tChild)) + { + recursionFn(list, tChild); + } + } + } + + /** + * 得到子节点列表 + */ + private List getChildList(List list, SysMenu t) + { + List tlist = new ArrayList(); + Iterator it = list.iterator(); + while (it.hasNext()) + { + SysMenu n = (SysMenu) it.next(); + if (n.getParentId().longValue() == t.getMenuId().longValue()) + { + tlist.add(n); + } + } + return tlist; + } + + /** + * 判断是否有子节点 + */ + private boolean hasChild(List list, SysMenu t) + { + return getChildList(list, t).size() > 0; + } + + /** + * 内链域名特殊字符替换 + * + * @return + */ + public String innerLinkReplaceEach(String path) + { + return StringUtils.replaceEach(path, new String[] { Constants.HTTP, Constants.HTTPS, Constants.WWW, "." }, + new String[] { "", "", "", "/" }); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysNoticeServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysNoticeServiceImpl.java new file mode 100644 index 0000000..59de02f --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysNoticeServiceImpl.java @@ -0,0 +1,92 @@ +package com.dcsoft.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.dcsoft.system.domain.SysNotice; +import com.dcsoft.system.mapper.SysNoticeMapper; +import com.dcsoft.system.service.ISysNoticeService; + +/** + * 公告 服务层实现 + * + * @author dcsoft + */ +@Service +public class SysNoticeServiceImpl implements ISysNoticeService +{ + @Autowired + private SysNoticeMapper noticeMapper; + + /** + * 查询公告信息 + * + * @param noticeId 公告ID + * @return 公告信息 + */ + @Override + public SysNotice selectNoticeById(Long noticeId) + { + return noticeMapper.selectNoticeById(noticeId); + } + + /** + * 查询公告列表 + * + * @param notice 公告信息 + * @return 公告集合 + */ + @Override + public List selectNoticeList(SysNotice notice) + { + return noticeMapper.selectNoticeList(notice); + } + + /** + * 新增公告 + * + * @param notice 公告信息 + * @return 结果 + */ + @Override + public int insertNotice(SysNotice notice) + { + return noticeMapper.insertNotice(notice); + } + + /** + * 修改公告 + * + * @param notice 公告信息 + * @return 结果 + */ + @Override + public int updateNotice(SysNotice notice) + { + return noticeMapper.updateNotice(notice); + } + + /** + * 删除公告对象 + * + * @param noticeId 公告ID + * @return 结果 + */ + @Override + public int deleteNoticeById(Long noticeId) + { + return noticeMapper.deleteNoticeById(noticeId); + } + + /** + * 批量删除公告信息 + * + * @param noticeIds 需要删除的公告ID + * @return 结果 + */ + @Override + public int deleteNoticeByIds(Long[] noticeIds) + { + return noticeMapper.deleteNoticeByIds(noticeIds); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysOperLogServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysOperLogServiceImpl.java new file mode 100644 index 0000000..e39f36b --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysOperLogServiceImpl.java @@ -0,0 +1,79 @@ +package com.dcsoft.system.service.impl; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.dcsoft.system.api.domain.SysOperLog; +import com.dcsoft.system.mapper.SysOperLogMapper; +import com.dcsoft.system.service.ISysOperLogService; + +/** + * 操作日志 服务层处理 + * + * @author dcsoft + */ +@Service +public class SysOperLogServiceImpl implements ISysOperLogService +{ + @Autowired + private SysOperLogMapper operLogMapper; + + /** + * 新增操作日志 + * + * @param operLog 操作日志对象 + * @return 结果 + */ + @Override + public int insertOperlog(SysOperLog operLog) + { + //对接操作日志(判断是否开启对接中法航空大学统一日志服务) + return operLogMapper.insertOperlog(operLog); + } + + /** + * 查询系统操作日志集合 + * + * @param operLog 操作日志对象 + * @return 操作日志集合 + */ + @Override + public List selectOperLogList(SysOperLog operLog) + { + return operLogMapper.selectOperLogList(operLog); + } + + /** + * 批量删除系统操作日志 + * + * @param operIds 需要删除的操作日志ID + * @return 结果 + */ + @Override + public int deleteOperLogByIds(Long[] operIds) + { + return operLogMapper.deleteOperLogByIds(operIds); + } + + /** + * 查询操作日志详细 + * + * @param operId 操作ID + * @return 操作日志对象 + */ + @Override + public SysOperLog selectOperLogById(Long operId) + { + return operLogMapper.selectOperLogById(operId); + } + + /** + * 清空操作日志 + */ + @Override + public void cleanOperLog() + { + operLogMapper.cleanOperLog(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPeopleEquipmentServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPeopleEquipmentServiceImpl.java new file mode 100644 index 0000000..04e78e4 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPeopleEquipmentServiceImpl.java @@ -0,0 +1,135 @@ +package com.dcsoft.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.dcsoft.system.mapper.SysPeopleEquipmentMapper; +import com.dcsoft.system.domain.SysPeopleEquipment; +import com.dcsoft.system.service.ISysPeopleEquipmentService; + +/** + * 人员设备下发信息Service业务层处理 + * + * @author dcsoft + * @date 2023-06-12 + */ +@Service +public class SysPeopleEquipmentServiceImpl implements ISysPeopleEquipmentService +{ + @Autowired + private SysPeopleEquipmentMapper sysPeopleEquipmentMapper; + + /** + * 查询人员设备下发信息 + * + * @param id 人员设备下发信息主键 + * @return 人员设备下发信息 + */ + @Override + public SysPeopleEquipment selectSysPeopleEquipmentById(Long id) + { + return sysPeopleEquipmentMapper.selectSysPeopleEquipmentById(id); + } + + /** + * 查询人员设备下发信息列表 + * + * @param sysPeopleEquipment 人员设备下发信息 + * @return 人员设备下发信息 + */ + @Override + public List selectSysPeopleEquipmentList(SysPeopleEquipment sysPeopleEquipment) + { + return sysPeopleEquipmentMapper.selectSysPeopleEquipmentList(sysPeopleEquipment); + } + + /** + * 新增人员设备下发信息 + * + * @param sysPeopleEquipment 人员设备下发信息 + * @return 结果 + */ + @Override + public int insertSysPeopleEquipment(SysPeopleEquipment sysPeopleEquipment) + { + return sysPeopleEquipmentMapper.insertSysPeopleEquipment(sysPeopleEquipment); + } + + /** + * 修改人员设备下发信息 + * + * @param sysPeopleEquipment 人员设备下发信息 + * @return 结果 + */ + @Override + public int updateSysPeopleEquipment(SysPeopleEquipment sysPeopleEquipment) + { + return sysPeopleEquipmentMapper.updateSysPeopleEquipment(sysPeopleEquipment); + } + + /** + * 批量删除人员设备下发信息 + * + * @param ids 需要删除的人员设备下发信息主键 + * @return 结果 + */ + @Override + public int deleteSysPeopleEquipmentByIds(Long[] ids) + { + return sysPeopleEquipmentMapper.deleteSysPeopleEquipmentByIds(ids); + } + + /** + * 删除人员设备下发信息信息 + * + * @param id 人员设备下发信息主键 + * @return 结果 + */ + @Override + public int deleteSysPeopleEquipmentById(Long id) + { + return sysPeopleEquipmentMapper.deleteSysPeopleEquipmentById(id); + } + + /** + * 查询人员设备下发信息 + * + * @param guid 人员设备下发信息主键 + * @return 人员设备下发信息 + */ + @Override + public SysPeopleEquipment selectSysPeopleEquipmentByGuId(String guid) + { + return sysPeopleEquipmentMapper.selectSysPeopleEquipmentByGuId(guid); + } + + /** + * 查询人员设备下发信息 + * + * @param peopleId 人员设备下发信息主键 + * @return 人员设备下发信息 + */ + @Override + public List selectSysPeopleEquipmentByPeopleId(String peopleId) + { + return sysPeopleEquipmentMapper.selectSysPeopleEquipmentByPeopleId(peopleId); + } + + /** + * 查询人员设备下发信息 + * + * @param peopleId 人员设备下发信息主键 + * @return 人员设备下发信息 + */ + @Override + public List selectSysPeopleEquipmentByVisitorId(Long visitorId) + { + return sysPeopleEquipmentMapper.selectSysPeopleEquipmentByVisitorId(visitorId); + } + + @Override + public int deleteSysPeopleEquipmentByOtherId(Long otherId) { + return sysPeopleEquipmentMapper.deleteSysPeopleEquipmentByOtherId(otherId); + } + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPeopleLeaveServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPeopleLeaveServiceImpl.java new file mode 100644 index 0000000..184eaee --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPeopleLeaveServiceImpl.java @@ -0,0 +1,230 @@ +package com.dcsoft.system.service.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import com.dcsoft.common.core.exception.ServiceException; +import com.dcsoft.common.core.utils.DateUtils; +import com.dcsoft.system.domain.SysBranch; +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.mapper.SysBranchMapper; +import com.dcsoft.system.mapper.SysPeopleMapper; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.dcsoft.system.mapper.SysPeopleLeaveMapper; +import com.dcsoft.system.domain.SysPeopleLeave; +import com.dcsoft.system.service.ISysPeopleLeaveService; +import org.springframework.util.CollectionUtils; + +/** + * 离职管理Service业务层处理 + * + * @author nichun + * @date 2023-09-09 + */ +@Service +public class SysPeopleLeaveServiceImpl implements ISysPeopleLeaveService +{ + @Autowired + private SysPeopleLeaveMapper sysPeopleLeaveMapper; + + @Autowired + private SysPeopleMapper sysPeopleMapper; + + @Autowired + private SysBranchMapper sysBranchMapper; + + /** + * 查询离职管理 + * + * @param id 离职管理主键 + * @return 离职管理 + */ + @Override + public SysPeopleLeave selectSysPeopleLeaveById(Long id) + { + return sysPeopleLeaveMapper.selectSysPeopleLeaveById(id); + } + + /** + * 查询离职管理列表 + * + * @param sysPeopleLeave 离职管理 + * @return 离职管理 + */ + @Override + public List selectSysPeopleLeaveList(SysPeopleLeave sysPeopleLeave) + { + return sysPeopleLeaveMapper.selectSysPeopleLeaveList(sysPeopleLeave); + } + + /** + * 新增离职管理 + * + * @param sysPeopleLeave 离职管理 + * @return 结果 + */ + @Override + public int insertSysPeopleLeave(SysPeopleLeave sysPeopleLeave) + { + sysPeopleLeave.setCreateTime(DateUtils.getNowDate()); + return sysPeopleLeaveMapper.insertSysPeopleLeave(sysPeopleLeave); + } + + /** + * 修改离职管理 + * + * @param sysPeopleLeave 离职管理 + * @return 结果 + */ + @Override + public int updateSysPeopleLeave(SysPeopleLeave sysPeopleLeave) + { + sysPeopleLeave.setUpdateTime(DateUtils.getNowDate()); + return sysPeopleLeaveMapper.updateSysPeopleLeave(sysPeopleLeave); + } + + /** + * 批量删除离职管理 + * + * @param ids 需要删除的离职管理主键 + * @return 结果 + */ + @Override + public int deleteSysPeopleLeaveByIds(Long[] ids) + { + for(Long peopleId:ids){ + SysPeopleLeave peopleLeave =sysPeopleLeaveMapper.selectSysPeopleLeaveById(peopleId); + if(peopleLeave.getPeopleId()!=null){ + SysPeople people=new SysPeople(); + people.setId(peopleLeave.getPeopleId()); + people.setDelFlag(0L); + sysPeopleMapper.updateSysPeople(people); + } + } + return sysPeopleLeaveMapper.deleteSysPeopleLeaveByIds(ids); + } + + /** + * 删除离职管理信息 + * + * @param id 离职管理主键 + * @return 结果 + */ + @Override + public int deleteSysPeopleLeaveById(Long id) + { + SysPeopleLeave peopleLeave =sysPeopleLeaveMapper.selectSysPeopleLeaveById(id); + if(peopleLeave.getPeopleId()!=null){ + SysPeople people=new SysPeople(); + people.setId(peopleLeave.getPeopleId()); + people.setDelFlag(0L); + sysPeopleMapper.updateSysPeople(people); + } + return sysPeopleLeaveMapper.deleteSysPeopleLeaveById(id); + } + + /** + * 离职人员导入 + * @param userList + * @param updateSupport + * @param operName + * @return + */ + @Override + public String importPeople(List userList, boolean updateSupport, String operName) { + if (CollectionUtils.isEmpty(userList)) { + throw new ServiceException("导入用户数据不能为空!"); + } + // 更具工号查询用户信息 + List collect = userList.stream().map(SysPeopleLeave::getGh).collect(Collectors.toList()); + List u = sysPeopleMapper.queryPeople(collect); + Map collect1 = u.stream().collect(Collectors.toMap(SysPeople::getGh, SysPeople::getId)); + int i = 0; + for (SysPeopleLeave sysPeopleLeave : userList) { + i++; + if(StringUtils.isEmpty(sysPeopleLeave.getGh())) { + throw new ServiceException("第" + i + "行的工号不能为空"); + } + if(sysPeopleLeave.getLeaveTime() == null) { + throw new ServiceException("第" + i + "行的离职时间不能为空"); + } + SysBranch branch=new SysBranch(); + branch.setName(sysPeopleLeave.getBranchName()); + List branchlist = sysBranchMapper.selectSysBranchList(branch); + if(CollectionUtils.isEmpty(branchlist)) { + sysPeopleLeave.setBranchId(branchlist.get(0).getId()); + } + Long l = collect1.get(sysPeopleLeave.getGh()); + if(l != null) { + sysPeopleLeave.setPeopleId(l); + } + } + + // excel表中工号重复校验 + removeDuplicateOrder(userList); + + int successNum = 0; + int failureNum = 0; + StringBuilder successMsg = new StringBuilder(); + StringBuilder failureMsg = new StringBuilder(); + + // 获取在人员表中没有工号的数据(需要抛出异常提示工号不存在) + List peopleLeaves = new ArrayList<>(userList); + peopleLeaves.removeIf(c -> u.stream().anyMatch(n -> n.getGh().equals(c.getGh()))); + for (SysPeopleLeave people : peopleLeaves) { + failureNum ++; + failureMsg.append("
").append(failureNum).append("、工号 ").append(people.getGh()).append(" 不存在"); + } + + // 获取在人员表中工号存在的数据(可以正常导入) + List list = new ArrayList<>(userList); + list.removeIf(c -> u.stream().anyMatch(n -> !c.getGh().equals(n.getGh()))); + if(!CollectionUtils.isEmpty(list) && !CollectionUtils.isEmpty(u)) { + List peopleLeaveList = sysPeopleLeaveMapper.queryPeopleLeaveList(list); + if(updateSupport) { + for (SysPeopleLeave sysPeopleLeave : peopleLeaveList) { + successMsg.append("
").append(successNum).append("、工号 ").append(sysPeopleLeave.getGh()).append(" 更新成功"); + } + sysPeopleLeaveMapper.updatePeopleLeaveList(peopleLeaveList); + } + + list.removeIf(c -> peopleLeaveList.stream().anyMatch(n -> n.getGh().equals(c.getGh()))); + if(!CollectionUtils.isEmpty(list)) { + for (SysPeopleLeave sysPeopleLeave : list) { + successMsg.append("
").append(successNum).append("、工号 ").append(sysPeopleLeave.getGh()).append(" 导入成功"); + } + sysPeopleLeaveMapper.savePeopleLeaveList(list); + } + successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:"); + + } + + if(failureNum > 0) { + failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:"); + return failureMsg.toString(); + } + + return successMsg.toString(); + } + + + /** + * 去重校验 + */ + private void removeDuplicateOrder(List orderList) { + Map articleNameMap = new HashMap<>(); + for (SysPeopleLeave importArticleInfoVo : orderList) { + if (articleNameMap.containsKey(importArticleInfoVo.getGh())) { + throw new ServiceException("excel中有多条工号为:" + importArticleInfoVo.getGh() + "的重复数据"); + } else { + articleNameMap.put(importArticleInfoVo.getGh(), 1); + } + } + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPeopleOtherServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPeopleOtherServiceImpl.java new file mode 100644 index 0000000..bd025af --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPeopleOtherServiceImpl.java @@ -0,0 +1,348 @@ +package com.dcsoft.system.service.impl; + +import com.dcsoft.common.core.exception.ServiceException; +import com.dcsoft.common.core.utils.DateUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.datascope.annotation.DataScope; +import com.dcsoft.system.domain.SysBranch; +import com.dcsoft.system.domain.SysPeopleOther; +import com.dcsoft.system.domain.vo.JjDivisionVo; +import com.dcsoft.system.mapper.SysBranchMapper; +import com.dcsoft.system.mapper.SysPeopleOtherMapper; +import com.dcsoft.system.service.ISysPeopleOtherService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import static com.dcsoft.common.core.utils.PageUtils.startPage; + + +/** + * 人员管理Service业务层处理 + * + * @author nichun + * @date 2023-03-08 + */ +@Service +public class SysPeopleOtherServiceImpl implements ISysPeopleOtherService +{ + @Autowired + private SysPeopleOtherMapper sysPeopleOtherMapper; + + @Autowired + private SysBranchMapper sysBranchMapper; + + + /** + * 查询人员管理 + * + * @param id 人员管理主键 + * @return 人员管理 + */ + @Override + public SysPeopleOther selectSysPeopleOtherById(Long id) + { + return sysPeopleOtherMapper.selectSysPeopleOtherById(id); + } + + /** + * 查询人员管理列表 + * + * @param sysPeople 人员管理 + * @return 人员管理 + */ + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List selectSysPeopleOtherList(SysPeopleOther sysPeople) + { + List listStr = new ArrayList<>(); + if(!"0".equals(sysPeople.getBranchId()) && StringUtils.isNotEmpty(sysPeople.getBranchId())) { + List list = sysBranchMapper.selectBranchTreeOther(sysPeople); + List list1 = new ArrayList<>(); + getParentNode(list1, list, sysPeople.getBranchId()); + listStr = list1.stream().map(JjDivisionVo::getId).collect(Collectors.toList()); + listStr.add(sysPeople.getBranchId()); + } +// if(org.apache.commons.lang3.StringUtils.isNotEmpty(sysPeople.getBranchId())) { +// listStr.add(sysPeople.getBranchId()); +// } + startPage(); + sysPeople.setDelFlag(0L); + return sysPeopleOtherMapper.selectSysPeopleOtherList(sysPeople, listStr); + } + + + @Override + public List queryPeopleList(SysPeopleOther sysPeople) { + List listStr = new ArrayList<>(); + if(!"0".equals(sysPeople.getBranchId()) && StringUtils.isNotEmpty(sysPeople.getBranchId())) { + List list = sysBranchMapper.selectBranchTreeOther(sysPeople); + List list1 = new ArrayList<>(); + getParentNode(list1, list, sysPeople.getBranchId()); + listStr = list1.stream().map(JjDivisionVo::getId).collect(Collectors.toList()); + listStr.add(sysPeople.getBranchId()); + } + + sysPeople.setDelFlag(0L); + List sysPeople1 = sysPeopleOtherMapper.selectSysPeopleOtherList(sysPeople, listStr); + for (SysPeopleOther people : sysPeople1) { + people.setName(people.getName() + "-" + people.getPhone()); + } + return sysPeople1; + } + + + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List selectSysPeopleOtherLists(SysPeopleOther sysPeople) + { + List listStr = new ArrayList<>(); + if(!"0".equals(sysPeople.getBranchId()) && StringUtils.isNotEmpty(sysPeople.getBranchId())) { + List list = sysBranchMapper.selectBranchTreeOther(sysPeople); + List list1 = new ArrayList<>(); + getParentNode(list1, list, sysPeople.getBranchId()); + listStr = list1.stream().map(JjDivisionVo::getId).collect(Collectors.toList()); + listStr.add(sysPeople.getBranchId()); + } + sysPeople.setDelFlag(0L); + return sysPeopleOtherMapper.selectSysPeopleOtherList(sysPeople, listStr); + } + + private void getParentNode(List childMenu, List menuList, String pid) { + menuList.stream() + //过滤出父id等于参数的id + .filter(menu -> StringUtils.isNotBlank(menu.getParentId()) && menu.getParentId().equals(pid)) + .forEach(menu -> { + //递归遍历下一级 + getParentNode(childMenu, menuList, menu.getId()); + //添加 + childMenu.add(menu); + }); + } + + /** + * 新增人员管理 + * + * @param sysPeople 人员管理 + * @return 结果 + */ + @Override + public int insertSysPeopleOther(SysPeopleOther sysPeople) + { + sysPeople.setCreateTime(DateUtils.getNowDate()); + return sysPeopleOtherMapper.insertSysPeopleOther(sysPeople); + } + + /** + * 修改人员管理 + * + * @param sysPeople 人员管理 + * @return 结果 + */ + @Override + public int updateSysPeopleOther(SysPeopleOther sysPeople) + { + sysPeople.setUpdateTime(DateUtils.getNowDate()); + return sysPeopleOtherMapper.updateSysPeopleOther(sysPeople); + } + + /** + * 批量删除人员管理 + * + * @param ids 需要删除的人员管理主键 + * @return 结果 + */ + @Override + public int deleteSysPeopleOtherByIds(Long[] ids) + { + + return sysPeopleOtherMapper.deleteSysPeopleOtherByIds(ids); + } + + /** + * 删除人员管理信息 + * + * @param id 人员管理主键 + * @return 结果 + */ + @Override + public int deleteSysPeopleOtherById(Long id) + { + return sysPeopleOtherMapper.deleteSysPeopleOtherById(id); + } + + @Override + public SysPeopleOther selectByGuid(SysPeopleOther sysPeople) { + return sysPeopleOtherMapper.selectByGuid(sysPeople); + } + + @Override + public SysPeopleOther selectSysPeopleByUserId(Long userId) { + return sysPeopleOtherMapper.selectSysPeopleOtherByUserId(userId); + } + + @Override + public SysPeopleOther selectSysPeopleByBranchUser(String branchName, String userName) { + return sysPeopleOtherMapper.selectSysPeopleOtherByBranchUser(branchName,userName); + } + + @Override + public SysPeopleOther selectSysPeopleByPhoneUser(SysPeopleOther sysPeople) { + return sysPeopleOtherMapper.selectSysPeopleOtherByPhoneUser(sysPeople); + } + + @Override + public List queryPeopleInfo() { + return sysPeopleOtherMapper.queryPeopleInfo(); + } + + /** + * 查询ids + */ + @Override + public List queryPeople(List collectStr) { + return sysPeopleOtherMapper.queryPeople(collectStr); + } + + /** + * 查询人员详情 + */ + @Override + public SysPeopleOther queryPeopleDetails(String details) { + return sysPeopleOtherMapper.queryPeopleDetails(details); + } + + @Override + public int updateSysPeoples(SysPeopleOther sysPeople) { + //规则下发 + return sysPeopleOtherMapper.updateSysPeopleOther(sysPeople); + } + + @Override + public int insertSysPeoples(SysPeopleOther sysPeople) { + int i=sysPeopleOtherMapper.insertSysPeopleOther(sysPeople); + return i; + } + + @Override + public int deleteSysPeopleOtherByGuid(String guid) { + //规则下发 + return sysPeopleOtherMapper.deleteSysPeopleOtherByGuid(guid); + } + + @Override + public void updatePeople(SysPeopleOther people) { + sysPeopleOtherMapper.updatePeople(people); + } + + @Override + public String selectDoorNo(Long id) { + return sysPeopleOtherMapper.selectDoorNo(id); + } + + @Override + public String selectPeopleById(String card) { + return sysPeopleOtherMapper.selectPeopleById(card); + } + + @Override + public void updatePeopleInfo(SysPeopleOther sysPeople) { + sysPeopleOtherMapper.updatePeopleInfo(sysPeople); + } + + @Override + public SysPeopleOther queryPeopleById(String id) { + return sysPeopleOtherMapper.queryPeopleById(id); + } + + @Override + public SysPeopleOther selectSysPeopleByOpenId(String openid) { + return sysPeopleOtherMapper.selectSysPeopleOtherByOpenId(openid); + } + + @Override + public SysPeopleOther selectSysPeopleByGh(String phone,String name) { + return sysPeopleOtherMapper.selectSysPeopleOtherGh(phone,name); + } + + @Override + public SysPeopleOther queryPeopleName(String phone) { + return sysPeopleOtherMapper.queryPeopleName(phone); + } + + + + + /** + * 导入用户数据 + * + * @param userList 用户数据列表 + * @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据 + * @param operName 操作用户 + * @return 结果 + */ + @Override + public String importPeople(List userList, boolean isUpdateSupport, String operName) + { + if (StringUtils.isNull(userList) || userList.size() == 0) + { + throw new ServiceException("导入用户数据不能为空!"); + } + int successNum = 0; + int failureNum = 0; + StringBuilder successMsg = new StringBuilder(); + StringBuilder failureMsg = new StringBuilder(); + for (SysPeopleOther user : userList) + { + try + { + // 验证是否存在这个用户 + SysPeopleOther u = sysPeopleOtherMapper.selectSysPeopleOtherByPhoneUser(user); + SysBranch branch=new SysBranch(); + branch.setName(user.getBranchName()); + List branchlist=sysBranchMapper.selectSysBranchList(branch); + if(branchlist.size()>0){ + user.setBranchId(branchlist.get(0).getId()); + } + if (StringUtils.isNull(u)) + { + this.insertSysPeopleOther(user); + successNum++; + successMsg.append("
" + successNum + "、手机号 " + user.getPhone() + " 导入成功"); + } + else if (isUpdateSupport) + { + this.updateSysPeopleOther(user); + successNum++; + successMsg.append("
" + successNum + "、手机号 " + user.getPhone() + " 更新成功"); + } + else + { + failureNum++; + failureMsg.append("
" + failureNum + "、手机号 " + user.getPhone() + " 已存在"); + } + } + catch (Exception e) + { + failureNum++; + String msg = "
" + failureNum + "、手机号 " + user.getPhone() + " 导入失败:"; + failureMsg.append(msg + e.getMessage()); + } + } + if (failureNum > 0) + { + failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:"); + throw new ServiceException(failureMsg.toString()); + } + else + { + successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:"); + } + return successMsg.toString(); + } + + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPeopleRecordServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPeopleRecordServiceImpl.java new file mode 100644 index 0000000..5ee4a13 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPeopleRecordServiceImpl.java @@ -0,0 +1,134 @@ +package com.dcsoft.system.service.impl; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import com.dcsoft.common.core.utils.DateUtils; +import com.dcsoft.common.core.web.domain.AjaxResult; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.dcsoft.system.mapper.SysPeopleRecordMapper; +import com.dcsoft.system.domain.SysPeopleRecord; +import com.dcsoft.system.service.ISysPeopleRecordService; + +/** + * 人员识别记录Service业务层处理 + * + * @author nichun + * @date 2023-03-08 + */ +@Service +public class SysPeopleRecordServiceImpl implements ISysPeopleRecordService +{ + @Autowired + private SysPeopleRecordMapper sysPeopleRecordMapper; + + /** + * 查询人员识别记录 + * + * @param id 人员识别记录主键 + * @return 人员识别记录 + */ + @Override + public SysPeopleRecord selectSysPeopleRecordById(Long id) + { + return sysPeopleRecordMapper.selectSysPeopleRecordById(id); + } + + /** + * 查询人员识别记录列表 + * + * @param sysPeopleRecord 人员识别记录 + * @return 人员识别记录 + */ + @Override + public List selectSysPeopleRecordList(SysPeopleRecord sysPeopleRecord) + { + return sysPeopleRecordMapper.selectSysPeopleRecordList(sysPeopleRecord); + } + + /** + * 查询人员识别记录列表 + * + * @param sysPeopleRecord 人员识别记录 + * @return 人员识别记录 + */ + @Override + public List selectSysPeopleRecordLists(SysPeopleRecord sysPeopleRecord) + { + return sysPeopleRecordMapper.selectSysPeopleRecordLists(sysPeopleRecord); + } + + /** + * 新增人员识别记录 + * + * @param sysPeopleRecord 人员识别记录 + * @return 结果 + */ + @Override + public int insertSysPeopleRecord(SysPeopleRecord sysPeopleRecord) + { + sysPeopleRecord.setCreateTime(DateUtils.getNowDate()); + return sysPeopleRecordMapper.insertSysPeopleRecord(sysPeopleRecord); + } + + /** + * 修改人员识别记录 + * + * @param sysPeopleRecord 人员识别记录 + * @return 结果 + */ + @Override + public int updateSysPeopleRecord(SysPeopleRecord sysPeopleRecord) + { + sysPeopleRecord.setUpdateTime(DateUtils.getNowDate()); + return sysPeopleRecordMapper.updateSysPeopleRecord(sysPeopleRecord); + } + + /** + * 批量删除人员识别记录 + * + * @param ids 需要删除的人员识别记录主键 + * @return 结果 + */ + @Override + public int deleteSysPeopleRecordByIds(Long[] ids) + { + return sysPeopleRecordMapper.deleteSysPeopleRecordByIds(ids); + } + + /** + * 删除人员识别记录信息 + * + * @param id 人员识别记录主键 + * @return 结果 + */ + @Override + public int deleteSysPeopleRecordById(Long id) + { + return sysPeopleRecordMapper.deleteSysPeopleRecordById(id); + } + + @Override + public AjaxResult topApi() { + List> list=sysPeopleRecordMapper.topApi(); + + return AjaxResult.success(list); + } + + + @Override + public String selectPeopleRecordById(String deviceKey) { + return sysPeopleRecordMapper.selectPeopleRecordById(deviceKey); + } + + /** + * 查询通行统计数量(昨天,今天) + * @return + */ + @Override + public List queryThroughCount() { + return sysPeopleRecordMapper.queryThroughCount(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPeopleRuleServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPeopleRuleServiceImpl.java new file mode 100644 index 0000000..654a4db --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPeopleRuleServiceImpl.java @@ -0,0 +1,96 @@ +package com.dcsoft.system.service.impl; + +import java.util.List; +import com.dcsoft.common.core.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.dcsoft.system.mapper.SysPeopleRuleMapper; +import com.dcsoft.system.domain.SysPeopleRule; +import com.dcsoft.system.service.ISysPeopleRuleService; + +/** + * 人员规则关联Service业务层处理 + * + * @author dcsoft + * @date 2023-12-22 + */ +@Service +public class SysPeopleRuleServiceImpl implements ISysPeopleRuleService +{ + @Autowired + private SysPeopleRuleMapper sysPeopleRuleMapper; + + /** + * 查询人员规则关联 + * + * @param id 人员规则关联主键 + * @return 人员规则关联 + */ + @Override + public SysPeopleRule selectSysPeopleRuleById(Long id) + { + return sysPeopleRuleMapper.selectSysPeopleRuleById(id); + } + + /** + * 查询人员规则关联列表 + * + * @param sysPeopleRule 人员规则关联 + * @return 人员规则关联 + */ + @Override + public List selectSysPeopleRuleList(SysPeopleRule sysPeopleRule) + { + return sysPeopleRuleMapper.selectSysPeopleRuleList(sysPeopleRule); + } + + /** + * 新增人员规则关联 + * + * @param sysPeopleRule 人员规则关联 + * @return 结果 + */ + @Override + public int insertSysPeopleRule(SysPeopleRule sysPeopleRule) + { + sysPeopleRule.setCreateTime(DateUtils.getNowDate()); + return sysPeopleRuleMapper.insertSysPeopleRule(sysPeopleRule); + } + + /** + * 修改人员规则关联 + * + * @param sysPeopleRule 人员规则关联 + * @return 结果 + */ + @Override + public int updateSysPeopleRule(SysPeopleRule sysPeopleRule) + { + sysPeopleRule.setUpdateTime(DateUtils.getNowDate()); + return sysPeopleRuleMapper.updateSysPeopleRule(sysPeopleRule); + } + + /** + * 批量删除人员规则关联 + * + * @param ids 需要删除的人员规则关联主键 + * @return 结果 + */ + @Override + public int deleteSysPeopleRuleByIds(Long[] ids) + { + return sysPeopleRuleMapper.deleteSysPeopleRuleByIds(ids); + } + + /** + * 删除人员规则关联信息 + * + * @param id 人员规则关联主键 + * @return 结果 + */ + @Override + public int deleteSysPeopleRuleById(Long id) + { + return sysPeopleRuleMapper.deleteSysPeopleRuleById(id); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPeopleServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPeopleServiceImpl.java new file mode 100644 index 0000000..bb080a1 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPeopleServiceImpl.java @@ -0,0 +1,401 @@ +package com.dcsoft.system.service.impl; + +import com.dcsoft.common.core.exception.ServiceException; +import com.dcsoft.common.core.utils.DateUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.utils.uuid.IdUtils; +import com.dcsoft.common.datascope.annotation.DataScope; +import com.dcsoft.system.domain.SysBranch; +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.domain.vo.JjDivisionVo; +import com.dcsoft.system.domain.vo.OfficialAccountVo; +import com.dcsoft.system.mapper.SysBranchMapper; +import com.dcsoft.system.mapper.SysPeopleMapper; +import com.dcsoft.system.service.ISysPeopleService; +import com.dcsoft.system.service.ISysSyncRuleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import static com.dcsoft.common.core.utils.PageUtils.startPage; + + +/** + * 人员管理Service业务层处理 + * + * @author nichun + * @date 2023-03-08 + */ +@Service +public class SysPeopleServiceImpl implements ISysPeopleService +{ + @Autowired + private SysPeopleMapper sysPeopleMapper; + + @Autowired + private SysBranchMapper sysBranchMapper; + + @Autowired + private ISysSyncRuleService syncRuleService; + + + + /** + * 查询人员管理 + * + * @param id 人员管理主键 + * @return 人员管理 + */ + @Override + public SysPeople selectSysPeopleById(Long id) + { + return sysPeopleMapper.selectSysPeopleById(id); + } + + /** + * 查询人员管理列表 + * + * @param sysPeople 人员管理 + * @return 人员管理 + */ + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List selectSysPeopleList(SysPeople sysPeople) + { + List listStr = new ArrayList<>(); + if(!"1".equals(sysPeople.getBranchId())) { + List list = sysBranchMapper.selectBranchTree(sysPeople); + List list1 = new ArrayList<>(); + if(StringUtils.isNotEmpty(sysPeople.getBranchId())) { + getParentNode(list1, list, sysPeople.getBranchId()); + } else { + list1.addAll(list); + } + listStr = list1.stream().map(JjDivisionVo::getId).collect(Collectors.toList()); + listStr.add(sysPeople.getBranchId()); + } + startPage(); + sysPeople.setDelFlag(0L); + return sysPeopleMapper.selectSysPeopleList(sysPeople, listStr); + } + + + @Override + public List queryPeopleList(SysPeople sysPeople) { + List listStr = new ArrayList<>(); + if(!"0".equals(sysPeople.getBranchId()) && StringUtils.isNotEmpty(sysPeople.getBranchId())) { + List list = sysBranchMapper.selectBranchTree(null); + List list1 = new ArrayList<>(); + getParentNode(list1, list, sysPeople.getBranchId()); + listStr = list1.stream().map(JjDivisionVo::getId).collect(Collectors.toList()); + listStr.add(sysPeople.getBranchId()); + } + + sysPeople.setDelFlag(0L); + List sysPeople1 = sysPeopleMapper.selectSysPeopleList(sysPeople, listStr); + for (SysPeople people : sysPeople1) { + people.setName(people.getName() + "-" + people.getPhone()); + } + return sysPeople1; + } + + @Override + public SysPeople selectSysPeopleByGh(String gh) { + return sysPeopleMapper.selectSysPeopleByGh(gh); + } + + @Override + public SysPeople selectSysPeopleByDoorNo(String doorNo) { + return sysPeopleMapper.selectSysPeopleByDoorNo(doorNo); + } + + @Override + public SysPeople queryEmpowerRecord(String phone) { + return sysPeopleMapper.queryEmpowerRecord(phone); + } + + @Override + public SysPeople queryPeopleByOpenid(String openid) { + return sysPeopleMapper.queryPeopleByOpenid(openid); + } + + /** + * 通过职位标签查询人员信息 + * @param position + * @return + */ + @Override + public List queryPeopleByPosition(String position) { + return sysPeopleMapper.queryPeopleByPosition(position); + } + + @Override + public List querySysPeopleInfo(Long userId) { + return sysPeopleMapper.querySysPeopleInfo(userId); + } + + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List selectSysPeopleLists(SysPeople sysPeople) + { + List listStr = new ArrayList<>(); + if(!"0".equals(sysPeople.getBranchId())) { + List list = sysBranchMapper.selectBranchTree(sysPeople); + List list1 = new ArrayList<>(); + if(StringUtils.isNotEmpty(sysPeople.getBranchId())) { + getParentNode(list1, list, sysPeople.getBranchId()); + } else { + list1.addAll(list); + } + listStr = list1.stream().map(JjDivisionVo::getId).collect(Collectors.toList()); + listStr.add(sysPeople.getBranchId()); + } + sysPeople.setDelFlag(0L); + return sysPeopleMapper.selectSysPeopleList(sysPeople, listStr); + } + + private void getParentNode(List childMenu, List menuList, String pid) { + menuList.stream() + //过滤出父id等于参数的id + .filter(menu -> StringUtils.isNotBlank(menu.getParentId()) && menu.getParentId().equals(pid)) + .forEach(menu -> { + //递归遍历下一级 + getParentNode(childMenu, menuList, menu.getId()); + //添加 + childMenu.add(menu); + }); + } + + /** + * 新增人员管理 + * + * @param sysPeople 人员管理 + * @return 结果 + */ + @Override + public int insertSysPeople(SysPeople sysPeople) + { + sysPeople.setCreateTime(DateUtils.getNowDate()); + syncRuleService.addPeople(sysPeople,"add"); + return sysPeopleMapper.insertSysPeople(sysPeople); + } + + /** + * 修改人员管理 + * + * @param sysPeople 人员管理 + * @return 结果 + */ + @Override + public int updateSysPeople(SysPeople sysPeople) + { + sysPeople.setUpdateTime(DateUtils.getNowDate()); + if (!"10".equals(sysPeople.getWxFlag())) { + syncRuleService.addPeople(sysPeople,"update"); + } + return sysPeopleMapper.updateSysPeople(sysPeople); + } + + /** + * 批量删除人员管理 + * + * @param ids 需要删除的人员管理主键 + * @return 结果 + */ + @Override + public int deleteSysPeopleByIds(Long[] ids) + { + for(Long id:ids){ + SysPeople branch=new SysPeople(); + branch.setId(id); + syncRuleService.addPeople(branch,"delete"); + } + return sysPeopleMapper.deleteSysPeopleByIds(ids); + } + + /** + * 删除人员管理信息 + * + * @param id 人员管理主键 + * @return 结果 + */ + @Override + public int deleteSysPeopleById(Long id) + { + return sysPeopleMapper.deleteSysPeopleById(id); + } + + @Override + public SysPeople selectByGuid(SysPeople sysPeople) { + return sysPeopleMapper.selectByGuid(sysPeople); + } + + @Override + public SysPeople selectSysPeopleByUserId(Long userId) { + return sysPeopleMapper.selectSysPeopleByUserId(userId); + } + + @Override + public SysPeople selectSysPeopleByBranchUser(String branchName, String userName) { + return sysPeopleMapper.selectSysPeopleByBranchUser(branchName,userName); + } + + @Override + public SysPeople selectSysPeopleByPhoneUser(SysPeople sysPeople) { + return sysPeopleMapper.selectSysPeopleByPhoneUser(sysPeople); + } + + @Override + public List queryPeopleInfo() { + return sysPeopleMapper.queryPeopleInfo(); + } + + /** + * 查询ids + */ + @Override + public List queryPeople(List collectStr) { + return sysPeopleMapper.queryPeople(collectStr); + } + + /** + * 查询人员详情 + */ + @Override + public SysPeople queryPeopleDetails(String details) { + return sysPeopleMapper.queryPeopleDetails(details); + } + + @Override + public int updateSysPeoples(SysPeople sysPeople) { + //规则下发 + return sysPeopleMapper.updateSysPeople(sysPeople); + } + + @Override + public int insertSysPeoples(SysPeople sysPeople) { + int i=sysPeopleMapper.insertSysPeople(sysPeople); + return i; + } + + @Override + public int deleteSysPeopleByGuid(String guid) { + //规则下发 + return sysPeopleMapper.deleteSysPeopleByGuid(guid); + } + + @Override + public void updatePeople(SysPeople people) { + sysPeopleMapper.updatePeople(people); + } + + @Override + public String selectDoorNo(Long id) { + return sysPeopleMapper.selectDoorNo(id); + } + + @Override + public String selectPeopleById(String card) { + return sysPeopleMapper.selectPeopleById(card); + } + + @Override + public void updatePeopleInfo(SysPeople sysPeople) { + sysPeopleMapper.updatePeopleInfo(sysPeople); + } + + @Override + public OfficialAccountVo queryPeopleById(String id) { + return sysPeopleMapper.queryPeopleById(id); + } + + @Override + public SysPeople selectSysPeopleByOpenId(String openid) { + return sysPeopleMapper.selectSysPeopleByOpenId(openid); + } + + @Override + public SysPeople selectSysPeopleByGh(String phone,String name) { + return sysPeopleMapper.selectSysPeopleGh(phone,name); + } + + @Override + public SysPeople queryPeopleName(String phone, List collect) { + return sysPeopleMapper.queryPeopleName(phone, collect); + } + + + + + /** + * 导入用户数据 + * + * @param userList 用户数据列表 + * @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据 + * @param operName 操作用户 + * @return 结果 + */ + @Override + public String importPeople(List userList, boolean isUpdateSupport, String operName) + { + if (StringUtils.isNull(userList) || userList.size() == 0) + { + throw new ServiceException("导入用户数据不能为空!"); + } + int successNum = 0; + int failureNum = 0; + StringBuilder successMsg = new StringBuilder(); + StringBuilder failureMsg = new StringBuilder(); + for (SysPeople user : userList) + { + try + { + // 验证是否存在这个用户 + SysPeople u = sysPeopleMapper.selectSysPeopleByGh(user.getGh()); + SysBranch branch=new SysBranch(); + branch.setName(user.getBranchName()); + List branchlist=sysBranchMapper.selectSysBranchList(branch); + if(branchlist.size()>0){ + user.setBranchId(branchlist.get(0).getId()); + } + if (StringUtils.isNull(u)) + { + user.setGuid(IdUtils.simpleUUID()); + this.insertSysPeople(user); + successNum++; + successMsg.append("
" + successNum + "、工号 " + user.getGh() + " 导入成功"); + } + else if (isUpdateSupport) + { + this.updateSysPeople(user); + successNum++; + successMsg.append("
" + successNum + "、工号 " + user.getGh() + " 更新成功"); + } + else + { + failureNum++; + failureMsg.append("
" + failureNum + "、工号 " + user.getGh() + " 已存在"); + } + } + catch (Exception e) + { + failureNum++; + String msg = "
" + failureNum + "、工号 " + user.getGh() + " 导入失败:"; + failureMsg.append(msg + e.getMessage()); + } + } + if (failureNum > 0) + { + failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:"); + throw new ServiceException(failureMsg.toString()); + } + else + { + successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:"); + } + return successMsg.toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPermissionServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPermissionServiceImpl.java new file mode 100644 index 0000000..73d1bff --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPermissionServiceImpl.java @@ -0,0 +1,85 @@ +package com.dcsoft.system.service.impl; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.dcsoft.system.api.domain.SysRole; +import com.dcsoft.system.api.domain.SysUser; +import com.dcsoft.system.service.ISysMenuService; +import com.dcsoft.system.service.ISysPermissionService; +import com.dcsoft.system.service.ISysRoleService; + +/** + * 用户权限处理 + * + * @author dcsoft + */ +@Service +public class SysPermissionServiceImpl implements ISysPermissionService +{ + @Autowired + private ISysRoleService roleService; + + @Autowired + private ISysMenuService menuService; + + /** + * 获取角色数据权限 + * + * @param userId 用户Id + * @return 角色权限信息 + */ + @Override + public Set getRolePermission(SysUser user) + { + Set roles = new HashSet(); + // 管理员拥有所有权限 + if (user.isAdmin()) + { + roles.add("admin"); + } + else + { + roles.addAll(roleService.selectRolePermissionByUserId(user.getUserId())); + } + return roles; + } + + /** + * 获取菜单数据权限 + * + * @param userId 用户Id + * @return 菜单权限信息 + */ + @Override + public Set getMenuPermission(SysUser user) + { + Set perms = new HashSet(); + // 管理员拥有所有权限 + if (user.isAdmin()) + { + perms.add("*:*:*"); + } + else + { + List roles = user.getRoles(); + if (!roles.isEmpty() && roles.size() > 1) + { + // 多角色设置permissions属性,以便数据权限匹配权限 + for (SysRole role : roles) + { + Set rolePerms = menuService.selectMenuPermsByRoleId(role.getRoleId()); + role.setPermissions(rolePerms); + perms.addAll(rolePerms); + } + } + else + { + perms.addAll(menuService.selectMenuPermsByUserId(user.getUserId())); + } + } + return perms; + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPointServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPointServiceImpl.java new file mode 100644 index 0000000..2e753e3 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPointServiceImpl.java @@ -0,0 +1,96 @@ +package com.dcsoft.system.service.impl; + +import java.util.List; +import com.dcsoft.common.core.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.dcsoft.system.mapper.SysPointMapper; +import com.dcsoft.system.domain.SysPoint; +import com.dcsoft.system.service.ISysPointService; + +/** + * 点位管理Service业务层处理 + * + * @author nichun + * @date 2023-03-08 + */ +@Service +public class SysPointServiceImpl implements ISysPointService +{ + @Autowired + private SysPointMapper sysPointMapper; + + /** + * 查询点位管理 + * + * @param id 点位管理主键 + * @return 点位管理 + */ + @Override + public SysPoint selectSysPointById(Long id) + { + return sysPointMapper.selectSysPointById(id); + } + + /** + * 查询点位管理列表 + * + * @param sysPoint 点位管理 + * @return 点位管理 + */ + @Override + public List selectSysPointList(SysPoint sysPoint) + { + return sysPointMapper.selectSysPointList(sysPoint); + } + + /** + * 新增点位管理 + * + * @param sysPoint 点位管理 + * @return 结果 + */ + @Override + public int insertSysPoint(SysPoint sysPoint) + { + sysPoint.setCreateTime(DateUtils.getNowDate()); + return sysPointMapper.insertSysPoint(sysPoint); + } + + /** + * 修改点位管理 + * + * @param sysPoint 点位管理 + * @return 结果 + */ + @Override + public int updateSysPoint(SysPoint sysPoint) + { + sysPoint.setUpdateTime(DateUtils.getNowDate()); + return sysPointMapper.updateSysPoint(sysPoint); + } + + /** + * 批量删除点位管理 + * + * @param ids 需要删除的点位管理主键 + * @return 结果 + */ + @Override + public int deleteSysPointByIds(Long[] ids) + { + return sysPointMapper.deleteSysPointByIds(ids); + } + + /** + * 删除点位管理信息 + * + * @param id 点位管理主键 + * @return 结果 + */ + @Override + public int deleteSysPointById(Long id) + { + return sysPointMapper.deleteSysPointById(id); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPostServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPostServiceImpl.java new file mode 100644 index 0000000..45d5508 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysPostServiceImpl.java @@ -0,0 +1,178 @@ +package com.dcsoft.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.dcsoft.common.core.constant.UserConstants; +import com.dcsoft.common.core.exception.ServiceException; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.system.domain.SysPost; +import com.dcsoft.system.mapper.SysPostMapper; +import com.dcsoft.system.mapper.SysUserPostMapper; +import com.dcsoft.system.service.ISysPostService; + +/** + * 岗位信息 服务层处理 + * + * @author dcsoft + */ +@Service +public class SysPostServiceImpl implements ISysPostService +{ + @Autowired + private SysPostMapper postMapper; + + @Autowired + private SysUserPostMapper userPostMapper; + + /** + * 查询岗位信息集合 + * + * @param post 岗位信息 + * @return 岗位信息集合 + */ + @Override + public List selectPostList(SysPost post) + { + return postMapper.selectPostList(post); + } + + /** + * 查询所有岗位 + * + * @return 岗位列表 + */ + @Override + public List selectPostAll() + { + return postMapper.selectPostAll(); + } + + /** + * 通过岗位ID查询岗位信息 + * + * @param postId 岗位ID + * @return 角色对象信息 + */ + @Override + public SysPost selectPostById(Long postId) + { + return postMapper.selectPostById(postId); + } + + /** + * 根据用户ID获取岗位选择框列表 + * + * @param userId 用户ID + * @return 选中岗位ID列表 + */ + @Override + public List selectPostListByUserId(Long userId) + { + return postMapper.selectPostListByUserId(userId); + } + + /** + * 校验岗位名称是否唯一 + * + * @param post 岗位信息 + * @return 结果 + */ + @Override + public boolean checkPostNameUnique(SysPost post) + { + Long postId = StringUtils.isNull(post.getPostId()) ? -1L : post.getPostId(); + SysPost info = postMapper.checkPostNameUnique(post.getPostName()); + if (StringUtils.isNotNull(info) && info.getPostId().longValue() != postId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验岗位编码是否唯一 + * + * @param post 岗位信息 + * @return 结果 + */ + @Override + public boolean checkPostCodeUnique(SysPost post) + { + Long postId = StringUtils.isNull(post.getPostId()) ? -1L : post.getPostId(); + SysPost info = postMapper.checkPostCodeUnique(post.getPostCode()); + if (StringUtils.isNotNull(info) && info.getPostId().longValue() != postId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 通过岗位ID查询岗位使用数量 + * + * @param postId 岗位ID + * @return 结果 + */ + @Override + public int countUserPostById(Long postId) + { + return userPostMapper.countUserPostById(postId); + } + + /** + * 删除岗位信息 + * + * @param postId 岗位ID + * @return 结果 + */ + @Override + public int deletePostById(Long postId) + { + return postMapper.deletePostById(postId); + } + + /** + * 批量删除岗位信息 + * + * @param postIds 需要删除的岗位ID + * @return 结果 + */ + @Override + public int deletePostByIds(Long[] postIds) + { + for (Long postId : postIds) + { + SysPost post = selectPostById(postId); + if (countUserPostById(postId) > 0) + { + throw new ServiceException(String.format("%1$s已分配,不能删除", post.getPostName())); + } + } + return postMapper.deletePostByIds(postIds); + } + + /** + * 新增保存岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + @Override + public int insertPost(SysPost post) + { + return postMapper.insertPost(post); + } + + /** + * 修改保存岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + @Override + public int updatePost(SysPost post) + { + return postMapper.updatePost(post); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysProductServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysProductServiceImpl.java new file mode 100644 index 0000000..2b6236a --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysProductServiceImpl.java @@ -0,0 +1,96 @@ +package com.dcsoft.system.service.impl; + +import java.util.List; +import com.dcsoft.common.core.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.dcsoft.system.mapper.SysProductMapper; +import com.dcsoft.system.domain.SysProduct; +import com.dcsoft.system.service.ISysProductService; + +/** + * 产品信息Service业务层处理 + * + * @author nichun + * @date 2023-03-08 + */ +@Service +public class SysProductServiceImpl implements ISysProductService +{ + @Autowired + private SysProductMapper sysProductMapper; + + /** + * 查询产品信息 + * + * @param id 产品信息主键 + * @return 产品信息 + */ + @Override + public SysProduct selectSysProductById(Long id) + { + return sysProductMapper.selectSysProductById(id); + } + + /** + * 查询产品信息列表 + * + * @param sysProduct 产品信息 + * @return 产品信息 + */ + @Override + public List selectSysProductList(SysProduct sysProduct) + { + return sysProductMapper.selectSysProductList(sysProduct); + } + + /** + * 新增产品信息 + * + * @param sysProduct 产品信息 + * @return 结果 + */ + @Override + public int insertSysProduct(SysProduct sysProduct) + { + sysProduct.setCreateTime(DateUtils.getNowDate()); + return sysProductMapper.insertSysProduct(sysProduct); + } + + /** + * 修改产品信息 + * + * @param sysProduct 产品信息 + * @return 结果 + */ + @Override + public int updateSysProduct(SysProduct sysProduct) + { + sysProduct.setUpdateTime(DateUtils.getNowDate()); + return sysProductMapper.updateSysProduct(sysProduct); + } + + /** + * 批量删除产品信息 + * + * @param ids 需要删除的产品信息主键 + * @return 结果 + */ + @Override + public int deleteSysProductByIds(Long[] ids) + { + return sysProductMapper.deleteSysProductByIds(ids); + } + + /** + * 删除产品信息信息 + * + * @param id 产品信息主键 + * @return 结果 + */ + @Override + public int deleteSysProductById(Long id) + { + return sysProductMapper.deleteSysProductById(id); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysRoleServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysRoleServiceImpl.java new file mode 100644 index 0000000..4a008d7 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysRoleServiceImpl.java @@ -0,0 +1,424 @@ +package com.dcsoft.system.service.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.dcsoft.common.core.constant.UserConstants; +import com.dcsoft.common.core.exception.ServiceException; +import com.dcsoft.common.core.utils.SpringUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.datascope.annotation.DataScope; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.api.domain.SysRole; +import com.dcsoft.system.api.domain.SysUser; +import com.dcsoft.system.domain.SysRoleDept; +import com.dcsoft.system.domain.SysRoleMenu; +import com.dcsoft.system.domain.SysUserRole; +import com.dcsoft.system.mapper.SysRoleDeptMapper; +import com.dcsoft.system.mapper.SysRoleMapper; +import com.dcsoft.system.mapper.SysRoleMenuMapper; +import com.dcsoft.system.mapper.SysUserRoleMapper; +import com.dcsoft.system.service.ISysRoleService; + +/** + * 角色 业务层处理 + * + * @author dcsoft + */ +@Service +public class SysRoleServiceImpl implements ISysRoleService +{ + @Autowired + private SysRoleMapper roleMapper; + + @Autowired + private SysRoleMenuMapper roleMenuMapper; + + @Autowired + private SysUserRoleMapper userRoleMapper; + + @Autowired + private SysRoleDeptMapper roleDeptMapper; + + /** + * 根据条件分页查询角色数据 + * + * @param role 角色信息 + * @return 角色数据集合信息 + */ + @Override + @DataScope(deptAlias = "d") + public List selectRoleList(SysRole role) + { + return roleMapper.selectRoleList(role); + } + + /** + * 根据用户ID查询角色 + * + * @param userId 用户ID + * @return 角色列表 + */ + @Override + public List selectRolesByUserId(Long userId) + { + List userRoles = roleMapper.selectRolePermissionByUserId(userId); + List roles = selectRoleAll(); + for (SysRole role : roles) + { + for (SysRole userRole : userRoles) + { + if (role.getRoleId().longValue() == userRole.getRoleId().longValue()) + { + role.setFlag(true); + break; + } + } + } + return roles; + } + + /** + * 根据用户ID查询权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + @Override + public Set selectRolePermissionByUserId(Long userId) + { + List perms = roleMapper.selectRolePermissionByUserId(userId); + Set permsSet = new HashSet<>(); + for (SysRole perm : perms) + { + if (StringUtils.isNotNull(perm)) + { + permsSet.addAll(Arrays.asList(perm.getRoleKey().trim().split(","))); + } + } + return permsSet; + } + + /** + * 查询所有角色 + * + * @return 角色列表 + */ + @Override + public List selectRoleAll() + { + return SpringUtils.getAopProxy(this).selectRoleList(new SysRole()); + } + + /** + * 根据用户ID获取角色选择框列表 + * + * @param userId 用户ID + * @return 选中角色ID列表 + */ + @Override + public List selectRoleListByUserId(Long userId) + { + return roleMapper.selectRoleListByUserId(userId); + } + + /** + * 通过角色ID查询角色 + * + * @param roleId 角色ID + * @return 角色对象信息 + */ + @Override + public SysRole selectRoleById(Long roleId) + { + return roleMapper.selectRoleById(roleId); + } + + /** + * 校验角色名称是否唯一 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + public boolean checkRoleNameUnique(SysRole role) + { + Long roleId = StringUtils.isNull(role.getRoleId()) ? -1L : role.getRoleId(); + SysRole info = roleMapper.checkRoleNameUnique(role.getRoleName()); + if (StringUtils.isNotNull(info) && info.getRoleId().longValue() != roleId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验角色权限是否唯一 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + public boolean checkRoleKeyUnique(SysRole role) + { + Long roleId = StringUtils.isNull(role.getRoleId()) ? -1L : role.getRoleId(); + SysRole info = roleMapper.checkRoleKeyUnique(role.getRoleKey()); + if (StringUtils.isNotNull(info) && info.getRoleId().longValue() != roleId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验角色是否允许操作 + * + * @param role 角色信息 + */ + @Override + public void checkRoleAllowed(SysRole role) + { + if (StringUtils.isNotNull(role.getRoleId()) && role.isAdmin()) + { + throw new ServiceException("不允许操作超级管理员角色"); + } + } + + /** + * 校验角色是否有数据权限 + * + * @param roleId 角色id + */ + @Override + public void checkRoleDataScope(Long roleId) + { + if (!SysUser.isAdmin(SecurityUtils.getUserId())) + { + SysRole role = new SysRole(); + role.setRoleId(roleId); + List roles = SpringUtils.getAopProxy(this).selectRoleList(role); + if (StringUtils.isEmpty(roles)) + { + throw new ServiceException("没有权限访问角色数据!"); + } + } + } + + /** + * 通过角色ID查询角色使用数量 + * + * @param roleId 角色ID + * @return 结果 + */ + @Override + public int countUserRoleByRoleId(Long roleId) + { + return userRoleMapper.countUserRoleByRoleId(roleId); + } + + /** + * 新增保存角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int insertRole(SysRole role) + { + // 新增角色信息 + roleMapper.insertRole(role); + return insertRoleMenu(role); + } + + /** + * 修改保存角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int updateRole(SysRole role) + { + // 修改角色信息 + roleMapper.updateRole(role); + // 删除角色与菜单关联 + roleMenuMapper.deleteRoleMenuByRoleId(role.getRoleId()); + return insertRoleMenu(role); + } + + /** + * 修改角色状态 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + public int updateRoleStatus(SysRole role) + { + return roleMapper.updateRole(role); + } + + /** + * 修改数据权限信息 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int authDataScope(SysRole role) + { + // 修改角色信息 + roleMapper.updateRole(role); + // 删除角色与部门关联 + roleDeptMapper.deleteRoleDeptByRoleId(role.getRoleId()); + // 新增角色和部门信息(数据权限) + return insertRoleDept(role); + } + + /** + * 新增角色菜单信息 + * + * @param role 角色对象 + */ + public int insertRoleMenu(SysRole role) + { + int rows = 1; + // 新增用户与角色管理 + List list = new ArrayList(); + for (Long menuId : role.getMenuIds()) + { + SysRoleMenu rm = new SysRoleMenu(); + rm.setRoleId(role.getRoleId()); + rm.setMenuId(menuId); + list.add(rm); + } + if (list.size() > 0) + { + rows = roleMenuMapper.batchRoleMenu(list); + } + return rows; + } + + /** + * 新增角色部门信息(数据权限) + * + * @param role 角色对象 + */ + public int insertRoleDept(SysRole role) + { + int rows = 1; + // 新增角色与部门(数据权限)管理 + List list = new ArrayList(); + for (Long deptId : role.getDeptIds()) + { + SysRoleDept rd = new SysRoleDept(); + rd.setRoleId(role.getRoleId()); + rd.setDeptId(deptId); + list.add(rd); + } + if (list.size() > 0) + { + rows = roleDeptMapper.batchRoleDept(list); + } + return rows; + } + + /** + * 通过角色ID删除角色 + * + * @param roleId 角色ID + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int deleteRoleById(Long roleId) + { + // 删除角色与菜单关联 + roleMenuMapper.deleteRoleMenuByRoleId(roleId); + // 删除角色与部门关联 + roleDeptMapper.deleteRoleDeptByRoleId(roleId); + return roleMapper.deleteRoleById(roleId); + } + + /** + * 批量删除角色信息 + * + * @param roleIds 需要删除的角色ID + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int deleteRoleByIds(Long[] roleIds) + { + for (Long roleId : roleIds) + { + checkRoleAllowed(new SysRole(roleId)); + checkRoleDataScope(roleId); + SysRole role = selectRoleById(roleId); + if (countUserRoleByRoleId(roleId) > 0) + { + throw new ServiceException(String.format("%1$s已分配,不能删除", role.getRoleName())); + } + } + // 删除角色与菜单关联 + roleMenuMapper.deleteRoleMenu(roleIds); + // 删除角色与部门关联 + roleDeptMapper.deleteRoleDept(roleIds); + return roleMapper.deleteRoleByIds(roleIds); + } + + /** + * 取消授权用户角色 + * + * @param userRole 用户和角色关联信息 + * @return 结果 + */ + @Override + public int deleteAuthUser(SysUserRole userRole) + { + return userRoleMapper.deleteUserRoleInfo(userRole); + } + + /** + * 批量取消授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要取消授权的用户数据ID + * @return 结果 + */ + @Override + public int deleteAuthUsers(Long roleId, Long[] userIds) + { + return userRoleMapper.deleteUserRoleInfos(roleId, userIds); + } + + /** + * 批量选择授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要授权的用户数据ID + * @return 结果 + */ + @Override + public int insertAuthUsers(Long roleId, Long[] userIds) + { + // 新增用户与角色管理 + List list = new ArrayList(); + for (Long userId : userIds) + { + SysUserRole ur = new SysUserRole(); + ur.setUserId(userId); + ur.setRoleId(roleId); + list.add(ur); + } + return userRoleMapper.batchUserRole(list); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysRuleServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysRuleServiceImpl.java new file mode 100644 index 0000000..2639891 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysRuleServiceImpl.java @@ -0,0 +1,212 @@ +package com.dcsoft.system.service.impl; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; + +import com.dcsoft.common.core.utils.CollUtil; +import com.dcsoft.common.core.utils.DateUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.system.domain.SysPoint; +import com.dcsoft.system.domain.SysSpace; +import com.dcsoft.system.domain.vo.SysAuthTree; +import com.dcsoft.system.domain.vo.TreeSelect; +import com.dcsoft.system.mapper.SysPointMapper; +import com.dcsoft.system.mapper.SysSpaceMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.dcsoft.system.mapper.SysRuleMapper; +import com.dcsoft.system.domain.SysRule; +import com.dcsoft.system.service.ISysRuleService; + +/** + * 通行规则Service业务层处理 + * + * @author nichun + * @date 2023-03-08 + */ +@Service +public class SysRuleServiceImpl implements ISysRuleService +{ + @Autowired + private SysRuleMapper sysRuleMapper; + + @Autowired + private SysSpaceMapper spaceManager; + + @Autowired + private SysPointMapper pointManager; + + /** + * 查询通行规则 + * + * @param id 通行规则主键 + * @return 通行规则 + */ + @Override + public SysRule selectSysRuleById(Long id) + { + return sysRuleMapper.selectSysRuleById(id); + } + + /** + * 查询通行规则列表 + * + * @param sysRule 通行规则 + * @return 通行规则 + */ + @Override + public List selectSysRuleList(SysRule sysRule) + { + return sysRuleMapper.selectSysRuleList(sysRule); + } + + /** + * 新增通行规则 + * + * @param sysRule 通行规则 + * @return 结果 + */ + @Override + public int insertSysRule(SysRule sysRule) + { + sysRule.setCreateTime(DateUtils.getNowDate()); + return sysRuleMapper.insertSysRule(sysRule); + } + + /** + * 修改通行规则 + * + * @param sysRule 通行规则 + * @return 结果 + */ + @Override + public int updateSysRule(SysRule sysRule) + { + sysRule.setUpdateTime(DateUtils.getNowDate()); + return sysRuleMapper.updateSysRule(sysRule); + } + + /** + * 批量删除通行规则 + * + * @param ids 需要删除的通行规则主键 + * @return 结果 + */ + @Override + public int deleteSysRuleByIds(Long[] ids) + { + return sysRuleMapper.deleteSysRuleByIds(ids); + } + + /** + * 删除通行规则信息 + * + * @param id 通行规则主键 + * @return 结果 + */ + @Override + public int deleteSysRuleById(Long id) + { + return sysRuleMapper.deleteSysRuleById(id); + } + + @Override + public List selectRuleAuthScope() { + List modules = spaceManager.selectSysSpaceList(new SysSpace()); + return buildSpaceTreeSelect(modules); + } + + @Override + public List queryRuleAuth() { + return null; + } + + /** + * 构建前端所需要下拉树结构 + * + * @param spaces 空间列表 + * @return 下拉树结构列表 + */ + public List buildSpaceTreeSelect(List spaces) + { + List spaceTrees = buildSpaceTree(spaces); + return spaceTrees.stream().map(SysAuthTree::new).collect(Collectors.toList()); + } + + /** + * 构建前端所需要树结构 + * + * @param spaces 空间列表 + * @return 树结构列表 + */ + public List buildSpaceTree(List spaces) + { + List returnList = new ArrayList(); + List tempList = spaces.stream().map(SysSpace::getId).collect(Collectors.toList()); + for (SysSpace space : spaces) + { + // 如果是顶级节点, 遍历该父节点的所有子节点 + if (!tempList.contains(space.getParentId())) + { + recursionFn(spaces, space); + returnList.add(space); + } + + } + if (returnList.isEmpty()) + { + returnList = spaces; + } + return returnList; + } + + /** + * 递归列表 + */ + private void recursionFn(List list, SysSpace t) + { + // 得到子节点列表 + List childList = getChildList(list, t); + t.setChildren(childList); + SysPoint point=new SysPoint(); + point.setSpaceId(t.getId()); + List pointList = pointManager.selectSysPointList(point); + t.setChildren1(pointList); + for (SysSpace tChild : childList) + { + recursionFn(list, tChild); + /* if (hasChild(list, tChild)) + { + recursionFn(list, tChild); + }*/ + } + } + + /** + * 得到子节点列表 + */ + private List getChildList(List list, SysSpace t) + { + List tlist = new ArrayList(); + Iterator it = list.iterator(); + while (it.hasNext()) + { + SysSpace n = (SysSpace) it.next(); + if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getId().longValue()) + { + tlist.add(n); + } + } + return tlist; + } + + /** + * 判断是否有子节点 + */ + private boolean hasChild(List list, SysSpace t) + { + return getChildList(list, t).size() > 0 ? true : false; + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysSpaceServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysSpaceServiceImpl.java new file mode 100644 index 0000000..519f8b2 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysSpaceServiceImpl.java @@ -0,0 +1,201 @@ +package com.dcsoft.system.service.impl; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; + +import com.dcsoft.common.core.utils.DateUtils; +import com.dcsoft.common.core.utils.SpringUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.system.domain.vo.TreeSelect; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.dcsoft.system.mapper.SysSpaceMapper; +import com.dcsoft.system.domain.SysSpace; +import com.dcsoft.system.service.ISysSpaceService; + +/** + * 空间管理Service业务层处理 + * + * @author nichun + * @date 2023-03-08 + */ +@Service +public class SysSpaceServiceImpl implements ISysSpaceService +{ + @Autowired + private SysSpaceMapper sysSpaceMapper; + + /** + * 查询空间管理 + * + * @param id 空间管理主键 + * @return 空间管理 + */ + @Override + public SysSpace selectSysSpaceById(Long id) + { + return sysSpaceMapper.selectSysSpaceById(id); + } + + /** + * 查询空间管理列表 + * + * @param sysSpace 空间管理 + * @return 空间管理 + */ + @Override + public List selectSysSpaceList(SysSpace sysSpace) + { + return sysSpaceMapper.selectSysSpaceList(sysSpace); + } + + /** + * 新增空间管理 + * + * @param sysSpace 空间管理 + * @return 结果 + */ + @Override + public int insertSysSpace(SysSpace sysSpace) + { + sysSpace.setCreateTime(DateUtils.getNowDate()); + return sysSpaceMapper.insertSysSpace(sysSpace); + } + + /** + * 修改空间管理 + * + * @param sysSpace 空间管理 + * @return 结果 + */ + @Override + public int updateSysSpace(SysSpace sysSpace) + { + sysSpace.setUpdateTime(DateUtils.getNowDate()); + return sysSpaceMapper.updateSysSpace(sysSpace); + } + + /** + * 批量删除空间管理 + * + * @param ids 需要删除的空间管理主键 + * @return 结果 + */ + @Override + public int deleteSysSpaceByIds(Long[] ids) + { + return sysSpaceMapper.deleteSysSpaceByIds(ids); + } + + /** + * 删除空间管理信息 + * + * @param id 空间管理主键 + * @return 结果 + */ + @Override + public int deleteSysSpaceById(Long id) + { + return sysSpaceMapper.deleteSysSpaceById(id); + } + + /** + * 查询部门树结构信息 + * + * @param space 空间信息 + * @return 部门树信息集合 + */ + @Override + public List selectSpaceTreeList(SysSpace space) + { + List spaces = sysSpaceMapper.selectSysSpaceList(space); + return buildSpaceTreeSelect(spaces); + } + + + /** + * 构建前端所需要下拉树结构 + * + * @param spaces 空间列表 + * @return 下拉树结构列表 + */ + @Override + public List buildSpaceTreeSelect(List spaces) + { + List spaceTrees = buildSpaceTree(spaces); + return spaceTrees.stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + /** + * 构建前端所需要树结构 + * + * @param spaces 空间列表 + * @return 树结构列表 + */ + @Override + public List buildSpaceTree(List spaces) + { + List returnList = new ArrayList(); + List tempList = spaces.stream().map(SysSpace::getId).collect(Collectors.toList()); + for (SysSpace space : spaces) + { + // 如果是顶级节点, 遍历该父节点的所有子节点 + if (!tempList.contains(space.getParentId())) + { + recursionFn(spaces, space); + returnList.add(space); + } + } + if (returnList.isEmpty()) + { + returnList = spaces; + } + return returnList; + } + + /** + * 递归列表 + */ + private void recursionFn(List list, SysSpace t) + { + // 得到子节点列表 + List childList = getChildList(list, t); + t.setChildren(childList); + for (SysSpace tChild : childList) + { + if (hasChild(list, tChild)) + { + recursionFn(list, tChild); + } + } + } + + /** + * 得到子节点列表 + */ + private List getChildList(List list, SysSpace t) + { + List tlist = new ArrayList(); + Iterator it = list.iterator(); + while (it.hasNext()) + { + SysSpace n = (SysSpace) it.next(); + if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getId().longValue()) + { + tlist.add(n); + } + } + return tlist; + } + + /** + * 判断是否有子节点 + */ + private boolean hasChild(List list, SysSpace t) + { + return getChildList(list, t).size() > 0 ? true : false; + } + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysSyncRuleServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysSyncRuleServiceImpl.java new file mode 100644 index 0000000..510a655 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysSyncRuleServiceImpl.java @@ -0,0 +1,159 @@ +package com.dcsoft.system.service.impl; + +import java.util.List; + +import com.alibaba.fastjson.JSONObject; +import com.dcsoft.common.core.utils.DateUtils; +import com.dcsoft.system.domain.SysBranch; +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.domain.SysSyncItem; +import com.dcsoft.system.utils.HttpUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.dcsoft.system.mapper.SysSyncRuleMapper; +import com.dcsoft.system.domain.SysSyncRule; +import com.dcsoft.system.service.ISysSyncRuleService; + +/** + * 同步规则Service业务层处理 + * + * @author nichun + * @date 2024-01-11 + */ +@Service +public class SysSyncRuleServiceImpl implements ISysSyncRuleService +{ + @Autowired + private SysSyncRuleMapper sysSyncRuleMapper; + + /** + * 查询同步规则 + * + * @param id 同步规则主键 + * @return 同步规则 + */ + @Override + public SysSyncRule selectSysSyncRuleById(Long id) + { + return sysSyncRuleMapper.selectSysSyncRuleById(id); + } + + /** + * 查询同步规则列表 + * + * @param sysSyncRule 同步规则 + * @return 同步规则 + */ + @Override + public List selectSysSyncRuleList(SysSyncRule sysSyncRule) + { + return sysSyncRuleMapper.selectSysSyncRuleList(sysSyncRule); + } + + /** + * 新增同步规则 + * + * @param sysSyncRule 同步规则 + * @return 结果 + */ + @Override + public int insertSysSyncRule(SysSyncRule sysSyncRule) + { + sysSyncRule.setCreateTime(DateUtils.getNowDate()); + return sysSyncRuleMapper.insertSysSyncRule(sysSyncRule); + } + + /** + * 修改同步规则 + * + * @param sysSyncRule 同步规则 + * @return 结果 + */ + @Override + public int updateSysSyncRule(SysSyncRule sysSyncRule) + { + sysSyncRule.setUpdateTime(DateUtils.getNowDate()); + return sysSyncRuleMapper.updateSysSyncRule(sysSyncRule); + } + + /** + * 批量删除同步规则 + * + * @param ids 需要删除的同步规则主键 + * @return 结果 + */ + @Override + public int deleteSysSyncRuleByIds(Long[] ids) + { + return sysSyncRuleMapper.deleteSysSyncRuleByIds(ids); + } + + /** + * 删除同步规则信息 + * + * @param id 同步规则主键 + * @return 结果 + */ + @Override + public int deleteSysSyncRuleById(Long id) + { + return sysSyncRuleMapper.deleteSysSyncRuleById(id); + } + + @Override + public int insetSysSyncRuleItem(SysSyncItem item) { + return sysSyncRuleMapper.insetSysSyncRuleItem(item); + } + + @Override + public int deleteSysSyncRuleItem(Long id) { + return sysSyncRuleMapper.deleteSysSyncRuleItem(id); + } + + @Override + public List selectSysSyncRuleItem(Long id) { + return sysSyncRuleMapper.selectSysSyncRuleItem(id); + } + + @Override + public String addDept(SysBranch branch, String flag) { + String msg=""; + //判断规则部门,推送到相应增量规则上 + SysSyncRule rule=new SysSyncRule(); + rule.setBranchId(branch.getParentId()); + List itemList=sysSyncRuleMapper.selectSysSyncItemRuleList(rule); + for(SysSyncRule item:itemList){ + JSONObject paramMap=new JSONObject(); + paramMap.put("sysBranch",branch); + paramMap.put("flag",flag); + msg= HttpUtil.postDataJson(item.getAddDeptUrl(),paramMap); + } + return msg; + } + + @Override + public String addPeople(SysPeople sysPeople, String flag) { + String msg=""; + //判断规则部门,推送到相应增量规则上 + SysSyncRule rule=new SysSyncRule(); + rule.setBranchId(sysPeople.getBranchId()); + List itemList=sysSyncRuleMapper.selectSysSyncItemRuleList(rule); + for(SysSyncRule item:itemList){ + JSONObject paramMap=new JSONObject(); + paramMap.put("sysPeople",sysPeople); + paramMap.put("flag",flag); + msg= HttpUtil.postDataJson(item.getAddPeopleUrl(),paramMap); + } + return msg; + } + + /** + * 查询园区对映的部门 + * @param tdGuid + * @return + */ + @Override + public List queryParkDept(String tdGuid) { + return sysSyncRuleMapper.queryParkDept(tdGuid); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysUserOnlineServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysUserOnlineServiceImpl.java new file mode 100644 index 0000000..988065c --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysUserOnlineServiceImpl.java @@ -0,0 +1,89 @@ +package com.dcsoft.system.service.impl; + +import org.springframework.stereotype.Service; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.system.api.model.LoginUser; +import com.dcsoft.system.domain.SysUserOnline; +import com.dcsoft.system.service.ISysUserOnlineService; + +/** + * 在线用户 服务层处理 + * + * @author dcsoft + */ +@Service +public class SysUserOnlineServiceImpl implements ISysUserOnlineService +{ + /** + * 通过登录地址查询信息 + * + * @param ipaddr 登录地址 + * @param user 用户信息 + * @return 在线用户信息 + */ + @Override + public SysUserOnline selectOnlineByIpaddr(String ipaddr, LoginUser user) + { + if (StringUtils.equals(ipaddr, user.getIpaddr())) + { + return loginUserToUserOnline(user); + } + return null; + } + + /** + * 通过用户名称查询信息 + * + * @param userName 用户名称 + * @param user 用户信息 + * @return 在线用户信息 + */ + @Override + public SysUserOnline selectOnlineByUserName(String userName, LoginUser user) + { + if (StringUtils.equals(userName, user.getUsername())) + { + return loginUserToUserOnline(user); + } + return null; + } + + /** + * 通过登录地址/用户名称查询信息 + * + * @param ipaddr 登录地址 + * @param userName 用户名称 + * @param user 用户信息 + * @return 在线用户信息 + */ + @Override + public SysUserOnline selectOnlineByInfo(String ipaddr, String userName, LoginUser user) + { + if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername())) + { + return loginUserToUserOnline(user); + } + return null; + } + + /** + * 设置在线用户信息 + * + * @param user 用户信息 + * @return 在线用户 + */ + @Override + public SysUserOnline loginUserToUserOnline(LoginUser user) + { + if (StringUtils.isNull(user)) + { + return null; + } + SysUserOnline sysUserOnline = new SysUserOnline(); + sysUserOnline.setTokenId(user.getToken()); + sysUserOnline.setUserName(user.getUsername()); + sysUserOnline.setIpaddr(user.getIpaddr()); + sysUserOnline.setLoginTime(user.getLoginTime()); + return sysUserOnline; + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysUserServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysUserServiceImpl.java new file mode 100644 index 0000000..4c10f8a --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/service/impl/SysUserServiceImpl.java @@ -0,0 +1,659 @@ +package com.dcsoft.system.service.impl; + +import com.dcsoft.common.core.constant.UserConstants; +import com.dcsoft.common.core.domain.R; +import com.dcsoft.common.core.exception.ServiceException; +import com.dcsoft.common.core.utils.SpringUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.utils.bean.BeanValidators; +import com.dcsoft.common.datascope.annotation.DataScope; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.api.RemoteAuthApplication; +import com.dcsoft.system.api.RemoteFileService; +import com.dcsoft.system.api.domain.LoginBody; +import com.dcsoft.system.api.domain.SysFile; +import com.dcsoft.system.api.domain.SysRole; +import com.dcsoft.system.api.domain.SysUser; +import com.dcsoft.system.domain.SysPost; +import com.dcsoft.system.domain.SysUserPost; +import com.dcsoft.system.domain.SysUserRole; +import com.dcsoft.system.domain.vo.AppletInfoVo; +import com.dcsoft.system.mapper.*; +import com.dcsoft.system.service.ISysConfigService; +import com.dcsoft.system.service.ISysUserService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; +import org.springframework.web.multipart.MultipartFile; + +import javax.validation.Validator; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 用户 业务层处理 + * + * @author dcsoft + */ +@Service +public class SysUserServiceImpl implements ISysUserService +{ + private static final Logger log = LoggerFactory.getLogger(SysUserServiceImpl.class); + + @Autowired + private SysUserMapper userMapper; + + @Autowired + private SysRoleMapper roleMapper; + + @Autowired + private SysPostMapper postMapper; + + @Autowired + private SysUserRoleMapper userRoleMapper; + + @Autowired + private SysUserPostMapper userPostMapper; + + @Autowired + private ISysConfigService configService; + + @Autowired + protected Validator validator; + + @Autowired + protected RemoteAuthApplication remoteAuthApplication; + + @Autowired + private RemoteFileService remoteFileService; + + /** + * 根据条件分页查询用户列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List selectUserList(SysUser user) + { + return userMapper.selectUserList(user); + } + + /** + * 根据条件分页查询已分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List selectAllocatedList(SysUser user) + { + return userMapper.selectAllocatedList(user); + } + + /** + * 根据条件分页查询未分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List selectUnallocatedList(SysUser user) + { + return userMapper.selectUnallocatedList(user); + } + + /** + * 通过用户名查询用户 + * + * @param userName 用户名 + * @return 用户对象信息 + */ + @Override + public SysUser selectUserByUserName(String userName) + { + return userMapper.selectUserByUserName(userName); + } + + /** + * 通过用户ID查询用户 + * + * @param userId 用户ID + * @return 用户对象信息 + */ + @Override + public SysUser selectUserById(Long userId) + { + return userMapper.selectUserById(userId); + } + + /** + * 查询用户所属角色组 + * + * @param userName 用户名 + * @return 结果 + */ + @Override + public String selectUserRoleGroup(String userName) + { + List list = roleMapper.selectRolesByUserName(userName); + if (CollectionUtils.isEmpty(list)) + { + return StringUtils.EMPTY; + } + return list.stream().map(SysRole::getRoleName).collect(Collectors.joining(",")); + } + + /** + * 查询用户所属岗位组 + * + * @param userName 用户名 + * @return 结果 + */ + @Override + public String selectUserPostGroup(String userName) + { + List list = postMapper.selectPostsByUserName(userName); + if (CollectionUtils.isEmpty(list)) + { + return StringUtils.EMPTY; + } + return list.stream().map(SysPost::getPostName).collect(Collectors.joining(",")); + } + + /** + * 校验用户名称是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public boolean checkUserNameUnique(SysUser user) + { + Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId(); + SysUser info = userMapper.checkUserNameUnique(user.getUserName()); + if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验手机号码是否唯一 + * + * @param user 用户信息 + * @return + */ + @Override + public boolean checkPhoneUnique(SysUser user) + { + Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId(); + SysUser info = userMapper.checkPhoneUnique(user.getPhonenumber()); + if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验email是否唯一 + * + * @param user 用户信息 + * @return + */ + @Override + public boolean checkEmailUnique(SysUser user) + { + Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId(); + SysUser info = userMapper.checkEmailUnique(user.getEmail()); + if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验用户是否允许操作 + * + * @param user 用户信息 + */ + @Override + public void checkUserAllowed(SysUser user) + { + if (StringUtils.isNotNull(user.getUserId()) && user.isAdmin()) + { + throw new ServiceException("不允许操作超级管理员用户"); + } + } + + /** + * 校验用户是否有数据权限 + * + * @param userId 用户id + */ + @Override + public void checkUserDataScope(Long userId) + { + if (!SysUser.isAdmin(SecurityUtils.getUserId())) + { + SysUser user = new SysUser(); + user.setUserId(userId); + List users = SpringUtils.getAopProxy(this).selectUserList(user); + if (StringUtils.isEmpty(users)) + { + throw new ServiceException("没有权限访问用户数据!"); + } + } + } + + /** + * 新增保存用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int insertUser(SysUser user) + { + // 新增用户信息 + int rows = userMapper.insertUser(user); + // 新增用户岗位关联 + insertUserPost(user); + // 新增用户与角色管理 + insertUserRole(user); + return rows; + } + + /** + * 注册用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public boolean registerUser(SysUser user) + { + return userMapper.insertUser(user) > 0; + } + + /** + * 修改保存用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int updateUser(SysUser user) + { + Long userId = user.getUserId(); + // 删除用户与角色关联 + userRoleMapper.deleteUserRoleByUserId(userId); + // 新增用户与角色管理 + insertUserRole(user); + // 删除用户与岗位关联 + userPostMapper.deleteUserPostByUserId(userId); + // 新增用户与岗位管理 + insertUserPost(user); + return userMapper.updateUser(user); + } + + /** + * 用户授权角色 + * + * @param userId 用户ID + * @param roleIds 角色组 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void insertUserAuth(Long userId, Long[] roleIds) + { + userRoleMapper.deleteUserRoleByUserId(userId); + insertUserRole(userId, roleIds); + } + + /** + * 修改用户状态 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public int updateUserStatus(SysUser user) + { + return userMapper.updateUser(user); + } + + /** + * 修改用户基本信息 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public int updateUserProfile(SysUser user) + { + return userMapper.updateUser(user); + } + + /** + * 修改用户头像 + * + * @param userName 用户名 + * @param avatar 头像地址 + * @return 结果 + */ + @Override + public boolean updateUserAvatar(String userName, String avatar) + { + return userMapper.updateUserAvatar(userName, avatar) > 0; + } + + /** + * 重置用户密码 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public int resetPwd(SysUser user) + { + return userMapper.updateUser(user); + } + + /** + * 重置用户密码 + * + * @param userName 用户名 + * @param password 密码 + * @return 结果 + */ + @Override + public int resetUserPwd(String userName, String password) + { + return userMapper.resetUserPwd(userName, password); + } + + /** + * 新增用户角色信息 + * + * @param user 用户对象 + */ + public void insertUserRole(SysUser user) + { + this.insertUserRole(user.getUserId(), user.getRoleIds()); + } + + /** + * 新增用户岗位信息 + * + * @param user 用户对象 + */ + public void insertUserPost(SysUser user) + { + Long[] posts = user.getPostIds(); + if (StringUtils.isNotEmpty(posts)) + { + // 新增用户与岗位管理 + List list = new ArrayList(); + for (Long postId : posts) + { + SysUserPost up = new SysUserPost(); + up.setUserId(user.getUserId()); + up.setPostId(postId); + list.add(up); + } + userPostMapper.batchUserPost(list); + } + } + + /** + * 新增用户角色信息 + * + * @param userId 用户ID + * @param roleIds 角色组 + */ + public void insertUserRole(Long userId, Long[] roleIds) + { + if (StringUtils.isNotEmpty(roleIds)) + { + // 新增用户与角色管理 + List list = new ArrayList(); + for (Long roleId : roleIds) + { + SysUserRole ur = new SysUserRole(); + ur.setUserId(userId); + ur.setRoleId(roleId); + list.add(ur); + } + userRoleMapper.batchUserRole(list); + } + } + + /** + * 通过用户ID删除用户 + * + * @param userId 用户ID + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int deleteUserById(Long userId) + { + // 删除用户与角色关联 + userRoleMapper.deleteUserRoleByUserId(userId); + // 删除用户与岗位表 + userPostMapper.deleteUserPostByUserId(userId); + return userMapper.deleteUserById(userId); + } + + /** + * 批量删除用户信息 + * + * @param userIds 需要删除的用户ID + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int deleteUserByIds(Long[] userIds) + { + for (Long userId : userIds) + { + checkUserAllowed(new SysUser(userId)); + checkUserDataScope(userId); + } + // 删除用户与角色关联 + userRoleMapper.deleteUserRole(userIds); + // 删除用户与岗位关联 + userPostMapper.deleteUserPost(userIds); + return userMapper.deleteUserByIds(userIds); + } + + /** + * 导入用户数据 + * + * @param userList 用户数据列表 + * @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据 + * @param operName 操作用户 + * @return 结果 + */ + @Override + public String importUser(List userList, Boolean isUpdateSupport, String operName) + { + if (StringUtils.isNull(userList) || userList.size() == 0) + { + throw new ServiceException("导入用户数据不能为空!"); + } + int successNum = 0; + int failureNum = 0; + StringBuilder successMsg = new StringBuilder(); + StringBuilder failureMsg = new StringBuilder(); + String password = configService.selectConfigByKey("sys.user.initPassword"); + for (SysUser user : userList) + { + try + { + // 验证是否存在这个用户 + SysUser u = userMapper.selectUserByUserName(user.getUserName()); + if (StringUtils.isNull(u)) + { + BeanValidators.validateWithException(validator, user); + user.setPassword(SecurityUtils.encryptPassword(password)); + user.setCreateBy(operName); + this.insertUser(user); + successNum++; + successMsg.append("
" + successNum + "、账号 " + user.getUserName() + " 导入成功"); + } + else if (isUpdateSupport) + { + BeanValidators.validateWithException(validator, user); + checkUserAllowed(user); + checkUserDataScope(user.getUserId()); + user.setUpdateBy(operName); + this.updateUser(user); + successNum++; + successMsg.append("
" + successNum + "、账号 " + user.getUserName() + " 更新成功"); + } + else + { + failureNum++; + failureMsg.append("
" + failureNum + "、账号 " + user.getUserName() + " 已存在"); + } + } + catch (Exception e) + { + failureNum++; + String msg = "
" + failureNum + "、账号 " + user.getUserName() + " 导入失败:"; + failureMsg.append(msg + e.getMessage()); + log.error(msg, e); + } + } + if (failureNum > 0) + { + failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:"); + throw new ServiceException(failureMsg.toString()); + } + else + { + successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:"); + } + return successMsg.toString(); + } + + /** + * 通过用户名查询用户 + * + * @param openid 微信openid + * @return 用户对象信息 + */ + @Override + public SysUser selectUserByOpenId(String openid) + { + return userMapper.selectUserByOpenId(openid); + } + + @Override + public int updateOpenId(SysUser sysUser) { + return userMapper.updateOpenId(sysUser); + } + + /** + * 小程序获取token + * @param appletInfoVo + * @return + */ + @Override + public AppletInfoVo queryAppletToken(AppletInfoVo appletInfoVo) { + if(StringUtils.isEmpty(appletInfoVo.getOpenId())) { + throw new ServiceException("小程序唯一标识不能为空"); + } + if(StringUtils.isEmpty(appletInfoVo.getUserName())) { + throw new ServiceException("用户名不能为空"); + } + AppletInfoVo infoVo = new AppletInfoVo(); + SysUser user = userMapper.queryUserInfo(appletInfoVo); + if(user != null) { + String token = getToken(appletInfoVo); + if(StringUtils.isNotEmpty(user.getAvatar())) { + infoVo.setAvatar(user.getAvatar()); + } + infoVo.setToken(token); + return infoVo; + } + SysUser sysUser = new SysUser(); + sysUser.setUserName(appletInfoVo.getUserName()); + sysUser.setNickName(appletInfoVo.getUserName()); + sysUser.setPassword("123456"); + sysUser.setPhonenumber(appletInfoVo.getUserName()); + sysUser.setOpenid(appletInfoVo.getOpenId()); + sysUser.setCreateBy(SecurityUtils.getUsername()); + sysUser.setPassword(SecurityUtils.encryptPassword(sysUser.getPassword())); + int i = userMapper.insertUser(sysUser); + if(i > 0) { + infoVo.setToken(getToken(appletInfoVo)); + return infoVo; + } + return infoVo; + } + + /** + * 小程序更新头像 + * @param file + * @param userName + * @return + */ + @Override + public String updateAppletAvatar(MultipartFile file, String userName) { + String applet = "applet"; + R fileResult = remoteFileService.uploadMinio1(file, applet); + if (StringUtils.isNull(fileResult) || StringUtils.isNull(fileResult.getData())) + { + throw new ServiceException("文件服务异常,请联系管理员"); + } + String url = fileResult.getData().getUrl(); + AppletInfoVo appletInfoVo = new AppletInfoVo(); + appletInfoVo.setUserName(userName); + appletInfoVo.setAvatar(url); + userMapper.updateAppletAvatar(appletInfoVo); + return url; + } + + /** + * 获取token + */ + private String getToken(AppletInfoVo appletInfoVo) { + LoginBody form = new LoginBody(); + form.setUsername(appletInfoVo.getUserName()); + form.setPassword("123456"); + R> login = remoteAuthApplication.login(form); + if(!Boolean.TRUE.equals(R.isSuccess(login))) { + throw new ServiceException("登录失败"); + } + return login.getData().get("access_token").toString(); + } + + /** + * 通过用户名查询用户 + * + * @param externalId IDaas + * @return 用户对象信息 + */ + @Override + public SysUser selectUserByExternalId(String externalId) + { + return userMapper.selectUserByExternalId(externalId); + } + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/controller/SysApiController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/controller/SysApiController.java new file mode 100644 index 0000000..b7be197 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/controller/SysApiController.java @@ -0,0 +1,648 @@ +package com.dcsoft.system.uniubi.controller; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.dcsoft.common.core.constant.CacheConstants; +import com.dcsoft.common.core.constant.SecurityConstants; +import com.dcsoft.common.core.domain.R; +import com.dcsoft.common.core.utils.JwtUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.utils.uuid.IdUtils; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.redis.service.RedisService; +import com.dcsoft.system.api.RemoteFileService; +import com.dcsoft.system.api.domain.SysFile; +import com.dcsoft.system.api.domain.SysUser; +import com.dcsoft.system.domain.*; +import com.dcsoft.system.service.*; +import com.dcsoft.system.uniubi.domain.EventResult; +import com.dcsoft.system.uniubi.service.ISysApiService; +import com.dcsoft.system.uniubi.service.ISysSdkService; +import com.dcsoft.system.utils.HttpUtil; +import com.dcsoft.system.utils.PictureUtils; +import com.dcsoft.system.utils.WeChatUtil; +import com.dcsoft.system.visitor.domain.Visitor; +import com.dcsoft.system.visitor.service.IVisVisitorExamineService; +import com.dcsoft.system.visitor.service.IVisVisitorRegisterService; +import com.dcsoft.system.visitor.service.IVisitorService; +import io.jsonwebtoken.Claims; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +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 javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.*; +import java.util.concurrent.TimeUnit; + +import static com.dcsoft.common.core.web.domain.AjaxResult.error; +import static com.dcsoft.common.core.web.domain.AjaxResult.success; + + +/** + * 用户管理 业务处理 + * + * @author xueyi + */ +@Slf4j +@RestController +@RequestMapping("/api") +public class SysApiController { + + @Autowired + protected ISysApiService apiService; + + @Autowired + protected ISysEquipmentService equipmentService; + + @Autowired + protected ISysPeopleService peopleService; + + @Autowired + protected ISysPeopleRecordService peopleRecordService; + + + @Autowired + protected IVisitorService visitorService; + + + @Autowired + private ISysUserService userService; + + @Autowired + private RedisService redisService; + + @Autowired + private ISysBranchService sysBranchService; + + @Value("${weixin.appid}") + public String appid; + @Value("${weixin.appSecret}") + public String appSecret; + + @Autowired + protected ISysSdkService sdkService; + + @Resource + private IVisVisitorRegisterService registerService; + + private final static long expireTime = CacheConstants.EXPIRATION; + + + + @Autowired + private RemoteFileService remoteFileService; + + @Autowired + private ISysBranchService branchService; + + @Autowired + private ISysRuleService sysRuleService; + + @Autowired + private IVisVisitorExamineService visVisitorExamineService; + + + /** + * 获取用户信息A + * + * @return 用户信息 + */ + @PostMapping("/backUrl") + public AjaxResult backUrl(EventResult event) { + System.out.println("======回调信息============="+event); + if("100002".equals(event.getEventCode())){//设备上线 + String data=event.getEventMsg(); + JSONObject json= JSONObject.parseObject(data); + String deviceNo=json.get("deviceNo").toString(); + SysEquipment eqs=equipmentService.selectEquipmentBySequence(deviceNo); + if(eqs!=null){ + eqs.setFlag("0"); + equipmentService.updateSysEquipment(eqs); + } + } else if ("100003".equals(event.getEventCode())) {//设备下线 + String data=event.getEventMsg(); + JSONObject json= JSONObject.parseObject(data); + String deviceNo=json.get("deviceNo").toString(); + SysEquipment eqs=equipmentService.selectEquipmentBySequence(deviceNo); + if(eqs!=null){ + SysEquipment equipment=eqs; + equipment.setFlag("1"); + equipmentService.updateSysEquipment(equipment); + } + } else if ("101004".equals(event.getEventCode())) {//识别记录上报 + String data=event.getEventMsg(); + SysPeopleRecord peopleRecord = JSON.parseObject(data,SysPeopleRecord.class); + SysEquipment eqs=equipmentService.selectEquipmentBySequence(peopleRecord.getDeviceNo()); + peopleRecord.setEquipmentId(eqs.getId()+""); + + SysPeople pq=new SysPeople(); + pq.setGuid(peopleRecord.getAdmitGuid()); + SysPeople pqs=peopleService.selectByGuid(pq); + if(pqs!=null){ +// peopleRecord.setPeopleId(pqs.getId()+""); +// peopleRecord.setFlag("0"); +// //判断识别人员是否在考勤组中,是在考勤组中将识别信息塞入到考勤记录中 +// KqGroupUser kqGroupUser=new KqGroupUser(); +// kqGroupUser.setUserId(pqs.getId()); +// List list=groupUserService.selectKqGroupUserList(kqGroupUser); +// if(list.size()>0){//考勤记录 +// peopleRecord.setGroupId(list.get(0).getGroupId()); +// //依据考勤记录将信息放入到考勤结果表中 +// sdkService.insertKqxx(peopleRecord); +// } + }else{ + Visitor vis= visitorService.selectByGuid(peopleRecord.getAdmitGuid()); + if(vis!=null){ + peopleRecord.setPeopleId(vis.getId()+""); + } + peopleRecord.setFlag("1"); + } + if(peopleRecord.getShowTime()!=null){ + Date date=new Date(peopleRecord.getShowTime()); + peopleRecord.setShowDate(date); + } + peopleRecordService.insertSysPeopleRecord(peopleRecord); + + + }else{ + + } + + + return success(event); + } + + + @GetMapping(value = "/peopleEwm") + public AjaxResult getInfo(@RequestParam("id") Long id,@RequestParam("time") Long timeLong) + { + + SysPeople people =peopleService.selectSysPeopleById(id); + + return success(people); + } + + @GetMapping(value = "/visEwm") + public AjaxResult visEwm(@RequestParam("id") Long id,@RequestParam("time") Long timeLong) + { + + Visitor visitor =visitorService.selectVisitorById(id); + + return success(visitor); + } + + //根据code获取openid + @GetMapping(value = "/getOpenIdUser") + public AjaxResult getInfo(@RequestParam("code") String code) + { + //防止统一code重复提交 + String verifyKey = CacheConstants.WX_KEY + code; + String openid = redisService.getCacheObject(verifyKey); + SysUser sysUser=new SysUser(); + System.out.println("获取openid==============================" + openid); + if(StringUtils.isEmpty(openid)) {//重新获取openid + String url = "https://api.weixin.qq.com/sns/oauth2/access_token?&appid=" + appid + "&secret=" + appSecret + "&code=" + code + "&grant_type=authorization_code"; + String response = HttpUtil.getData(url); + JSONObject json = JSONObject.parseObject(response); + System.out.println("微信获取openid==============================" + json); + sysUser = userService.selectUserByOpenId(json.get("openid").toString()); + redisService.setCacheObject(verifyKey,json.get("openid").toString()); + redisService.expire(verifyKey,60*60); + if (StringUtils.isNull(sysUser)) { + sysUser=new SysUser(); + sysUser.setOpenid(json.get("openid").toString()); + return success(sysUser); + } + }else{ + sysUser= userService.selectUserByOpenId(openid); + if (StringUtils.isNull(sysUser)) { + sysUser=new SysUser(); + sysUser.setOpenid(openid); + return success(sysUser); + } + } + return success(sysUser); + } + + @RequestMapping(value = "app",method = RequestMethod.POST) + @ApiOperation("获取openid") + public JSONObject app(@RequestBody JSONObject json){ + String phone=json.get("phone")+""; + String name=json.get("name")+""; + String openid=json.get("openid")+""; + log.info("openid:" + openid); + JSONObject result=new JSONObject(); + SysPeople people = peopleService.selectSysPeopleByOpenId(openid); + if(people!=null){//已绑定人员 + result.put("code",200); + result.put("data",people); + }else{//未绑定人员 + SysPeople peoples =peopleService.selectSysPeopleByGh(phone,name); + log.info("人员信信息:" + peoples); + if(peoples!=null){//已绑定人员 + result.put("data",peoples); + result.put("code",200); + peoples.setOpenid(openid); + peopleService.updateSysPeople(peoples); + }else{ + result.put("code",200); + } + } + return result; + } + + //根据code获取openid + @GetMapping(value = "/getWxUser") + public JSONObject getWxUser(@RequestParam("code") String code) + { + JSONObject result=new JSONObject(); + //防止统一code重复提交 + String verifyKey = CacheConstants.WX_KEY + code; + String openid = redisService.getCacheObject(verifyKey); + //String openid ="oQvJy6PpmGoEw9TthhcuB1Nnb39E"; + SysPeople people=new SysPeople(); + System.out.println("获取openid==============================" + openid); + if("null".equals(openid) || StringUtils.isEmpty(openid)) {//重新获取openid + String url = "https://api.weixin.qq.com/sns/oauth2/access_token?&appid=" + appid + "&secret=" + appSecret + "&code=" + code + "&grant_type=authorization_code"; + String response = HttpUtil.getData(url); + JSONObject json = JSONObject.parseObject(response); + System.out.println("微信获取openid==============================" + json); + people = peopleService.selectSysPeopleByOpenId(json.get("openid").toString()); + redisService.setCacheObject(verifyKey,json.get("openid").toString()); + redisService.expire(verifyKey,60*60); + if (people==null) { + people=new SysPeople(); + people.setOpenid(json.get("openid").toString()); + } + result.put("code",200); + result.put("data",people); + return result; + }else{ + people= peopleService.selectSysPeopleByOpenId(openid); + if (people==null) { + people=new SysPeople(); + people.setOpenid(openid); + } + result.put("code",200); + result.put("data",people); + return result; + } + } + + /** + * getSign,初始化config信息 + * @return + */ + @RequestMapping("/getSign") + @ResponseBody + public AjaxResult getSign(HttpServletRequest request, String url) throws Exception { + String jsapi_ticket = WeChatUtil.getJsapiTicket(WeChatUtil.getAccessToken()); + Map ret = WeChatUtil.sign(jsapi_ticket, url); + System.out.println("======getSign============="+ret); + return AjaxResult.success("请求成功",ret); + } + + /** + * 获取大华防护数据 + * + * @return 用户信息 + */ + @PostMapping("/dHInfo") + public AjaxResult dHInfo(EventResult event) { + System.out.println("======大华回调信息============="+event); + + + return success(event); + } + + @PostMapping("/getPeople") + public Map getPeople(@RequestBody SysPeople sysPeople) + { + Map rspMap = new HashMap(); + // 更具openid判断是否绑定人员,没有绑定注册人员 + if(StringUtils.isNotEmpty(sysPeople.getOpenid())) { + SysPeople people = peopleService.queryPeopleByOpenid(sysPeople.getOpenid()); + if(people != null) { + sysPeople.setName(people.getName()); + sysPeople.setPhone(people.getPhone()); + } + String i = registerService.queryVisitorRegister(sysPeople); + if(StringUtils.isEmpty(i)) { + sysPeople.setVisitorRegisterId(UUID.randomUUID().toString().replace("-", "")); + registerService.saveVisitorRegister(sysPeople); + faceStudents(sysPeople, rspMap); + return rspMap; + } + sysPeople.setVisitorRegisterId(i); + registerService.updateVisitorRegisterByOpenid(sysPeople); + faceStudents(sysPeople, rspMap); + return rspMap; + } + SysPeople faceStudents = peopleService.selectSysPeopleByPhoneUser(sysPeople); + faceStudents(faceStudents, rspMap); + return rspMap; + } + + + private void faceStudents(SysPeople sysPeople, Map rspMap) { + if(sysPeople!=null){ + String token = IdUtils.fastUUID(); + // Jwt存储信息 + Map claimsMap = new HashMap(); + claimsMap.put(SecurityConstants.USER_KEY, token); + claimsMap.put(SecurityConstants.DETAILS_USER_ID, sysPeople.getId() != null ? sysPeople.getId() : sysPeople.getVisitorRegisterId()); + claimsMap.put(SecurityConstants.DETAILS_USERNAME, sysPeople.getName()); + // 接口返回信息 + String access_token= JwtUtils.createToken(claimsMap); + rspMap.put("access_token", access_token); + rspMap.put("expires_in", expireTime); + rspMap.put("sysPeople",sysPeople); + Claims claims = JwtUtils.parseToken(access_token); + String userKey = JwtUtils.getUserKey(claims); + // 根据uuid将loginUser缓存 + redisService.setCacheObject(getTokenKey(userKey), sysPeople, expireTime, TimeUnit.MINUTES); + log.info("用户登录信息:" + sysPeople); + peopleService.updatePeopleInfo(sysPeople); + } + } + + /** + * 根据openid获取用户信息 + * @param openid + * @return + */ + @PostMapping("/queryPeopleByOpenid") + public AjaxResult queryPeopleByOpenid(String openid) { + SysPeople people = peopleService.queryPeopleByOpenid(openid); + return AjaxResult.success(people); + } + + + + private String getTokenKey(String token) + { + return CacheConstants.LOGIN_TOKEN_KEY + token; + } + + @PostMapping("/uploadMinioCar") + public R uploadMinioCar(@RequestBody JSONObject data) { + String url=data.get("url")+""; + if(StringUtils.isEmpty(url)){ + return R.fail("图片地址不能为空"); + } + MultipartFile files= PictureUtils.base64ToMultipartFiles(url); + R file=remoteFileService.uploadMinioCar(files); + return file; + } + + + /** + * 获取大华防护数据 + * + * @return 用户信息 + */ + @PostMapping("/allDeptUrl") + public AjaxResult allDeptUrl(@RequestBody JSONObject event) { + System.out.println("======全部部门回调信息============="+event); + + + return success(event); + } + + @PostMapping("/addDeptUrl") + public AjaxResult addDeptUrl(@RequestBody JSONObject event) { + if("update".equals(event.get("flag"))){ + String studentJson = JSON.toJSONString(event.get("sysBranch")); + SysBranch sysBranch = JSON.parseObject(studentJson,SysBranch.class); + SysBranch SysBranchs= branchService.selectSysBranchById(sysBranch.getId()); + if(SysBranchs!=null){ + sysBranch.setId(SysBranchs.getId()); + branchService.updateSysBranchs(sysBranch); + } + } + if("add".equals(event.get("flag"))){ + String studentJson = JSON.toJSONString(event.get("sysBranch")); + SysBranch sysBranch = JSON.parseObject(studentJson,SysBranch.class); + branchService.insertSysBranchs(sysBranch); + } + if("delete".equals(event.get("flag"))){ + String studentJson = JSON.toJSONString(event.get("sysBranch")); + SysBranch sysBranch = JSON.parseObject(studentJson,SysBranch.class); + branchService.deleteSysBranchByBranchId(sysBranch.getId()); + } + + return success(event); + } + + @PostMapping("/allPeopleUrl") + public AjaxResult allPeopleUrl(@RequestBody JSONObject event) { + System.out.println("======全部人员回调信息============="+event); + + + return success(event); + } + + @PostMapping("/addPeopleUrl") + public AjaxResult addPeopleUrl(@RequestBody JSONObject event) { + if("update".equals(event.get("flag"))){ + String studentJson = JSON.toJSONString(event.get("sysPeople")); + SysPeople sysPeople = JSON.parseObject(studentJson,SysPeople.class); + SysPeople sysPeoples= peopleService.selectByGuid(sysPeople); + if(sysPeoples!=null){ + sysPeople.setId(sysPeoples.getId()); + peopleService.updateSysPeoples(sysPeople); + }else{ + peopleService.insertSysPeoples(sysPeople); + } + //下发设备 + if(sysPeople.getBranchId()!=null){ + SysBranch branch=sysBranchService.selectSysBranchById(sysPeople.getBranchId()); + if (branch.getRuleId()!= null) { + //添加人员授权信息 + SysRule rule=sysRuleService.selectSysRuleById(branch.getRuleId()); + String data=sdkService.authDeviceNew(rule,sysPeople); + sysPeople.setDown(1L); + if("".equals(data)){ + return error("该规则未绑定设备!"); + } + } + peopleService.updateSysPeoples(sysPeople); + } + + } + if("add".equals(event.get("flag"))){ + String studentJson = JSON.toJSONString(event.get("sysPeople")); + SysPeople sysPeople = JSON.parseObject(studentJson,SysPeople.class); + peopleService.insertSysPeoples(sysPeople); + //下发设备 + if(sysPeople.getBranchId()!=null){ + SysBranch branch=sysBranchService.selectSysBranchById(sysPeople.getBranchId()); + if (branch.getRuleId()!= null) { + //添加人员授权信息 + SysRule rule=sysRuleService.selectSysRuleById(branch.getRuleId()); + String data=sdkService.authDeviceNew(rule,sysPeople); + sysPeople.setDown(1L); + if("".equals(data)){ + return error("该规则未绑定设备!"); + } + } + peopleService.updateSysPeoples(sysPeople); + } + } + if("delete".equals(event.get("flag"))){ + String studentJson = JSON.toJSONString(event.get("sysPeople")); + SysPeople sysPeople = JSON.parseObject(studentJson,SysPeople.class); + peopleService.deleteSysPeopleByGuid(sysPeople.getGuid()); + } + return success(event); + } + + /*private AjaxResult sendWeixinJspay(String tradeId, int amounts,String openid) throws Exception { + WeixinPayConfig wxPayConfig = new WeixinPayConfig();// 支付宝配置 + + Map params = new HashMap<>(); + params.put("appid",wxPayConfig.getAppid()); + params.put("mch_id",wxPayConfig.getMerchantId()); + params.put("description","测试消费"); + params.put("out_trade_no",tradeId); + params.put("notify_url",wxPayConfig.getNotify_url()); + Map amount = new HashMap<>(); + amount.put("total",amounts); //订单总金额,单位为分。 + amount.put("currency","CNY"); + params.put("amount",amount.toString()); + params.put("nonce_str", generateNonceStr()); + Map payer = new HashMap<>(); + payer.put("openid",openid); + params.put("payer",payer.toString()); + //创建Httpclient对象 + HttpClient client = new HttpClient(wxPayConfig.getJspayUrl()); + //支持https协议sorry + client.setHttps(true); + //设置请求的参数 + String xml= WXPayUtil.mapToXml(params); + client.setXmlParam(xml); + //发送post请求 + client.post(); + //获取请求的响应结果 + String content = client.getContent(); + Map map = WXPayUtil.xmlToMap(content); + if (map.get("result_code").equals("SUCCESS")){//扣款成功 + System.out.println("调用成功"); + }else{ + System.out.println("调用失败"); + } + // 构造支付参数 + String timestamp = String.valueOf(System.currentTimeMillis() / 1000); // 时间戳 + String nonceStr = WXPayUtil.generateNonceStr(); // 随机字符串 + String packageStr = map.get("prepay_id"); // 预支付订单ID + String signType = "MD5"; // 签名类型 + //构造签名串 + Map param = new HashMap<>(); + param.put("appId",wxPayConfig.getAppid()); + param.put("timeStamp",timestamp); + param.put("nonceStr",nonceStr); + param.put("packageStr",packageStr); + String sign =WXPayUtil.generateSignature(param, wxPayConfig.getApiV3Key()); + + Map payParams = new HashMap<>(); + payParams.put("appId", wxPayConfig.getAppid()); + payParams.put("timeStamp", timestamp); + payParams.put("nonceStr", nonceStr); + payParams.put("package", packageStr); + payParams.put("signType", signType); + payParams.put("paySign", sign); + return AjaxResult.success("调用成功",payParams); + } + + + private AjaxResult sendZfb(String tradeId, Double amounts) throws AlipayApiException { + AlipayConfig alipayConfig = new AlipayConfig();// 支付宝配置 + String appid=alipayConfig.getAppid(); + String private_key=alipayConfig.getRsa_private_key(); + String public_key=alipayConfig.getAlipay_public_key(); + AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",appid,private_key,"json","GBK",public_key,"RSA2"); + AlipayTradePayRequest request = new AlipayTradePayRequest(); + //异步接收地址,仅支持http/https,公网可访问 + request.setNotifyUrl(alipayConfig.getNotify_url()); + *//******必传参数******//* + JSONObject bizContent = new JSONObject(); + //商户订单号,商家自定义,保持唯一性 + bizContent.put("out_trade_no", tradeId); + //支付金额,最小值0.01元 单位为元,精确到小数点后两位 + bizContent.put("total_amount",amounts); + //订单标题,不可使用特殊符号 + bizContent.put("subject", "测试消费"); + //1.条码场景:bar_code;2.刷脸场景:security_code + bizContent.put("product_code", "QUICK_WAP_WAY"); + request.setBizContent(bizContent.toString()); + AlipayTradePayResponse response = alipayClient.execute(request); + String pageRedirectionData = response.getBody(); + System.out.println("调用数据"+pageRedirectionData); + if(response.isSuccess()){ + System.out.println("调用成功"); + } else { + System.out.println("调用失败"); + } + return AjaxResult.success("调用成功",pageRedirectionData); + } + + @PostMapping("/alipay_callback") + public AjaxResult alipay_callback(HttpServletRequest request) { + try{ + Map params = new HashMap(); + Map requestParams =request.getParameterMap(); + for(Iterator iter = requestParams.keySet().iterator();iter.hasNext();){ + String name =(String)iter.next(); + String[] values =(String[])requestParams.get(name); + String valuestr =""; + for(int i =0 ; i 0 ? AjaxResult.success() : error(); + } + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/controller/SysSdkController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/controller/SysSdkController.java new file mode 100644 index 0000000..341c68c --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/controller/SysSdkController.java @@ -0,0 +1,767 @@ +package com.dcsoft.system.uniubi.controller; + + +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.dcsoft.common.core.constant.Constants; +import com.dcsoft.common.core.domain.R; +import com.dcsoft.common.core.enums.exception.CommonExceptionEnum; +import com.dcsoft.common.core.exception.ServiceException; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.redis.service.RedisService; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.api.RemoteFileService; +import com.dcsoft.system.api.domain.SysFile; +import com.dcsoft.system.api.model.LoginUser; +import com.dcsoft.system.domain.*; +import com.dcsoft.system.service.*; +import com.dcsoft.system.uniubi.domain.*; +import com.dcsoft.system.uniubi.service.ISysSdkService; +import com.dcsoft.system.utils.FTPUtil; +import com.dcsoft.system.utils.PictureUtils; +import com.dcsoft.system.visitor.controller.VisitorMachineController; +import com.dcsoft.system.visitor.domain.CheckCodeVo; +import com.dcsoft.system.visitor.domain.VisVisitorExamine; +import com.dcsoft.system.visitor.domain.Visitor; +import com.dcsoft.system.visitor.domain.VisitorRecordVo; +import com.dcsoft.system.visitor.service.IVisVisitorExamineService; +import com.dcsoft.system.visitor.service.IVisitorService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.net.ftp.FTPClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.util.CollectionUtils; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import java.io.*; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import static com.dcsoft.common.core.web.domain.AjaxResult.success; + + +/** + * 用户管理 业务处理 + * + * @author xueyi + */ +@Slf4j +@RestController +@RequestMapping("/sdk") +public class SysSdkController { + + @Value("${sdk.path}") + public String pathUrl; + + @Value("${sdk.identifyRecords}") + public String identifyRecords; + + @Value("${dingTalk.getToken}") + public String getToken; + + @Value("${dingTalk.deCode}") + public String deCode; + + @Value("${dingTalk.getDetails}") + public String getDetails; + + @Value("${dingTalk.asyncsendV2}") + public String asyncsendV2; + + @Value("${dingTalk.agentId}") + public String agentId; + + @Value("${qd.url}") + public String qdUrl; + + @Value("${sdk.uploadMiddling}") + public String uploadMiddling; + + @Value("${sdk.uploadUrl}") + public String uploadUrl; + + @Value("${sdk.saveVisitorRecord}") + public String saveVisitorRecord; + + @Value("${sdk.sign}") + public String sign; + + @Autowired + protected ISysSdkService sdkService; + + @Autowired + protected ISysPeopleService peopleService; + + @Autowired + protected IVisitorService visitorService; + + @Autowired + protected ISysPeopleRecordService peopleRecordService; + + @Autowired + protected ISysEquipmentService equipmentService; + + @Autowired + protected ISysPeopleEquipmentService peopleEquipmentService; + + @Autowired + private ISysEmpowerRecordService sysEmpowerRecordService; + + @Autowired + private ISysRuleService sysRuleService; + + @Autowired + private IVisVisitorExamineService visVisitorExamineService; + + @Autowired + private RedisService redisService; + + @Autowired + private RemoteFileService fileService; + + @Autowired + private ISysBlackListService sysBlackListService; + + + /** + * 宇泛人脸设备二维码回调地址 + * @param info + * @return + */ + @PostMapping("/backUrlEwm") + public JSONObject ewm(EwmInfo info) { + // 钉工牌二维码校验 + if(info.getQRdata().contains("dingbadge")) { + return dingTalkEwm(info); + } + CheckCodeVo codeVo = visitorService.queryVisCheckCodeById(info.getQRdata()); + if(codeVo == null || !codeVo.getCode().contains("/pages/visitor/visitor/visExamineEwm")) { + throw new ServiceException("无效验证码"); + } + JSONObject obj=new JSONObject(); + SysEquipment equipment=equipmentService.selectEquipmentBySequence(info.getDeviceKey()); + //判断是用户二维码还是访客二维码 + //用户,判断是否是时间是否是分钟内的码 + String qRdata=codeVo.getCode(); + String[] time=qRdata.split("&time="); + //判断改设备是否绑定改人员 +// if(StringUtils.isNotEmpty(time[1])){ +// //判断是否在权限时间内 +// if(new Date().getTime()-Long.parseLong(time[1])<5*60*1000){ +// String[] ids=time[0].split("id="); //判断改设备是否绑定改人员 +// SysEmpowerRecord sysEmpowerRecord=new SysEmpowerRecord(); +// sysEmpowerRecord.setEquipmentId(equipment.getId()); +// sysEmpowerRecord.setPeopleId(ids[1]); +// List SysEmpowerRecordList= sysEmpowerRecordService.selectSysEmpowerRecordList(sysEmpowerRecord); +// if(SysEmpowerRecordList.size()>0){ +// SysRule rule=sysRuleService.selectSysRuleById(SysEmpowerRecordList.get(0).getRuleId()); +// if(rule.getEndTime().getTime()>new Date().getTime()){ +// SysPeople people=peopleService.selectSysPeopleById(Long.parseLong(ids[1])); +// obj.put("ttsModContent",people.getName()+"请进"); +// obj.put("displayModContent",people.getName()+"请进"); +// obj.put("isOpenRelay",1); +// } +// }else{ +// obj.put("ttsModContent","未授权,请联系管理员"); +// obj.put("displayModContent","未授权,请联系管理员"); +// obj.put("isOpenRelay",2); +// } +// }else{ +// obj.put("ttsModContent","二维码已过期"); +// obj.put("displayModContent","二维码已过期"); +// obj.put("isOpenRelay",2); +// } +// }else{ + //访客 + + String[] ids=qRdata.split("id="); + String[] split = ids[1].split("&time="); + Visitor visitor1 = visitorService.selectVisitorById(Long.parseLong(split[0])); + SysEmpowerRecord sysEmpowerRecord=new SysEmpowerRecord(); + sysEmpowerRecord.setEquipmentId(equipment.getId()); + sysEmpowerRecord.setPeopleId(String.valueOf(visitor1.getUserId())); + List sysEmpowerRecordList = sysEmpowerRecordService.selectSysEmpowerRecordList(sysEmpowerRecord); + if(!CollectionUtils.isEmpty(sysEmpowerRecordList)){ + SysRule rule=sysRuleService.selectSysRuleById(sysEmpowerRecordList.get(0).getRuleId()); + if(rule.getEndTime().getTime()>new Date().getTime()){ + Visitor visitor=visitorService.selectVisitorById(Long.parseLong(split[0])); + obj.put("ttsModContent",visitor.getName()+"请进"); + obj.put("displayModContent",visitor.getName()+"请进"); + obj.put("isOpenRelay",1); + // 保存识别记录 + VisitorRecordVo record = new VisitorRecordVo(); + String entryExitType = sysEmpowerRecordList.get(0).getEntryExitType(); + // 进门设备 + if("1".equals(entryExitType)) { + record.setVisitorId(split[0]); + record.setSequence(info.getDeviceKey()); + record.setStartTime(new Date(Long.parseLong(info.getTime()))); + record.setType("1"); + visitorService.saveVisitorRecord(record); + visitor.setInTime(new Date()); + visitorService.updateVisitor(visitor); + saveHeadOffice(record); + return obj; + } + // 出门设备 + if("2".equals(entryExitType)) { + record.setEndTime(new Date(Long.parseLong(info.getTime()))); + record.setVisitorId(split[0]); + record.setType("2"); + visitorService.updateVisitorRecord(record); + visitor.setOutTime(new Date()); + visitorService.updateVisitor(visitor); + saveHeadOffice(record); + return obj; + } + } else { + obj.put("ttsModContent","您的二维码已过期"); + obj.put("displayModContent","您的二维码已过期"); + obj.put("isOpenRelay",2); + } + }else{ + obj.put("ttsModContent","未授权,请联系管理员"); + obj.put("displayModContent","未授权,请联系管理员"); + obj.put("isOpenRelay",2); + } + +// } + return obj; + } + + /** + * 同步总部访客记录信息 + * @param record + */ + private void saveHeadOffice(VisitorRecordVo record) { + //推送记录给总平台 + if("true".equals(uploadMiddling)){ + String body = HttpUtil.createPost(saveVisitorRecord).body(JSON.toJSONString(record)).execute().body(); + log.info("同步总部访客记录信息:{}", body); + } + + } + + /** + * 钉工牌二维码校验开门 + */ + @PostMapping("/dingTalkEwm") + public JSONObject dingTalkEwm(EwmInfo info) { + JSONObject obj = new JSONObject(); + + // 校验二维码 + DingtalkCode code = deCode(info); + if("invalidPayCode".equals(code.getCode())) { + obj.put("ttsModContent", "无效二维码"); + obj.put("displayModContent", "无效二维码"); + obj.put("isOpenRelay", Constants.ACCESS_CONTROL_TWO); + return obj; + } + + if(StringUtils.isNotEmpty(code.getCode())) { + obj.put("ttsModContent", code.getMessage()); + obj.put("displayModContent", code.getMessage()); + obj.put("isOpenRelay", Constants.ACCESS_CONTROL_TWO); + return obj; + } + + // 获取钉工牌工号校验是否有权限通过 + String details = getDetails(code.getUserId()); + SysPeople people = new SysPeople(); + people.setGh(details); + people.setSequence(info.getDeviceKey()); + SysPeople sysPeople = equipmentService.queryPeopleInfo(people); + if(sysPeople == null) { + obj.put("ttsModContent", Constants.TTS_MOD_CONTENT); + obj.put("displayModContent", Constants.DISPLAY_MOD_CONTENT); + obj.put("isOpenRelay", Constants.ACCESS_CONTROL_TWO); + return obj; + } + + // 校验通行规则 + SysRule rule = sysRuleService.selectSysRuleById(sysPeople.getRuleId()); + if(rule.getEndTime().getTime() > new Date().getTime()) { + asyncsendV2(code.getUserId(), "text", "开门"); + obj.put("ttsModContent", sysPeople.getName()+"请进"); + obj.put("displayModContent", sysPeople.getName()+"请进"); + obj.put("isOpenRelay", Constants.ACCESS_CONTROL_ONE); + return obj; + } + obj.put("ttsModContent", "通行时间已过期"); + obj.put("displayModContent", "通行时间已过期"); + obj.put("isOpenRelay",Constants.ACCESS_CONTROL_TWO); + return obj; + } + + + /** + * 宇泛人脸设备回调地址 + * + * @return 回调信息 + */ + @PostMapping("/backUrl") + public BackResult backUrl(BackInfo info) { + SysPeopleRecord peopleRecord = new SysPeopleRecord(); + if (!"STRANGERBABY".equals(info.getPersonId())){ + log.info("设备序列号:{}", info); + SysEquipment eqs=equipmentService.selectEquipmentBySequence(info.getDeviceKey()); + peopleRecord.setEquipmentId(eqs.getId()+""); + peopleRecord.setAdmitGuid(info.getPersonId()); + peopleRecord.setAliveType(info.getAliveType()); + peopleRecord.setDeviceNo(info.getDeviceKey()); + peopleRecord.setType(info.getIdentifyType()); + peopleRecord.setCardNo(info.getIdcardNum()); + peopleRecord.setRecType(info.getRecType()); + peopleRecord.setPermissionTimeType(info.getPermissionTimeType()); + peopleRecord.setPassTimeType(info.getPassTimeType()); + peopleRecord.setRecModeType(info.getRecModeType()); + peopleRecord.setTimestamp(Long.parseLong(info.getTime())); + peopleRecord.setShowTime(Long.parseLong(info.getTime())); + peopleRecord.setShowDate(new Date(Long.parseLong(info.getTime()))); + peopleRecord.setRecMode(info.getModel()); + peopleRecord.setDeviceIp(info.getIp()); + //标准版本 + /*SysPeopleEquipment peopleEquipment= peopleEquipmentService.selectSysPeopleEquipmentByGuId(info.getPersonId()); + if(peopleEquipment!=null){ + peopleRecord.setPeopleId(peopleEquipment.getPeopleId()+""); + peopleRecord.setFlag("0"); + //判断识别人员是否在考勤组中,是在考勤组中将识别信息塞入到考勤记录中 + KqGroupUser kqGroupUser=new KqGroupUser(); + kqGroupUser.setUserId(peopleEquipment.getPeopleId()); + List list=groupUserService.selectKqGroupUserList(kqGroupUser); + if(list.size()>0){//考勤记录 + peopleRecord.setGroupId(list.get(0).getGroupId()); + //依据考勤记录将信息放入到考勤结果表中 + sdkService.insertKqxx(peopleRecord); + } + }else{ + Visitor vis= visitorService.selectByGuid(peopleRecord.getAdmitGuid()); + if(vis!=null){ + peopleRecord.setPeopleId(vis.getId()+""); + } + peopleRecord.setFlag("1"); + }*/ + SysPeople sysPeople=new SysPeople(); + sysPeople.setGuid(info.getPersonId()); + SysPeople people= peopleService.selectByGuid(sysPeople); + if(people!=null){ + peopleRecord.setPeopleId(people.getId()+""); + //考勤版本 +// ; +// peopleRecord.setFlag("0"); +// //判断识别人员是否在考勤组中,是在考勤组中将识别信息塞入到考勤记录中 +// KqGroupUser kqGroupUser=new KqGroupUser(); +// kqGroupUser.setUserId(people.getId()); +// List list=groupUserService.selectKqGroupUserList(kqGroupUser); +// if(list!=null&&list.size()>0){//考勤记录 +// peopleRecord.setGroupId(list.get(0).getGroupId()); +// //依据考勤记录将信息放入到考勤结果表中 +// sdkService.insertKqxx(peopleRecord); +// } + //标准版本 +// String imgUrl=getImg(info.getPath(),info.getIp(),eqs.getPassword()); +// peopleRecord.setFilePath(imgUrl); + } + if(StringUtils.isNotEmpty(info.getPath())){//考勤版本 + String urls="http://"+eqs.getIp()+":8090/download/image?pass="+eqs.getPassword()+"&filename="+info.getPath(); + MultipartFile file= PictureUtils.createMultipartFile(urls,eqs.getSequence()+".jpg"); + R datas= fileService.uploadMinio(file,"IdentifyRecords"); + if(datas.getData()!=null){ + peopleRecord.setFilePath(datas.getData().getUrl()); + } + } + + Visitor visitor = visitorService.queryVisitorGuid(info.getPersonId()); + if(visitor != null && StringUtils.isNotEmpty(visitor.getGuid())) { + VisitorRecordVo record = new VisitorRecordVo(); + String entryExitType = eqs.getEntryExitType(); + // 进门设备 + if("1".equals(entryExitType)) { + record.setVisitorId(String.valueOf(visitor.getId())); + record.setSequence(info.getDeviceKey()); + record.setStartTime(new Date(Long.parseLong(info.getTime()))); + record.setType("1"); + visitorService.saveVisitorRecord(record); + visitor.setInTime(new Date()); + visitor.setType(Constants.ONE); + visitorService.updateVisitor(visitor); + saveHeadOffice(record); + return new BackResult(1,true); + } + // 出门设备 + if("2".equals(entryExitType)) { + record.setEndTime(new Date(Long.parseLong(info.getTime()))); + record.setVisitorId(String.valueOf(visitor.getId())); + record.setType("2"); + visitorService.updateVisitorRecord(record); + visitor.setOutTime(new Date()); + visitor.setType(Constants.TWO); + visitorService.updateVisitor(visitor); + saveHeadOffice(record); + return new BackResult(1,true); + } + } + + peopleRecordService.insertSysPeopleRecord(peopleRecord); + + + //推送记录给总平台 + if("true".equals(uploadMiddling)){ + JSONObject paramMap=new JSONObject(); + peopleRecord.setSign(sign); + paramMap.put("peopleRecord",peopleRecord); + com.dcsoft.system.utils.HttpUtil.postDataJson(uploadUrl,paramMap); + } + } + return new BackResult(1,true); + } + + private String getImg(String path,String ip,String pass) { + String url=""; + InputStream in = null; + OutputStream os= null; + try{ + String paths = "/IdentifyRecords/"; + //读取单个文件 + FTPClient ftpClient = FTPUtil.getFTPClient(ip,8010,"admin",pass); + String fileName = path.split("IdentifyRecords")[1]; + + String pathsl =paths+fileName.substring(0,fileName.lastIndexOf("/")+1); + String fileNames =fileName.substring(fileName.lastIndexOf("/")+1,fileName.length()); + + String savePath=pathUrl +paths+fileName; + + in = FTPUtil.getFTPFile(ftpClient,pathsl,fileNames); + File file = new File(savePath);//System.getProperty("java.io.tmpdir")缓存 + System.out.println("文件夹"+savePath.substring(0,savePath.lastIndexOf("/"))); + if (!file.exists()|| !file.isDirectory()) { //如果是目录先创建 + new File(savePath.substring(0,savePath.lastIndexOf("/"))).mkdirs(); //目录先创建 + } + os = new FileOutputStream(file); + + int bytesRead; + int len = 8192; + byte[] buffer = new byte[len]; + while ((bytesRead = in.read(buffer, 0, len)) != -1) { + os.write(buffer, 0, bytesRead); + } + url=identifyRecords+paths+fileName; + //关闭连接 + FTPUtil.disConnection(ftpClient); + }catch (Exception e){ + e.printStackTrace(); + }finally { + try{ + //关闭流 + if (in != null) { + in.close(); + } + if (os != null) { + os.close(); + } + }catch (IOException e){ + e.printStackTrace(); + } + } + return url; + } + + + /** + * 回调信息 + * + * @return 回调信息 + */ + @GetMapping("/personCreate") + public AjaxResult personCreate() { + /* Person person =new Person(); + person.setId("323dc840fabc42d9afd4401e911a579e"); + person.setName("test1"); + String msg=sdkService.personCreate(person,"192.168.1.34","123123a");*/ + return success(); + } + + @PostMapping("/backUrlHeart") + public AjaxResult heart(HeartInfo info) { + //获取设备缓存的设备时间 + redisService.setCacheObject(info.getDeviceKey(),info.getTime()); + redisService.expire(info.getDeviceKey(),2*60); + SysEquipment equipment=new SysEquipment(); + equipment.setProductId(3L); + List list=equipmentService.selectSysEquipmentList(equipment); + for(SysEquipment e:list){ + String time = redisService.getCacheObject(e.getSequence()); + if(StringUtils.isNotEmpty(time)){ + e.setFlag("0"); + equipmentService.updateSysEquipment(e); + }else{ + e.setFlag("1"); + equipmentService.updateSysEquipment(e); + } + } + return success(); + + } + + /** + * 获取钉工牌token + */ + private String getToken() { + String body = HttpUtil.createGet(getToken).execute().body(); + JSONObject object = JSONObject.parseObject(body); + return object.get("access_token").toString(); + + } + + /** + * 解析钉工牌二维码 + */ + private DingtalkCode deCode(EwmInfo info) { + String requestId = redisService.getCacheObject(info.getQRdata()); + if(StringUtils.isEmpty(requestId)) { + requestId = String.valueOf(UUID.randomUUID()); + redisService.setCacheObject(info.getQRdata(), requestId, 10L, TimeUnit.MINUTES); + } + info.setRequestId(requestId); + info.setPayCode(info.getQRdata()); + String body = HttpUtil.createPost(deCode) + .header("x-acs-dingtalk-access-token", getToken()) + .body(JSON.toJSONString(info)) + .execute() + .body(); + JSONObject object = JSONObject.parseObject(body); + DingtalkCode code = new DingtalkCode(); + if(object.get("code") != null) { + code.setMessage(object.get("message").toString()); + code.setCode(object.get("code").toString()); + return code; + } + code.setUserId(object.get("userId").toString()); + return code; + } + + /** + * 查询钉工牌详情 + */ + private String getDetails(String userId) { + Map map = new HashMap<>(); + map.put("userid", userId); + String body = HttpUtil.createPost(getDetails + "?access_token=" + getToken()) + .body(JSON.toJSONString(map)) + .execute() + .body(); + JSONObject object = JSONObject.parseObject(body); + if(!Constants.OK.equals(object.get("errmsg").toString())) { + log.error("钉工牌详情接口异常码:" + object.get("errmsg").toString()); + throw new ServiceException(CommonExceptionEnum.REQUEST_ERROR.getCode(), "钉工牌详情接口" + CommonExceptionEnum.REQUEST_ERROR.getMessage()); + } + JSONObject jsonObject = JSONObject.parseObject(object.get("result").toString()); + return jsonObject.get("job_number").toString(); + } + + /** + * 钉工牌消息通知 + */ + public void asyncsendV2(String userId, String msgType, String content) { + DingtalkMsgVo msgVo = new DingtalkMsgVo(); + DingtalkMsgVo.Text text = new DingtalkMsgVo.Text(); + text.setContent(content); + msgVo.setMsgtype(msgType); + msgVo.setText(text); + Map map = new HashMap<>(); + map.put("agent_id", agentId); + map.put("msg", msgVo); + map.put("userid_list", userId); + String body = HttpUtil.createPost(asyncsendV2 + "?access_token=" + getToken()) + .body(JSON.toJSONString(map)) + .execute() + .body(); + JSONObject object = JSONObject.parseObject(body); + if(!Constants.ZERO.equals(object.get("errcode").toString())) { + log.error("钉工牌消息通知接口异常码:" + object.get("errcode").toString()); + throw new ServiceException(CommonExceptionEnum.REQUEST_ERROR.getCode(), "钉工牌消息通知接口" + CommonExceptionEnum.REQUEST_ERROR.getMessage()); + } + + } + + @PostMapping("/uploadMiddling") + public AjaxResult uploadMiddling(@RequestBody JSONObject event) { + System.out.println("======通行回调信息============="+event); + String studentJson = JSON.toJSONString(event.get("peopleRecord")); + SysPeopleRecord peopleRecord = JSON.parseObject(studentJson,SysPeopleRecord.class); + //根据guId查找上级平台的人员ID + SysPeople people=new SysPeople(); + people.setGuid(peopleRecord.getAdmitGuid()); + SysPeople peoples=peopleService.selectByGuid(people); + if(peoples!=null){ + peopleRecord.setPeopleId(peoples.getId()+""); + }else{ + peopleRecord.setPeopleId(null); + } + peopleRecordService.insertSysPeopleRecord(peopleRecord); + return success(event); + } + + @PostMapping("/saveVisitorAuditing") + public AjaxResult saveVisitorAuditing(@RequestBody Visitor visitor) { + log.info("修改访客信息:{}", visitor); + VisVisitorExamine examine=visitor.getExamine(); + Visitor item=new Visitor(); + item.setParentId(visitor.getId()); + List itemList=visitorService.selectVisitorItemList(item); + + visitor.setItemList(itemList); + if("0".equals(examine.getExamine())){//审核通过 + //判断是否存在黑名单,存在即审核失败 + SysBlackList sysBlackList=new SysBlackList(); + sysBlackList.setPhone(visitor.getPhone()); + List list=sysBlackListService.selectSysBlackListList(sysBlackList); + if(list.size()>0){ + return AjaxResult.error("存在黑名单无法审核通过"); + } + for(Visitor items:itemList){ + SysBlackList sysBlackLists=new SysBlackList(); + sysBlackLists.setPhone(items.getPhone()); + List lists=sysBlackListService.selectSysBlackListList(sysBlackLists); + if(lists.size()>0){ + return AjaxResult.error("存在黑名单无法审核通过"); + } + } + + Visitor visitor1 = visitorService.selectVisitorById(visitor.getId()); + CheckCodeVo codeVo = new CheckCodeVo(); + codeVo.setCode(qdUrl+visitor.getId() + "&time=" + new Date().getTime()); + codeVo.setVisitorId(String.valueOf(visitor.getId())); + codeVo.setId(UUID.randomUUID().toString().replace("-", "")); + if(StringUtils.isNotEmpty(visitor.getCheckCodeId())) { + codeVo.setId(visitor.getCheckCodeId()); + } + if(visitor1 != null) { + codeVo.setStartTime(visitor1.getStartTime()); + codeVo.setEndTime(visitor1.getEndTime()); + } + visitorService.saveVisCheckCode(codeVo); + } + + Visitor visitor1 = new Visitor(); + visitor1.setId(visitor.getId()); + visitor1.setType("1"); + visitorService.updateVisitor(visitor1); + + + examine.setVisitorId(visitor.getId()); + LoginUser user= SecurityUtils.getLoginUser(); + visitor.setUserName(user == null ? visitor.getPeopleName() : user.getUsername()); + examine.setCreateBy(visitor.getUserName()); + return success(visVisitorExamineService.insertVisVisitorExamine(examine)); + } + + + @PostMapping("/updateState") + public AjaxResult updateState(@RequestBody Visitor visitor) { + return success(visitorService.updateState(visitor)); + } + + /** + * 修改总部签离状态 + * @param visitor + * @return + */ + @PostMapping("/updateGroupSignOut") + public AjaxResult updateGroupSignOut(@RequestBody Visitor visitor) { + return success(visitorService.updateSignOut(visitor)); + } + + /** + * 修改园区签离状态 + * @param visitor + * @return + */ + @PostMapping("/updateParkSignOut") + public AjaxResult updateParkSignOut(@RequestBody Visitor visitor) { + return success(visitorService.updateSignOut(visitor)); + } + + /** + * 通行二维码识别 + * @param info + * @return + */ + @PostMapping("/equipmentQrCodeUrl") + public AjaxResult equipmentQrCodeUrl(@RequestBody EwmInfo info) { + // 钉工牌二维码校验 + LadderControlVo controlVo = new LadderControlVo(); + info.setQRdata(info.getQrCode()); + if(info.getQRdata().contains("dingbadge")) { + String gh = dingTalkEquipmentEwm(info); + controlVo.setDeviceKey(info.getDeviceKey()); + List list = new ArrayList<>(); + list.add("1"); + controlVo.setList(list); + // 保存记录 + SysPeople people = new SysPeople(); + people.setGh(gh); + savePeopleRecord(people, info.getDeviceKey()); + log.info("通行二维码回调:" + success(controlVo)); + return success(controlVo); + } + return success(); + } + + /** + * 钉钉通行规则 + */ + private String dingTalkEquipmentEwm(EwmInfo info) { + // 校验二维码 + DingtalkCode code = deCode(info); + if("invalidPayCode".equals(code.getCode())) { + throw new ServiceException(10001, "无效二维码"); + } + + if(StringUtils.isNotEmpty(code.getCode())) { + throw new ServiceException(10002, "二维码过期"); + } + + // 获取钉工牌工号校验是否有权限通过 + String details = getDetails(code.getUserId()); + SysPeople people = new SysPeople(); + people.setGh(details); + people.setSequence(info.getDeviceKey()); + List list = equipmentService.queryEmpowerRecord(people); + if(CollectionUtils.isEmpty(list)) { + throw new ServiceException(10003, "您未授权"); + } + return details; + } + + /** + * 保存通行授权记录 + * @param sysPeople + * @param sequence + */ + private void savePeopleRecord(SysPeople sysPeople, String sequence) { + SysPeople people = equipmentService.queryPeople(sysPeople); + SysEquipment equipment = equipmentService.queryEmpower(sequence); + + if(people != null && equipment != null) { + SysPeopleRecord peopleRecord = new SysPeopleRecord(); + peopleRecord.setDeviceName(equipment.getName()); + peopleRecord.setRecMode("8"); + peopleRecord.setCardNo(people.getDoorNo()); + peopleRecord.setDeviceName(equipment.getName()); + peopleRecord.setRecType("1"); + peopleRecord.setTimestamp(new Date().getTime()); + peopleRecord.setEquipmentId(String.valueOf(equipment.getId())); + peopleRecord.setPeopleId(String.valueOf(people.getId())); + peopleRecordService.insertSysPeopleRecord(peopleRecord); + } + } + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/controller/test.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/controller/test.java new file mode 100644 index 0000000..5db4629 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/controller/test.java @@ -0,0 +1,83 @@ +package com.dcsoft.system.uniubi.controller; + +import cn.hutool.core.util.NumberUtil; +import com.alibaba.nacos.shaded.com.google.gson.JsonParser; +import com.dcsoft.common.core.constant.Constants; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +public class test { + public static void main(String[] args) throws ParseException { + + double floorNum = NumberUtil.div(20, 4); + if (floorNum % 1 != 0) { + floorNum = floorNum + 1; + } + int floorCount = (int) NumberUtil.mul((int) floorNum, 4); + List list = new ArrayList<>(); + for (int i = 0; i < floorCount; i++) { + list.add("0"); + } + + list.set(floorCount - 20, "1"); + list.set(floorCount - 19, "1"); + list.set(floorCount - 18, "1"); + list.set(floorCount - 17, "1"); + list.set(floorCount - 16, "1"); + list.set(floorCount - 15, "1"); + list.set(floorCount - 14, "1"); + list.set(floorCount - 13, "1"); + list.set(floorCount - 12, "1"); + list.set(floorCount - 11, "1"); + list.set(floorCount - 10, "1"); + list.set(floorCount - 9, "1"); + list.set(floorCount - 8, "1"); + list.set(floorCount - 7, "1"); + list.set(floorCount - 6, "1"); + list.set(floorCount - 5, "1"); + list.set(floorCount - 4, "1"); + list.set(floorCount - 3, "1"); + list.set(floorCount - 2, "1"); + list.set(floorCount - 1, "1"); + + + // 二进制数 + String binaryString = String.join("", list); + // 转换为十进制数 + int binaryNumber = Integer.parseInt(binaryString, 2); + // 转换为十六进制数 + String hexString = Integer.toHexString(binaryNumber); + System.out.println("十六进制数: " + hexString); + + String formattedNumber = String.format("%16s", hexString).replace(' ', '0'); + System.out.println(formattedNumber); + + String zeroString = String.format("%052d", 0); + System.out.println(zeroString); + + String floor = "FF" + formattedNumber + zeroString; + System.out.println(floor); + + + SimpleDateFormat sf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); + Date parse = sf.parse("2024年02月26日 11:14:08"); + System.out.println(parse); + + String s = "{\"first\": {\n" + + " \"value\": \"广州腾讯科技有限公司\"\n" + + " },\n" + + " \"keyword1\": {\n" + + " \"value\": \"广州腾讯科技有限公司\"\n" + + " },\n" + + " \"keyword2\": {\n" + + " \"value\": \"2019年8月8日\"\n" + + " }}"; + System.out.println(JsonParser.parseString(Constants.CONTENT).getAsJsonObject()); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/BackInfo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/BackInfo.java new file mode 100644 index 0000000..6d4fe1b --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/BackInfo.java @@ -0,0 +1,100 @@ +package com.dcsoft.system.uniubi.domain; + +import lombok.Data; + + +/** + * Uface回调参数 持久化对象 + * + * @author nichun + */ +@Data +public class BackInfo { + + /** 设备序列号 **/ + protected String deviceKey; + + /** 识别记录毫秒级时间戳*/ + protected String time; + + /** 设备当前 IP 地址 "*/ + protected String ip; + + /** 现场照保存路径 "*/ + protected String path; + + /** 人员 ID .陌生人为 STRANGERBAB "*/ + protected String personId; + + /** personId 对应的卡号 "*/ + protected String idcardNum; + + /** 识别模式 "*/ + protected String model; + + /** 活体判断结果 "*/ + protected String aliveType; + + /** 人员比对结果 "*/ + protected String identifyType; + + /** 有效时间段判断 "*/ + protected String passTimeType; + + /** 有效日期判断 "*/ + protected String permissionTimeType; + + /** 识别模式判断 "*/ + protected String recModeType; + + /** 身份证信息 "*/ + protected String data; + + /** 识别方式_人员类型 "*/ + protected String type; + + /** 现场照 base64 码 "*/ + protected String base64; + + /** 识别方式"*/ + protected String recType; + + /** 人员测量温度值"*/ + protected String temperature; + + /** 设置的体温异常标准"*/ + protected String standard; + + /** 体温状态"*/ + protected String temperatureState; + + /** 温度单位"*/ + protected String tempUnit; + + + @Override + public String toString() { + return "BackInfo{" + + "deviceKey='" + deviceKey + '\'' + + ", time='" + time + '\'' + + ", ip='" + ip + '\'' + + ", path='" + path + '\'' + + ", personId='" + personId + '\'' + + ", idcardNum='" + idcardNum + '\'' + + ", model='" + model + '\'' + + ", aliveType='" + aliveType + '\'' + + ", identifyType='" + identifyType + '\'' + + ", passTimeType='" + passTimeType + '\'' + + ", permissionTimeType='" + permissionTimeType + '\'' + + ", recModeType='" + recModeType + '\'' + + ", data='" + data + '\'' + + ", type='" + type + '\'' + + ", base64='" + base64 + '\'' + + ", recType='" + recType + '\'' + + ", temperature='" + temperature + '\'' + + ", standard='" + standard + '\'' + + ", temperatureState='" + temperatureState + '\'' + + ", tempUnit='" + tempUnit + '\'' + + '}'; + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/BackResult.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/BackResult.java new file mode 100644 index 0000000..7e588b6 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/BackResult.java @@ -0,0 +1,52 @@ +package com.dcsoft.system.uniubi.domain; + +import lombok.Data; + +import java.util.HashMap; + + +/** + * Uface回调参数 持久化对象 + * + * @author nichun + */ +@Data +public class BackResult extends HashMap { + + + + /** 返回内容 */ + public static final String RESULT_TAG = "result"; + + /** 数据对象 */ + public static final String SUCCESS_TAG = "success"; + + + public BackResult() + { + } + + /** + * 初始化一个新创建的 AjaxResult 对象 + * + * @param code 状态码 + * @param msg 返回内容 + */ + public BackResult(int code, Boolean msg) + { + super.put(RESULT_TAG, code); + super.put(SUCCESS_TAG, msg); + } + + /** + * 返回成功消息 + * + * @return 成功消息 + */ + public static BackResult success() + { + return BackResult.success(); + } + + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/DingtalkCode.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/DingtalkCode.java new file mode 100644 index 0000000..3767046 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/DingtalkCode.java @@ -0,0 +1,22 @@ +package com.dcsoft.system.uniubi.domain; + +import lombok.Data; + +@Data +public class DingtalkCode { + + /** + * 用户id + */ + private String userId; + + /** + * 二维码过期 + */ + private String message; + + /** + * 错误类型 + */ + private String code; +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/DingtalkMsgVo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/DingtalkMsgVo.java new file mode 100644 index 0000000..6938deb --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/DingtalkMsgVo.java @@ -0,0 +1,27 @@ +package com.dcsoft.system.uniubi.domain; + +import lombok.Data; +import lombok.Getter; +import lombok.Setter; + +/** + * 钉钉消息 + */ +@Data +public class DingtalkMsgVo { + /** + * 消息类型 + */ + private String msgtype; + + private Text text; + + @Getter + @Setter + public static class Text { + /** + * 类容 + */ + private String content; + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/EventResult.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/EventResult.java new file mode 100644 index 0000000..8fbd962 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/EventResult.java @@ -0,0 +1,24 @@ +package com.dcsoft.system.uniubi.domain; + +import lombok.Data; + + +/** + * Uface回调参数 持久化对象 + * + * @author nichun + */ +@Data +public class EventResult { + + /** 事件Guid,唯一不重复标志*/ + protected String eventGuid; + + /** 事件编码,具体见文档描述*/ + protected String eventCode; + + /** 具体时间内容(JSON格式),具体见文档描述*/ + protected String eventMsg; + + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/EwmInfo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/EwmInfo.java new file mode 100644 index 0000000..2e4c09d --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/EwmInfo.java @@ -0,0 +1,41 @@ +package com.dcsoft.system.uniubi.domain; + +import lombok.Data; + + +/** + * Uface回调参数 持久化对象 + * + * @author nichun + */ +@Data +public class EwmInfo { + + /** 设备序列号 **/ + protected String deviceKey; + + /** 识别记录毫秒级时间戳*/ + protected String time; + + /** 设备当前 IP 地址 "*/ + protected String ip; + + /** 现场照保存路径 "*/ + protected String QRdata; + + + /** + * 码值 + */ + private String payCode; + + /** + * 请求id,随机生成 + */ + private String requestId; + + private String qrCode; + + + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/HeartInfo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/HeartInfo.java new file mode 100644 index 0000000..dbc24dc --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/HeartInfo.java @@ -0,0 +1,54 @@ +package com.dcsoft.system.uniubi.domain; + +import lombok.Data; + + +/** + * Uface回调参数 持久化对象 + * + * @author nichun + */ +@Data +public class HeartInfo { + + /** 设备序列号 **/ + protected String deviceKey; + + /** 识别记录毫秒级时间戳*/ + protected String time; + + /** 设备当前 IP 地址 "*/ + protected String ip; + + /** 设备上的人员数量 "*/ + protected String personCount; + + /** 设备上的照片数量 "*/ + protected String faceCount; + + /** 设备上的指纹数量 "*/ + protected String fingerCount; + + /** 设备版本号 "*/ + protected String version; + + /** 磁盘剩余空间,单位:M "*/ + protected String freeDiskSpace; + + /** CPU 使用率,单位:% "*/ + protected String cpuUsageRate; + + /** CPU 温度,单位:℃ "*/ + protected String cpuTemperature; + + /** 设备名称 "*/ + protected String deviceName; + + /** 设备算法版本 "*/ + protected String SDKVersion; + + /** 公司名称 "*/ + protected String companyName; + + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/LadderControlVo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/LadderControlVo.java new file mode 100644 index 0000000..d03ed15 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/LadderControlVo.java @@ -0,0 +1,44 @@ +package com.dcsoft.system.uniubi.domain; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Data; + +import java.util.List; + +@Data +@JsonInclude(value= JsonInclude.Include.NON_NULL) +public class LadderControlVo { + + /** + * 设备序列号 + **/ + private String deviceKey; + + private List list; + + /** + * 工号 + */ + private String gh; + + /** + * 人员id + */ + private String peopleId; + + /** + * 姓名 + */ + private String name; + + /** + * 梯控状态1.卡号;2.二维码 + */ + private String ladderType; + + /** + * 访客id + */ + private String visitorId; + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/Person.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/Person.java new file mode 100644 index 0000000..f06047d --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/Person.java @@ -0,0 +1,172 @@ +package com.dcsoft.system.uniubi.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import com.dcsoft.system.domain.SysBranch; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 人员管理对象 person + * + * @author nichun + * @date 2023-03-08 + */ +public class Person extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 人员Id */ + private String id; + + /** 人员名称 */ + private String name; + + /** 人员卡号 */ + private String idcardNum; + + /** 身份证号 */ + private String iDNumber; + + /** 人像模式权限 1:关 2:开 (默认) */ + private int facePermission=2; + + /** 刷卡模式权限 1:关 2:开 (默认)*/ + private int idCardPermission=2; + + /** 人卡合一模式权限 1:关(默认) 2:开*/ + private int faceAndCardPermission=1; + + /** 单一验证方式 指纹验证 1:关(默认) 2:开*/ + private int fingerPermission=2; + + /** 人证比对模式权限 1:关(默认) 2:开 */ + private int iDPermission=1; + + /** 人员备注 */ + private String tag; + + /** 手机号 */ + private String phone; + + /** 用户密码 */ + private String password; + + /** 用户密码权限 1:关 (默认) 2:开 */ + private int passwordPermssion=1; + + /** 人员类型 0:长期人员(默认),1:临时员工 2:黑名单用户,*/ + private int role=0; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getIdcardNum() { + return idcardNum; + } + + public void setIdcardNum(String idcardNum) { + this.idcardNum = idcardNum; + } + + public String getiDNumber() { + return iDNumber; + } + + public void setiDNumber(String iDNumber) { + this.iDNumber = iDNumber; + } + + public int getFacePermission() { + return facePermission; + } + + public void setFacePermission(int facePermission) { + this.facePermission = facePermission; + } + + public int getIdCardPermission() { + return idCardPermission; + } + + public void setIdCardPermission(int idCardPermission) { + this.idCardPermission = idCardPermission; + } + + public int getFaceAndCardPermission() { + return faceAndCardPermission; + } + + public void setFaceAndCardPermission(int faceAndCardPermission) { + this.faceAndCardPermission = faceAndCardPermission; + } + + public int getiDPermission() { + return iDPermission; + } + + public void setiDPermission(int iDPermission) { + this.iDPermission = iDPermission; + } + + public String getTag() { + return tag; + } + + public void setTag(String tag) { + this.tag = tag; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public int getPasswordPermssion() { + return passwordPermssion; + } + + public void setPasswordPermssion(int passwordPermssion) { + this.passwordPermssion = passwordPermssion; + } + + public int getRole() { + return role; + } + + public void setRole(int role) { + this.role = role; + } + + public int getFingerPermission() { + return fingerPermission; + } + + public void setFingerPermission(int fingerPermission) { + this.fingerPermission = fingerPermission; + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/QrCodeVo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/QrCodeVo.java new file mode 100644 index 0000000..cbaa813 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/domain/QrCodeVo.java @@ -0,0 +1,37 @@ +package com.dcsoft.system.uniubi.domain; + +import lombok.Data; + +@Data +public class QrCodeVo { + + /** + * 设备序列号 + **/ + protected String deviceKey; + + /** + * 识别记录毫秒级时间戳 + */ + protected String time; + + /** + * 设备当前 IP 地址 " + */ + protected String ip; + + /** + * 现场照保存路径 " + */ + protected String qrData; + + /** + * 码值 + */ + private String payCode; + + /** + * 请求id,随机生成 + */ + private String requestId; +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/service/ISysApiService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/service/ISysApiService.java new file mode 100644 index 0000000..16c6c56 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/service/ISysApiService.java @@ -0,0 +1,93 @@ +package com.dcsoft.system.uniubi.service; + + +import com.dcsoft.system.domain.SysEquipment; +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.domain.SysRule; +import com.dcsoft.system.visitor.domain.Visitor; + + +import java.util.List; + +/** + * Uface 服务层 + * + * @author xueyi + */ +public interface ISysApiService { + + + //获取token值 + String getToken(); + + //人员接口-创建识别对象的主体信息 + String admitCreate(SysPeople people); + + //人员接口-更新识别对象的主体信息 + String admitUpdate(SysPeople people); + + //人员接口-删除识别对象的主体信息 + String admitDelete(String admitGuids); + + //人员接口-上传人像照片 + String faceRegister(SysPeople people); + + //人员接口-删除人像照片 + String faceDelete(SysPeople people); + + //设备信息-设备添加 + String deviceCreate(SysEquipment equipment); + + //设备信息-设备修改 + String deviceUpdate(SysEquipment equipment); + + //设备信息-删除设备信息 + String deviceDelete(SysEquipment equipment); + + //设备信息-设备配置查询 + String deviceSettingQuery(SysEquipment equipment); + + //设备信息-远程配置设备参数 + String deviceSettingUpdate(SysEquipment equipment); + + //设备信息-批量查询设备在线状态 + String deviceOnlineState(List equipment); + + //设备信息-设备状态操作的指令下发 + String deviceCommand(SysEquipment equipment,int operateType); + + String deviceInteractive(SysEquipment equipment); + + //人像门禁服务-设备授权识别主体 + String authDevice(SysRule rule, SysPeople people); + + String authDevice(SysRule rule, SysPeople people,SysEquipment equipment); + + //人像门禁服务-设备修改识别主体权限 + String authDeviceUpdate(SysRule rule,SysPeople people); + + //人像门禁服务-设备销权识别主体 + String authDeviceRevoke(SysEquipment equipment, SysPeople people); + + //人像门禁服务-授权列表查询 + String sceneAuth(); + + //访客人员接口-创建识别对象的主体信息 + String admitCreate(Visitor visitor); + + //访客人员接口-更新识别对象的主体信息 + String admitUpdate(Visitor visitor); + + //访客人员接口-上传人像照片 + String faceRegister(Visitor visitor); + + //访客人员接口-删除人像照片 + String faceDelete(Visitor visitor); + + //访客人像门禁服务-设备授权识别主体 + String authDeviceExamine(Visitor visitor); + + String authDeviceRevoke(Visitor visitor); + + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/service/ISysSdkService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/service/ISysSdkService.java new file mode 100644 index 0000000..f035baa --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/service/ISysSdkService.java @@ -0,0 +1,122 @@ +package com.dcsoft.system.uniubi.service; + + +import com.alibaba.fastjson.JSONObject; +import com.dcsoft.system.domain.SysEquipment; +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.domain.SysPeopleRecord; +import com.dcsoft.system.domain.SysRule; +import com.dcsoft.system.uniubi.domain.Person; +import com.dcsoft.system.visitor.domain.Visitor; + +import java.util.List; + +/** + * Uface 服务层 + * + * @author nichun + */ +public interface ISysSdkService { + + //人员接口-人员注册 + String personCreate(Person person, String ip, String pass); + + //人员接口-人员删除(若删除多个人员,id 用英文逗号拼接,传入-1 则删除所有人员) + String personDelete(String id, String ip, String pass); + + //人员接口-人员更新 + String personUpdate(Person person, String ip, String pass); + + //人员接口-人员查询(若删除多个人员,id 用英文逗号拼接,传入-1 则删除所有人员) + String personFind(String id, String ip, String pass); + + //人员接口-人员卡号注册 + String icCardRegist(String id, String ip, String pass); + + //人员接口-时间段权限设置 + String createPasstime(JSONObject object, String ip, String pass); + + //人员接口-时间段权限设置(安卓设备不支持) + String passtime(JSONObject object, String ip, String pass); + + //人员接口-时间段权限批量删除(传入-1 可清除所有人员的passtime) + String deletePasstime(String id, String ip, String pass); + + //人员接口-人员有效期设置(2017-07-15 12:05:00) 仅支持单个人员 + String permissionsCreate(String id, String time, String ip, String pass); + + //人员有效期批量设置(安卓设备不支持) + //2017-07-15 12:05:00 + //传入-1 则选择为所有人员进行设置权限时间 + String permissionTime(String id, String startTime, String endTime, String ip, String pass); + + //人员接口-人员有效期批量删除(传入-1,可清除所有人员的权限时间) + String permissionsDelete(String id, String ip, String pass); + + //照片管理-照片注册册(base64)(不推荐使用)图片像素大于112*112、分辨率小于1080p、文件大小小于2M + String imageCreate64(String id, String imgBase64, String ip, String pass); + + //照片管理-照片注册册(url)(不推荐使用)图片像素大于112*112、分辨率小于1080p、文件大小小于2M + String imageCreateUrl(String id,String faceId, String imgUrl, String ip, String pass); + + String imageCreateUrl(String id,String imgUrl, String ip, String pass); + + //照片管理-照片删除 + String imageDeletel(String faceId, String ip, String pass); + + //照片管理-照片更新(base64) + String imageUpdate64(String id, String faceId, String imgBase64, String ip, String pass); + + //照片管理-拍照注册 + String takeImg(String id, String ip, String pass); + + //照片管理-清空人员注册照片 + String deletePerson(String id, String ip, String pass); + + //设备管理-识别回调 + String setIdentifyCallBack(String callbackUrl, String ip, String pass); + + //远程控制输出--默认远程开门 + String openDoorControl(String ip, String pass); + + //远程控制输出--设备重启 + String restartDevice(String ip, String pass); + + //远程控制输出--设备重置 + String resetDevice(String ip, String pass); + + String authDevice(SysRule rule, SysPeople people); + + String authDevice(SysRule rule, SysPeople people, SysEquipment equipment); + + String authDeviceExamine(Visitor visitor); + + String authDeviceRevoke(Visitor visitor); + + //设备管理-二维码回调 + String setQRCodeCallback(String callbackUrl, String ip, String pass); + + + //设备管理-心跳回调 + String setDeviceHeartBeat(String callbackUrl, String ip, String pass); + + //设备管理-指纹采集 + String fingerRegist(String id, String ip, String pass); + + + //设备管理-指纹特征值查询 + String featureInfo(String id, String ip, String pass); + + //设备管理-照片查询 + String faceFind(String id, String ip, String pass); + + + //设备管理-指纹特征值注册 + String featureReg(String id,String fingerprint, String ip, String pass); + + String authDeviceNew(SysRule rule, SysPeople sysPeople); + + String authDeviceNews(SysRule rule, SysPeople sysPeople); + + String authDevices(SysPeople people, SysEquipment equipment); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/service/ISysVehicleService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/service/ISysVehicleService.java new file mode 100644 index 0000000..c0931b3 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/service/ISysVehicleService.java @@ -0,0 +1,15 @@ +package com.dcsoft.system.uniubi.service; + + +import com.dcsoft.system.domain.SysEquipment; + +/** + * Uface 服务层 + * + * @author nichun + */ +public interface ISysVehicleService { + + //人员接口-人员注册 + String config(String ip); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/service/impl/SysApiServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/service/impl/SysApiServiceImpl.java new file mode 100644 index 0000000..a17306c --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/service/impl/SysApiServiceImpl.java @@ -0,0 +1,674 @@ +package com.dcsoft.system.uniubi.service.impl; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.dcsoft.common.core.constant.CacheConstants; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.system.domain.SysEmpowerRecord; +import com.dcsoft.system.domain.SysEquipment; +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.domain.SysRule; +import com.dcsoft.system.service.ISysEmpowerRecordService; +import com.dcsoft.system.service.ISysEquipmentService; +import com.dcsoft.system.service.ISysRuleService; +import com.dcsoft.system.uniubi.service.ISysApiService; +import com.dcsoft.system.utils.HttpUtil; +import com.dcsoft.system.utils.ImageToBase64Utils; +import com.dcsoft.system.visitor.domain.VisVisitorExamine; +import com.dcsoft.system.visitor.domain.Visitor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import com.dcsoft.common.redis.service.RedisService; + +import java.math.BigInteger; +import java.security.MessageDigest; +import java.util.*; + +/** + * 用户管理 服务层处理 + * + * @author xueyi + */ +@Service +public class SysApiServiceImpl implements ISysApiService { + + @Autowired + private RedisService redisService; + @Autowired + private ISysEquipmentService equipmentService; + + @Autowired + private ISysEmpowerRecordService empowerRecordService; + + @Autowired + private ISysRuleService ruleService; + + + @Value("${uni.url}") + public String uniUrl; + //** 资源映射路径 前缀 *//* + @Value("${uni.appKey}") + public String appKey; + @Value("${uni.appSecret}") + public String appSecret; + + @Value("${uni.projectGuid}") + public String projectGuid; + + //获取token值 + @Override + public String getToken() { + //通过缓存获取,如果没有就重新获取,时间间隔为20小时 + //token 有效期为 24 小时,过期后需再次获取;建议定时更新 token,比如每 20 小时更新一次 + //所有请求 token 及其他参数都写在 header 中 + String verifyKey = CacheConstants.AUTH_KEY + appKey; + String token = redisService.getCacheObject(verifyKey); + if(StringUtils.isEmpty(token)){//重新获取token + String url=uniUrl+"/v1/"+projectGuid+"/auth?"; + Map headMap=new HashMap(); + headMap.put("appKey",appKey); + String timestamp=new Date().getTime()+""; + headMap.put("timestamp",timestamp); + String sign= EncodeByMD5(appKey+timestamp+appSecret).toLowerCase(); + headMap.put("sign",sign); + String response= HttpUtil.getUrl(url,headMap,projectGuid); + JSONObject json= JSONObject.parseObject(response); + token=json.get("data").toString(); + redisService.setCacheObject(verifyKey,token); + redisService.expire(verifyKey,20*60*60); + } + return token; + } + + //人员接口--识别主体创建 + public String admitCreate(SysPeople people){ + String url=uniUrl+"/v2/admit/create?"; + Map headMap=new HashMap(); + headMap.put("token",getToken()); + headMap.put("projectGuid",projectGuid); + Map paramMap=new HashMap(); + paramMap.put("name",people.getName()); + paramMap.put("phone",people.getPhone()); + paramMap.put("idCardNo",people.getIdcard()); + paramMap.put("cardNo",people.getDoorNo()); + paramMap.put("tag",people.getRemark()); + //获取识别主体admitGuid 人员 guid需保存 + String response= HttpUtil.postData(url,headMap,paramMap); + return response; + } + + //人员接口--更新识别对象的主体信息 + public String admitUpdate(SysPeople people){ + String url=uniUrl+"/v2/admit/update?"; + Map headMap=new HashMap(); + headMap.put("token",getToken()); + headMap.put("projectGuid",projectGuid); + Map paramMap=new HashMap(); + paramMap.put("admitGuid",people.getGuid()); + paramMap.put("name",people.getName()); + paramMap.put("cardNo",people.getDoorNo()); + paramMap.put("phone",people.getPhone()); + paramMap.put("idCardNo",people.getIdcard()); + paramMap.put("tag",people.getRemark()); + String response= HttpUtil.postData(url,headMap,paramMap); + return response; + } + + //人员接口--删除识别对象的主体信息 + public String admitDelete(String admitGuids){ + String url=uniUrl+"/v2/admit/delete?"; + Map headMap=new HashMap(); + headMap.put("token",getToken()); + headMap.put("projectGuid",projectGuid); + Map paramMap=new HashMap(); + paramMap.put("admitGuids",admitGuids); + String response= HttpUtil.postData(url,headMap,paramMap); + return response; + } + + //人像注册--上传人像照片 + public String faceRegister(SysPeople people){ + String url=uniUrl+"/v2/face/register?"; + Map headMap=new HashMap(); + headMap.put("token",getToken()); + headMap.put("projectGuid",projectGuid); + Map paramMap=new HashMap(); + String base64= ImageToBase64Utils.getImgStrToBase64(people.getAvatar()); + paramMap.put("base64",base64); + paramMap.put("admitGuid",people.getGuid()); + String response= HttpUtil.postData(url,headMap,paramMap); + return response; + } + + //人像注册--删除人像照片 + public String faceDelete(SysPeople people){ + String url=uniUrl+"/v2/face/delete?"; + Map headMap=new HashMap(); + headMap.put("token",getToken()); + headMap.put("projectGuid",projectGuid); + Map paramMap=new HashMap(); + paramMap.put("admitGuid",people.getGuid()); + paramMap.put("faceGuid",people.getFaceGuid()); + String response= HttpUtil.postData(url,headMap,paramMap); + return response; + } + + //设备信息-设备添加 + @Override + public String deviceCreate(SysEquipment equipment) { + String url=uniUrl+"/v2/device/create"; + Map headMap=new HashMap(); + headMap.put("token",getToken()); + headMap.put("projectGuid",projectGuid); + Map paramMap=new HashMap(); + paramMap.put("name",equipment.getName()); + paramMap.put("source","000000");//设备来源-Uface 系列 + paramMap.put("deviceNo",equipment.getSequence()); + String response= HttpUtil.postData(url,headMap,paramMap); + return response; + } + + //设备信息-设备修改 + @Override + public String deviceUpdate(SysEquipment equipment) { + String url=uniUrl+"/v2/device/update?"; + Map headMap=new HashMap(); + headMap.put("token",getToken()); + headMap.put("projectGuid",projectGuid); + Map paramMap=new HashMap(); + paramMap.put("name",equipment.getName()); + paramMap.put("source","000000");//设备来源-Uface 系列 + paramMap.put("deviceNo",equipment.getSequence()); + paramMap.put("addition","{'recType':'1'}"); + String response= HttpUtil.postData(url,headMap,paramMap); + return response; + } + + //设备信息-删除设备信息 + @Override + public String deviceDelete(SysEquipment equipment) { + String url=uniUrl+"/v2/device/delete?"; + Map headMap=new HashMap(); + headMap.put("token",getToken()); + headMap.put("projectGuid",projectGuid); + Map paramMap=new HashMap(); + paramMap.put("source","000000");//设备来源-Uface 系列 + paramMap.put("deviceNo",equipment.getSequence()); + String response= HttpUtil.postData(url,headMap,paramMap); + return response; + } + + //设备信息-设备配置查询 + @Override + public String deviceSettingQuery(SysEquipment equipment) { + String url=uniUrl+"/v2/device/setting/query"; + Map headMap=new HashMap(); + headMap.put("token",getToken()); + headMap.put("projectGuid",projectGuid); + Map paramMap=new HashMap(); + paramMap.put("source","000000");//设备来源-Uface 系列 + paramMap.put("deviceNo",equipment.getSequence()); + String response= HttpUtil.postData(url,headMap,paramMap); + return response; + } + + //设备信息-远程配置设备参数 + @Override + public String deviceSettingUpdate(SysEquipment equipment) { + String url=uniUrl+"/v2/device/setting/update?"; + Map headMap=new HashMap(); + headMap.put("token",getToken()); + headMap.put("projectGuid",projectGuid); + Map paramMap=new HashMap(); + paramMap.put("source","000000");//设备来源-Uface 系列 + paramMap.put("deviceNo",equipment.getSequence()); + //不对接内容 + SysEquipment equipments=equipment; + equipments.setId(null); + equipments.setProductId(null); + equipments.setSequence(null); + equipments.setIp(null); + equipments.setPassword(null); + equipments.setPointId(null); + equipments.setRemark(null); + equipments.setState(null); + equipments.setUpdateBy(null); + equipments.setCreateBy(null); + Map map = JSON.parseObject(JSON.toJSONString(equipments), Map.class); + JSONArray objs= new JSONArray(); + Set> entrys = map.entrySet(); //此行可省略,直接将map.entrySet()写在for-each循环的条件中 + for(Map.Entry entry:entrys){ + JSONObject jsons=new JSONObject(); + jsons.put("key",entry.getKey()+""); + jsons.put("value",entry.getValue()); + objs.add(jsons); + } + paramMap.put("deviceConfigs",objs); + String response= HttpUtil.postData(url,headMap,paramMap); + return response; + } + + @Override + public String deviceOnlineState(List equipment) { + String url=uniUrl+"/v2/device/onlineState?"; + Map headMap=new HashMap(); + headMap.put("token",getToken()); + headMap.put("projectGuid",projectGuid); + Map paramMap=new HashMap(); + paramMap.put("source","000000");//设备来源-Uface 系列 + String eqs=""; + for(SysEquipment eq:equipment){ + eqs+=eq.getSequence()+","; + } + paramMap.put("deviceNos",eqs); + String response= HttpUtil.postData(url,headMap,paramMap); + return response; + } + + @Override + public String deviceCommand(SysEquipment equipment, int operateType) { + String url=uniUrl+"/v2/device/command?"; + Map headMap=new HashMap(); + headMap.put("token",getToken()); + headMap.put("projectGuid",projectGuid); + Map paramMap=new HashMap(); + paramMap.put("source","000000");//设备来源-Uface 系列 + paramMap.put("deviceNo",equipment.getSequence()); + paramMap.put("operateType",operateType);//1 重启 2:重置 3:启用 4 禁用 + String response= HttpUtil.postData(url,headMap,paramMap); + return response; + } + + @Override + public String deviceInteractive(SysEquipment equipment) { + String url=uniUrl+"/v2/device/interactive?"; + Map headMap=new HashMap(); + headMap.put("token",getToken()); + headMap.put("projectGuid",projectGuid); + Map paramMap=new HashMap(); + paramMap.put("type","1");//远程开门 + paramMap.put("deviceNo",equipment.getSequence()); + String response= HttpUtil.postData(url,headMap,paramMap); + return response; + } + + //人像门禁服务-设备授权识别主体 + @Override + public String authDevice(SysRule rule, SysPeople people) { + String response=""; + String url=uniUrl+"/v2/auth/device?"; + Map headMap=new HashMap(); + headMap.put("token",getToken()); + headMap.put("projectGuid",projectGuid); + String[] pointIds=rule.getPointId().split(","); + List equipList=new ArrayList<>(); + if(pointIds!=null){ + for(String point:pointIds){ + SysEquipment equipment=new SysEquipment(); + equipment.setPointId(Long.parseLong(point)); + List equipmentDtoList=equipmentService.selectSysEquipmentList(equipment); + equipList.addAll(equipmentDtoList); + } + } + //通过规则获取绑定设备信息 + if(equipList!=null){ + for(SysEquipment e:equipList){ + Map paramMap=new HashMap(); + paramMap.put("deviceNo",e.getSequence()); + paramMap.put("admitGuids",people.getGuid());//设备来源-Uface 系列 + paramMap.put("type",rule.getType()); + paramMap.put("passTime",rule.getAdmittanceStart()+","+rule.getAdmittanceEnd()); + paramMap.put("permissionTime",rule.getStartTime().getTime()+","+rule.getEndTime().getTime()); + JSONObject jsons=new JSONObject(); + if(rule.getPermission().contains("idCardFacePermission")){ + jsons.put("idCardFacePermission",2); + }else{ + jsons.put("idCardFacePermission",1); + } + if(rule.getPermission().contains("passwordPermission")){ + jsons.put("passwordPermission",2); + }else{ + jsons.put("passwordPermission",1); + } + if(rule.getPermission().contains("facePermission")){ + jsons.put("facePermission",2); + }else{ + jsons.put("facePermission",1); + } + if(rule.getPermission().contains("idCardPermission")){ + jsons.put("idCardPermission",2); + }else{ + jsons.put("idCardPermission",1); + } + if(rule.getPermission().contains("faceAndCardPermission")){ + jsons.put("faceAndCardPermission",2); + }else{ + jsons.put("faceAndCardPermission",1); + } + if(rule.getPermission().contains("QRCodePermission")){ + jsons.put("QRCodePermission",2); + }else{ + jsons.put("QRCodePermission",1); + } + paramMap.put("permission",jsons); + response= HttpUtil.postData(url,headMap,paramMap); + JSONObject json= JSONObject.parseObject(response); + if("1".equals(json.get("result")+"")){//授权记录保存 + SysEmpowerRecord manageRecordDto=new SysEmpowerRecord(); + manageRecordDto.setPeopleId(people.getId()+""); + manageRecordDto.setEmpower(rule.getType()); + manageRecordDto.setEquipmentId(e.getId()); + manageRecordDto.setStatus("0"); + manageRecordDto.setInfoDown("0"); + manageRecordDto.setRuleId(rule.getId()); + empowerRecordService.insertSysEmpowerRecord(manageRecordDto); + }else{ + SysEmpowerRecord manageRecordDto=new SysEmpowerRecord(); + manageRecordDto.setPeopleId(people.getId()+""); + manageRecordDto.setEmpower(rule.getType()); + manageRecordDto.setEquipmentId(e.getId()); + manageRecordDto.setStatus("0"); + manageRecordDto.setInfoDown("1"); + manageRecordDto.setRuleId(rule.getId()); + empowerRecordService.insertSysEmpowerRecord(manageRecordDto); + } + } + } + return response; + } + + //人像门禁服务-设备授权识别主体 + @Override + public String authDevice(SysRule rule, SysPeople people, SysEquipment equipment) { + String url=uniUrl+"/v2/auth/device?"; + Map headMap=new HashMap(); + headMap.put("token",getToken()); + headMap.put("projectGuid",projectGuid); + Map paramMap=new HashMap(); + paramMap.put("deviceNo",equipment.getSequence()); + paramMap.put("admitGuids",people.getGuid());//设备来源-Uface 系列 + paramMap.put("type",rule.getType()); + paramMap.put("passTime",rule.getAdmittanceStart()+","+rule.getAdmittanceEnd()); + paramMap.put("permissionTime",rule.getStartTime().getTime()+","+rule.getEndTime().getTime()); + JSONObject jsons=new JSONObject(); + if(rule.getPermission().contains("idCardFacePermission")){ + jsons.put("idCardFacePermission",2); + }else{ + jsons.put("idCardFacePermission",1); + } + if(rule.getPermission().contains("passwordPermission")){ + jsons.put("passwordPermission",2); + }else{ + jsons.put("passwordPermission",1); + } + if(rule.getPermission().contains("facePermission")){ + jsons.put("facePermission",2); + }else{ + jsons.put("facePermission",1); + } + if(rule.getPermission().contains("idCardPermission")){ + jsons.put("idCardPermission",2); + }else{ + jsons.put("idCardPermission",1); + } + if(rule.getPermission().contains("faceAndCardPermission")){ + jsons.put("faceAndCardPermission",2); + }else{ + jsons.put("faceAndCardPermission",1); + } + if(rule.getPermission().contains("QRCodePermission")){ + jsons.put("QRCodePermission",2); + }else{ + jsons.put("QRCodePermission",1); + } + paramMap.put("permission",jsons); + String response= HttpUtil.postData(url,headMap,paramMap); + return response; + } + + //人像门禁服务-设备修改识别主体权限 + @Override + public String authDeviceUpdate(SysRule rule, SysPeople people) { + return null; + } + + //人像门禁服务-设备销权识别主体 + @Override + public String authDeviceRevoke(SysEquipment equipment, SysPeople people) { + String url=uniUrl+"/v2/auth/device/revoke?"; + Map headMap=new HashMap(); + headMap.put("token",getToken()); + headMap.put("projectGuid",projectGuid); + Map paramMap=new HashMap(); + paramMap.put("deviceNo",equipment.getSequence()); + paramMap.put("admitGuids",people.getGuid());//设备来源-Uface 系列 + String response= HttpUtil.postData(url,headMap,paramMap); + return response; + } + + //人像门禁服务-授权列表查询 + @Override + public String sceneAuth() { + return null; + } + + + //访客人员接口--识别主体创建 + public String admitCreate(Visitor visitor){ + String url=uniUrl+"/v2/admit/create?"; + Map headMap=new HashMap(); + headMap.put("token",getToken()); + headMap.put("projectGuid",projectGuid); + Map paramMap=new HashMap(); + paramMap.put("name",visitor.getName()); + paramMap.put("phone",visitor.getPhone()); + paramMap.put("idCardNo",visitor.getIdcard()); + paramMap.put("tag",visitor.getRemark()); + //获取识别主体admitGuid 人员 guid需保存 + String response= HttpUtil.postData(url,headMap,paramMap); + return response; + } + + //访客人员接口--更新识别对象的主体信息 + public String admitUpdate(Visitor visitor){ + String url=uniUrl+"/v2/admit/update?"; + Map headMap=new HashMap(); + headMap.put("token",getToken()); + headMap.put("projectGuid",projectGuid); + Map paramMap=new HashMap(); + paramMap.put("admitGuid",visitor.getGuid()); + paramMap.put("name",visitor.getName()); + paramMap.put("phone",visitor.getPhone()); + paramMap.put("idCardNo",visitor.getIdcard()); + paramMap.put("tag",visitor.getRemark()); + String response= HttpUtil.postData(url,headMap,paramMap); + return response; + } + + //访客人像注册--上传人像照片 + public String faceRegister(Visitor visitor){ + String url=uniUrl+"/v2/face/register?"; + Map headMap=new HashMap(); + headMap.put("token",getToken()); + headMap.put("projectGuid",projectGuid); + Map paramMap=new HashMap(); + String base64= ImageToBase64Utils.getImgStrToBase64(visitor.getAvatar()); + paramMap.put("base64",base64); + paramMap.put("admitGuid",visitor.getGuid()); + String response= HttpUtil.postData(url,headMap,paramMap); + return response; + } + + //访客人像注册--删除人像照片 + public String faceDelete(Visitor visitor){ + String url=uniUrl+"/v2/face/delete?"; + Map headMap=new HashMap(); + headMap.put("token",getToken()); + headMap.put("projectGuid",projectGuid); + Map paramMap=new HashMap(); + paramMap.put("admitGuid",visitor.getGuid()); + paramMap.put("faceGuid",visitor.getFaceGuid()); + String response= HttpUtil.postData(url,headMap,paramMap); + return response; + } + + + + /** + * 对字符串进行32位MD5加密 + * @param str + * @return + */ + public static String EncodeByMD5(String str) { + try { + // 生成一个MD5加密计算摘要 + MessageDigest md = MessageDigest.getInstance("MD5"); + // 计算md5函数 + md.update(str.getBytes("UTF-8")); + // digest()最后确定返回md5 hash值,返回值为8为字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符 + // BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值 + String md5=new BigInteger(1, md.digest()).toString(16); + //BigInteger会把0省略掉,需补全至32位 + return fillMD5(md5); + } catch (Exception e) { + throw new RuntimeException("MD5加密错误:"+e.getMessage(),e); + } + } + + @Override + public String authDeviceExamine(Visitor visitor) { + String response=""; + String url=uniUrl+"/v2/auth/device?"; + Map headMap=new HashMap(); + headMap.put("token",getToken()); + headMap.put("projectGuid",projectGuid); + VisVisitorExamine examine= visitor.getExamine(); + //通过访问人员的地点 + SysRule rule=ruleService.selectSysRuleById(examine.getRuleId()); + String[] pointIds=rule.getPointId().split(","); + List equipList=new ArrayList<>(); + if(pointIds!=null){ + for(String point:pointIds){ + SysEquipment equipment=new SysEquipment(); + equipment.setPointId(Long.parseLong(point)); + List equipmentDtoList=equipmentService.selectSysEquipmentList(equipment); + equipList.addAll(equipmentDtoList); + } + } + //授权人员 + String admitGuids=""; + if(StringUtils.isNotEmpty(visitor.getGuid())){ + admitGuids+=visitor.getGuid()+","; + } + if(visitor.getItemList()!=null){ + for(Visitor item:visitor.getItemList()){ + admitGuids+= item.getGuid()+","; + } + } + if(!"".equals(admitGuids)){ + admitGuids=admitGuids.substring(0,admitGuids.length()-1); + } + + //通过规则获取绑定设备信息 + if(equipList!=null){ + for(SysEquipment e:equipList){ + Map paramMap=new HashMap(); + paramMap.put("deviceNo",e.getSequence()); + paramMap.put("admitGuids",admitGuids); + Long endTime= visitor.getEndTime().getTime()+24*60*60*1000; + paramMap.put("permissionTime",visitor.getStartTime().getTime()+","+endTime); + paramMap.put("type",rule.getType()); + paramMap.put("passTime",rule.getAdmittanceStart()+","+rule.getAdmittanceEnd()); + JSONObject jsons=new JSONObject(); + if(rule.getPermission().contains("idCardFacePermission")){ + jsons.put("idCardFacePermission",2); + }else{ + jsons.put("idCardFacePermission",1); + } + if(rule.getPermission().contains("passwordPermission")){ + jsons.put("passwordPermission",2); + }else{ + jsons.put("passwordPermission",1); + } + if(rule.getPermission().contains("facePermission")){ + jsons.put("facePermission",2); + }else{ + jsons.put("facePermission",1); + } + if(rule.getPermission().contains("idCardPermission")){ + jsons.put("idCardPermission",2); + }else{ + jsons.put("idCardPermission",1); + } + if(rule.getPermission().contains("faceAndCardPermission")){ + jsons.put("faceAndCardPermission",2); + }else{ + jsons.put("faceAndCardPermission",1); + } + if(rule.getPermission().contains("QRCodePermission")){ + jsons.put("QRCodePermission",2); + }else{ + jsons.put("QRCodePermission",1); + } + paramMap.put("permission",jsons); + response= HttpUtil.postData(url,headMap,paramMap); + } + } + return response; + } + + //人像门禁服务-设备销权识别主体 + @Override + public String authDeviceRevoke(Visitor visitor) { + String response=""; + String url=uniUrl+"/v2/auth/device/revoke?"; + Map headMap=new HashMap(); + headMap.put("token",getToken()); + headMap.put("projectGuid",projectGuid); + Map paramMap=new HashMap(); + VisVisitorExamine examine= visitor.getExamine(); + //通过访问人员的地点 + SysRule rule=ruleService.selectSysRuleById(examine.getRuleId()); + String[] pointIds=rule.getPointId().split(","); + List equipList=new ArrayList<>(); + if(pointIds!=null){ + for(String point:pointIds){ + SysEquipment equipment=new SysEquipment(); + equipment.setPointId(Long.parseLong(point)); + List equipmentDtoList=equipmentService.selectSysEquipmentList(equipment); + equipList.addAll(equipmentDtoList); + } + } + //授权人员 + String admitGuids=""; + if(StringUtils.isNotEmpty(visitor.getGuid())){ + admitGuids+=visitor.getGuid()+","; + } + if(visitor.getItemList()!=null){ + for(Visitor item:visitor.getItemList()){ + admitGuids+= item.getGuid()+","; + } + } + if(!"".equals(admitGuids)){ + admitGuids=admitGuids.substring(0,admitGuids.length()-1); + } + + //通过规则获取绑定设备信息 + if(equipList!=null){ + for(SysEquipment e:equipList){ + paramMap.put("deviceNo",e.getSequence()); + paramMap.put("admitGuids",admitGuids);//设备来源-Uface 系列 + response= HttpUtil.postData(url,headMap,paramMap); + } + } + return response; + } + + private static String fillMD5(String md5) { + //如果不够32位则回调自身补零,最后返回32位长度的签名 + return md5.length() == 32 ? md5 : fillMD5("0" + md5); + } + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/service/impl/SysSdkServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/service/impl/SysSdkServiceImpl.java new file mode 100644 index 0000000..6cc4c20 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/service/impl/SysSdkServiceImpl.java @@ -0,0 +1,718 @@ +package com.dcsoft.system.uniubi.service.impl; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.dcsoft.system.domain.*; +import com.dcsoft.system.service.*; +import com.dcsoft.system.uniubi.domain.Person; +import com.dcsoft.system.uniubi.service.ISysSdkService; +import com.dcsoft.system.utils.HttpUtil; +import com.dcsoft.system.visitor.domain.Visitor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * 用户管理 服务层处理 + * + * @author xueyi + */ +@Service +@Slf4j +public class SysSdkServiceImpl implements ISysSdkService { + + @Autowired + private ISysEquipmentService equipmentService; + + @Autowired + private ISysEmpowerRecordService empowerRecordService; + + @Autowired + private ISysPeopleEquipmentService peopleEquipmentService; + + @Autowired + private ISysPeopleService sysPeopleService; + + @Autowired + private ISysConfigService configService; + + /** + * 卡权限创建接口 + */ + public static final String create = "/cardinfo/create"; + + + @Override + public String personCreate(Person person, String ip, String pass) { + String url="http://"+ip+":8090/person/create"; + Map paramMap=new HashMap(); + JSONObject personObject = JSONObject.parseObject(JSON.toJSONString(person)); + paramMap.put("pass",pass); + paramMap.put("person",personObject); + String response= HttpUtil.sendxwwwform(url,paramMap); + return response; + } + + @Override + public String personDelete(String id, String ip, String pass) { + String url="http://"+ip+":8090/person/delete"; + Map paramMap=new HashMap(); + paramMap.put("pass",pass); + paramMap.put("id",id); + String response= HttpUtil.sendxwwwform(url,paramMap); + return response; + } + + @Override + public String personUpdate(Person person, String ip, String pass) { + String url="http://"+ip+":8090/person/update"; + Map paramMap=new HashMap(); + JSONObject personObject = JSONObject.parseObject(JSON.toJSONString(person)); + paramMap.put("pass",pass); + paramMap.put("person",personObject); + String response= HttpUtil.sendxwwwform(url,paramMap); + return response; + } + + @Override + public String personFind(String id, String ip, String pass) { + String url="http://"+ip+":8090/person/find?pass="+pass+"&id="+id; + String response= HttpUtil.getData(url); + return response; + } + + + @Override + public String icCardRegist(String id, String ip, String pass) { + String url="http://"+ip+":8090/face/icCardRegist"; + Map paramMap=new HashMap(); + paramMap.put("pass",pass); + paramMap.put("personId",id); + String response= HttpUtil.sendxwwwform(url,paramMap); + return response; + } + + @Override + public String createPasstime(JSONObject object, String ip, String pass) { + /* {"personId":"9eecc839cd7941c5a4d3165202dd3c32","passtime":"09:00:00,10: + 00:00,17:00:00,17:30:00,18:30:00,20:25:00"}*/ + String url="http://"+ip+":8090/person/createPasstime"; + Map paramMap=new HashMap(); + paramMap.put("pass",pass); + paramMap.put("passtime",object); + String response= HttpUtil.sendxwwwform(url,paramMap); + return response; + } + + @Override + public String passtime(JSONObject object, String ip, String pass) { + /* {"personId":"9eecc839cd7941c5a4d3165202dd3c32","passtime":"09:00:00,10: + 00:00,17:00:00,17:30:00,18:30:00,20:25:00"}*/ + String url="http://"+ip+":8090/person/passtime"; + Map paramMap=new HashMap(); + paramMap.put("pass",pass); + paramMap.put("passtime",object.get("passtime")); + paramMap.put("personId",object.get("personId")); + String response= HttpUtil.sendxwwwform(url,paramMap); + return response; + } + + @Override + public String deletePasstime(String id, String ip, String pass) { + String url="http://"+ip+":8090/person/deletePasstime"; + Map paramMap=new HashMap(); + paramMap.put("pass",pass); + paramMap.put("personId",id); + String response= HttpUtil.sendxwwwform(url,paramMap); + return response; + } + + @Override + public String permissionsCreate(String id, String time,String ip, String pass) { + String url="http://"+ip+":8090/person/permissionsCreate"; + Map paramMap=new HashMap(); + paramMap.put("pass",pass); + paramMap.put("time",time); + paramMap.put("personId",id); + String response= HttpUtil.sendxwwwform(url,paramMap); + return response; + } + + @Override + public String permissionTime(String id, String startTime, String endTime, String ip, String pass) { + String url="http://"+ip+":8090/person/permissionTime"; + Map paramMap=new HashMap(); + paramMap.put("pass",pass); + paramMap.put("personId",id); + paramMap.put("startTime",startTime); + paramMap.put("endTime",endTime); + String response= HttpUtil.sendxwwwform(url,paramMap); + return response; + } + + @Override + public String permissionsDelete(String id,String ip, String pass) { + String url="http://"+ip+":8090/person/permissionsCreate"; + Map paramMap=new HashMap(); + paramMap.put("pass",pass); + paramMap.put("personId",id); + String response= HttpUtil.sendxwwwform(url,paramMap); + return response; + } + + @Override + public String imageCreate64(String id, String imgBase64, String ip, String pass) { + String url="http://"+ip+":8090/face/create"; + Map paramMap=new HashMap(); + paramMap.put("pass",pass); + paramMap.put("personId",id); + paramMap.put("faceId",id);//可不传,设为空 + paramMap.put("imgBase64",imgBase64); + String response= HttpUtil.sendxwwwform(url,paramMap); + return response; + } + + @Override + public String imageCreateUrl(String id,String imgUrl, String ip, String pass) { + String url="http://"+ip+":8090/face/createByUrl"; + Map paramMap=new HashMap(); + paramMap.put("pass",pass); + paramMap.put("personId",id); + paramMap.put("faceId","");//可不传,设为空 + //照地址替换 + if(imgUrl.contains("http://tdmj.kmlygroup.com")){ + imgUrl=imgUrl.replace("http://tdmj.kmlygroup.com","http://192.168.1.35"); + } + if(imgUrl.contains("https://mj.kmlygroup.com/")){ + imgUrl=imgUrl.replace("https://mj.kmlygroup.com/","http://192.168.255.51:9000/"); + } + if(imgUrl.contains("https://fk.xyxaks.cn/")){ + imgUrl=imgUrl.replace("https://fk.xyxaks.cn/","http://192.168.33.96:9000/"); + } + paramMap.put("imgUrl",imgUrl); + String response= HttpUtil.sendxwwwform(url,paramMap); + return response; + } + + @Override + public String imageCreateUrl(String id,String faceId, String imgUrl, String ip, String pass) { + String url="http://"+ip+":8090/face/createByUrl"; + Map paramMap=new HashMap(); + paramMap.put("pass",pass); + paramMap.put("personId",id); + paramMap.put("faceId",faceId);//可不传,设为空 + //照地址替换 + if(imgUrl.contains("http://tdmj.kmlygroup.com")){ + imgUrl=imgUrl.replace("http://tdmj.kmlygroup.com","http://192.168.251.16"); + } + if(imgUrl.contains("https://mj.kmlygroup.com/")){ + imgUrl=imgUrl.replace("https://mj.kmlygroup.com/","http://192.168.255.51:9000/"); + } + if(imgUrl.contains("https://fk.xyxaks.cn/")){ + imgUrl=imgUrl.replace("https://fk.xyxaks.cn/","http://192.168.33.96:9000/"); + } + paramMap.put("imgUrl",imgUrl); + String response= HttpUtil.sendxwwwform(url,paramMap); + return response; + } + + @Override + public String imageDeletel(String faceId, String ip, String pass) { + String url="http://"+ip+":8090/face/delete"; + Map paramMap=new HashMap(); + paramMap.put("pass",pass); + paramMap.put("faceId",faceId);//可不传,设为空 + String response= HttpUtil.sendxwwwform(url,paramMap); + return response; + } + + @Override + public String imageUpdate64(String id, String faceId, String imgBase64, String ip, String pass) { + String url="http://"+ip+":8090/face/update"; + Map paramMap=new HashMap(); + paramMap.put("pass",pass); + paramMap.put("personId",id); + paramMap.put("faceId",faceId); + paramMap.put("imgBase64",imgBase64); + String response= HttpUtil.sendxwwwform(url,paramMap); + return response; + } + + @Override + public String takeImg(String id, String ip, String pass) { + String url="http://"+ip+":8090/face/takeImg"; + Map paramMap=new HashMap(); + paramMap.put("pass",pass); + paramMap.put("personId",id); + String response= HttpUtil.sendxwwwform(url,paramMap); + return response; + } + + @Override + public String deletePerson(String id, String ip, String pass) { + String url="http://"+ip+":8090/face/deletePerson"; + Map paramMap=new HashMap(); + paramMap.put("pass",pass); + paramMap.put("personId",id); + String response= HttpUtil.sendxwwwform(url,paramMap); + return response; + } + + @Override + public String setIdentifyCallBack(String callbackUrl, String ip, String pass) { + String url="http://"+ip+":8090/setIdentifyCallBack"; + Map paramMap=new HashMap(); + paramMap.put("pass",pass); + paramMap.put("callbackUrl",callbackUrl); + String response= HttpUtil.sendxwwwform(url,paramMap); + return response; + } + + @Override + public String openDoorControl(String ip, String pass) { + String url="http://"+ip+":8090/device/openDoorControl"; + Map paramMap=new HashMap(); + paramMap.put("pass",pass); + String response= HttpUtil.sendxwwwform(url,paramMap); + return response; + } + + @Override + public String restartDevice(String ip, String pass) { + String url="http://"+ip+":8090/restartDevice"; + Map paramMap=new HashMap(); + paramMap.put("pass",pass); + String response= HttpUtil.sendxwwwform(url,paramMap); + return response; + } + + @Override + public String resetDevice(String ip, String pass) { + String url="http://"+ip+":8090/device/reset"; + Map paramMap=new HashMap(); + paramMap.put("pass",pass); + String response= HttpUtil.sendxwwwform(url,paramMap); + return response; + } + + //人像门禁服务-设备授权识别主体 + @Override + public String authDevice(SysRule rule, SysPeople people) { + String response=""; + String[] pointIds=rule.getPointId().split(","); + List equipList=new ArrayList<>(); + if(pointIds!=null){ + for(String point:pointIds){ + SysEquipment equipment=new SysEquipment(); + equipment.setPointId(Long.parseLong(point)); + equipment.setIsCj("0"); + equipment.setFlag("0"); +// equipment.setProductId(3L); + List equipmentDtoList=equipmentService.selectSysEquipmentList(equipment); + equipList.addAll(equipmentDtoList); + } + } + //通过规则获取绑定设备信息 + if(equipList!=null){ + for(SysEquipment e:equipList){ + //将人员信息下发到设备 + Person person=new Person(); + person.setName(people.getName()); + person.setId(people.getGuid()); + person.setiDNumber(people.getIdcard()); + person.setIdcardNum(people.getDoorNo()); + person.setPhone(people.getPhone()); + String ip=e.getIp(); + String pass=e.getPassword(); + String admitGuid=""; + String faceGuid=""; + if(3L == e.getProductId()) { + log.info("通过规则信息" + e); + this.personDelete(people.getGuid(),ip,pass); + String data=this.personCreate(person,ip,pass); + log.info("通过规则下发" + data); + JSONObject json= JSONObject.parseObject(data); + + if(!"1".equals(json.get("result")+"")) { + continue; + } + JSONObject obj1 = (JSONObject) json.get("data"); + admitGuid=obj1.get("id")+""; + if(StringUtils.isNotEmpty(people.getAvatar())) { + String datas=this.imageCreateUrl(admitGuid,people.getAvatar(),ip,pass); + JSONObject jsons= JSONObject.parseObject(datas); + if("1".equals(jsons.get("result")+"")){ + faceGuid=jsons.get("data")+""; + } + } + } + + + //保存到人员设备关联表中 + SysPeopleEquipment sysPeopleEquipment=new SysPeopleEquipment(); + sysPeopleEquipment.setGuid(admitGuid); + sysPeopleEquipment.setFaceGuid(faceGuid); + sysPeopleEquipment.setPeopleId(people.getId()); + sysPeopleEquipment.setEquipmentId(e.getId()); + peopleEquipmentService.insertSysPeopleEquipment(sysPeopleEquipment); + JSONObject jsons = new JSONObject(); + if(3L == e.getProductId()) { + //人员权限下发设备 + SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date endTime=rule.getEndTime(); + response=this.permissionsCreate(admitGuid,sdf.format(endTime),ip,pass); + JSONObject obj=new JSONObject(); + obj.put("personId",admitGuid); + obj.put("passtime",rule.getAdmittanceStart()+","+rule.getAdmittanceEnd()); + this.createPasstime(obj,ip,pass); + jsons = JSONObject.parseObject(response); + } + + //授权记录保存 + if("1".equals(jsons.get("result")+"")){ + SysEmpowerRecord manageRecordDto=new SysEmpowerRecord(); + manageRecordDto.setPeopleId(people.getId()+""); + manageRecordDto.setEmpower(rule.getType()); + manageRecordDto.setEquipmentId(e.getId()); + manageRecordDto.setStatus("0"); + manageRecordDto.setInfoDown("0"); + manageRecordDto.setRuleId(rule.getId()); + empowerRecordService.insertSysEmpowerRecord(manageRecordDto); + }else{ + SysEmpowerRecord manageRecordDto=new SysEmpowerRecord(); + manageRecordDto.setPeopleId(people.getId()+""); + manageRecordDto.setEmpower(rule.getType()); + manageRecordDto.setEquipmentId(e.getId()); + manageRecordDto.setStatus("0"); + manageRecordDto.setInfoDown("1"); + manageRecordDto.setRuleId(rule.getId()); + empowerRecordService.insertSysEmpowerRecord(manageRecordDto); + } + } + } + return response; + } + + //人像门禁服务-设备授权识别主体 + @Override + public String authDevice(SysRule rule, SysPeople people, SysEquipment equipment) { + String response=""; + //将人员信息下发到设备 + Person person=new Person(); + person.setName(people.getName()); + person.setiDNumber(people.getIdcard()); + person.setPhone(people.getPhone()); + person.setIdcardNum(people.getDoorNo()); + person.setId(people.getGuid()); + String ip=equipment.getIp(); + String pass=equipment.getPassword(); + this.personDelete(people.getGuid(),ip,pass); + String data=this.personCreate(person,ip,pass); + JSONObject json= JSONObject.parseObject(data); + String admitGuid=""; + String faceGuid=""; + if("1".equals(json.get("result")+"")) { + JSONObject obj= (JSONObject) json.get("data"); + admitGuid=obj.get("id")+""; + String datas=this.imageCreateUrl(admitGuid,people.getAvatar(),ip,pass); + JSONObject jsons= JSONObject.parseObject(datas); + if("1".equals(jsons.get("result")+"")){ + faceGuid=jsons.get("data")+""; + } + //保存到人员设备关联表中 + SysPeopleEquipment sysPeopleEquipment=new SysPeopleEquipment(); + sysPeopleEquipment.setGuid(admitGuid); + sysPeopleEquipment.setFaceGuid(faceGuid); + sysPeopleEquipment.setPeopleId(people.getId()); + sysPeopleEquipment.setEquipmentId(equipment.getId()); + peopleEquipmentService.insertSysPeopleEquipment(sysPeopleEquipment); + } + //人员权限下发设备 + SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date endTime=rule.getEndTime(); + response=this.permissionsCreate(admitGuid,sdf.format(endTime),ip,pass); + JSONObject obj=new JSONObject(); + obj.put("personId",admitGuid); + obj.put("passtime",rule.getAdmittanceStart()+","+rule.getAdmittanceEnd()); + this.createPasstime(obj,ip,pass); + return response; + } + + @Override + public String authDeviceExamine(Visitor visitor) { + String response=""; + //将人员信息下发到设备 + Person person=new Person(); + person.setName(visitor.getName()); + person.setiDNumber(visitor.getIdcard()); + person.setPhone(visitor.getPhone()); + List equipmentDtoList=equipmentService.selectSysEquipmentList(new SysEquipment()); + for(SysEquipment equipment:equipmentDtoList){ + String ip=equipment.getIp(); + String pass=equipment.getPassword(); + String data=this.personCreate(person,ip,pass); + JSONObject json= JSONObject.parseObject(data); + String admitGuid=""; + String faceGuid=""; + if("1".equals(json.get("result")+"")) { + JSONObject obj= (JSONObject) json.get("data"); + admitGuid=obj.get("id")+""; + String datas=this.imageCreateUrl(admitGuid,visitor.getAvatar(),ip,pass); + JSONObject jsons= JSONObject.parseObject(datas); + if("1".equals(jsons.get("result")+"")){ + faceGuid=jsons.get("data")+""; + } + //保存到人员设备关联表中 + SysPeopleEquipment sysPeopleEquipment=new SysPeopleEquipment(); + sysPeopleEquipment.setGuid(admitGuid); + sysPeopleEquipment.setFaceGuid(faceGuid); + sysPeopleEquipment.setVisitorId(visitor.getId()); + sysPeopleEquipment.setEquipmentId(equipment.getId()); + peopleEquipmentService.insertSysPeopleEquipment(sysPeopleEquipment); + } + //人员权限下发设备 + SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date endTime=visitor.getEndTime(); + response=this.permissionsCreate(admitGuid,sdf.format(endTime),ip,pass); + JSONObject obj=new JSONObject(); + obj.put("personId",admitGuid); + obj.put("passtime",visitor.getInTime()+","+visitor.getOutTime()); + this.createPasstime(obj,ip,pass); + } + return response; + } + + //人像门禁服务-设备销权识别主体 + @Override + public String authDeviceRevoke(Visitor visitor) { + String response = ""; + + List equipmentDtoList = equipmentService.selectSysEquipmentList(new SysEquipment()); + for(SysEquipment eq:equipmentDtoList){ + List list=peopleEquipmentService.selectSysPeopleEquipmentByVisitorId(visitor.getId()); + for(SysPeopleEquipment spe:list){ + if(spe.getEquipmentId().equals(eq.getId())){ + this.personDelete(spe.getGuid(), eq.getIp(), eq.getPassword()); + } + } + } + + return response; + } + + @Override + public String setQRCodeCallback(String callbackUrl, String ip, String pass) { + String url="http://"+ip+":8090/setQRCodeCallback"; + Map paramMap=new HashMap(); + paramMap.put("pass",pass); + paramMap.put("url",callbackUrl+"Ewm"); + String response= HttpUtil.sendxwwwform(url,paramMap); + return response; + } + + @Override + public String setDeviceHeartBeat(String callbackUrl, String ip, String pass) { + String url="http://"+ip+":8090/setDeviceHeartBeat"; + Map paramMap=new HashMap(); + paramMap.put("pass",pass); + paramMap.put("url",callbackUrl+"Heart"); + String response= HttpUtil.sendxwwwform(url,paramMap); + return response; + } + + @Override + public String fingerRegist(String id, String ip, String pass) { + String url="http://"+ip+":8090/face/fingerRegist"; + Map paramMap=new HashMap(); + paramMap.put("pass",pass); + paramMap.put("personId",id); + String response= HttpUtil.sendxwwwform(url,paramMap); + return response; + } + + @Override + public String featureInfo(String id, String ip, String pass) { + String url="http://"+ip+":8090/person/featureInfo?pass="+pass+"&personId="+id+"&type="+2; + String response= HttpUtil.getData(url); + return response; + } + + @Override + public String faceFind(String id, String ip, String pass) { + String url="http://"+ip+":8090/face/find"; + Map paramMap=new HashMap(); + paramMap.put("pass",pass); + paramMap.put("personId",id); + String response= HttpUtil.sendxwwwform(url,paramMap); + return response; + } + + @Override + public String featureReg(String id,String fingerprint, String ip, String pass) { + String url="http://"+ip+":8090/face/featureReg"; + Map paramMap=new HashMap(); + paramMap.put("pass",pass); + paramMap.put("personId",id); + paramMap.put("faceId",""); + paramMap.put("feature",fingerprint); + paramMap.put("type",2); + String response= HttpUtil.sendxwwwform(url,paramMap); + return response; + } + + @Override + public String authDeviceNew(SysRule rule, SysPeople people) { + String response=""; + String[] pointIds=rule.getPointId().split(","); + List equipList=new ArrayList<>(); + if(pointIds!=null){ + for(String point:pointIds){ + SysEquipment equipment=new SysEquipment(); + equipment.setPointId(Long.parseLong(point)); + equipment.setFlag("0"); + equipment.setIsCj("0"); +// equipment.setProductId(3L); + List equipmentDtoList=equipmentService.selectSysEquipmentList(equipment); + equipList.addAll(equipmentDtoList); + } + } + //通过规则获取绑定设备信息 + if(equipList!=null){ + for(SysEquipment e:equipList){ + if(3L == e.getProductId()) { + //将人员信息下发到设备 + Person person=new Person(); + person.setName(people.getName()); + person.setIdcardNum(people.getDoorNo()); + person.setiDNumber(people.getIdcard()); + person.setPhone(people.getPhone()); + person.setId(people.getGuid()); + String ip=e.getIp(); + String pass=e.getPassword(); + this.personDelete(people.getGuid(),ip,pass); + response=this.personCreate(person,ip,pass); + if(StringUtils.isNotEmpty(people.getFaceGuid())){//人脸 + this.imageCreateUrl(people.getGuid(),people.getFaceGuid(),people.getAvatar(), e.getIp(), e.getPassword()); + } + } + + //保存下发记录 + SysPeopleEquipment sysPeopleEquipment=new SysPeopleEquipment(); + sysPeopleEquipment.setPeopleId(people.getId()); + sysPeopleEquipment.setEquipmentId(e.getId()); + sysPeopleEquipment.setGuid(people.getGuid()); + sysPeopleEquipment.setFaceGuid(people.getFaceGuid()); + peopleEquipmentService.insertSysPeopleEquipment(sysPeopleEquipment); + SysEmpowerRecord manageRecordDto=new SysEmpowerRecord(); + manageRecordDto.setPeopleId(people.getId()+""); + manageRecordDto.setEmpower(rule.getType()); + manageRecordDto.setEquipmentId(e.getId()); + manageRecordDto.setStatus("0"); + manageRecordDto.setInfoDown("0"); + manageRecordDto.setRuleId(rule.getId()); + empowerRecordService.insertSysEmpowerRecord(manageRecordDto); + /*String data=this.personCreate(person,ip,pass); + JSONObject json= JSONObject.parseObject(data); + String admitGuid=""; + String faceGuid=""; + if("1".equals(json.get("result")+"")) { + JSONObject obj= (JSONObject) json.get("data"); + admitGuid=obj.get("id")+""; + String datas=this.imageCreateUrl(admitGuid,people.getAvatar(),ip,pass); + JSONObject jsons= JSONObject.parseObject(datas); + if("1".equals(jsons.get("result")+"")){ + faceGuid=jsons.get("data")+""; + } + //保存到人员设备关联表中 + SysPeopleEquipment sysPeopleEquipment=new SysPeopleEquipment(); + sysPeopleEquipment.setGuid(admitGuid); + sysPeopleEquipment.setFaceGuid(faceGuid); + sysPeopleEquipment.setPeopleId(people.getId()); + sysPeopleEquipment.setEquipmentId(e.getId()); + peopleEquipmentService.insertSysPeopleEquipment(sysPeopleEquipment); + } + //人员权限下发设备 + SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date endTime=rule.getEndTime(); + response=this.permissionsCreate(admitGuid,sdf.format(endTime),ip,pass); + JSONObject obj=new JSONObject(); + obj.put("personId",admitGuid); + obj.put("passtime",rule.getAdmittanceStart()+","+rule.getAdmittanceEnd()); + this.createPasstime(obj,ip,pass); + JSONObject jsons= JSONObject.parseObject(response);*/ + /* if("1".equals(jsons.get("result")+"")){//授权记录保存 + + }else{ + SysEmpowerRecord manageRecordDto=new SysEmpowerRecord(); + manageRecordDto.setPeopleId(people.getId()+""); + manageRecordDto.setEmpower(rule.getType()); + manageRecordDto.setEquipmentId(e.getId()); + manageRecordDto.setStatus("0"); + manageRecordDto.setInfoDown("1"); + manageRecordDto.setRuleId(rule.getId()); + empowerRecordService.insertSysEmpowerRecord(manageRecordDto); + }*/ + } + } + return response; + } + + @Override + public String authDeviceNews(SysRule rule, SysPeople people) { + String response=""; + String[] pointIds=rule.getPointId().split(","); + List equipList=new ArrayList<>(); + if(pointIds!=null){ + for(String point:pointIds){ + SysEquipment equipment=new SysEquipment(); + equipment.setPointId(Long.parseLong(point)); + equipment.setFlag("0"); + equipment.setIsCj("0"); + equipment.setProductId(3L); + List equipmentDtoList=equipmentService.selectSysEquipmentList(equipment); + equipList.addAll(equipmentDtoList); + } + } + //通过规则获取绑定设备信息 + if(equipList!=null){ + for(SysEquipment e:equipList){ + //将人员信息下发到设备 + Person person=new Person(); + person.setName(people.getName()); + person.setIdcardNum(people.getDoorNo()); + person.setiDNumber(people.getIdcard()); + person.setPhone(people.getPhone()); + person.setId(people.getGuid()); + String ip=e.getIp(); + String pass=e.getPassword(); + this.personDelete(people.getGuid(),ip,pass); + response=this.personCreate(person,ip,pass); + if(StringUtils.isNotEmpty(people.getFaceGuid())){//人脸 + this.imageCreateUrl(people.getGuid(),people.getFaceGuid(),people.getAvatar(), e.getIp(), e.getPassword()); + } + } + } + return response; + } + + @Override + public String authDevices(SysPeople people, SysEquipment equipment) { + String response=""; + //将人员信息下发到设备 + Person person=new Person(); + person.setName(people.getName()); + person.setiDNumber(people.getIdcard()); + person.setIdcardNum(people.getDoorNo()); + person.setPhone(people.getPhone()); + person.setId(people.getGuid()); + String ip=equipment.getIp(); + String pass=equipment.getPassword(); + response=this.personCreate(person,ip,pass); + this.imageCreateUrl(people.getGuid(),people.getAvatar(),ip,pass); + return response; + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/service/impl/SysVehicleServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/service/impl/SysVehicleServiceImpl.java new file mode 100644 index 0000000..0d60426 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/uniubi/service/impl/SysVehicleServiceImpl.java @@ -0,0 +1,169 @@ +//package com.dcsoft.system.uniubi.service.impl; +// +//import com.alibaba.fastjson.JSON; +//import com.alibaba.fastjson.JSONObject; +//import com.dcsoft.system.domain.*; +//import com.dcsoft.system.kq.domain.*; +//import com.dcsoft.system.kq.service.*; +//import com.dcsoft.system.service.*; +//import com.dcsoft.system.uniubi.domain.Person; +//import com.dcsoft.system.uniubi.service.ISysSdkService; +//import com.dcsoft.system.uniubi.service.ISysVehicleService; +//import com.dcsoft.system.utils.HttpUtil; +//import com.dcsoft.system.vehicle.domain.CarInfo; +//import com.dcsoft.system.vehicle.service.ICarInfoService; +//import com.dcsoft.system.visitor.domain.Visitor; +//import org.apache.commons.lang3.StringUtils; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.stereotype.Service; +// +//import java.io.IOException; +//import java.io.OutputStream; +//import java.net.Socket; +//import java.net.SocketException; +//import java.text.ParseException; +//import java.text.SimpleDateFormat; +//import java.util.*; +// +///** +// * 用户管理 服务层处理 +// * +// * @author xueyi +// */ +//@Service +//public class SysVehicleServiceImpl implements ISysVehicleService { +// public static final String getsnCmd = "{\"cmd\" :\"getsn\"}"; +// public static final String triggerCmd = "{\"cmd\" :\"trigger\"}"; +// public static final int DISABLE_PUSH = 0; +// public static final int ENABLE_PUSH = 1; +// public static final int JSON_FMT = 1; +// public static final int BIN_FMT = 0; +// public static final int DISABLE_IMAGE = 0; +// public static final int ENABLE_IMAGE = 1; +// public static final int BLOCK_TYPE_BIN_RESULT = 1; +// public static final int BLOCK_TYPE_IMAGE_DATA = 2; +// +// @Autowired +// private ICarInfoService carInfoService; +// +// @Autowired +// private ISysEquipmentService equipmentService; +// +// //定义一个Socket对象 +// private Socket socket = null; +// +// @Override +// public String config(String ip) { +// String host=ip.split(":")[0]; +// int port= Integer.parseInt(ip.split(":")[1]); +// String response="ok"; +// try { +// socket = new Socket(host, port); +// sendCmd(socket, getsnCmd); +// configFormat(socket, ENABLE_PUSH, JSON_FMT, ENABLE_IMAGE); +// }catch (IOException e) { +// response=e.getMessage(); +// } +// return response; +// } +// +// @Override +// public String addWhite(SysEquipment equipment, CarInfo carInfo) { +// String ip =equipment.getIp(); +// String host=ip.split(":")[0]; +// int port= Integer.parseInt(ip.split(":")[1]); +// String response="ok"; +// try { +// socket = new Socket(host, port); +// AddWhiteList(socket,carInfo); +// }catch (IOException e) { +// response=e.getMessage(); +// } +// return response; +// } +// +// public void AddWhiteList(Socket socket,CarInfo cars) +// { +// SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); +// String create_time =sdf.format(cars.getCreateTime()); +// String enable_time =sdf.format(cars.getEnableTime()); +// String overdue_time=sdf.format(cars.getOverdueTime()); +// String enable=cars.getEnable(); +// String plate =cars.getPlate(); +// String time_seg_enable =cars.getTimeSegEnable(); +// String seg_time=cars.getSegTime(); +// String need_alarm=cars.getNeedAlarm(); +// String vehicle_code=cars.getVehicleCode(); +// String vehicle_comment=cars.getVehicleComment(); +// Long customer_id=cars.getCustomerId(); +// String cmd = "{" +// + "\"cmd\":\"white_list_operator\"," +// + "\"operator_type\":\"update_or_add\"," +// + "\"dldb_rec\":{" +// + "\"create_time\":"+create_time+"," +// + "\"enable_time\":"+enable_time+"," +// + "\"overdue_time\":"+overdue_time+"," +// + "\"enable\":"+enable+"," +// + "\"plate\":"+plate+"," +// + "\"time_seg_enable\":"+time_seg_enable+"," +// + "\"seg_time\": "+seg_time+"," +// + "\"need_alarm\":"+need_alarm+"," +// + "\"vehicle_code\":"+vehicle_code+"," +// + "\"vehicle_comment\":"+vehicle_comment+"," +// + "\"customer_id\":"+customer_id+"" +// + "}" +// + "} "; +// try +// { +// byte[] b = cmd.getBytes("gb2312");//编码 +// String sa = new String(b, "gb2312");//解码 +// +// sendCmd(socket,sa); +// } +// catch(Exception e) +// { +// System.out.println("Error:"+e); +// } +// +// } +// +// +// +// public static boolean configFormat(Socket socket,int enable,int fmt,int image) +// { +// String cmd; +// cmd = String.format("{"+ +// "\"cmd\" : \"ivsresult\" ,"+ +// "\"enable\" : %s,"+ +// "\"format\" : \"%s\","+ +// "\"image\" : %s"+ +// "}", +// enable!=0?"true":"false", +// fmt !=0 ?"json":"bin", +// image!=0?"true":"false"); +// +// return sendCmd(socket,cmd); +// } +// +// public static boolean sendCmd(Socket socket,String cmd) +// { +// try{ +// int len = cmd.getBytes().length; +// byte[] header = {'V','Z',0,0,0,0,0,0}; +// header[4] += (byte) ((len >>24) & 0xFF); +// header[5] += (byte) ((len >>16) & 0xFF); +// header[6] += (byte) ((len >>8) & 0xFF); +// header[7] += (byte) (len & 0xFF); +// +// OutputStream out = socket.getOutputStream(); +// out.write(header); +// out.write(cmd.getBytes()); +// }catch(Exception e) +// { +// System.out.println("Error:"+e.getMessage()); +// return false; +// } +// return true; +// } +// +//} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/BackupConfig.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/BackupConfig.java new file mode 100644 index 0000000..38d15d6 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/BackupConfig.java @@ -0,0 +1,122 @@ +package com.dcsoft.system.utils; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +/** + * SMS短信 配置属性 + * + * @author Lion Li + * @version 4.2.0 + */ +@Configuration +@ConfigurationProperties(prefix = "backup") +public class BackupConfig { + + //参考示例:# /usr/local/mysql/bin/mysqldump -uroot -p123456 -P3306 shuju > shuju.sql + /** + * 备份路径 + */ + private String backupPath; + + /** + * mysql的绝对路径 + */ + private String mysqlPath; + + /** + * mysqldump的绝对路径 + */ + private String mysqldumpPath; + + + /** + * ip地址 + */ + private String ip; + + /** + * 数据库用户名 + */ + private String username; + + /** + * 数据库密码 + */ + private String password; + + /* + * 数据库端口号 + */ + private String port; + + /** + * 数据库名 + */ + private String dbName; + + + public String getBackupPath() { + return backupPath; + } + + public void setBackupPath(String backupPath) { + this.backupPath = backupPath; + } + + public String getMysqldumpPath() { + return mysqldumpPath; + } + + public void setMysqldumpPath(String mysqldumpPath) { + this.mysqldumpPath = mysqldumpPath; + } + + 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 getPort() { + return port; + } + + public void setPort(String port) { + this.port = port; + } + + public String getDbName() { + return dbName; + } + + public void setDbName(String dbName) { + this.dbName = dbName; + } + + public String getMysqlPath() { + return mysqlPath; + } + + public void setMysqlPath(String mysqlPath) { + this.mysqlPath = mysqlPath; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/Base64DecodeMultipartFile.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/Base64DecodeMultipartFile.java new file mode 100644 index 0000000..d9f4c89 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/Base64DecodeMultipartFile.java @@ -0,0 +1,57 @@ +package com.dcsoft.system.utils; + + +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; + +//java将图片的url转换成File,File转换成二进制流byte +public class Base64DecodeMultipartFile implements MultipartFile { + private final byte[] imgContent; + private final String header; + + public Base64DecodeMultipartFile(byte[] imgContent, String header) { + this.imgContent = imgContent; + this.header = header.split(";")[0]; + } + + @Override + public String getName() { + return System.currentTimeMillis() + Math.random() + "." + header.split("/")[1]; + } + + @Override + public String getOriginalFilename() { + return System.currentTimeMillis() + (int) Math.random() * 10000 + "." + header.split("/")[1]; + } + + @Override + public String getContentType() { + return header.split(":")[1]; + } + + @Override + public boolean isEmpty() { + return imgContent == null || imgContent.length == 0; + } + + @Override + public long getSize() { + return imgContent.length; + } + + @Override + public byte[] getBytes() throws IOException { + return imgContent; + } + + @Override + public InputStream getInputStream() throws IOException { + return new ByteArrayInputStream(imgContent); + } + + @Override + public void transferTo(File dest) throws IOException, IllegalStateException { + new FileOutputStream(dest).write(imgContent); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/FTPUtil.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/FTPUtil.java new file mode 100644 index 0000000..e83fd06 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/FTPUtil.java @@ -0,0 +1,162 @@ +package com.dcsoft.system.utils; + +import org.apache.commons.net.ftp.FTPClient; +import org.apache.commons.net.ftp.FTPFile; +import org.apache.commons.net.ftp.FTPReply; + +import java.io.*; +import java.net.SocketException; + +public class FTPUtil { + + /** + * 打开FTP服务链接 + * @param ftpHost + * @param ftpPort + * @param ftpUserName + * @param ftpPassword + */ + public static FTPClient getFTPClient(String ftpHost, Integer ftpPort, String ftpUserName, String ftpPassword){ + FTPClient ftpClient = null; + try { + ftpClient = new FTPClient(); + ftpClient.setConnectTimeout(60000); + if(ftpPort != null){ + ftpClient.connect(ftpHost, ftpPort);// 连接FTP服务器 + }else { + ftpClient.connect(ftpHost);// 连接FTP服务器 + } + if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) { + if (ftpClient.login(ftpUserName, ftpPassword)) {// 登陆FTP服务器 + if (FTPReply.isPositiveCompletion(ftpClient.sendCommand( + "OPTS UTF8", "ON"))) {// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK). + ftpClient.setControlEncoding("UTF-8"); + }else { + ftpClient.setControlEncoding("GBK"); + } + ftpClient.enterLocalPassiveMode();// 设置被动模式 + ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);// 设置传输的模式,以二进制流的方式读取 + ftpClient.enterLocalPassiveMode(); + System.out.println("FTP服务连接成功!"); + }else { + System.out.println("FTP服务用户名或密码错误!"); + disConnection(ftpClient); + } + }else { + System.out.println("连接到FTP服务失败!"); + disConnection(ftpClient); + } + } catch (SocketException e) { + e.printStackTrace(); + disConnection(ftpClient); + System.out.println("FTP的IP地址可能错误,请正确配置。"); + } catch (IOException e) { + e.printStackTrace(); + disConnection(ftpClient); + System.out.println("FTP的端口错误,请正确配置。"); + } + return ftpClient; + } + + /** + * 关闭FTP服务链接 + * @throws IOException + */ + public static void disConnection(FTPClient ftpClient){ + try { + if(ftpClient.isConnected()){ + ftpClient.disconnect(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * 获取文件夹下的所有文件信息 + * @param path 文件路径 + */ + public static FTPFile[] getFTPDirectoryFiles(FTPClient ftpClient,String path){ + FTPFile[] files = null; + try { + ftpClient.changeWorkingDirectory(path); + files = ftpClient.listFiles(); + }catch (Exception e){ + e.printStackTrace(); + //关闭连接 + disConnection(ftpClient); + System.out.println("FTP读取数据异常!"); + } + return files; + } + + + /** + * 获取文件夹下的所有文件信息 + * @param path 文件路径 + */ + public static InputStream getFTPFile(FTPClient ftpClient,String path,String fileName){ + InputStream in = null; + try { + ftpClient.changeWorkingDirectory(path); + FTPFile[] files = ftpClient.listFiles(); + if(files.length > 0){ + in = ftpClient.retrieveFileStream(fileName); + } + }catch (Exception e){ + e.printStackTrace(); + System.out.println("FTP读取数据异常!"); + }finally { + //关闭连接 + disConnection(ftpClient); + } + return in; + } + + public static void main(String args[]){ + InputStream in = null; + BufferedReader br = null; + try{ + String path = "/home/ftp/"; + //读取单个文件 + FTPClient ftpClient = getFTPClient("10.1.1.1",21,"username","123456"); + String fileName = "person.txt"; + in = getFTPFile(ftpClient,path,fileName); + if(in != null){ + br = new BufferedReader(new InputStreamReader(in,"GBK")); + String data = null; + while ((data = br.readLine()) != null) { + String[] empData = data.split(";"); + System.out.println(empData[0]+" "+empData[1]); + } + } + + //读取文件夹下的所有文件 + FTPClient ftpClient1 = getFTPClient("10.1.1.1",21,"username","123456"); + FTPFile[] files = getFTPDirectoryFiles(ftpClient1,path); + if(files != null && files.length > 0){ + for (int i = 0; i < files.length; i++) { + if(files[i].isFile()){ + in = ftpClient1.retrieveFileStream(files[i].getName()); + br = new BufferedReader(new InputStreamReader(in,"GBK")); + System.out.println(files[i].getName()); + } + } + } + //关闭连接 + disConnection(ftpClient1); + }catch (Exception e){ + e.printStackTrace(); + }finally { + try{ + //关闭流 + if (br != null) + br.close(); + if (in != null) + in.close(); + }catch (IOException e){ + e.printStackTrace(); + } + } + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/FileUtils.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/FileUtils.java new file mode 100644 index 0000000..f3782d6 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/FileUtils.java @@ -0,0 +1,164 @@ +package com.dcsoft.system.utils; + +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.commons.CommonsMultipartFile; + +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.file.Files; + + +public class FileUtils { + /** + * url转File + * + * @url:图片URL + * @fileName:文件名 + * @return:返回的文件 + */ + public static File urlToFile(String fileName, String url) { + File file = null; + try { + HttpURLConnection httpUrl = (HttpURLConnection) new URL(url).openConnection(); + httpUrl.connect(); + file = inputStreamToFile(httpUrl.getInputStream(), fileName); + httpUrl.disconnect(); + } catch (Exception e) { + e.printStackTrace(); + } + return file; + } + + /** + * MultipartFile转File + * + * @param multipartFile + * @return + * @throws Exception + */ + public static File multipartFileToFile(MultipartFile multipartFile) throws Exception { + InputStream ins; + ins = multipartFile.getInputStream(); + File file = new File(System.getProperty("java.io.tmpdir") + File.separator + multipartFile.getOriginalFilename()); + inputStreamToFile(ins, file); + ins.close(); + return file; + } + + /** + * url转MultipartFile + * + * @param url + * @param fileName + * @return + */ + public static MultipartFile urlToMultipartFile(String url, String fileName) { + MultipartFile multipartFile = null; + try { + HttpURLConnection httpUrl = (HttpURLConnection) new URL(url).openConnection(); + httpUrl.connect(); + File file = inputStreamToFile(httpUrl.getInputStream(), fileName); + multipartFile = fileToMultipartFile(file); + httpUrl.disconnect(); + } catch (Exception e) { + e.printStackTrace(); + } + return multipartFile; + } + + public static CommonsMultipartFile fileToMultipartFile(File file) { + DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory(16, null); + FileItem item = diskFileItemFactory.createItem(file.getName(), "text/plain", true, file.getName()); + int bytesRead; + byte[] buffer = new byte[8192]; + try { + FileInputStream fis = new FileInputStream(file); + OutputStream os = item.getOutputStream(); + int len = 8192; + while ((bytesRead = fis.read(buffer, 0, len)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + fis.close(); + } catch (IOException e) { + e.printStackTrace(); + } + return new CommonsMultipartFile(item); + } + + public static File inputStreamToFile(InputStream ins, File file) { + try { + OutputStream os = Files.newOutputStream(file.toPath()); + int bytesRead; + byte[] buffer = new byte[8192]; + while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + ins.close(); + return file; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + public static File inputStreamToFile(InputStream ins, String name) throws Exception { + File file = new File(System.getProperty("java.io.tmpdir") + File.separator + name); + OutputStream os = Files.newOutputStream(file.toPath()); + int len = 8192; + byte[] buffer = new byte[len]; + int bytesRead; + while ((bytesRead = ins.read(buffer, 0, len)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + ins.close(); + return file; + } + + /** + * 将image类型转为File类型 + * + * @param url + * @return + */ + public static File downloadWxFile(String url) { + String reptype = ""; + File file = null; + InputStream inputStream = null; + OutputStream outputStream = null; + try { + file = File.createTempFile("wx_image", reptype); + //下载 + URL urlfile = new URL(url); + inputStream = urlfile.openStream(); + outputStream = Files.newOutputStream(file.toPath()); + + int bytesRead; + byte[] buffer = new byte[8192]; + while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + if (null != outputStream) { + outputStream.close(); + } + if (null != inputStream) { + inputStream.close(); + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + return file; + } + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/FloorUtil.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/FloorUtil.java new file mode 100644 index 0000000..c2b918f --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/FloorUtil.java @@ -0,0 +1,56 @@ +package com.dcsoft.system.utils; + +import cn.hutool.core.util.NumberUtil; +import com.dcsoft.common.core.constant.Constants; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +public class FloorUtil { + + public static String floorConvert(List storeyInfoVos) { + int j = 0; + for (String storeyInfoVo : storeyInfoVos) { + if ("19A".equals(storeyInfoVo)) { + storeyInfoVos.set(j, "18"); + } + j++; + } + String storey = storeyInfoVos.get(storeyInfoVos.size() - 1); + double floorNum = NumberUtil.div(Integer.parseInt(storey), 4); + if (floorNum % 1 != 0) { + floorNum = floorNum + 1; + } + int floorCount = (int) NumberUtil.mul((int) floorNum, 4); + List list = new ArrayList<>(); + for (int i = 0; i < floorCount; i++) { + list.add(Constants.ZERO); + } + + for (String storeyInfoVo : storeyInfoVos) { + list.set(floorCount - Integer.parseInt(storeyInfoVo), "1"); + } + + // 二进制数 + String binaryString = String.join("", list); + // 转换为十进制数 + int binaryNumber = Integer.parseInt(binaryString, 2); + // 转换为十六进制数 + String hexString = Integer.toHexString(binaryNumber); + System.out.println("十六进制数: " + hexString); + + log.info("十六进制数hexString:" + hexString); + String formattedNumber = String.format("%16s", hexString).replace(' ', '0'); + + log.info("formattedNumber:" + formattedNumber); + String zeroString = String.format("%052d", 0); + + log.info("zeroString:" + zeroString); + String floor = "FF" + formattedNumber + zeroString; + + log.info("楼层floor:" + floor); + return floor.toUpperCase(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/HttpClient.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/HttpClient.java new file mode 100644 index 0000000..e69de29 diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/HttpUtil.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/HttpUtil.java new file mode 100644 index 0000000..1cf5885 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/HttpUtil.java @@ -0,0 +1,408 @@ +package com.dcsoft.system.utils; + +import com.alibaba.fastjson.JSONObject; +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.entity.mime.HttpMultipartMode; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.util.*; +import java.util.Map.Entry; + +public class HttpUtil { + + public static String getData(String url) { + CloseableHttpClient httpClient = null; + CloseableHttpResponse response = null; + String result = ""; + try { + // 通过址默认配置创建一个httpClient实例 + httpClient = HttpClients.createDefault(); + // 创建httpGet远程连接实例 + HttpGet httpGet = new HttpGet(url); + // 设置请求头信息,鉴权 + httpGet.setHeader("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0"); + // 设置配置请求参数 + RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 连接主机服务超时时间 + .setConnectionRequestTimeout(35000)// 请求超时时间 + .setSocketTimeout(60000)// 数据读取超时时间 + .build(); + // 为httpGet实例设置配置 + httpGet.setConfig(requestConfig); + // 执行get请求得到返回对象 + response = httpClient.execute(httpGet); + // 通过返回对象获取返回数据 + HttpEntity entity = response.getEntity(); + // 通过EntityUtils中的toString方法将结果转换为字符串 + result = EntityUtils.toString(entity); + } catch (ClientProtocolException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + // 关闭资源 + if (null != response) { + try { + response.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (null != httpClient) { + try { + httpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return result; + } + + public static String postData(String url, Map paramMap) { + HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); + HttpPost post = new HttpPost(url); + String result = ""; + try (CloseableHttpClient closeableHttpClient = httpClientBuilder.build()) { + // HttpEntity entity = new StringEntity(jsonStrData); + // 修复 POST json 导致中文乱码 + HttpEntity entity = new StringEntity(JSONObject.toJSONString(paramMap), "UTF-8"); + post.setEntity(entity); + post.setHeader("Content-type", "application/json"); + HttpResponse resp = closeableHttpClient.execute(post); + try { + InputStream respIs = resp.getEntity().getContent(); + byte[] respBytes = IOUtils.toByteArray(respIs); + result = new String(respBytes, Charset.forName("UTF-8")); + } catch (Exception e) { + e.printStackTrace(); + } + return result; + } catch (IOException e) { + e.printStackTrace(); + } + return result; + } + + public static String postDataJson(String url, JSONObject paramMap) { + HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); + HttpPost post = new HttpPost(url); + String result = ""; + try (CloseableHttpClient closeableHttpClient = httpClientBuilder.build()) { + // HttpEntity entity = new StringEntity(jsonStrData); + // 修复 POST json 导致中文乱码 + HttpEntity entity = new StringEntity(paramMap.toJSONString(), "UTF-8"); + post.setEntity(entity); + post.setHeader("Content-type", "application/json"); + HttpResponse resp = closeableHttpClient.execute(post); + try { + InputStream respIs = resp.getEntity().getContent(); + byte[] respBytes = IOUtils.toByteArray(respIs); + result = new String(respBytes, Charset.forName("UTF-8")); + } catch (Exception e) { + e.printStackTrace(); + } + return result; + } catch (IOException e) { + e.printStackTrace(); + } + return result; + } + + + /** + * form表单提交 + * + * @param url + * @param paramMap + * @return + */ + public static String sendxwwwform(String url, Map paramMap) { + CloseableHttpClient httpClient = null; + CloseableHttpResponse httpResponse = null; + String result = ""; + // 创建httpClient实例 + httpClient = HttpClients.createDefault(); + // 创建httpPost远程连接实例 + HttpPost httpPost = new HttpPost(url); + // 配置请求参数实例 + RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 设置连接主机服务超时时间 + .setConnectionRequestTimeout(35000)// 设置连接请求超时时间 + .setSocketTimeout(60000)// 设置读取数据连接超时时间 + .build(); + // 为httpPost实例设置配置 + httpPost.setConfig(requestConfig); + // 设置请求头 + httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded"); + // 封装post请求参数 + if (null != paramMap && paramMap.size() > 0) { + List nvps = new ArrayList(); + // 通过map集成entrySet方法获取entity + Set> entrySet = paramMap.entrySet(); + // 循环遍历,获取迭代器 + Iterator> iterator = entrySet.iterator(); + while (iterator.hasNext()) { + Entry mapEntry = iterator.next(); + nvps.add(new BasicNameValuePair(mapEntry.getKey(), mapEntry.getValue().toString())); + } + + // 为httpPost设置封装好的请求参数 + try { + httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8")); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } + try { + // httpClient对象执行post请求,并返回响应参数对象 + httpResponse = httpClient.execute(httpPost); + // 从响应对象中获取响应内容 + HttpEntity entity = httpResponse.getEntity(); + result = EntityUtils.toString(entity); + } catch (ClientProtocolException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + // 关闭资源 + if (null != httpResponse) { + try { + httpResponse.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (null != httpClient) { + try { + httpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return result; + } + + public static String getUrl(String url,Map headMap,String projectGuid ) { + CloseableHttpClient httpClient = null; + CloseableHttpResponse response = null; + String result = ""; + try { + // 通过址默认配置创建一个httpClient实例 + httpClient = HttpClients.createDefault(); + // 创建httpGet远程连接实例 + StringBuffer sb = new StringBuffer(url); + sb.append("projectGuid=" + projectGuid); + HttpGet httpGet = new HttpGet(sb.toString()); + // 设置请求头信息,鉴权 + httpGet.setHeader("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0"); + httpGet.setHeader("appKey",headMap.get("appKey").toString()); + httpGet.setHeader("timestamp",headMap.get("timestamp").toString()); + httpGet.setHeader("sign",headMap.get("sign").toString()); + // 设置配置请求参数 + RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 连接主机服务超时时间 + .setConnectionRequestTimeout(35000)// 请求超时时间 + .setSocketTimeout(60000)// 数据读取超时时间 + .build(); + // 为httpGet实例设置配置 + httpGet.setConfig(requestConfig); + // 执行get请求得到返回对象 + response = httpClient.execute(httpGet); + // 通过返回对象获取返回数据 + HttpEntity entity = response.getEntity(); + // 通过EntityUtils中的toString方法将结果转换为字符串 + result = EntityUtils.toString(entity); + } catch (ClientProtocolException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + // 关闭资源 + if (null != response) { + try { + response.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (null != httpClient) { + try { + httpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return result; + } + + public static String postData(String url,Map headMap, Map paramMap) { + HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); + HttpPost post = new HttpPost(url); + String result = ""; + try (CloseableHttpClient closeableHttpClient = httpClientBuilder.build()) { + // HttpEntity entity = new StringEntity(jsonStrData); + // 修复 POST json 导致中文乱码 + HttpEntity entity = new StringEntity(JSONObject.toJSONString(paramMap), "UTF-8"); + post.setEntity(entity); + post.setHeader("Content-type", "application/json"); + if (null != headMap && headMap.size() > 0) { + // 通过map集成entrySet方法获取entity + Set> entrySet = headMap.entrySet(); + // 循环遍历,获取迭代器 + Iterator> iterator = entrySet.iterator(); + while (iterator.hasNext()) { + Entry mapEntry = iterator.next(); + post.setHeader(mapEntry.getKey(),mapEntry.getValue().toString()); + } + } + HttpResponse resp = closeableHttpClient.execute(post); + try { + InputStream respIs = resp.getEntity().getContent(); + byte[] respBytes = IOUtils.toByteArray(respIs); + result = new String(respBytes, Charset.forName("UTF-8")); + } catch (Exception e) { + e.printStackTrace(); + } + return result; + } catch (IOException e) { + e.printStackTrace(); + } + return result; + } + + public static String getDataToken(String url,String token) { + CloseableHttpClient httpClient = null; + CloseableHttpResponse response = null; + String result = ""; + try { + // 通过址默认配置创建一个httpClient实例 + httpClient = HttpClients.createDefault(); + // 创建httpGet远程连接实例 + HttpGet httpGet = new HttpGet(url); + // 设置请求头信息,鉴权 + httpGet.setHeader("Authorization", "Bearer "+token); + // 设置配置请求参数 + RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 连接主机服务超时时间 + .setConnectionRequestTimeout(35000)// 请求超时时间 + .setSocketTimeout(60000)// 数据读取超时时间 + .build(); + // 为httpGet实例设置配置 + httpGet.setConfig(requestConfig); + // 执行get请求得到返回对象 + response = httpClient.execute(httpGet); + // 通过返回对象获取返回数据 + HttpEntity entity = response.getEntity(); + // 通过EntityUtils中的toString方法将结果转换为字符串 + result = EntityUtils.toString(entity); + } catch (ClientProtocolException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + // 关闭资源 + if (null != response) { + try { + response.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (null != httpClient) { + try { + httpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return result; + } + + /** + * form表单提交 + * + * @param url + * @param paramMap + * @return + */ + public static String syncFace(String url, String token, Map paramMap, MultipartFile file) { + HttpPost httpPost = new HttpPost(url); +// 随机设计 + String boundary ="--------------4585696313564699"; + //设置请求头(百度好多都没有设置这个请求头) + httpPost.setHeader("Content-Type", "multipart/form-data;boundary="+boundary); + httpPost.setHeader("authorization", token); + CloseableHttpClient client = HttpClients.createDefault(); + String respContent = null; + //模拟浏览器 + MultipartEntityBuilder builder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE); + //字符编码 + builder.setCharset(Charset.forName("UTF-8")); + builder.setBoundary(boundary); + //设置请求携带的参数 + // 封装post请求参数 + if (null != paramMap && paramMap.size() > 0) { + List nvps = new ArrayList(); + // 通过map集成entrySet方法获取entity + Set> entrySet = paramMap.entrySet(); + // 循环遍历,获取迭代器 + Iterator> iterator = entrySet.iterator(); + while (iterator.hasNext()) { + Entry mapEntry = iterator.next(); + builder.addTextBody(mapEntry.getKey(), mapEntry.getValue().toString(), ContentType.create("text/plain", Charset.forName("UTF-8"))); + } + } + //builder.addTextBody("参数名", jsonParam, ContentType.create("text/plain", Charset.forName("UTF-8"))); + //这里根据自身业务需求,自行判断 + if (file != null) { + //设置请求携带的文件(文件类型:MultipartFile ) + //file.getName() 会返回不正确的结果 不知是不是接口还是java的原因 + try { + builder.addBinaryBody( + "file", + file.getInputStream(), + ContentType.MULTIPART_FORM_DATA, + file.getOriginalFilename() + ); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +// file 文件这样写 +// builder.addPart("参数名",new FileBody(file)); + HttpEntity multipart = builder.build(); + HttpResponse resp = null; + try { + httpPost.setEntity(multipart); + // 提交 + resp = client.execute(httpPost); + //根据业务需求 自行调整 + HttpEntity entity = resp.getEntity(); + respContent = EntityUtils.toString(entity, "UTF-8"); + } catch (Exception e) { + } + return respContent; + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/IWXPayDomain.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/IWXPayDomain.java new file mode 100644 index 0000000..e69de29 diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/ImageToBase64Utils.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/ImageToBase64Utils.java new file mode 100644 index 0000000..9912154 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/ImageToBase64Utils.java @@ -0,0 +1,155 @@ +package com.dcsoft.system.utils; + + +import org.apache.commons.codec.binary.Base64; + +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URL; + + +public class ImageToBase64Utils { + /** + * 本地图片转base64 + */ + public static String getImgFileToBase642(String imgFile) { + //将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] buffer = null; + //读取图片字节数组 + try(InputStream inputStream = new FileInputStream(imgFile);){ + int count = 0; + while (count == 0) { + count = inputStream.available(); + } + buffer = new byte[count]; + inputStream.read(buffer); + } catch (IOException e) { + e.printStackTrace(); + } + // 对字节数组Base64编码 + return new String(Base64.encodeBase64(buffer)); + } + + /** + * 网络图片转base64 + */ + public static String getImgUrlToBase64(String imgUrl) { + byte[] buffer = null; + InputStream inputStream = null; + try ( + ByteArrayOutputStream outputStream = new ByteArrayOutputStream();){ + // 创建URL + URL url = new URL(imgUrl); + // 创建链接 + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("GET"); + conn.setConnectTimeout(5000); + inputStream = conn.getInputStream(); + // 将内容读取内存中 + buffer = new byte[1024]; + int len = -1; + while ((len = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, len); + } + buffer = outputStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (inputStream != null) { + try { + // 关闭inputStream流 + inputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + // 对字节数组Base64编码 + return new String(Base64.encodeBase64(buffer)); + } + + /** + * 本地或网络图片转base64 + */ + public static String getImgStrToBase64(String imgStr) { + InputStream inputStream = null; + byte[] buffer = null; + try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream();){ + //判断网络链接图片文件/本地目录图片文件 + if (imgStr.startsWith("http://") || imgStr.startsWith("https://")) { + // 创建URL + URL url = new URL(imgStr); + // 创建链接 + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("GET"); + conn.setConnectTimeout(5000); + inputStream = conn.getInputStream(); + // 将内容读取内存中 + buffer = new byte[1024]; + int len = -1; + while ((len = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, len); + } + buffer = outputStream.toByteArray(); + } else { + inputStream = new FileInputStream(imgStr); + int count = 0; + while (count == 0) { + count = inputStream.available(); + } + buffer = new byte[count]; + inputStream.read(buffer); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (inputStream != null) { + try { + // 关闭inputStream流 + inputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + // 对字节数组Base64编码 + + return new String(Base64.encodeBase64(buffer)); + } + + /** + * 对字节数组字符串进行Base64解码并生成图片 + * @param imgStr 图片数据 + * @param imgFilePath 保存图片全路径地址 + * @return + */ + public static boolean generateImage(String imgStr,String imgFilePath){ + // + if (imgStr == null) //图像数据为空 + return false; + try + { + //Base64解码 + byte[] b = Base64.decodeBase64(imgStr); + for(int i=0;i buildTree(List list, String pid) { +// List tree = new ArrayList<>(); +// for (DeviceTreeVo node : list) { +// if (Objects.equals(node.getParentId(), pid)) { +// tree.add(findChild(node, list)); +// } +// } +// return tree; +// } +// +// public static DeviceTreeVo findChild(DeviceTreeVo node, List list) { +// for (DeviceTreeVo n : list) { +// if (Objects.equals(n.getParentId(), node.getId())) { +// if (node.getChildren() == null) { +// node.setChildren(new ArrayList<>()); +// } +// node.getChildren().add(findChild(n, list)); +// } +// } +// return node; +// } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/WXPayConfig.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/WXPayConfig.java new file mode 100644 index 0000000..e69de29 diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/WXPayConstants.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/WXPayConstants.java new file mode 100644 index 0000000..e69de29 diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/WXPayReport.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/WXPayReport.java new file mode 100644 index 0000000..e69de29 diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/WXPayUtil.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/WXPayUtil.java new file mode 100644 index 0000000..e69de29 diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/WXPayXmlUtil.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/WXPayXmlUtil.java new file mode 100644 index 0000000..e69de29 diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/WeChatUtil.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/WeChatUtil.java new file mode 100644 index 0000000..f15f21a --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/WeChatUtil.java @@ -0,0 +1,182 @@ +package com.dcsoft.system.utils; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.ssl.SSLContextBuilder; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import java.io.UnsupportedEncodingException; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.cert.X509Certificate; +import java.util.*; + +/** + * @author jsy + * @description: 接口请求sign类 + * @date 2021/3/4 16:00 + */ +@Component +public class WeChatUtil { + + public static String appid; + public static String appSecret; + + + @Value("${weixin.appid}") + public void setAppid(String appid) { + WeChatUtil.appid = appid; + } + @Value("${weixin.appSecret}") + public void setAppSecret(String appSecret) { + WeChatUtil.appSecret = appSecret; + } + + public static Map sign(String jsapi_ticket, String url) { + Map ret = new HashMap(); + String nonce_str = create_nonce_str(); + String timestamp = create_timestamp(); + String string1; + String signature = ""; + + //注意这里参数名必须全部小写,且必须有序 + string1 = "jsapi_ticket=" + jsapi_ticket + + "&noncestr=" + nonce_str + + "×tamp=" + timestamp + + "&url=" + url; + System.out.println(string1); + + try + { + MessageDigest crypt = MessageDigest.getInstance("SHA-1"); + crypt.reset(); + crypt.update(string1.getBytes("UTF-8")); + signature = byteToHex(crypt.digest()); + } + catch (NoSuchAlgorithmException e) + { + e.printStackTrace(); + } + catch (UnsupportedEncodingException e) + { + e.printStackTrace(); + } + + ret.put("url", url); + ret.put("appId",appid); + ret.put("jsapi_ticket", jsapi_ticket); + ret.put("nonceStr", nonce_str); + ret.put("timestamp", timestamp); + ret.put("signature", signature); + + return ret; + } + + + + private static String byteToHex(final byte[] hash) { + Formatter formatter = new Formatter(); + for (byte b : hash) + { + formatter.format("%02x", b); + } + String result = formatter.toString(); + formatter.close(); + return result; + } + + private static String create_nonce_str() { + return UUID.randomUUID().toString(); + } + + private static String create_timestamp() { + return Long.toString(System.currentTimeMillis() / 1000); + } + + /** + * 获取access_token(access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token) + * @return + * @throws KeyStoreException + * @throws NoSuchAlgorithmException + * @throws KeyManagementException + */ + public static String getAccessToken() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException { + RestTemplate restTemplate = new RestTemplate(factory()); + Map params = new HashMap<>(); + params.put("APPID",appid);//前面准备工作提到 + params.put("APPSECRET",appSecret); + String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" + + "&appid={APPID}&secret={APPSECRET}"; + ResponseEntity responseEntity = + restTemplate.getForEntity(url, String.class,params); + String body = responseEntity.getBody(); + JSONObject object = JSON.parseObject(body); + System.out.println("object=========================="+object); + String Access_Token = object.getString("access_token"); + return Access_Token; + } + /** + * 根据token获取jsapiTicket(jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket) + * @param token + * @return + * @throws KeyStoreException + * @throws NoSuchAlgorithmException + * @throws KeyManagementException + */ + public static String getJsapiTicket(String token) throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException { + RestTemplate restTemplate = new RestTemplate(factory()); + Map params = new HashMap<>(); + params.put("access_token",token); + String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi" + + "&access_token={access_token}"; + ResponseEntity responseEntity = + restTemplate.getForEntity(url, String.class,params); + String body = responseEntity.getBody(); + JSONObject object = JSON.parseObject(body); + String ticket = object.getString("ticket"); + return ticket; + } + /** + * restTemplate支持https请求 + * @return + * @throws KeyStoreException + * @throws NoSuchAlgorithmException + * @throws KeyManagementException + */ + public static HttpComponentsClientHttpRequestFactory factory() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException { + //rest忽略证书访问 + HttpComponentsClientHttpRequestFactory factory = new + HttpComponentsClientHttpRequestFactory(); + factory.setConnectionRequestTimeout(1000); + factory.setConnectTimeout(1000); + factory.setReadTimeout(1000); + // https + SSLContextBuilder builder = new SSLContextBuilder(); + builder.loadTrustMaterial(null, (X509Certificate[] x509Certificates, String s) -> true); + SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(builder.build(), new String[]{"SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.2"}, null, NoopHostnameVerifier.INSTANCE); + Registry registry = RegistryBuilder.create() + .register("http", new PlainConnectionSocketFactory()) + .register("https", socketFactory).build(); + PoolingHttpClientConnectionManager phccm = new PoolingHttpClientConnectionManager(registry); + phccm.setMaxTotal(200); + CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory).setConnectionManager(phccm).setConnectionManagerShared(true).build(); + factory.setHttpClient(httpClient); + return factory; + } +} + diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/ZipUtil.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/ZipUtil.java new file mode 100644 index 0000000..d8a2cbc --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/utils/ZipUtil.java @@ -0,0 +1,127 @@ +//package com.dcsoft.system.utils; +// +//import com.dcsoft.system.face.domain.FaceStudent; +//import org.apache.tools.zip.ZipEntry; +//import org.apache.tools.zip.ZipFile; +// +//import java.io.*; +//import java.util.*; +// +//public class ZipUtil { +// +// public static List getOriginalPic(String zipPath, String unzipPath) throws Exception +// { +// unZip(zipPath); +// List personDtoList=readfile(unzipPath); +// return personDtoList; +// } +// +// public static void unZip(String path) { +// int count = -1; +// String savepath = ""; +// File file = null; +// InputStream is = null; +// FileOutputStream fos = null; +// BufferedOutputStream bos = null; +// savepath = path.substring(0, path.lastIndexOf(".")) + File.separator; //保存解压文件目录 +// new File(savepath).mkdir(); //创建保存目录 +// ZipFile zipFile = null; +// try { +// zipFile = new ZipFile(path, "gbk"); //解决中文乱码问题 +// Enumeration < ? > entries = zipFile.getEntries(); +// while (entries.hasMoreElements()) { +// byte buf[] = new byte[4096]; +// ZipEntry entry = (ZipEntry) entries.nextElement(); +// String filename = entry.getName(); +// boolean ismkdir = false; +// if (filename.lastIndexOf("/") != -1) { //检查此文件是否带有文件夹 +// ismkdir = true; +// } +// filename = savepath + filename; +// if (entry.isDirectory()) { //如果是文件夹先创建 +// file = new File(filename); +// file.mkdirs(); +// continue; +// } +// file = new File(filename); +// if (!file.exists()) { //如果是目录先创建 +// if (ismkdir) { +// new File(filename.substring(0, filename.lastIndexOf("/"))).mkdirs(); //目录先创建 +// } +// } +// file.createNewFile(); //创建文件 +// is = zipFile.getInputStream(entry); +// fos = new FileOutputStream(file); +// bos = new BufferedOutputStream(fos, 4096); +// while ((count = is.read(buf)) > -1) { +// bos.write(buf, 0, count); +// } +// bos.flush(); +// bos.close(); +// fos.close(); +// is.close(); +// } +// zipFile.close(); +// } catch (IOException ioe) { +// ioe.printStackTrace(); +// } finally { +// try { +// if (bos != null) { +// bos.close(); +// } +// if (fos != null) { +// fos.close(); +// } +// if (is != null) { +// is.close(); +// } +// if (zipFile != null) { +// zipFile.close(); +// } +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// +// public static List readfile(String filepath) throws Exception { +// File file = new File(filepath); +// List personDtoList = new LinkedList(); +// if (!file.isDirectory()) { +// return null; +// } else if (file.isDirectory()) { +// String[] filelist = file.list(); +// for (int i = 0; i < filelist.length; i++) { +// //windows 的读取方法 +// File readfile = new File(filepath + "\\" + filelist[i]); +//// // linux 的读取方法 +//// File readfile = new File(filepath + "/" + filelist[i]); +// if (!readfile.isDirectory()) { +// String fileName = readfile.getName(); +// File file1Save = new File(readfile.getAbsolutePath()); +// FaceStudent peopleDto = new FaceStudent(); +// // peopleDto.setImgs(byteBuffer); +// peopleDto.setImgs(fileName); +// peopleDto.setFile(file1Save); +// personDtoList.add(peopleDto); +// } else if (readfile.isDirectory()) { +// String[] fileList1 = readfile.list();// 返回该路径下的所有文件和文件夹名 +// for (int j = 0; j < fileList1.length; j++) { +// File readfile1 = new File(filepath + "\\" +filelist[0] + "\\"+fileList1[j]); +// //File readfile1 = new File(filepath + "/" +filelist[i] + "/"+fileList1[j]); +// if (!readfile1.isDirectory()) {// 判断是否为目录 +// String fileName = readfile1.getName(); +// File file1Save = new File(readfile1.getAbsolutePath()); +// FaceStudent peopleDto = new FaceStudent(); +// // peopleDto.setImgs(byteBuffer); +// peopleDto.setImgs(fileName); +// peopleDto.setFile(file1Save); +// personDtoList.add(peopleDto); +// } +// } +// } +// } +// } +// return personDtoList; +// } +//} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/controller/CarChargeController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/controller/CarChargeController.java new file mode 100644 index 0000000..c77d611 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/controller/CarChargeController.java @@ -0,0 +1,123 @@ +package com.dcsoft.system.vehicle.controller; + +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDataInfo; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.system.vehicle.domain.CarCharge; +import com.dcsoft.system.vehicle.domain.CarChargeItem; +import com.dcsoft.system.vehicle.service.ICarChargeItemService; +import com.dcsoft.system.vehicle.service.ICarChargeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 收费配置Controller + * + * @author nichun + * @date 2024-01-19 + */ +@RestController +@RequestMapping("/carCharge") +public class CarChargeController extends BaseController +{ + @Autowired + private ICarChargeService carChargeService; + + @Autowired + private ICarChargeItemService carChargeItemService; + + /** + * 查询收费配置列表 + */ + @RequiresPermissions("system:carCharge:list") + @GetMapping("/list") + public TableDataInfo list(CarCharge carCharge) + { + startPage(); + List list = carChargeService.selectCarChargeList(carCharge); + return getDataTable(list); + } + + /** + * 导出收费配置列表 + */ + @RequiresPermissions("system:carCharge:export") + @Log(title = "收费配置", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, CarCharge carCharge) + { + List list = carChargeService.selectCarChargeList(carCharge); + ExcelUtil util = new ExcelUtil(CarCharge.class); + util.exportExcel(response, list, "收费配置数据"); + } + + /** + * 获取收费配置详细信息 + */ + @RequiresPermissions("system:carCharge:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + CarCharge carCharge =carChargeService.selectCarChargeById(id); + CarChargeItem item=new CarChargeItem(); + item.setChargeId(id); + List itemList=carChargeItemService.selectCarChargeItemList(item); + carCharge.setItemList(itemList); + return success(carCharge); + } + + /** + * 新增收费配置 + */ + @RequiresPermissions("system:carCharge:add") + @Log(title = "收费配置", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody CarCharge carCharge) + { + int i=carChargeService.insertCarCharge(carCharge); + List itemList=carCharge.getItemList(); + for(CarChargeItem item:itemList){ + item.setChargeId(carCharge.getId()); + carChargeItemService.insertCarChargeItem(item); + } + return toAjax(i); + } + + /** + * 修改收费配置 + */ + @RequiresPermissions("system:carCharge:edit") + @Log(title = "收费配置", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody CarCharge carCharge) + { + carChargeItemService.deleteChargeItemByChargeId(carCharge.getId()); + List itemList=carCharge.getItemList(); + for(CarChargeItem item:itemList){ + item.setChargeId(carCharge.getId()); + carChargeItemService.insertCarChargeItem(item); + } + return toAjax(carChargeService.updateCarCharge(carCharge)); + } + + /** + * 删除收费配置 + */ + @RequiresPermissions("system:carCharge:remove") + @Log(title = "收费配置", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + for(Long id:ids){ + carChargeItemService.deleteChargeItemByChargeId(id); + } + return toAjax(carChargeService.deleteCarChargeByIds(ids)); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/controller/CarInfoController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/controller/CarInfoController.java new file mode 100644 index 0000000..1554d0a --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/controller/CarInfoController.java @@ -0,0 +1,215 @@ +package com.dcsoft.system.vehicle.controller; + +import cn.hutool.core.util.StrUtil; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDataInfo; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.vehicle.domain.CarInfo; +import com.dcsoft.system.vehicle.domain.CarParkItem; +import com.dcsoft.system.vehicle.domain.CarParkRecord; +import com.dcsoft.system.vehicle.service.ICarInfoService; +import com.dcsoft.system.vehicle.service.ICarParkItemService; +import com.dcsoft.system.vehicle.service.ICarParkRecordService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.regex.Pattern; + +/** + * 车辆信息Controller + * + * @author nichun + * @date 2023-12-26 + */ +@RestController +@RequestMapping("/carInfo") +public class CarInfoController extends BaseController +{ + @Autowired + private ICarInfoService carInfoService; + + @Autowired + private ICarParkRecordService carParkRecordService; + + @Autowired + private ICarParkItemService carParkItemService; + + /** + * 查询车辆信息列表 + */ + @RequiresPermissions("system:carInfo:list") + @GetMapping("/list") + public TableDataInfo list(CarInfo carInfo) + { + startPage(); + List list = carInfoService.selectCarInfoList(carInfo); + return getDataTable(list); + } + + /** + * 导出车辆信息列表 + */ + @RequiresPermissions("system:carInfo:export") + @Log(title = "车辆信息", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, CarInfo carInfo) + { + List list = carInfoService.selectCarInfoList(carInfo); + ExcelUtil util = new ExcelUtil(CarInfo.class); + util.exportExcel(response, list, "车辆信息数据"); + } + + @Log(title = "车辆信息", businessType = BusinessType.IMPORT) + @RequiresPermissions("system:carInfo:import") + @PostMapping("/importData") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception + { + ExcelUtil util = new ExcelUtil(CarInfo.class); + List userList = util.importExcel(file.getInputStream()); + String operName = SecurityUtils.getUsername(); + String message = carInfoService.importData(userList, updateSupport, operName); + return success(message); + } + + @PostMapping("/importTemplate") + public void importTemplate(HttpServletResponse response) throws IOException + { + ExcelUtil util = new ExcelUtil(CarInfo.class); + util.importTemplateExcel(response, "出勤调整数据"); + } + + + /** + * 获取车辆信息详细信息 + */ + @RequiresPermissions("system:carInfo:query") + @GetMapping(value = "/{customerId}") + public AjaxResult getInfo(@PathVariable("customerId") Long customerId) + { + return success(carInfoService.selectCarInfoByCustomerId(customerId)); + } + + /** + * 新增车辆信息 + */ + @RequiresPermissions("system:carInfo:add") + @Log(title = "车辆信息", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody CarInfo carInfo) + { + if (!StrUtil.equals("2", carInfo.getCarType()) && !checkPlateNumberFormat(carInfo.getPlate())) { + return AjaxResult.error("车牌号不正确!"); + } + int i=carInfoService.insertCarInfo(carInfo); + //保存车辆授权 + //根据车场查询车辆 + if(carInfo.getParkId()!=null){ + CarParkItem carParkItem=new CarParkItem(); + carParkItem.setParkId(carInfo.getParkId()); + List itemList=carParkItemService.selectCarParkItemList(carParkItem); + for(CarParkItem a:itemList){ + CarParkRecord carParkRecord=new CarParkRecord(); + carParkRecord.setCustomerId(carInfo.getCustomerId()); + carParkRecord.setParkId(carInfo.getParkId()); + carParkRecord.setEquipmentId(a.getEquipmentId()); + carParkRecordService.insertCarParkRecord(carParkRecord); + } + } + return toAjax(i); + } + + /** + * 修改车辆信息 + */ + @RequiresPermissions("system:carInfo:edit") + @Log(title = "车辆信息", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody CarInfo carInfo) + { + if(!checkPlateNumberFormat(carInfo.getPlate())){ + return AjaxResult.error("车牌号不正确!"); + } + //根据车场查询车辆 + if(carInfo.getParkId()!=null){ + //删除车辆授权 + carParkRecordService.deleteCarParkRecordByCustomerId(carInfo.getCustomerId()); + CarParkItem carParkItem=new CarParkItem(); + carParkItem.setParkId(carInfo.getParkId()); + List itemList=carParkItemService.selectCarParkItemList(carParkItem); + for(CarParkItem a:itemList){ + CarParkRecord carParkRecord=new CarParkRecord(); + carParkRecord.setCustomerId(carInfo.getCustomerId()); + carParkRecord.setParkId(carInfo.getParkId()); + carParkRecord.setEquipmentId(a.getEquipmentId()); + carParkRecordService.insertCarParkRecord(carParkRecord); + + } + } + return toAjax(carInfoService.updateCarInfo(carInfo)); + } + + /** + * 删除车辆信息 + */ + @RequiresPermissions("system:carInfo:remove") + @Log(title = "车辆信息", businessType = BusinessType.DELETE) + @DeleteMapping("/{customerIds}") + public AjaxResult remove(@PathVariable Long[] customerIds) + { + //carParkRecordService.deleteCarParkRecordByCustomerIds(customerIds); + return toAjax(carInfoService.deleteCarInfoByCustomerIds(customerIds)); + } + + /** + * 获取企业模块|菜单权限树 + */ + @GetMapping(value = "/tree") + public AjaxResult tree() { + AjaxResult ajax = AjaxResult.success(); + ajax.put("depts", carInfoService.selectTree()); + return ajax; + } + + /** + * 获取企业模块|菜单权限树 + */ + @GetMapping(value = "/carPlay/{id}") + public AjaxResult carPlay(@PathVariable("id") Long id) { + AjaxResult ajax = AjaxResult.success(); + ajax.put("plays", carInfoService.carPlay(id)); + return ajax; + } + + /** + * 获取企业模块|菜单权限树 + */ + @GetMapping(value = "/carPlayRecord/{id}") + public AjaxResult carPlayRecord(@PathVariable("id") Long id) { + AjaxResult ajax = AjaxResult.success(); + ajax.put("records", carInfoService.carPlayRecord(id)); + return ajax; + } + + /** + * 获取企业模块|菜单权限树 + */ + @GetMapping(value = "/selectCarInfo/{id}/{flag}") + public AjaxResult selectCarInfo(@PathVariable("id") Long id,@PathVariable("flag") String flag) { + return toAjax(carInfoService.selectCarInfo(id,flag)); + } + + public boolean checkPlateNumberFormat(String content) { + String pattern = "([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼]{1}(([A-HJ-Z]{1}[A-HJ-NP-Z0-9]{5})|([A-HJ-Z]{1}(([DF]{1}[A-HJ-NP-Z0-9]{1}[0-9]{4})|([0-9]{5}[DF]{1})))|([A-HJ-Z]{1}[A-D0-9]{1}[0-9]{3}警)))|([0-9]{6}使)|((([沪粤川云桂鄂陕蒙藏黑辽渝]{1}A)|鲁B|闽D|蒙E|蒙H)[0-9]{4}领)|(WJ[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼·•]{1}[0-9]{4}[TDSHBXJ0-9]{1})|([VKHBSLJNGCE]{1}[A-DJ-PR-TVY]{1}[0-9]{5})"; + return Pattern.matches(pattern, content); + } + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/controller/CarParkController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/controller/CarParkController.java new file mode 100644 index 0000000..6975529 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/controller/CarParkController.java @@ -0,0 +1,125 @@ +package com.dcsoft.system.vehicle.controller; + +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDataInfo; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.system.vehicle.domain.CarPark; +import com.dcsoft.system.vehicle.domain.CarParkItem; +import com.dcsoft.system.vehicle.service.ICarParkItemService; +import com.dcsoft.system.vehicle.service.ICarParkService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 车场信息Controller + * + * @author nichun + * @date 2023-12-27 + */ +@RestController +@RequestMapping("/carPark") +public class CarParkController extends BaseController +{ + @Autowired + private ICarParkService carParkService; + + @Autowired + private ICarParkItemService carParkItemService; + + /** + * 查询车场信息列表 + */ + @RequiresPermissions("system:carPark:list") + @GetMapping("/list") + public TableDataInfo list(CarPark carPark) + { + startPage(); + List list = carParkService.selectCarParkList(carPark); + return getDataTable(list); + } + + /** + * 导出车场信息列表 + */ + @RequiresPermissions("system:carPark:export") + @Log(title = "车场信息", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, CarPark carPark) + { + List list = carParkService.selectCarParkList(carPark); + ExcelUtil util = new ExcelUtil(CarPark.class); + util.exportExcel(response, list, "车场信息数据"); + } + + /** + * 获取车场信息详细信息 + */ + @RequiresPermissions("system:carPark:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + CarPark park =carParkService.selectCarParkById(id); + CarParkItem item=new CarParkItem(); + item.setParkId(id); + List itemList=carParkItemService.selectCarParkItemList(item); + park.setItemList(itemList); + return success(park); + } + + /** + * 新增车场信息 + */ + @RequiresPermissions("system:carPark:add") + @Log(title = "车场信息", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody CarPark carPark) + { + int i=carParkService.insertCarPark(carPark); + List itemList=carPark.getItemList(); + for(CarParkItem item:itemList){ + item.setParkId(carPark.getId()); + carParkItemService.insertCarParkItem(item); + } + return toAjax(i); + } + + /** + * 修改车场信息 + */ + @RequiresPermissions("system:carPark:edit") + @Log(title = "车场信息", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody CarPark carPark) + { + //先删除关联子项再进行增加 + //删除子项存在的注册人员信息 + carParkItemService.deleteParkItemByParkId(carPark.getId()); + List itemList=carPark.getItemList(); + for(CarParkItem item:itemList){ + item.setParkId(carPark.getId()); + carParkItemService.insertCarParkItem(item); + } + return toAjax(carParkService.updateCarPark(carPark)); + } + + /** + * 删除车场信息 + */ + @RequiresPermissions("system:carPark:remove") + @Log(title = "车场信息", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + for(Long id:ids){ + carParkItemService.deleteParkItemByParkId(id); + } + return toAjax(carParkService.deleteCarParkByIds(ids)); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/controller/CarParkRecordController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/controller/CarParkRecordController.java new file mode 100644 index 0000000..21a4caa --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/controller/CarParkRecordController.java @@ -0,0 +1,116 @@ +package com.dcsoft.system.vehicle.controller; + +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDataInfo; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.system.vehicle.domain.CarParkRecord; +import com.dcsoft.system.vehicle.service.ICarParkRecordService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 车辆授权Controller + * + * @author dcsoft + * @date 2023-12-29 + */ +@RestController +@RequestMapping("/parkRecord") +public class CarParkRecordController extends BaseController +{ + @Autowired + private ICarParkRecordService carParkRecordService; + + /** + * 查询车辆授权列表 + */ + @RequiresPermissions("system:parkRecord:list") + @GetMapping("/list") + public TableDataInfo list(CarParkRecord carParkRecord) + { + startPage(); + List list = carParkRecordService.selectCarParkRecordList(carParkRecord); + return getDataTable(list); + } + + /** + * 导出车辆授权列表 + */ + @RequiresPermissions("system:parkRecord:export") + @Log(title = "车辆授权", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, CarParkRecord carParkRecord) + { + List list = carParkRecordService.selectCarParkRecordList(carParkRecord); + ExcelUtil util = new ExcelUtil(CarParkRecord.class); + util.exportExcel(response, list, "车辆授权数据"); + } + + /** + * 获取车辆授权详细信息 + */ + @RequiresPermissions("system:parkRecord:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(carParkRecordService.selectCarParkRecordById(id)); + } + + /** + * 新增车辆授权 + */ + @RequiresPermissions("system:parkRecord:add") + @Log(title = "车辆授权", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody CarParkRecord carParkRecord) + { + return toAjax(carParkRecordService.insertCarParkRecord(carParkRecord)); + } + + /** + * 修改车辆授权 + */ + @RequiresPermissions("system:parkRecord:edit") + @Log(title = "车辆授权", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody CarParkRecord carParkRecord) + { + return toAjax(carParkRecordService.updateCarParkRecord(carParkRecord)); + } + + /** + * 删除车辆授权 + */ + @RequiresPermissions("system:parkRecord:remove") + @Log(title = "车辆授权", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(carParkRecordService.deleteCarParkRecordByIds(ids)); + } + + /** + * 删除车辆授权 + */ + @Log(title = "车辆授权", businessType = BusinessType.UPDATE) + @GetMapping("/down/{ids}") + public AjaxResult down(@PathVariable Long[] ids) + { + int i=0; + for(Long id:ids){ + CarParkRecord carParkRecord=carParkRecordService.selectCarParkRecordById(id); + carParkRecord.setSync("2"); + carParkRecordService.updateCarParkRecord(carParkRecord); + i++; + } + return toAjax(i); + } + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/controller/CarPassGatherController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/controller/CarPassGatherController.java new file mode 100644 index 0000000..53944f7 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/controller/CarPassGatherController.java @@ -0,0 +1,106 @@ +package com.dcsoft.system.vehicle.controller; + +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDataInfo; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.system.vehicle.domain.CarPassGather; +import com.dcsoft.system.vehicle.service.ICarPassGatherService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.Map; + +/** + * 在场记录Controller + * + * @author nichun + * @date 2024-01-08 + */ +@RestController +@RequestMapping("/passGather") +public class CarPassGatherController extends BaseController +{ + @Autowired + private ICarPassGatherService carPassGatherService; + + /** + * 查询在场记录列表 + */ + @RequiresPermissions("vehicle:passGather:list") + @GetMapping("/list") + public TableDataInfo list(CarPassGather carPassGather) + { + startPage(); + List list = carPassGatherService.selectCarPassGatherList(carPassGather); + return getDataTable(list); + } + + /** + * 导出在场记录列表 + */ + @RequiresPermissions("vehicle:passGather:export") + @Log(title = "在场记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, CarPassGather carPassGather) + { + List list = carPassGatherService.selectCarPassGatherList(carPassGather); + ExcelUtil util = new ExcelUtil(CarPassGather.class); + util.exportExcel(response, list, "在场记录数据"); + } + + /** + * 获取在场记录详细信息 + */ + @RequiresPermissions("vehicle:passGather:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(carPassGatherService.selectCarPassGatherById(id)); + } + + /** + * 新增在场记录 + */ + @RequiresPermissions("vehicle:passGather:add") + @Log(title = "在场记录", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody CarPassGather carPassGather) + { + return toAjax(carPassGatherService.insertCarPassGather(carPassGather)); + } + + /** + * 修改在场记录 + */ + @RequiresPermissions("vehicle:passGather:edit") + @Log(title = "在场记录", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody CarPassGather carPassGather) + { + return toAjax(carPassGatherService.updateCarPassGather(carPassGather)); + } + + /** + * 删除在场记录 + */ + @RequiresPermissions("vehicle:passGather:remove") + @Log(title = "在场记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(carPassGatherService.deleteCarPassGatherByIds(ids)); + } + + @GetMapping("/parkTop") + public AjaxResult parkTop(CarPassGather carPassGather) + { + List> list = carPassGatherService.parkTop(carPassGather.getParkId()); + return success(list); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/controller/CarPassRecordController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/controller/CarPassRecordController.java new file mode 100644 index 0000000..548530e --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/controller/CarPassRecordController.java @@ -0,0 +1,98 @@ +package com.dcsoft.system.vehicle.controller; + +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDataInfo; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.system.vehicle.domain.CarPassRecord; +import com.dcsoft.system.vehicle.service.ICarPassRecordService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 通行记录Controller + * + * @author nichun + * @date 2024-01-03 + */ +@RestController +@RequestMapping("/carPassRecord") +public class CarPassRecordController extends BaseController +{ + @Autowired + private ICarPassRecordService carPassRecordService; + + /** + * 查询通行记录列表 + */ + @RequiresPermissions("system:carPassRecord:list") + @GetMapping("/list") + public TableDataInfo list(CarPassRecord carPassRecord) + { + startPage(); + List list = carPassRecordService.selectCarPassRecordList(carPassRecord); + return getDataTable(list); + } + + /** + * 导出通行记录列表 + */ + @RequiresPermissions("system:carPassRecord:export") + @Log(title = "通行记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, CarPassRecord carPassRecord) + { + List list = carPassRecordService.selectCarPassRecordList(carPassRecord); + ExcelUtil util = new ExcelUtil(CarPassRecord.class); + util.exportExcel(response, list, "通行记录数据"); + } + + /** + * 获取通行记录详细信息 + */ + @RequiresPermissions("system:carPassRecord:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(carPassRecordService.selectCarPassRecordById(id)); + } + + /** + * 新增通行记录 + */ + @RequiresPermissions("system:carPassRecord:add") + @Log(title = "通行记录", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody CarPassRecord carPassRecord) + { + return toAjax(carPassRecordService.insertCarPassRecord(carPassRecord)); + } + + /** + * 修改通行记录 + */ + @RequiresPermissions("system:carPassRecord:edit") + @Log(title = "通行记录", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody CarPassRecord carPassRecord) + { + return toAjax(carPassRecordService.updateCarPassRecord(carPassRecord)); + } + + /** + * 删除通行记录 + */ + @RequiresPermissions("system:carPassRecord:remove") + @Log(title = "通行记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(carPassRecordService.deleteCarPassRecordByIds(ids)); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarCharge.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarCharge.java new file mode 100644 index 0000000..32abfa5 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarCharge.java @@ -0,0 +1,149 @@ +package com.dcsoft.system.vehicle.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +/** + * 收费配置对象 car_charge + * + * @author nichun + * @date 2024-01-19 + */ +public class CarCharge extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** id */ + private Long id; + + /** 所属车场 */ + + private Long parkId; + @Excel(name = "所属车场") + private String parkName; + /** 计费名称 */ + @Excel(name = "计费名称") + private String name; + + /** 计费类型 */ + @Excel(name = "计费类型") + private String type; + + /** 免费时长 */ + @Excel(name = "免费时长") + private Long timeLong; + + /** 收费金额 */ + @Excel(name = "收费金额") + private BigDecimal chargeMoney; + + /** 状态 */ + @Excel(name = "状态") + private String status; + + private List itemList = new ArrayList(); + + public List getItemList() { + return itemList; + } + + public void setItemList(List itemList) { + this.itemList = itemList; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setParkId(Long parkId) + { + this.parkId = parkId; + } + + public Long getParkId() + { + return parkId; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setType(String type) + { + this.type = type; + } + + public String getType() + { + return type; + } + public void setTimeLong(Long timeLong) + { + this.timeLong = timeLong; + } + + public Long getTimeLong() + { + return timeLong; + } + public void setChargeMoney(BigDecimal chargeMoney) + { + this.chargeMoney = chargeMoney; + } + + public BigDecimal getChargeMoney() + { + return chargeMoney; + } + public void setStatus(String status) + { + this.status = status; + } + + public String getStatus() + { + return status; + } + + public String getParkName() { + return parkName; + } + + public void setParkName(String parkName) { + this.parkName = parkName; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("parkId", getParkId()) + .append("name", getName()) + .append("type", getType()) + .append("timeLong", getTimeLong()) + .append("chargeMoney", getChargeMoney()) + .append("status", getStatus()) + .append("remark", getRemark()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarChargeItem.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarChargeItem.java new file mode 100644 index 0000000..7bd304d --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarChargeItem.java @@ -0,0 +1,95 @@ +package com.dcsoft.system.vehicle.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.math.BigDecimal; + +/** + * 收费配置子项对象 car_charge_item + * + * @author dcsoft + * @date 2024-01-24 + */ +public class CarChargeItem extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** id */ + private Long id; + + /** 所属车场 */ + @Excel(name = "所属车场") + private Long chargeId; + + /** 计费时段起 */ + @Excel(name = "计费时段起") + private Long startLong; + + /** 计费时段止 */ + @Excel(name = "计费时段止") + private Long endLong; + + /** 收费金额 */ + @Excel(name = "收费金额") + private BigDecimal chargeMoney; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setChargeId(Long chargeId) + { + this.chargeId = chargeId; + } + + public Long getChargeId() + { + return chargeId; + } + public void setStartLong(Long startLong) + { + this.startLong = startLong; + } + + public Long getStartLong() + { + return startLong; + } + public void setEndLong(Long endLong) + { + this.endLong = endLong; + } + + public Long getEndLong() + { + return endLong; + } + public void setChargeMoney(BigDecimal chargeMoney) + { + this.chargeMoney = chargeMoney; + } + + public BigDecimal getChargeMoney() + { + return chargeMoney; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("chargeId", getChargeId()) + .append("startLong", getStartLong()) + .append("endLong", getEndLong()) + .append("chargeMoney", getChargeMoney()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarInfo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarInfo.java new file mode 100644 index 0000000..770325f --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarInfo.java @@ -0,0 +1,297 @@ +package com.dcsoft.system.vehicle.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.Date; + +/** + * 车辆信息对象 car_info + * + * @author nichun + * @date 2023-12-26 + */ +public class CarInfo extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** customer_id */ + + private Long customerId; + + /** 白名单生效时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "白名单生效时间", width = 30, dateFormat = "yyyy-MM-dd",sort = 2) + private Date enableTime; + + /** 白名单失效时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "白名单失效时间", width = 30, dateFormat = "yyyy-MM-dd",sort = 3) + private Date overdueTime; + + /** 是否启动 */ + @Excel(name = "是否启动",sort = 4,readConverterExp="0=否,1=是") + private String enable; + + /** 车牌号 */ + @Excel(name = "车牌号",sort = 5) + private String plate; + + /** 是否启用时间段 */ + @Excel(name = "是否启用时间段",sort = 6,readConverterExp="0=否,1=是") + private String timeSegEnable; + + /** 时间段 */ + private String segTime; + + + /** 是否需要报警 */ + @Excel(name = "是否需要报警",sort = 7,readConverterExp="0=否,1=是") + private String needAlarm; + + /** 用户自定义代码 */ + private String vehicleCode; + + /** 用户自定义的注释 */ + private String vehicleComment; + + /** 所属人员 */ + + private Long peopleId; + + /** 是否删除 0 是未删除 2是删除 */ + private String delFlag; + + /** 同步标识 sync 0是未同步 1是已同步 */ + private String sync; + + private Long parkId; + @Excel(name = "所属员工",sort = 9) + private String peopleName; + + @Excel(name = "所属车场",sort = 1) + private String parkName; + + private int num; + + @Excel(name = "联系电话",sort = 10) + private String phone; + + @Excel(name = "备注",sort =11) + private String remark; + private String carType; + + @Excel(name = "所属单位",sort = 8,readConverterExp = "1=锦盛化工,2=锦亿科技,3=锦泽化工,4=锋盛环保,5=锦鑫化工,6=锦鑫稀材,7=锦盛电厂,8=锦桂科技,9=晟锦科技,10=锦淳公司") + private String unit; + + public Long getParkId() { + return parkId; + } + + public void setParkId(Long parkId) { + this.parkId = parkId; + } + + public String getPeopleName() { + return peopleName; + } + + public void setPeopleName(String peopleName) { + this.peopleName = peopleName; + } + + public String getParkName() { + return parkName; + } + + public void setParkName(String parkName) { + this.parkName = parkName; + } + + public void setCustomerId(Long customerId) + { + this.customerId = customerId; + } + + public Long getCustomerId() + { + return customerId; + } + public void setEnableTime(Date enableTime) + { + this.enableTime = enableTime; + } + + public Date getEnableTime() + { + return enableTime; + } + public void setOverdueTime(Date overdueTime) + { + this.overdueTime = overdueTime; + } + + public Date getOverdueTime() + { + return overdueTime; + } + public void setEnable(String enable) + { + this.enable = enable; + } + + public String getEnable() + { + return enable; + } + public void setPlate(String plate) + { + this.plate = plate; + } + + public String getPlate() + { + return plate; + } + public void setTimeSegEnable(String timeSegEnable) + { + this.timeSegEnable = timeSegEnable; + } + + public String getTimeSegEnable() + { + return timeSegEnable; + } + public void setSegTime(String segTime) + { + this.segTime = segTime; + } + + public String getSegTime() + { + return segTime; + } + public void setNeedAlarm(String needAlarm) + { + this.needAlarm = needAlarm; + } + + public String getNeedAlarm() + { + return needAlarm; + } + public void setVehicleCode(String vehicleCode) + { + this.vehicleCode = vehicleCode; + } + + public String getVehicleCode() + { + return vehicleCode; + } + public void setVehicleComment(String vehicleComment) + { + this.vehicleComment = vehicleComment; + } + + public String getVehicleComment() + { + return vehicleComment; + } + public void setPeopleId(Long peopleId) + { + this.peopleId = peopleId; + } + + public Long getPeopleId() + { + return peopleId; + } + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + public void setSync(String sync) + { + this.sync = sync; + } + + public String getSync() + { + return sync; + } + + public int getNum() { + return num; + } + + public void setNum(int num) { + this.num = num; + } + + public String getCarType() { + return carType; + } + + public void setCarType(String carType) { + this.carType = carType; + } + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } + + @Override + public String getRemark() { + return remark; + } + + @Override + public void setRemark(String remark) { + this.remark = remark; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("customerId", getCustomerId()) + .append("enableTime", getEnableTime()) + .append("overdueTime", getOverdueTime()) + .append("enable", getEnable()) + .append("plate", getPlate()) + .append("timeSegEnable", getTimeSegEnable()) + .append("segTime", getSegTime()) + .append("needAlarm", getNeedAlarm()) + .append("vehicleCode", getVehicleCode()) + .append("vehicleComment", getVehicleComment()) + .append("peopleId", getPeopleId()) + .append("delFlag", getDelFlag()) + .append("sync", getSync()) + .append("remark", getRemark()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarPark.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarPark.java new file mode 100644 index 0000000..c20052c --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarPark.java @@ -0,0 +1,121 @@ +package com.dcsoft.system.vehicle.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.ArrayList; +import java.util.List; + +/** + * 车场信息对象 car_park + * + * @author nichun + * @date 2023-12-27 + */ +public class CarPark extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** id */ + private Long id; + + /** 车场名称 */ + @Excel(name = "车场名称") + private String name; + + /** 所属空间 */ + @Excel(name = "所属空间") + private Long spaceId; + + private String spaceName; + + /** 车位总数 */ + @Excel(name = "车位总数") + private Long carsNum; + + /** 余位数 */ + @Excel(name = "余位数") + private Long surplusNum; + + private List itemList = new ArrayList(); + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setSpaceId(Long spaceId) + { + this.spaceId = spaceId; + } + + public Long getSpaceId() + { + return spaceId; + } + public void setCarsNum(Long carsNum) + { + this.carsNum = carsNum; + } + + public Long getCarsNum() + { + return carsNum; + } + public void setSurplusNum(Long surplusNum) + { + this.surplusNum = surplusNum; + } + + public Long getSurplusNum() + { + return surplusNum; + } + + public List getItemList() { + return itemList; + } + + public void setItemList(List itemList) { + this.itemList = itemList; + } + + public String getSpaceName() { + return spaceName; + } + + public void setSpaceName(String spaceName) { + this.spaceName = spaceName; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("spaceId", getSpaceId()) + .append("carsNum", getCarsNum()) + .append("surplusNum", getSurplusNum()) + .append("remark", getRemark()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarParkItem.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarParkItem.java new file mode 100644 index 0000000..4e6bcca --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarParkItem.java @@ -0,0 +1,89 @@ +package com.dcsoft.system.vehicle.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 车场设备信息对象 car_park_item + * + * @author nichun + * @date 2023-12-28 + */ +public class CarParkItem extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** id */ + private Long id; + + /** 设备id */ + @Excel(name = "设备id") + private Long equipmentId; + + /** 车场id */ + @Excel(name = "车场id") + private Long parkId; + + /** 通道方向 */ + @Excel(name = "通道方向") + private String way; + + private String area; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setEquipmentId(Long equipmentId) + { + this.equipmentId = equipmentId; + } + + public Long getEquipmentId() + { + return equipmentId; + } + public void setParkId(Long parkId) + { + this.parkId = parkId; + } + + public Long getParkId() + { + return parkId; + } + public void setWay(String way) + { + this.way = way; + } + + public String getWay() + { + return way; + } + + public String getArea() { + return area; + } + + public void setArea(String area) { + this.area = area; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("equipmentId", getEquipmentId()) + .append("parkId", getParkId()) + .append("way", getWay()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarParkRecord.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarParkRecord.java new file mode 100644 index 0000000..81ac025 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarParkRecord.java @@ -0,0 +1,128 @@ +package com.dcsoft.system.vehicle.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 车辆授权对象 car_park_record + * + * @author dcsoft + * @date 2023-12-29 + */ +public class CarParkRecord extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** id */ + private Long id; + + /** 设备id */ + + private Long equipmentId; + + /** 车场id */ + + private Long parkId; + + /** 车辆id */ + @Excel(name = "车辆") + private Long customerId; + + /** 是否下发(0未下发1已下发) */ + @Excel(name = "是否下发", readConverterExp = "0=未下发1已下发") + private String sync; + + @Excel(name = "设备") + private String equipmentName; + + /** 车场id */ + @Excel(name = "车场") + private String parkName; + + /** 车辆id */ + @Excel(name = "车牌号") + private String customerName; + + public String getEquipmentName() { + return equipmentName; + } + + public void setEquipmentName(String equipmentName) { + this.equipmentName = equipmentName; + } + + public String getParkName() { + return parkName; + } + + public void setParkName(String parkName) { + this.parkName = parkName; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setEquipmentId(Long equipmentId) + { + this.equipmentId = equipmentId; + } + + public Long getEquipmentId() + { + return equipmentId; + } + public void setParkId(Long parkId) + { + this.parkId = parkId; + } + + public Long getParkId() + { + return parkId; + } + public void setCustomerId(Long customerId) + { + this.customerId = customerId; + } + + public Long getCustomerId() + { + return customerId; + } + public void setSync(String sync) + { + this.sync = sync; + } + + public String getSync() + { + return sync; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("equipmentId", getEquipmentId()) + .append("parkId", getParkId()) + .append("customerId", getCustomerId()) + .append("sync", getSync()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarPassGather.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarPassGather.java new file mode 100644 index 0000000..bdf78bb --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarPassGather.java @@ -0,0 +1,151 @@ +package com.dcsoft.system.vehicle.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.Date; + +/** + * 在场记录对象 car_pass_gather + * + * @author nichun + * @date 2024-01-08 + */ +public class CarPassGather extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** id */ + private Long id; + + /** 停车场id */ + private Long parkId; + + @Excel(name = "停车场") + private String parkName; + /** 区域 */ + + private Long area; + + @Excel(name = "区域") + private String areaName; + + /** 车牌号码 */ + @Excel(name = "车牌号码") + private String license; + + /** 入场时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "入场时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date joinTime; + + private Long timeLong; + + /** 设备序列号 */ + @Excel(name = "设备序列号") + private String sn; + + private String equipmentName; + + public String getParkName() { + return parkName; + } + + public void setParkName(String parkName) { + this.parkName = parkName; + } + + public String getAreaName() { + return areaName; + } + + public void setAreaName(String areaName) { + this.areaName = areaName; + } + + public String getEquipmentName() { + return equipmentName; + } + + public void setEquipmentName(String equipmentName) { + this.equipmentName = equipmentName; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setParkId(Long parkId) + { + this.parkId = parkId; + } + + public Long getParkId() + { + return parkId; + } + public void setArea(Long area) + { + this.area = area; + } + + public Long getArea() + { + return area; + } + public void setLicense(String license) + { + this.license = license; + } + + public String getLicense() + { + return license; + } + public void setJoinTime(Date joinTime) + { + this.joinTime = joinTime; + } + + public Date getJoinTime() + { + return joinTime; + } + public void setSn(String sn) + { + this.sn = sn; + } + + public String getSn() + { + return sn; + } + + public Long getTimeLong() { + return timeLong; + } + + public void setTimeLong(Long timeLong) { + this.timeLong = timeLong; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("parkId", getParkId()) + .append("area", getArea()) + .append("license", getLicense()) + .append("joinTime", getJoinTime()) + .append("sn", getSn()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarPassRecord.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarPassRecord.java new file mode 100644 index 0000000..0a8f349 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/domain/CarPassRecord.java @@ -0,0 +1,245 @@ +package com.dcsoft.system.vehicle.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.Date; + +/** + * 通行记录对象 car_pass_record + * + * @author nichun + * @date 2024-01-03 + */ +public class CarPassRecord extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** id */ + private Long id; + + /** 停车场id */ + @Excel(name = "停车场id") + private String parkId; + + /** 过车信息唯一标识 */ + private String uniqueNo; + + /** 过车行驶方向 0 入场过车 1出场过车 */ + @Excel(name = "过车行驶方向 0 入场过车 1出场过车") + private String direction; + + /** 车牌号码 */ + @Excel(name = "车牌号码") + private String license; + + /** 通行时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "通行时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date passTime; + + /** 触发类型 */ + @Excel(name = "触发类型") + private String triggerType; + + /** 车牌颜色 */ + @Excel(name = "车牌颜色") + private String colorType; + + /** 车辆颜色 */ + @Excel(name = "车辆颜色") + private String carColor; + + /** 车牌图片数据 */ + @Excel(name = "车牌图片数据") + private String url; + + /** 数据类型 0 实时数据 1历史数据 */ + @Excel(name = "数据类型 0 实时数据 1历史数据") + private String dataType; + + /** 设备序列号 */ + @Excel(name = "设备序列号") + private String sn; + + private String parkName; + + private String way; + + private String equipmentName; + + private String unit; + + private String type; + + public String getEquipmentName() { + return equipmentName; + } + + public void setEquipmentName(String equipmentName) { + this.equipmentName = equipmentName; + } + + public String getParkName() { + return parkName; + } + + public void setParkName(String parkName) { + this.parkName = parkName; + } + + public String getWay() { + return way; + } + + public void setWay(String way) { + this.way = way; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setParkId(String parkId) + { + this.parkId = parkId; + } + + public String getParkId() + { + return parkId; + } + public void setUniqueNo(String uniqueNo) + { + this.uniqueNo = uniqueNo; + } + + public String getUniqueNo() + { + return uniqueNo; + } + public void setDirection(String direction) + { + this.direction = direction; + } + + public String getDirection() + { + return direction; + } + public void setLicense(String license) + { + this.license = license; + } + + public String getLicense() + { + return license; + } + public void setPassTime(Date passTime) + { + this.passTime = passTime; + } + + public Date getPassTime() + { + return passTime; + } + public void setTriggerType(String triggerType) + { + this.triggerType = triggerType; + } + + public String getTriggerType() + { + return triggerType; + } + public void setColorType(String colorType) + { + this.colorType = colorType; + } + + public String getColorType() + { + return colorType; + } + public void setCarColor(String carColor) + { + this.carColor = carColor; + } + + public String getCarColor() + { + return carColor; + } + public void setUrl(String url) + { + this.url = url; + } + + public String getUrl() + { + return url; + } + public void setDataType(String dataType) + { + this.dataType = dataType; + } + + public String getDataType() + { + return dataType; + } + public void setSn(String sn) + { + this.sn = sn; + } + + public String getSn() + { + return sn; + } + + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("parkId", getParkId()) + .append("uniqueNo", getUniqueNo()) + .append("direction", getDirection()) + .append("license", getLicense()) + .append("passTime", getPassTime()) + .append("triggerType", getTriggerType()) + .append("colorType", getColorType()) + .append("carColor", getCarColor()) + .append("url", getUrl()) + .append("dataType", getDataType()) + .append("sn", getSn()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarChargeItemMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarChargeItemMapper.java new file mode 100644 index 0000000..897c57b --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarChargeItemMapper.java @@ -0,0 +1,64 @@ +package com.dcsoft.system.vehicle.mapper; + +import com.dcsoft.system.vehicle.domain.CarChargeItem; + +import java.util.List; + +/** + * 收费配置子项Mapper接口 + * + * @author dcsoft + * @date 2024-01-24 + */ +public interface CarChargeItemMapper +{ + /** + * 查询收费配置子项 + * + * @param id 收费配置子项主键 + * @return 收费配置子项 + */ + public CarChargeItem selectCarChargeItemById(Long id); + + /** + * 查询收费配置子项列表 + * + * @param carChargeItem 收费配置子项 + * @return 收费配置子项集合 + */ + public List selectCarChargeItemList(CarChargeItem carChargeItem); + + /** + * 新增收费配置子项 + * + * @param carChargeItem 收费配置子项 + * @return 结果 + */ + public int insertCarChargeItem(CarChargeItem carChargeItem); + + /** + * 修改收费配置子项 + * + * @param carChargeItem 收费配置子项 + * @return 结果 + */ + public int updateCarChargeItem(CarChargeItem carChargeItem); + + /** + * 删除收费配置子项 + * + * @param id 收费配置子项主键 + * @return 结果 + */ + public int deleteCarChargeItemById(Long id); + + /** + * 批量删除收费配置子项 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteCarChargeItemByIds(Long[] ids); + + public int deleteChargeItemByChargeId(Long id); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarChargeMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarChargeMapper.java new file mode 100644 index 0000000..5a0dc9f --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarChargeMapper.java @@ -0,0 +1,62 @@ +package com.dcsoft.system.vehicle.mapper; + +import com.dcsoft.system.vehicle.domain.CarCharge; + +import java.util.List; + +/** + * 收费配置Mapper接口 + * + * @author nichun + * @date 2024-01-19 + */ +public interface CarChargeMapper +{ + /** + * 查询收费配置 + * + * @param id 收费配置主键 + * @return 收费配置 + */ + public CarCharge selectCarChargeById(Long id); + + /** + * 查询收费配置列表 + * + * @param carCharge 收费配置 + * @return 收费配置集合 + */ + public List selectCarChargeList(CarCharge carCharge); + + /** + * 新增收费配置 + * + * @param carCharge 收费配置 + * @return 结果 + */ + public int insertCarCharge(CarCharge carCharge); + + /** + * 修改收费配置 + * + * @param carCharge 收费配置 + * @return 结果 + */ + public int updateCarCharge(CarCharge carCharge); + + /** + * 删除收费配置 + * + * @param id 收费配置主键 + * @return 结果 + */ + public int deleteCarChargeById(Long id); + + /** + * 批量删除收费配置 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteCarChargeByIds(Long[] ids); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarInfoMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarInfoMapper.java new file mode 100644 index 0000000..1395135 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarInfoMapper.java @@ -0,0 +1,64 @@ +package com.dcsoft.system.vehicle.mapper; + +import com.dcsoft.system.vehicle.domain.CarInfo; + +import java.util.List; + +/** + * 车辆信息Mapper接口 + * + * @author nichun + * @date 2023-12-26 + */ +public interface CarInfoMapper +{ + /** + * 查询车辆信息 + * + * @param customerId 车辆信息主键 + * @return 车辆信息 + */ + public CarInfo selectCarInfoByCustomerId(Long customerId); + + /** + * 查询车辆信息列表 + * + * @param carInfo 车辆信息 + * @return 车辆信息集合 + */ + public List selectCarInfoList(CarInfo carInfo); + + /** + * 新增车辆信息 + * + * @param carInfo 车辆信息 + * @return 结果 + */ + public int insertCarInfo(CarInfo carInfo); + + /** + * 修改车辆信息 + * + * @param carInfo 车辆信息 + * @return 结果 + */ + public int updateCarInfo(CarInfo carInfo); + + /** + * 删除车辆信息 + * + * @param customerId 车辆信息主键 + * @return 结果 + */ + public int deleteCarInfoByCustomerId(Long customerId); + + /** + * 批量删除车辆信息 + * + * @param customerIds 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteCarInfoByCustomerIds(Long[] customerIds); + + public CarInfo selectCarInfoByCarNo(String plate); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarParkItemMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarParkItemMapper.java new file mode 100644 index 0000000..183d11a --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarParkItemMapper.java @@ -0,0 +1,64 @@ +package com.dcsoft.system.vehicle.mapper; + +import com.dcsoft.system.vehicle.domain.CarParkItem; + +import java.util.List; + +/** + * 车场设备信息Mapper接口 + * + * @author nichun + * @date 2023-12-28 + */ +public interface CarParkItemMapper +{ + /** + * 查询车场设备信息 + * + * @param id 车场设备信息主键 + * @return 车场设备信息 + */ + public CarParkItem selectCarParkItemById(Long id); + + /** + * 查询车场设备信息列表 + * + * @param carParkItem 车场设备信息 + * @return 车场设备信息集合 + */ + public List selectCarParkItemList(CarParkItem carParkItem); + + /** + * 新增车场设备信息 + * + * @param carParkItem 车场设备信息 + * @return 结果 + */ + public int insertCarParkItem(CarParkItem carParkItem); + + /** + * 修改车场设备信息 + * + * @param carParkItem 车场设备信息 + * @return 结果 + */ + public int updateCarParkItem(CarParkItem carParkItem); + + /** + * 删除车场设备信息 + * + * @param id 车场设备信息主键 + * @return 结果 + */ + public int deleteCarParkItemById(Long id); + + /** + * 批量删除车场设备信息 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteCarParkItemByIds(Long[] ids); + + public int deleteParkItemByParkId(Long parkId); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarParkMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarParkMapper.java new file mode 100644 index 0000000..4e35148 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarParkMapper.java @@ -0,0 +1,76 @@ +package com.dcsoft.system.vehicle.mapper; + +import com.dcsoft.system.vehicle.domain.CarPark; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * 车场信息Mapper接口 + * + * @author nichun + * @date 2023-12-27 + */ +public interface CarParkMapper +{ + /** + * 查询车场信息 + * + * @param id 车场信息主键 + * @return 车场信息 + */ + public CarPark selectCarParkById(Long id); + + /** + * 查询车场信息列表 + * + * @param carPark 车场信息 + * @return 车场信息集合 + */ + public List selectCarParkList(CarPark carPark); + + /** + * 新增车场信息 + * + * @param carPark 车场信息 + * @return 结果 + */ + public int insertCarPark(CarPark carPark); + + /** + * 修改车场信息 + * + * @param carPark 车场信息 + * @return 结果 + */ + public int updateCarPark(CarPark carPark); + + /** + * 删除车场信息 + * + * @param id 车场信息主键 + * @return 结果 + */ + public int deleteCarParkById(Long id); + + /** + * 批量删除车场信息 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteCarParkByIds(Long[] ids); + + public List> selectItemTreeList(Long id); + + public List> carPlay(Long id); + + public List> carPlayRecord(Long id); + + public int deleteSelectCarInfo(Long id); + + public int selectCarInfo(@Param("id") Long id,@Param("flag") String flag); + + public CarPark selectCarParkByName(String name); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarParkRecordMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarParkRecordMapper.java new file mode 100644 index 0000000..9e555ae --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarParkRecordMapper.java @@ -0,0 +1,70 @@ +package com.dcsoft.system.vehicle.mapper; + +import com.dcsoft.system.vehicle.domain.CarParkRecord; + +import java.util.List; + +/** + * 车辆授权Mapper接口 + * + * @author dcsoft + * @date 2023-12-29 + */ +public interface CarParkRecordMapper +{ + /** + * 查询车辆授权 + * + * @param id 车辆授权主键 + * @return 车辆授权 + */ + public CarParkRecord selectCarParkRecordById(Long id); + + /** + * 查询车辆授权列表 + * + * @param carParkRecord 车辆授权 + * @return 车辆授权集合 + */ + public List selectCarParkRecordList(CarParkRecord carParkRecord); + + /** + * 新增车辆授权 + * + * @param carParkRecord 车辆授权 + * @return 结果 + */ + public int insertCarParkRecord(CarParkRecord carParkRecord); + + /** + * 修改车辆授权 + * + * @param carParkRecord 车辆授权 + * @return 结果 + */ + public int updateCarParkRecord(CarParkRecord carParkRecord); + + /** + * 删除车辆授权 + * + * @param id 车辆授权主键 + * @return 结果 + */ + public int deleteCarParkRecordById(Long id); + + /** + * 批量删除车辆授权 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteCarParkRecordByIds(Long[] ids); + + public int deleteCarParkRecordByParkId(Long parkId); + + public int deleteCarParkRecordByCustomerIds(Long[] ids); + + public int deleteCarParkRecordByCustomerId(Long[] ids); + + public int deleteCarParkRecordByCustomerId(Long customerId); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarPassGatherMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarPassGatherMapper.java new file mode 100644 index 0000000..35a0e88 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarPassGatherMapper.java @@ -0,0 +1,65 @@ +package com.dcsoft.system.vehicle.mapper; + +import com.dcsoft.system.vehicle.domain.CarPassGather; + +import java.util.List; +import java.util.Map; + +/** + * 在场记录Mapper接口 + * + * @author nichun + * @date 2024-01-08 + */ +public interface CarPassGatherMapper +{ + /** + * 查询在场记录 + * + * @param id 在场记录主键 + * @return 在场记录 + */ + public CarPassGather selectCarPassGatherById(Long id); + + /** + * 查询在场记录列表 + * + * @param carPassGather 在场记录 + * @return 在场记录集合 + */ + public List selectCarPassGatherList(CarPassGather carPassGather); + + /** + * 新增在场记录 + * + * @param carPassGather 在场记录 + * @return 结果 + */ + public int insertCarPassGather(CarPassGather carPassGather); + + /** + * 修改在场记录 + * + * @param carPassGather 在场记录 + * @return 结果 + */ + public int updateCarPassGather(CarPassGather carPassGather); + + /** + * 删除在场记录 + * + * @param id 在场记录主键 + * @return 结果 + */ + public int deleteCarPassGatherById(Long id); + + /** + * 批量删除在场记录 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteCarPassGatherByIds(Long[] ids); + + public List> parkTop(Long carPassGather); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarPassRecordMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarPassRecordMapper.java new file mode 100644 index 0000000..980faca --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/mapper/CarPassRecordMapper.java @@ -0,0 +1,62 @@ +package com.dcsoft.system.vehicle.mapper; + +import com.dcsoft.system.vehicle.domain.CarPassRecord; + +import java.util.List; + +/** + * 通行记录Mapper接口 + * + * @author nichun + * @date 2024-01-03 + */ +public interface CarPassRecordMapper +{ + /** + * 查询通行记录 + * + * @param id 通行记录主键 + * @return 通行记录 + */ + public CarPassRecord selectCarPassRecordById(Long id); + + /** + * 查询通行记录列表 + * + * @param carPassRecord 通行记录 + * @return 通行记录集合 + */ + public List selectCarPassRecordList(CarPassRecord carPassRecord); + + /** + * 新增通行记录 + * + * @param carPassRecord 通行记录 + * @return 结果 + */ + public int insertCarPassRecord(CarPassRecord carPassRecord); + + /** + * 修改通行记录 + * + * @param carPassRecord 通行记录 + * @return 结果 + */ + public int updateCarPassRecord(CarPassRecord carPassRecord); + + /** + * 删除通行记录 + * + * @param id 通行记录主键 + * @return 结果 + */ + public int deleteCarPassRecordById(Long id); + + /** + * 批量删除通行记录 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteCarPassRecordByIds(Long[] ids); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarChargeItemService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarChargeItemService.java new file mode 100644 index 0000000..7f1afd9 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarChargeItemService.java @@ -0,0 +1,64 @@ +package com.dcsoft.system.vehicle.service; + +import com.dcsoft.system.vehicle.domain.CarChargeItem; + +import java.util.List; + +/** + * 收费配置子项Service接口 + * + * @author dcsoft + * @date 2024-01-24 + */ +public interface ICarChargeItemService +{ + /** + * 查询收费配置子项 + * + * @param id 收费配置子项主键 + * @return 收费配置子项 + */ + public CarChargeItem selectCarChargeItemById(Long id); + + /** + * 查询收费配置子项列表 + * + * @param carChargeItem 收费配置子项 + * @return 收费配置子项集合 + */ + public List selectCarChargeItemList(CarChargeItem carChargeItem); + + /** + * 新增收费配置子项 + * + * @param carChargeItem 收费配置子项 + * @return 结果 + */ + public int insertCarChargeItem(CarChargeItem carChargeItem); + + /** + * 修改收费配置子项 + * + * @param carChargeItem 收费配置子项 + * @return 结果 + */ + public int updateCarChargeItem(CarChargeItem carChargeItem); + + /** + * 批量删除收费配置子项 + * + * @param ids 需要删除的收费配置子项主键集合 + * @return 结果 + */ + public int deleteCarChargeItemByIds(Long[] ids); + + /** + * 删除收费配置子项信息 + * + * @param id 收费配置子项主键 + * @return 结果 + */ + public int deleteCarChargeItemById(Long id); + + public int deleteChargeItemByChargeId(Long id); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarChargeService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarChargeService.java new file mode 100644 index 0000000..fea4019 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarChargeService.java @@ -0,0 +1,62 @@ +package com.dcsoft.system.vehicle.service; + +import com.dcsoft.system.vehicle.domain.CarCharge; + +import java.util.List; + +/** + * 收费配置Service接口 + * + * @author nichun + * @date 2024-01-19 + */ +public interface ICarChargeService +{ + /** + * 查询收费配置 + * + * @param id 收费配置主键 + * @return 收费配置 + */ + public CarCharge selectCarChargeById(Long id); + + /** + * 查询收费配置列表 + * + * @param carCharge 收费配置 + * @return 收费配置集合 + */ + public List selectCarChargeList(CarCharge carCharge); + + /** + * 新增收费配置 + * + * @param carCharge 收费配置 + * @return 结果 + */ + public int insertCarCharge(CarCharge carCharge); + + /** + * 修改收费配置 + * + * @param carCharge 收费配置 + * @return 结果 + */ + public int updateCarCharge(CarCharge carCharge); + + /** + * 批量删除收费配置 + * + * @param ids 需要删除的收费配置主键集合 + * @return 结果 + */ + public int deleteCarChargeByIds(Long[] ids); + + /** + * 删除收费配置信息 + * + * @param id 收费配置主键 + * @return 结果 + */ + public int deleteCarChargeById(Long id); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarInfoService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarInfoService.java new file mode 100644 index 0000000..5da0259 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarInfoService.java @@ -0,0 +1,77 @@ +package com.dcsoft.system.vehicle.service; + +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.domain.vo.SysAuthTree; +import com.dcsoft.system.vehicle.domain.CarInfo; + +import java.util.List; +import java.util.Map; + +/** + * 车辆信息Service接口 + * + * @author nichun + * @date 2023-12-26 + */ +public interface ICarInfoService +{ + /** + * 查询车辆信息 + * + * @param customerId 车辆信息主键 + * @return 车辆信息 + */ + public CarInfo selectCarInfoByCustomerId(Long customerId); + + /** + * 查询车辆信息列表 + * + * @param carInfo 车辆信息 + * @return 车辆信息集合 + */ + public List selectCarInfoList(CarInfo carInfo); + + /** + * 新增车辆信息 + * + * @param carInfo 车辆信息 + * @return 结果 + */ + public int insertCarInfo(CarInfo carInfo); + + /** + * 修改车辆信息 + * + * @param carInfo 车辆信息 + * @return 结果 + */ + public int updateCarInfo(CarInfo carInfo); + + /** + * 批量删除车辆信息 + * + * @param customerIds 需要删除的车辆信息主键集合 + * @return 结果 + */ + public int deleteCarInfoByCustomerIds(Long[] customerIds); + + /** + * 删除车辆信息信息 + * + * @param customerId 车辆信息主键 + * @return 结果 + */ + public int deleteCarInfoByCustomerId(Long customerId); + + public int addOrUpdate(SysPeople sysPeople); + + List selectTree(); + + List> carPlay(Long id); + + List> carPlayRecord(Long id); + + public int selectCarInfo(Long id,String flag); + + String importData(List userList, boolean updateSupport, String operName); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarParkItemService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarParkItemService.java new file mode 100644 index 0000000..13fb240 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarParkItemService.java @@ -0,0 +1,64 @@ +package com.dcsoft.system.vehicle.service; + +import com.dcsoft.system.vehicle.domain.CarParkItem; + +import java.util.List; + +/** + * 车场设备信息Service接口 + * + * @author nichun + * @date 2023-12-28 + */ +public interface ICarParkItemService +{ + /** + * 查询车场设备信息 + * + * @param id 车场设备信息主键 + * @return 车场设备信息 + */ + public CarParkItem selectCarParkItemById(Long id); + + /** + * 查询车场设备信息列表 + * + * @param carParkItem 车场设备信息 + * @return 车场设备信息集合 + */ + public List selectCarParkItemList(CarParkItem carParkItem); + + /** + * 新增车场设备信息 + * + * @param carParkItem 车场设备信息 + * @return 结果 + */ + public int insertCarParkItem(CarParkItem carParkItem); + + /** + * 修改车场设备信息 + * + * @param carParkItem 车场设备信息 + * @return 结果 + */ + public int updateCarParkItem(CarParkItem carParkItem); + + /** + * 批量删除车场设备信息 + * + * @param ids 需要删除的车场设备信息主键集合 + * @return 结果 + */ + public int deleteCarParkItemByIds(Long[] ids); + + /** + * 删除车场设备信息信息 + * + * @param id 车场设备信息主键 + * @return 结果 + */ + public int deleteCarParkItemById(Long id); + + public int deleteParkItemByParkId(Long parkId); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarParkRecordService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarParkRecordService.java new file mode 100644 index 0000000..f371d36 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarParkRecordService.java @@ -0,0 +1,69 @@ +package com.dcsoft.system.vehicle.service; + +import com.dcsoft.system.vehicle.domain.CarParkRecord; + +import java.util.List; + +/** + * 车辆授权Service接口 + * + * @author dcsoft + * @date 2023-12-29 + */ +public interface ICarParkRecordService +{ + /** + * 查询车辆授权 + * + * @param id 车辆授权主键 + * @return 车辆授权 + */ + public CarParkRecord selectCarParkRecordById(Long id); + + /** + * 查询车辆授权列表 + * + * @param carParkRecord 车辆授权 + * @return 车辆授权集合 + */ + public List selectCarParkRecordList(CarParkRecord carParkRecord); + + /** + * 新增车辆授权 + * + * @param carParkRecord 车辆授权 + * @return 结果 + */ + public int insertCarParkRecord(CarParkRecord carParkRecord); + + /** + * 修改车辆授权 + * + * @param carParkRecord 车辆授权 + * @return 结果 + */ + public int updateCarParkRecord(CarParkRecord carParkRecord); + + /** + * 批量删除车辆授权 + * + * @param ids 需要删除的车辆授权主键集合 + * @return 结果 + */ + public int deleteCarParkRecordByIds(Long[] ids); + + /** + * 删除车辆授权信息 + * + * @param id 车辆授权主键 + * @return 结果 + */ + public int deleteCarParkRecordById(Long id); + + public int deleteCarParkRecordByParkId(Long parkId); + + public int deleteCarParkRecordByCustomerIds(Long[] customerIds); + + public int deleteCarParkRecordByCustomerId(Long customerId); + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarParkService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarParkService.java new file mode 100644 index 0000000..3559f2e --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarParkService.java @@ -0,0 +1,62 @@ +package com.dcsoft.system.vehicle.service; + +import com.dcsoft.system.vehicle.domain.CarPark; + +import java.util.List; + +/** + * 车场信息Service接口 + * + * @author nichun + * @date 2023-12-27 + */ +public interface ICarParkService +{ + /** + * 查询车场信息 + * + * @param id 车场信息主键 + * @return 车场信息 + */ + public CarPark selectCarParkById(Long id); + + /** + * 查询车场信息列表 + * + * @param carPark 车场信息 + * @return 车场信息集合 + */ + public List selectCarParkList(CarPark carPark); + + /** + * 新增车场信息 + * + * @param carPark 车场信息 + * @return 结果 + */ + public int insertCarPark(CarPark carPark); + + /** + * 修改车场信息 + * + * @param carPark 车场信息 + * @return 结果 + */ + public int updateCarPark(CarPark carPark); + + /** + * 批量删除车场信息 + * + * @param ids 需要删除的车场信息主键集合 + * @return 结果 + */ + public int deleteCarParkByIds(Long[] ids); + + /** + * 删除车场信息信息 + * + * @param id 车场信息主键 + * @return 结果 + */ + public int deleteCarParkById(Long id); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarPassGatherService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarPassGatherService.java new file mode 100644 index 0000000..1dad7d1 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarPassGatherService.java @@ -0,0 +1,65 @@ +package com.dcsoft.system.vehicle.service; + +import com.dcsoft.system.vehicle.domain.CarPassGather; + +import java.util.List; +import java.util.Map; + +/** + * 在场记录Service接口 + * + * @author nichun + * @date 2024-01-08 + */ +public interface ICarPassGatherService +{ + /** + * 查询在场记录 + * + * @param id 在场记录主键 + * @return 在场记录 + */ + public CarPassGather selectCarPassGatherById(Long id); + + /** + * 查询在场记录列表 + * + * @param carPassGather 在场记录 + * @return 在场记录集合 + */ + public List selectCarPassGatherList(CarPassGather carPassGather); + + /** + * 新增在场记录 + * + * @param carPassGather 在场记录 + * @return 结果 + */ + public int insertCarPassGather(CarPassGather carPassGather); + + /** + * 修改在场记录 + * + * @param carPassGather 在场记录 + * @return 结果 + */ + public int updateCarPassGather(CarPassGather carPassGather); + + /** + * 批量删除在场记录 + * + * @param ids 需要删除的在场记录主键集合 + * @return 结果 + */ + public int deleteCarPassGatherByIds(Long[] ids); + + /** + * 删除在场记录信息 + * + * @param id 在场记录主键 + * @return 结果 + */ + public int deleteCarPassGatherById(Long id); + + public List> parkTop(Long parkId); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarPassRecordService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarPassRecordService.java new file mode 100644 index 0000000..4ccaade --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/ICarPassRecordService.java @@ -0,0 +1,62 @@ +package com.dcsoft.system.vehicle.service; + +import com.dcsoft.system.vehicle.domain.CarPassRecord; + +import java.util.List; + +/** + * 通行记录Service接口 + * + * @author nichun + * @date 2024-01-03 + */ +public interface ICarPassRecordService +{ + /** + * 查询通行记录 + * + * @param id 通行记录主键 + * @return 通行记录 + */ + public CarPassRecord selectCarPassRecordById(Long id); + + /** + * 查询通行记录列表 + * + * @param carPassRecord 通行记录 + * @return 通行记录集合 + */ + public List selectCarPassRecordList(CarPassRecord carPassRecord); + + /** + * 新增通行记录 + * + * @param carPassRecord 通行记录 + * @return 结果 + */ + public int insertCarPassRecord(CarPassRecord carPassRecord); + + /** + * 修改通行记录 + * + * @param carPassRecord 通行记录 + * @return 结果 + */ + public int updateCarPassRecord(CarPassRecord carPassRecord); + + /** + * 批量删除通行记录 + * + * @param ids 需要删除的通行记录主键集合 + * @return 结果 + */ + public int deleteCarPassRecordByIds(Long[] ids); + + /** + * 删除通行记录信息 + * + * @param id 通行记录主键 + * @return 结果 + */ + public int deleteCarPassRecordById(Long id); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarChargeItemServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarChargeItemServiceImpl.java new file mode 100644 index 0000000..2c786db --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarChargeItemServiceImpl.java @@ -0,0 +1,102 @@ +package com.dcsoft.system.vehicle.service.impl; + +import com.dcsoft.system.vehicle.domain.CarChargeItem; +import com.dcsoft.system.vehicle.mapper.CarChargeItemMapper; +import com.dcsoft.system.vehicle.service.ICarChargeItemService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + + +/** + * 收费配置子项Service业务层处理 + * + * @author dcsoft + * @date 2024-01-24 + */ +@Service +public class CarChargeItemServiceImpl implements ICarChargeItemService +{ + @Autowired + private CarChargeItemMapper carChargeItemMapper; + + /** + * 查询收费配置子项 + * + * @param id 收费配置子项主键 + * @return 收费配置子项 + */ + @Override + public CarChargeItem selectCarChargeItemById(Long id) + { + return carChargeItemMapper.selectCarChargeItemById(id); + } + + /** + * 查询收费配置子项列表 + * + * @param carChargeItem 收费配置子项 + * @return 收费配置子项 + */ + @Override + public List selectCarChargeItemList(CarChargeItem carChargeItem) + { + return carChargeItemMapper.selectCarChargeItemList(carChargeItem); + } + + /** + * 新增收费配置子项 + * + * @param carChargeItem 收费配置子项 + * @return 结果 + */ + @Override + public int insertCarChargeItem(CarChargeItem carChargeItem) + { + return carChargeItemMapper.insertCarChargeItem(carChargeItem); + } + + /** + * 修改收费配置子项 + * + * @param carChargeItem 收费配置子项 + * @return 结果 + */ + @Override + public int updateCarChargeItem(CarChargeItem carChargeItem) + { + return carChargeItemMapper.updateCarChargeItem(carChargeItem); + } + + /** + * 批量删除收费配置子项 + * + * @param ids 需要删除的收费配置子项主键 + * @return 结果 + */ + @Override + public int deleteCarChargeItemByIds(Long[] ids) + { + return carChargeItemMapper.deleteCarChargeItemByIds(ids); + } + + /** + * 删除收费配置子项信息 + * + * @param id 收费配置子项主键 + * @return 结果 + */ + @Override + public int deleteCarChargeItemById(Long id) + { + return carChargeItemMapper.deleteCarChargeItemById(id); + } + + @Override + public int deleteChargeItemByChargeId(Long id) { + return carChargeItemMapper.deleteChargeItemByChargeId(id); + } + + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarChargeServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarChargeServiceImpl.java new file mode 100644 index 0000000..e18c1f8 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarChargeServiceImpl.java @@ -0,0 +1,97 @@ +package com.dcsoft.system.vehicle.service.impl; + +import com.dcsoft.common.core.utils.DateUtils; +import com.dcsoft.system.vehicle.domain.CarCharge; +import com.dcsoft.system.vehicle.mapper.CarChargeMapper; +import com.dcsoft.system.vehicle.service.ICarChargeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 收费配置Service业务层处理 + * + * @author nichun + * @date 2024-01-19 + */ +@Service +public class CarChargeServiceImpl implements ICarChargeService +{ + @Autowired + private CarChargeMapper carChargeMapper; + + /** + * 查询收费配置 + * + * @param id 收费配置主键 + * @return 收费配置 + */ + @Override + public CarCharge selectCarChargeById(Long id) + { + return carChargeMapper.selectCarChargeById(id); + } + + /** + * 查询收费配置列表 + * + * @param carCharge 收费配置 + * @return 收费配置 + */ + @Override + public List selectCarChargeList(CarCharge carCharge) + { + return carChargeMapper.selectCarChargeList(carCharge); + } + + /** + * 新增收费配置 + * + * @param carCharge 收费配置 + * @return 结果 + */ + @Override + public int insertCarCharge(CarCharge carCharge) + { + carCharge.setCreateTime(DateUtils.getNowDate()); + return carChargeMapper.insertCarCharge(carCharge); + } + + /** + * 修改收费配置 + * + * @param carCharge 收费配置 + * @return 结果 + */ + @Override + public int updateCarCharge(CarCharge carCharge) + { + carCharge.setUpdateTime(DateUtils.getNowDate()); + return carChargeMapper.updateCarCharge(carCharge); + } + + /** + * 批量删除收费配置 + * + * @param ids 需要删除的收费配置主键 + * @return 结果 + */ + @Override + public int deleteCarChargeByIds(Long[] ids) + { + return carChargeMapper.deleteCarChargeByIds(ids); + } + + /** + * 删除收费配置信息 + * + * @param id 收费配置主键 + * @return 结果 + */ + @Override + public int deleteCarChargeById(Long id) + { + return carChargeMapper.deleteCarChargeById(id); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarInfoServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarInfoServiceImpl.java new file mode 100644 index 0000000..b7a6c6b --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarInfoServiceImpl.java @@ -0,0 +1,340 @@ +package com.dcsoft.system.vehicle.service.impl; + +import com.dcsoft.common.core.exception.ServiceException; +import com.dcsoft.common.core.utils.DateUtils; +import com.dcsoft.common.core.utils.StringUtils; +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.domain.vo.SysAuthTree; +import com.dcsoft.system.mapper.SysPeopleMapper; +import com.dcsoft.system.vehicle.domain.CarInfo; +import com.dcsoft.system.vehicle.domain.CarPark; +import com.dcsoft.system.vehicle.domain.CarParkItem; +import com.dcsoft.system.vehicle.domain.CarParkRecord; +import com.dcsoft.system.vehicle.mapper.CarInfoMapper; +import com.dcsoft.system.vehicle.mapper.CarParkItemMapper; +import com.dcsoft.system.vehicle.mapper.CarParkMapper; +import com.dcsoft.system.vehicle.mapper.CarParkRecordMapper; +import com.dcsoft.system.vehicle.service.ICarInfoService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.regex.Pattern; + +/** + * 车辆信息Service业务层处理 + * + * @author nichun + * @date 2023-12-26 + */ +@Service +public class CarInfoServiceImpl implements ICarInfoService +{ + @Autowired + private CarInfoMapper carInfoMapper; + + @Autowired + private CarParkMapper carParkMapper; + + + @Autowired + private CarParkItemMapper carParkItemMapper; + + @Autowired + private CarParkRecordMapper carParkRecordMapper; + + @Autowired + private SysPeopleMapper peopleMapper; + + /** + * 查询车辆信息 + * + * @param customerId 车辆信息主键 + * @return 车辆信息 + */ + @Override + public CarInfo selectCarInfoByCustomerId(Long customerId) + { + return carInfoMapper.selectCarInfoByCustomerId(customerId); + } + + /** + * 查询车辆信息列表 + * + * @param carInfo 车辆信息 + * @return 车辆信息 + */ + @Override + public List selectCarInfoList(CarInfo carInfo) + { + return carInfoMapper.selectCarInfoList(carInfo); + } + + /** + * 新增车辆信息 + * + * @param carInfo 车辆信息 + * @return 结果 + */ + @Override + public int insertCarInfo(CarInfo carInfo) + { + carInfo.setCreateTime(DateUtils.getNowDate()); + return carInfoMapper.insertCarInfo(carInfo); + } + + /** + * 修改车辆信息 + * + * @param carInfo 车辆信息 + * @return 结果 + */ + @Override + public int updateCarInfo(CarInfo carInfo) + { + carInfo.setUpdateTime(DateUtils.getNowDate()); + return carInfoMapper.updateCarInfo(carInfo); + } + + /** + * 批量删除车辆信息 + * + * @param customerIds 需要删除的车辆信息主键 + * @return 结果 + */ + @Override + public int deleteCarInfoByCustomerIds(Long[] customerIds) + { + return carInfoMapper.deleteCarInfoByCustomerIds(customerIds); + } + + /** + * 删除车辆信息信息 + * + * @param customerId 车辆信息主键 + * @return 结果 + */ + @Override + public int deleteCarInfoByCustomerId(Long customerId) + { + return carInfoMapper.deleteCarInfoByCustomerId(customerId); + } + + @Override + public int addOrUpdate(SysPeople sysPeople) { + CarInfo carInfo=carInfoMapper.selectCarInfoByCarNo(sysPeople.getCarNo()); + if(carInfo==null){ + carInfo=new CarInfo(); + carInfo.setPeopleId(sysPeople.getId()); + List list=carParkMapper.selectCarParkList(new CarPark()); + CarPark park=list.get(0); + carInfo.setParkId(park.getId()); + carInfo.setPlate(sysPeople.getCarNo()); + carInfo.setEnableTime(new Date()); + Calendar calendar = new GregorianCalendar(); + Date date = new Date(); + calendar.setTime(date); + calendar.add(calendar.YEAR, 1);//把日期往后增加一年.整数往后推,负数往前移动 + date=calendar.getTime(); //这个时间就是日期往后推一天的结果 + carInfo.setOverdueTime(date); + carInfo.setEnable("1"); + carInfo.setTimeSegEnable("0"); + carInfo.setNeedAlarm("0"); + //根据车场查询车辆 + carInfoMapper.insertCarInfo(carInfo); + CarParkItem carParkItem=new CarParkItem(); + carParkItem.setParkId(carInfo.getParkId()); + List itemList=carParkItemMapper.selectCarParkItemList(carParkItem); + for(CarParkItem a:itemList){ + CarParkRecord carParkRecord=new CarParkRecord(); + carParkRecord.setCustomerId(carInfo.getCustomerId()); + carParkRecord.setParkId(carInfo.getParkId()); + carParkRecord.setEquipmentId(a.getEquipmentId()); + carParkRecordMapper.insertCarParkRecord(carParkRecord); + } + }/*else{ + carInfo.setPeopleId(sysPeople.getId()); + carInfo.setPlate(sysPeople.getCarNo()); + //根据车场查询车辆 + if(carInfo.getParkId()!=null){ + CarParkItem carParkItem=new CarParkItem(); + carParkItem.setParkId(carInfo.getParkId()); + List itemList=carParkItemMapper.selectCarParkItemList(carParkItem); + for(CarParkItem a:itemList){ + CarParkRecord carParkRecord=new CarParkRecord(); + carParkRecord.setCustomerId(carInfo.getCustomerId()); + carParkRecord.setParkId(carInfo.getParkId()); + carParkRecord.setEquipmentId(a.getEquipmentId()); + carParkRecordMapper.insertCarParkRecord(carParkRecord); + } + } + carInfoMapper.updateCarInfo(carInfo); + }*/ + return 0; + } + + @Override + public List selectTree() { + List tree=new ArrayList(); + List spaces =carParkMapper.selectCarParkList(new CarPark()); + for(CarPark s:spaces){ + List children=getChildren(s.getId()); + SysAuthTree a=new SysAuthTree(); + a.setId(s.getId()); + a.setLabel(s.getName()); + a.setType("0"); + a.setChildren(children); + tree.add(a); + } + + return tree; + } + + @Override + public List> carPlay(Long id) { + return carParkMapper.carPlay(id); + } + + @Override + public List> carPlayRecord(Long id) { + return carParkMapper.carPlayRecord(id); + } + + @Override + public int selectCarInfo(Long id,String flag) { + carParkMapper.deleteSelectCarInfo(id); + return carParkMapper.selectCarInfo(id,flag); + } + + private List getChildren(Long id) { + List tree=new ArrayList<>(); + List> points =carParkMapper.selectItemTreeList(id); + for(Map p:points){ + SysAuthTree a=new SysAuthTree(); + a.setId(Long.parseLong(p.get("id")+"")); + a.setLabel(p.get("name")+""); + a.setType("1"); + a.setParentId(id); + tree.add(a); + } + return tree; + } + + /** + * 导入用户数据 + * + * @param userList 用户数据列表 + * @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据 + * @param operName 操作用户 + * @return 结果 + */ + @Override + public String importData(List userList, boolean isUpdateSupport, String operName) + { + if (StringUtils.isNull(userList) || userList.size() == 0) + { + throw new ServiceException("导入用户数据不能为空!"); + } + int successNum = 0; + int failureNum = 0; + StringBuilder successMsg = new StringBuilder(); + StringBuilder failureMsg = new StringBuilder(); + int i=0; + for (CarInfo user : userList) + { + i++; + try + { + // 验证车牌是否合格 + if(!checkPlateNumberFormat(user.getPlate())){ + failureNum++; + failureMsg.append("
" + failureNum + "、车牌信息 " + user.getPlate() + "格式错误"); + }else{ + // 验证是否存在这个用户 + CarInfo u = carInfoMapper.selectCarInfoByCarNo(user.getPlate()); + SysPeople people=peopleMapper.selectSysPeopleByUserName(user.getPeopleName()); + if(people!=null){ + user.setPeopleId(people.getId()); + } + CarPark carPark=carParkMapper.selectCarParkByName(user.getParkName()); + if(carPark!=null){ + user.setParkId(carPark.getId()); + } + if (StringUtils.isNull(u)) + { + user.setCarType("0"); + user.setCreateBy(operName); + this.insertCarInfo(user); + //保存车辆授权 + //根据车场查询车辆 + if(user.getParkId()!=null){ + CarParkItem carParkItem=new CarParkItem(); + carParkItem.setParkId(user.getParkId()); + List itemList=carParkItemMapper.selectCarParkItemList(carParkItem); + for(CarParkItem a:itemList){ + CarParkRecord carParkRecord=new CarParkRecord(); + carParkRecord.setCustomerId(user.getCustomerId()); + carParkRecord.setParkId(user.getParkId()); + carParkRecord.setEquipmentId(a.getEquipmentId()); + carParkRecordMapper.insertCarParkRecord(carParkRecord); + } + } + successNum++; + successMsg.append("
" + successNum + "、车牌信息 " + user.getPlate() + " 导入成功"); + } + else if (isUpdateSupport) + { + user.setCarType("0"); + user.setCustomerId(u.getCustomerId()); + user.setUpdateBy(operName); + this.updateCarInfo(user); + //根据车场查询车辆 + if(user.getParkId()!=null){ + //删除车辆授权 + carParkRecordMapper.deleteCarParkRecordByCustomerId(user.getCustomerId()); + CarParkItem carParkItem=new CarParkItem(); + carParkItem.setParkId(user.getParkId()); + List itemList=carParkItemMapper.selectCarParkItemList(carParkItem); + for(CarParkItem a:itemList){ + CarParkRecord carParkRecord=new CarParkRecord(); + carParkRecord.setCustomerId(user.getCustomerId()); + carParkRecord.setParkId(user.getParkId()); + carParkRecord.setEquipmentId(a.getEquipmentId()); + carParkRecordMapper.insertCarParkRecord(carParkRecord); + } + } + successNum++; + successMsg.append("
" + successNum + "、车牌信息 " + user.getPlate() + " 更新成功"); + } + else + { + failureNum++; + failureMsg.append("
" + failureNum + "、车牌信息 " + user.getPlate() + " 已存在"); + } + } + } + catch (Exception e) + { + failureNum++; + String msg = "
" + failureNum + "、车牌信息 " + user.getPlate() + " 导入失败:"; + failureMsg.append(msg + e.getMessage()); + } + } + if (failureNum > 0) + { + failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:"); + throw new ServiceException(failureMsg.toString()); + } + else + { + successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:"); + } + return successMsg.toString(); + } + + public boolean checkPlateNumberFormat(String content) { + String pattern = "([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼]{1}(([A-HJ-Z]{1}[A-HJ-NP-Z0-9]{5})|([A-HJ-Z]{1}(([DF]{1}[A-HJ-NP-Z0-9]{1}[0-9]{4})|([0-9]{5}[DF]{1})))|([A-HJ-Z]{1}[A-D0-9]{1}[0-9]{3}警)))|([0-9]{6}使)|((([沪粤川云桂鄂陕蒙藏黑辽渝]{1}A)|鲁B|闽D|蒙E|蒙H)[0-9]{4}领)|(WJ[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼·•]{1}[0-9]{4}[TDSHBXJ0-9]{1})|([VKHBSLJNGCE]{1}[A-DJ-PR-TVY]{1}[0-9]{5})"; + return Pattern.matches(pattern, content); + } + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarParkItemServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarParkItemServiceImpl.java new file mode 100644 index 0000000..80ba438 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarParkItemServiceImpl.java @@ -0,0 +1,100 @@ +package com.dcsoft.system.vehicle.service.impl; + +import com.dcsoft.system.vehicle.domain.CarParkItem; +import com.dcsoft.system.vehicle.mapper.CarParkItemMapper; +import com.dcsoft.system.vehicle.service.ICarParkItemService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + + +/** + * 车场设备信息Service业务层处理 + * + * @author nichun + * @date 2023-12-28 + */ +@Service +public class CarParkItemServiceImpl implements ICarParkItemService +{ + @Autowired + private CarParkItemMapper carParkItemMapper; + + /** + * 查询车场设备信息 + * + * @param id 车场设备信息主键 + * @return 车场设备信息 + */ + @Override + public CarParkItem selectCarParkItemById(Long id) + { + return carParkItemMapper.selectCarParkItemById(id); + } + + /** + * 查询车场设备信息列表 + * + * @param carParkItem 车场设备信息 + * @return 车场设备信息 + */ + @Override + public List selectCarParkItemList(CarParkItem carParkItem) + { + return carParkItemMapper.selectCarParkItemList(carParkItem); + } + + /** + * 新增车场设备信息 + * + * @param carParkItem 车场设备信息 + * @return 结果 + */ + @Override + public int insertCarParkItem(CarParkItem carParkItem) + { + return carParkItemMapper.insertCarParkItem(carParkItem); + } + + /** + * 修改车场设备信息 + * + * @param carParkItem 车场设备信息 + * @return 结果 + */ + @Override + public int updateCarParkItem(CarParkItem carParkItem) + { + return carParkItemMapper.updateCarParkItem(carParkItem); + } + + /** + * 批量删除车场设备信息 + * + * @param ids 需要删除的车场设备信息主键 + * @return 结果 + */ + @Override + public int deleteCarParkItemByIds(Long[] ids) + { + return carParkItemMapper.deleteCarParkItemByIds(ids); + } + + /** + * 删除车场设备信息信息 + * + * @param id 车场设备信息主键 + * @return 结果 + */ + @Override + public int deleteCarParkItemById(Long id) + { + return carParkItemMapper.deleteCarParkItemById(id); + } + + @Override + public int deleteParkItemByParkId(Long parkId) { + return carParkItemMapper.deleteParkItemByParkId(parkId); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarParkRecordServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarParkRecordServiceImpl.java new file mode 100644 index 0000000..69f6d3c --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarParkRecordServiceImpl.java @@ -0,0 +1,113 @@ +package com.dcsoft.system.vehicle.service.impl; + +import com.dcsoft.system.vehicle.domain.CarParkRecord; +import com.dcsoft.system.vehicle.mapper.CarParkRecordMapper; +import com.dcsoft.system.vehicle.service.ICarParkRecordService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + + +/** + * 车辆授权Service业务层处理 + * + * @author dcsoft + * @date 2023-12-29 + */ +@Service +public class CarParkRecordServiceImpl implements ICarParkRecordService +{ + @Autowired + private CarParkRecordMapper carParkRecordMapper; + + /** + * 查询车辆授权 + * + * @param id 车辆授权主键 + * @return 车辆授权 + */ + @Override + public CarParkRecord selectCarParkRecordById(Long id) + { + return carParkRecordMapper.selectCarParkRecordById(id); + } + + /** + * 查询车辆授权列表 + * + * @param carParkRecord 车辆授权 + * @return 车辆授权 + */ + @Override + public List selectCarParkRecordList(CarParkRecord carParkRecord) + { + return carParkRecordMapper.selectCarParkRecordList(carParkRecord); + } + + /** + * 新增车辆授权 + * + * @param carParkRecord 车辆授权 + * @return 结果 + */ + @Override + public int insertCarParkRecord(CarParkRecord carParkRecord) + { + return carParkRecordMapper.insertCarParkRecord(carParkRecord); + } + + /** + * 修改车辆授权 + * + * @param carParkRecord 车辆授权 + * @return 结果 + */ + @Override + public int updateCarParkRecord(CarParkRecord carParkRecord) + { + return carParkRecordMapper.updateCarParkRecord(carParkRecord); + } + + /** + * 批量删除车辆授权 + * + * @param ids 需要删除的车辆授权主键 + * @return 结果 + */ + @Override + public int deleteCarParkRecordByIds(Long[] ids) + { + return carParkRecordMapper.deleteCarParkRecordByIds(ids); + } + + /** + * 删除车辆授权信息 + * + * @param id 车辆授权主键 + * @return 结果 + */ + @Override + public int deleteCarParkRecordById(Long id) + { + return carParkRecordMapper.deleteCarParkRecordById(id); + } + + @Override + public int deleteCarParkRecordByParkId(Long parkId) { + return carParkRecordMapper.deleteCarParkRecordByParkId(parkId); + } + + @Override + public int deleteCarParkRecordByCustomerIds(Long[] ids) + { + return carParkRecordMapper.deleteCarParkRecordByCustomerIds(ids); + } + + @Override + public int deleteCarParkRecordByCustomerId(Long customerId) { + return carParkRecordMapper.deleteCarParkRecordByCustomerId(customerId); + } + + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarParkServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarParkServiceImpl.java new file mode 100644 index 0000000..ab3adb1 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarParkServiceImpl.java @@ -0,0 +1,97 @@ +package com.dcsoft.system.vehicle.service.impl; + +import com.dcsoft.common.core.utils.DateUtils; +import com.dcsoft.system.vehicle.domain.CarPark; +import com.dcsoft.system.vehicle.mapper.CarParkMapper; +import com.dcsoft.system.vehicle.service.ICarParkService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 车场信息Service业务层处理 + * + * @author nichun + * @date 2023-12-27 + */ +@Service +public class CarParkServiceImpl implements ICarParkService +{ + @Autowired + private CarParkMapper carParkMapper; + + /** + * 查询车场信息 + * + * @param id 车场信息主键 + * @return 车场信息 + */ + @Override + public CarPark selectCarParkById(Long id) + { + return carParkMapper.selectCarParkById(id); + } + + /** + * 查询车场信息列表 + * + * @param carPark 车场信息 + * @return 车场信息 + */ + @Override + public List selectCarParkList(CarPark carPark) + { + return carParkMapper.selectCarParkList(carPark); + } + + /** + * 新增车场信息 + * + * @param carPark 车场信息 + * @return 结果 + */ + @Override + public int insertCarPark(CarPark carPark) + { + carPark.setCreateTime(DateUtils.getNowDate()); + return carParkMapper.insertCarPark(carPark); + } + + /** + * 修改车场信息 + * + * @param carPark 车场信息 + * @return 结果 + */ + @Override + public int updateCarPark(CarPark carPark) + { + carPark.setUpdateTime(DateUtils.getNowDate()); + return carParkMapper.updateCarPark(carPark); + } + + /** + * 批量删除车场信息 + * + * @param ids 需要删除的车场信息主键 + * @return 结果 + */ + @Override + public int deleteCarParkByIds(Long[] ids) + { + return carParkMapper.deleteCarParkByIds(ids); + } + + /** + * 删除车场信息信息 + * + * @param id 车场信息主键 + * @return 结果 + */ + @Override + public int deleteCarParkById(Long id) + { + return carParkMapper.deleteCarParkById(id); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarPassGatherServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarPassGatherServiceImpl.java new file mode 100644 index 0000000..a2b9bfe --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarPassGatherServiceImpl.java @@ -0,0 +1,100 @@ +package com.dcsoft.system.vehicle.service.impl; + +import com.dcsoft.system.vehicle.domain.CarPassGather; +import com.dcsoft.system.vehicle.mapper.CarPassGatherMapper; +import com.dcsoft.system.vehicle.service.ICarPassGatherService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * 在场记录Service业务层处理 + * + * @author nichun + * @date 2024-01-08 + */ +@Service +public class CarPassGatherServiceImpl implements ICarPassGatherService +{ + @Autowired + private CarPassGatherMapper carPassGatherMapper; + + /** + * 查询在场记录 + * + * @param id 在场记录主键 + * @return 在场记录 + */ + @Override + public CarPassGather selectCarPassGatherById(Long id) + { + return carPassGatherMapper.selectCarPassGatherById(id); + } + + /** + * 查询在场记录列表 + * + * @param carPassGather 在场记录 + * @return 在场记录 + */ + @Override + public List selectCarPassGatherList(CarPassGather carPassGather) + { + return carPassGatherMapper.selectCarPassGatherList(carPassGather); + } + + /** + * 新增在场记录 + * + * @param carPassGather 在场记录 + * @return 结果 + */ + @Override + public int insertCarPassGather(CarPassGather carPassGather) + { + return carPassGatherMapper.insertCarPassGather(carPassGather); + } + + /** + * 修改在场记录 + * + * @param carPassGather 在场记录 + * @return 结果 + */ + @Override + public int updateCarPassGather(CarPassGather carPassGather) + { + return carPassGatherMapper.updateCarPassGather(carPassGather); + } + + /** + * 批量删除在场记录 + * + * @param ids 需要删除的在场记录主键 + * @return 结果 + */ + @Override + public int deleteCarPassGatherByIds(Long[] ids) + { + return carPassGatherMapper.deleteCarPassGatherByIds(ids); + } + + /** + * 删除在场记录信息 + * + * @param id 在场记录主键 + * @return 结果 + */ + @Override + public int deleteCarPassGatherById(Long id) + { + return carPassGatherMapper.deleteCarPassGatherById(id); + } + + @Override + public List> parkTop(Long parkId) { + return carPassGatherMapper.parkTop(parkId); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarPassRecordServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarPassRecordServiceImpl.java new file mode 100644 index 0000000..115aee6 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/vehicle/service/impl/CarPassRecordServiceImpl.java @@ -0,0 +1,95 @@ +package com.dcsoft.system.vehicle.service.impl; + +import com.dcsoft.system.vehicle.domain.CarPassRecord; +import com.dcsoft.system.vehicle.mapper.CarPassRecordMapper; +import com.dcsoft.system.vehicle.service.ICarPassRecordService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + + +/** + * 通行记录Service业务层处理 + * + * @author nichun + * @date 2024-01-03 + */ +@Service +public class CarPassRecordServiceImpl implements ICarPassRecordService +{ + @Autowired + private CarPassRecordMapper carPassRecordMapper; + + /** + * 查询通行记录 + * + * @param id 通行记录主键 + * @return 通行记录 + */ + @Override + public CarPassRecord selectCarPassRecordById(Long id) + { + return carPassRecordMapper.selectCarPassRecordById(id); + } + + /** + * 查询通行记录列表 + * + * @param carPassRecord 通行记录 + * @return 通行记录 + */ + @Override + public List selectCarPassRecordList(CarPassRecord carPassRecord) + { + return carPassRecordMapper.selectCarPassRecordList(carPassRecord); + } + + /** + * 新增通行记录 + * + * @param carPassRecord 通行记录 + * @return 结果 + */ + @Override + public int insertCarPassRecord(CarPassRecord carPassRecord) + { + return carPassRecordMapper.insertCarPassRecord(carPassRecord); + } + + /** + * 修改通行记录 + * + * @param carPassRecord 通行记录 + * @return 结果 + */ + @Override + public int updateCarPassRecord(CarPassRecord carPassRecord) + { + return carPassRecordMapper.updateCarPassRecord(carPassRecord); + } + + /** + * 批量删除通行记录 + * + * @param ids 需要删除的通行记录主键 + * @return 结果 + */ + @Override + public int deleteCarPassRecordByIds(Long[] ids) + { + return carPassRecordMapper.deleteCarPassRecordByIds(ids); + } + + /** + * 删除通行记录信息 + * + * @param id 通行记录主键 + * @return 结果 + */ + @Override + public int deleteCarPassRecordById(Long id) + { + return carPassRecordMapper.deleteCarPassRecordById(id); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/controller/VisVisitorExamineController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/controller/VisVisitorExamineController.java new file mode 100644 index 0000000..2dc917f --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/controller/VisVisitorExamineController.java @@ -0,0 +1,100 @@ +package com.dcsoft.system.visitor.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.dcsoft.system.visitor.domain.VisVisitorExamine; +import com.dcsoft.system.visitor.service.IVisVisitorExamineService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.page.TableDataInfo; + +/** + * 访客审核Controller + * + * @author nichun + * @date 2023-03-11 + */ +@RestController +@RequestMapping("/visitorExamine") +public class VisVisitorExamineController extends BaseController +{ + @Autowired + private IVisVisitorExamineService visVisitorExamineService; + + /** + * 查询访客审核列表 + */ + @RequiresPermissions("visitor:visitorExamine:list") + @GetMapping("/list") + public TableDataInfo list(VisVisitorExamine visVisitorExamine) + { + startPage(); + List list = visVisitorExamineService.selectVisVisitorExamineList(visVisitorExamine); + return getDataTable(list); + } + + /** + * 导出访客审核列表 + */ + @Log(title = "访客审核", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, VisVisitorExamine visVisitorExamine) + { + List list = visVisitorExamineService.selectVisVisitorExamineList(visVisitorExamine); + ExcelUtil util = new ExcelUtil(VisVisitorExamine.class); + util.exportExcel(response, list, "访客审核数据"); + } + + /** + * 获取访客审核详细信息 + */ + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(visVisitorExamineService.selectVisVisitorExamineById(id)); + } + + /** + * 新增访客审核 + */ + @Log(title = "访客审核", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody VisVisitorExamine visVisitorExamine) + { + return toAjax(visVisitorExamineService.insertVisVisitorExamine(visVisitorExamine)); + } + + /** + * 修改访客审核 + */ + @Log(title = "访客审核", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody VisVisitorExamine visVisitorExamine) + { + return toAjax(visVisitorExamineService.updateVisVisitorExamine(visVisitorExamine)); + } + + /** + * 删除访客审核 + */ + @Log(title = "访客审核", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(visVisitorExamineService.deleteVisVisitorExamineByIds(ids)); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/controller/VisVisitorRegisterController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/controller/VisVisitorRegisterController.java new file mode 100644 index 0000000..fe4ea9d --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/controller/VisVisitorRegisterController.java @@ -0,0 +1,98 @@ +package com.dcsoft.system.visitor.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.dcsoft.system.visitor.domain.VisVisitorRegister; +import com.dcsoft.system.visitor.service.IVisVisitorRegisterService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.web.page.TableDataInfo; + +/** + * 访客注册Controller + * + * @author dcsoft + * @date 2024-05-21 + */ +@RestController +@RequestMapping("/register") +public class VisVisitorRegisterController extends BaseController { + @Autowired + private IVisVisitorRegisterService visVisitorRegisterService; + + /** + * 查询访客注册列表 + */ + @RequiresPermissions("system:register:list") + @GetMapping("/list") + public TableDataInfo list(VisVisitorRegister visVisitorRegister) { + startPage(); + List list = visVisitorRegisterService.selectVisVisitorRegisterList(visVisitorRegister); + return getDataTable(list); + } + + /** + * 导出访客注册列表 + */ + @RequiresPermissions("system:register:export") + @Log(title = "访客注册", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, VisVisitorRegister visVisitorRegister) { + List list = visVisitorRegisterService.selectVisVisitorRegisterList(visVisitorRegister); + ExcelUtil util = new ExcelUtil(VisVisitorRegister.class); + util.exportExcel(response, list, "访客注册数据"); + } + + /** + * 获取访客注册详细信息 + */ + @RequiresPermissions("system:register:query") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") String id) { + return success(visVisitorRegisterService.selectVisVisitorRegisterById(id)); + } + + /** + * 新增访客注册 + */ + @RequiresPermissions("system:register:add") + @Log(title = "访客注册", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody VisVisitorRegister visVisitorRegister) { + return toAjax(visVisitorRegisterService.insertVisVisitorRegister(visVisitorRegister)); + } + + /** + * 修改访客注册 + */ + @RequiresPermissions("system:register:edit") + @Log(title = "访客注册", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody VisVisitorRegister visVisitorRegister) { + return toAjax(visVisitorRegisterService.updateVisVisitorRegister(visVisitorRegister)); + } + + /** + * 删除访客注册 + */ + @RequiresPermissions("system:register:remove") + @Log(title = "访客注册", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable String[] ids) { + return toAjax(visVisitorRegisterService.deleteVisVisitorRegisterByIds(ids)); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/controller/VisitorController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/controller/VisitorController.java new file mode 100644 index 0000000..04ef7b8 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/controller/VisitorController.java @@ -0,0 +1,1227 @@ +package com.dcsoft.system.visitor.controller; + +import cn.hutool.http.HttpException; +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.dcsoft.common.core.constant.CacheConstants; +import com.dcsoft.common.core.constant.Constants; +import com.dcsoft.common.core.enums.exception.CommonExceptionEnum; +import com.dcsoft.common.core.exception.ServiceException; +import com.dcsoft.common.core.utils.SpringUtils; +import com.dcsoft.common.core.utils.poi.ExcelUtil; +import com.dcsoft.common.core.utils.uuid.IdUtils; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDataInfo; +import com.dcsoft.common.log.annotation.Log; +import com.dcsoft.common.log.enums.BusinessType; +import com.dcsoft.common.redis.service.RedisService; +import com.dcsoft.common.security.annotation.RequiresPermissions; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.common.sms.config.properties.SmsProperties; +import com.dcsoft.common.sms.entity.SmsResult; +import com.dcsoft.common.sms.service.SmsTemplate; +import com.dcsoft.system.api.model.LoginUser; +import com.dcsoft.system.domain.*; +import com.dcsoft.system.domain.vo.OfficialAccountVo; +import com.dcsoft.system.domain.vo.SysFileVo; +import com.dcsoft.system.service.*; +import com.dcsoft.system.uniubi.domain.DingtalkMsgVo; +import com.dcsoft.system.uniubi.domain.Person; +import com.dcsoft.system.uniubi.service.ISysApiService; +import com.dcsoft.system.uniubi.service.ISysSdkService; +import com.dcsoft.system.utils.FileUtils; +import com.dcsoft.system.visitor.domain.CheckCodeVo; +import com.dcsoft.system.visitor.domain.VisVisitorExamine; +import com.dcsoft.system.visitor.domain.Visitor; +import com.dcsoft.system.visitor.domain.VisitorRecordVo; +import com.dcsoft.system.visitor.service.IVisVisitorExamineService; +import com.dcsoft.system.visitor.service.IVisitorService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * 访客信息Controller + * + * @author 倪春 + * @date 2023-03-09 + */ +@Slf4j +@RestController +@RequestMapping("/visitor") +public class VisitorController extends BaseController { + @Autowired + private IVisitorService visitorService; + + @Autowired + private ISysApiService sysApiService; + + @Autowired + private IVisVisitorExamineService visVisitorExamineService; + + @Autowired + private SmsProperties smsProperties; + + @Autowired + private ISysBlackListService sysBlackListService; + + @Autowired + private ISysConfigService configService; + + @Autowired + protected ISysSdkService sdkService; + + @Autowired + private ISysEquipmentService equipmentService; + + @Autowired + private ISysPeopleService sysPeopleService; + + @Autowired + private RedisService redisService; + + @Autowired + private ISysRuleService sysRuleService; + + @Autowired + private ISysPeopleEquipmentService peopleEquipmentService; + + @Autowired + private ISysBranchService sysBranchService; + + @Autowired + private ISysDictDataService dictDataService; + + @Value("${qd.url}") + public String qdUrl; + + @Value("${dingTalk.getToken}") + public String getToken; + + @Value("${dingTalk.asyncsendV2}") + public String asyncsendV2; + + @Value("${dingTalk.agentId}") + public String dingAgentId; + + @Value("${weixin.token}") + public String weixinToken; + + @Value("${weixin.send}") + public String weixinSend; + + @Value("${system.type}") + public String systemType; + + @Value("${sdk.saveVisitor}") + public String saveVisitor; + + @Value("${sdk.updateVisitorExamine}") + public String updateVisitorExamine; + + @Value("${sdk.saveVisitorAuditing}") + public String saveVisitorAuditing; + + @Value("${sdk.upload}") + public String upload; + + @Value("${photo.url}") + public String url; + + @Value("${property_dep_id}") + public String propertyDepId; + + @Value("${minio.url}") + public String minioUrl; + + @Value("${minio.gwurl}") + public String minioGwurl; + + @Value("${applet.appid}") + public String appid; + + @Value("${applet.secret}") + public String secret; + + @Value("${weCom.corpid}") + public String corpid; + + @Value("${weCom.corpsecret}") + public String weComSecret; + + @Value("${weCom.agentid}") + public String weComAgentid; + + // 正则表达式匹配大部分国家的手机号码格式 + private static final Pattern PHONE_NUMBER_PATTERN = Pattern.compile("^1[3-9]\\d{9}$"); + + /** + * 查询访客信息列表 + */ +// @RequiresPermissions("visitor:visitor:list") + @GetMapping("/list") + public TableDataInfo list(Visitor visitor) { + if(StringUtils.isNotEmpty(visitor.getTabFlag())) { + if(StringUtils.isEmpty(visitor.getPeoplePhone())) { + Long userId = SecurityUtils.getUserId(); + if(userId > 1) { + List people = sysPeopleService.querySysPeopleInfo(userId); + if(CollectionUtils.isEmpty(people)) { + return getDataTable(new ArrayList<>()); + } + String collect = people.stream().map(SysPeople::getPhone).collect(Collectors.joining(",")); + visitor.setPeoplePhone(collect); + String collected = people.stream().map(e -> String.valueOf(e.getId())).collect(Collectors.joining(",")); + visitor.setNextStepReviewer(collected); + } + } else { + SysPeople sysPeople = sysPeopleService.queryPeopleName(visitor.getPeoplePhone(), new ArrayList<>()); + if(sysPeople != null) { +// visitor.setPosition(sysPeople.getPosition()); + visitor.setNextStepReviewer(String.valueOf(sysPeople.getId())); + } + } + } + + startPage(); + List list = visitorService.selectVisitorList(visitor); + Map map = dictDataService.queryDictData("sys_company_type"); + List sysBranches = sysBranchService.queryPropertyDept(null); + Map collect = sysBranches.stream().collect(Collectors.toMap(SysBranch::getId, SysBranch::getName)); + for (Visitor visitor1 : list) { + String s = map.get(visitor1.getDeptId()); + if(StringUtils.isNotEmpty(s)) { + visitor1.setDeptName(s); + continue; + } + visitor1.setDeptName(collect.get(visitor1.getDeptId())); + } + return getDataTable(list); + } + + /** + * 导出访客信息列表 + */ + @RequiresPermissions("visitor:visitor:export") + @Log(title = "访客信息", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, Visitor visitor) { + List list = visitorService.selectVisitorList(visitor); + ExcelUtil util = new ExcelUtil(Visitor.class); + util.exportExcel(response, list, "访客信息数据"); + } + + /** + * 获取访客信息详细信息(详情) + */ + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) { + Visitor visitor = visitorService.selectVisitorById(id); + return success(visitor); + } + + @GetMapping(value = "/queryVisitorById") + public AjaxResult queryVisitorById(Long id) { + Visitor visitor = visitorService.selectVisitorById(id); + return success(visitor); + } + + /** + * 新增访客信息 + */ + @Log(title = "访客信息", businessType = BusinessType.INSERT) + @PostMapping + @Transactional + public AjaxResult add(@RequestBody Visitor visitor) throws Exception { + if (visitor.getStartTime().getTime() > visitor.getEndTime().getTime()) { + throw new ServiceException("您输入的开始时间不能大于结束时间"); + } + + if (visitorService.queryVisitorByIdCount(visitor.getPhone()) > 0) { + throw new ServiceException("该手机号已存在访客预约信息"); + } + + if (visitorService.queryVisitor(visitor) > 0) { + throw new ServiceException("您已预约"); + } + + // 校验图片 +// checkPhoto(visitor.getAvatar(), visitor.getName()); + + log.info("新增访客信息:{}", visitor); + int i = visitorService.insertVisitor(visitor); + List itemList = visitor.getItemList(); + // 随访人员 + if (!CollectionUtils.isEmpty(itemList)) { + for (Visitor item : itemList) { + if (!validatePhoneNumber(item.getPhone())) { + throw new ServiceException("您输入的随访人员手机号格式不正确"); + } + // 校验图片 +// checkPhoto(item.getAvatar(), item.getName()); + item.setParentId(visitor.getId()); + item.setSource(Constants.ONE); + item.setUserId(visitor.getUserId()); + item.setDeptId(visitor.getDeptId()); + item.setCreateTime(visitor.getCreateTime()); + item.setStartTime(visitor.getStartTime()); + item.setEndTime(visitor.getEndTime()); + visitorService.insertVisitor(item); + } + } + + // 保存附件 + if(!CollectionUtils.isEmpty(visitor.getFileList())) { + saveSysFile(visitor.getFileList(), String.valueOf(visitor.getId())); + } + + // 审核通知企微发送消息(小程序来源) + String appletLink = getAppletLink(String.valueOf(visitor.getId()), "pages/visitor/visitor/examineIndex"); + SysPeople sysPeople = sysPeopleService.selectSysPeopleByUserId(visitor.getUserId()); + log.info("审核通知链接:{}", appletLink); + sendWeCom(sysPeople.getPhone(), appletLink + " --访客姓名:" + visitor.getName()); + + // 访客审核 + SysBranch sysBranch = sysBranchService.selectSysBranchById(visitor.getDeptId()); + if(sysBranch != null && Constants.ZERO.equals(sysBranch.getIsExamine())) { + VisVisitorExamine examine = new VisVisitorExamine(); + examine.setExamine(Constants.ZERO); + visitor.setExamine(examine); + updateVisitorExamine(visitor); + } + return toAjax(i); + } + + /** + * 保存附件 + */ + private void saveSysFile(List fileList, String visitorId) { + SysFileVo sysFile = new SysFileVo(); + sysFile.setBusinessId(visitorId); + sysFile.setBusinessType("sys_visitor_insurance"); + visitorService.deleteFile(sysFile); + List sysFiles = new ArrayList<>(); + for (SysFileVo fileVo : fileList) { + SysFileVo file = new SysFileVo(); + file.setBusinessId(visitorId); + file.setFileName(fileVo.getFileName()); + file.setUrl(fileVo.getUrl()); + file.setBusinessType("sys_visitor_insurance"); + file.setId(UUID.randomUUID().toString().replace("-", "")); + sysFiles.add(file); + } + visitorService.saveFile(sysFiles); + + } + + /** + * 验证手机号码是否有效 + * + * @param number 要验证的手机号码 + * @return 如果手机号码有效返回true,否则返回false + */ + public boolean validatePhoneNumber(String number) { + return PHONE_NUMBER_PATTERN.matcher(number).matches(); + } + + /** + * 钉工牌消息通知 + */ + private void asyncsendV2(String phone, String msgType, String content) { + DingtalkMsgVo msgVo = new DingtalkMsgVo(); + DingtalkMsgVo.Text text = new DingtalkMsgVo.Text(); + text.setContent(content); + msgVo.setMsgtype(msgType); + msgVo.setText(text); + Map map = new HashMap<>(); + map.put("agent_id", dingAgentId); + map.put("msg", msgVo); + map.put("userid_list", getDingUserId(phone)); + String body = HttpUtil.createPost(asyncsendV2 + "?access_token=" + getToken()) + .body(JSON.toJSONString(map)) + .execute() + .body(); + JSONObject object = JSONObject.parseObject(body); + log.info("钉工牌消息通知接口返回结果:" + body); + if (!Constants.ZERO.equals(object.get("errcode").toString())) { + log.error("钉工牌消息通知接口异常码:" + object.get("errcode").toString()); + //throw new ServiceException(CommonExceptionEnum.REQUEST_ERROR.getCode(), "钉工牌消息通知接口" + CommonExceptionEnum.REQUEST_ERROR.getMessage()); + } + + } + + /** + * 通过手机号获取userId(钉钉) + * @param phone + * @return + */ + private String getDingUserId(String phone) { + Map map = new HashMap<>(); + map.put("mobile", phone); + String body = HttpUtil.createPost("https://oapi.dingtalk.com/topapi/v2/user/getbymobile?access_token=" + getToken()) + .body(JSON.toJSONString(map)) + .execute() + .body(); + JSONObject object = JSON.parseObject(body); + if(!Constants.ZERO.equals(object.get("errcode").toString())) { + throw new ServiceException(CommonExceptionEnum.REQUEST_ERROR.getCode(), "通过手机号获取userId(钉钉)" + CommonExceptionEnum.REQUEST_ERROR.getMessage()); + } + String string = object.get("result").toString(); + JSONObject jsonObject = JSON.parseObject(string); + return jsonObject.get("userid").toString(); + } + + /** + * 获取钉工牌token + */ + private String getToken() { + String body = HttpUtil.createGet(getToken).execute().body(); + JSONObject object = JSONObject.parseObject(body); + return object.get("access_token").toString(); + } + + /** + * 获取微信公众号token + * + * @return + */ + private String getWxToken() { + String cacheObject = redisService.getCacheObject(CacheConstants.WEIXIN_TOKEN); + if (StringUtils.isNotEmpty(cacheObject)) { + return cacheObject; + } + String body = HttpUtil.createGet(weixinToken).execute().body(); + JSONObject object = JSONObject.parseObject(body); + String string = object.get("access_token").toString(); + redisService.setCacheObject(CacheConstants.LOGIN_TOKEN, string, Long.valueOf(object.get("expires_in").toString()), TimeUnit.SECONDS); + return string; + } + + private void weixinSend(String openId, String wxToken, String url) { + String s = Constants.CONTENT.replaceAll("%", openId); + String s1 = s.replaceAll("#", url); + String body = HttpUtil.createPost(weixinSend + wxToken) + .body(s1) + .execute() + .body(); + JSONObject object = JSON.parseObject(body); + if (!"0".equals(object.get("errcode").toString())) { + log.error("微信公众号消息通知接口异常"); + throw new ServiceException(CommonExceptionEnum.REQUEST_ERROR.getCode(), "微信公众号消息通知接口" + CommonExceptionEnum.REQUEST_ERROR.getMessage() + object.get("errcode").toString()); + } + } + + /** + * 获取小程序token + * @return + */ + private String getAppletToken() { + String body = HttpUtil.createGet("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+ appid +"&secret=" + secret).execute().body(); + JSONObject object = JSON.parseObject(body); + String string = object.get("access_token").toString(); + return string; + } + + /** + * 生成微信小程序链接 + * @return + */ + private String getAppletLink(String id, String path) { + Map map = new HashMap<>(); + map.put("path", path); + map.put("query", "id=" + id); + map.put("is_expire", true); + map.put("expire_type", 1); + map.put("expire_interval", 1); + map.put("env_version", "release"); +// map.put("env_version", "trial"); + String body = HttpUtil + .createPost("https://api.weixin.qq.com/wxa/generate_urllink?access_token=" + getAppletToken()) + .body(JSON.toJSONString(map)) + .execute() + .body(); + JSONObject object = JSON.parseObject(body); + String string = object.get("errcode").toString(); + if(!"0".equals(string)) { + throw new ServiceException(CommonExceptionEnum.REQUEST_ERROR.getCode(), "生成微信小程序链接接口" + CommonExceptionEnum.REQUEST_ERROR.getMessage() + object.get("errcode").toString()); + } + return object.get("url_link").toString(); + } + + /** + * 查询加密URLLink + * @param urlLink + * @return + * @throws Exception + */ + @GetMapping("/queryUrlLink") + public AjaxResult queryUrlLink(String urlLink) throws Exception { + String cacheObject = redisService.getCacheObject(CacheConstants.WEIXIN_URL_LINK + urlLink); + if(StringUtils.isEmpty(cacheObject)) { + return AjaxResult.success(); + } + Map map = new HashMap<>(); + map.put("url_link", cacheObject); + map.put("query_type", 0); + String body = HttpUtil.createPost("https://api.weixin.qq.com/wxa/query_urllink?access_token=" + getAppletToken()) + .body(JSON.toJSONString(map)) + .execute() + .body(); + JSONObject object = JSON.parseObject(body); + if(!"0".equals(object.get("errcode").toString())) { + throw new ServiceException(CommonExceptionEnum.REQUEST_ERROR.getCode(), "查询加密URLLink" + CommonExceptionEnum.REQUEST_ERROR.getMessage() + object.get("errcode").toString()); + } + String string = object.get("url_link_info").toString(); + JSONObject jsonObject = JSON.parseObject(string); + return AjaxResult.success(jsonObject.get("query")); + } + + /** + * 企微消息发送 + * @param phone + * @param content + */ + private void sendWeCom(String phone, String content) { + // 获取userId + String weComUserId = getWeComUserId(phone); + DingtalkMsgVo.Text text = new DingtalkMsgVo.Text(); + text.setContent(content); + Map map = new HashMap<>(); + map.put("touser", weComUserId); + map.put("msgtype", "text"); + map.put("agentid", weComAgentid); + map.put("text", text); + map.put("safe", 0); + map.put("enable_id_trans", 0); + map.put("enable_duplicate_check", 0); + map.put("duplicate_check_interval", 1800); + String body = HttpUtil.createPost("https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + getWeComToken()) + .body(JSON.toJSONString(map)) + .execute() + .body(); + JSONObject object = JSON.parseObject(body); + log.info("企微消息发送结果:{}", body); + if(!Constants.ZERO.equals(object.get("errcode").toString())) { + log.error("企微消息发送失败" + object.get("errcode").toString()); + } + } + + /** + * 更具手机号获取userId + * @param phone + * @return + */ + private String getWeComUserId(String phone) { + Map map = new HashMap<>(); + map.put("mobile", phone); + String body = HttpUtil.createPost("https://qyapi.weixin.qq.com/cgi-bin/user/getuserid?access_token=" + getWeComToken()) + .body(JSON.toJSONString(map)) + .execute() + .body(); + JSONObject object = JSON.parseObject(body); + if(!Constants.ZERO.equals(object.get("errcode").toString())) { + log.error("更具手机号获取userId" + object); + throw new ServiceException(CommonExceptionEnum.REQUEST_ERROR.getCode(), "获取企微userId" + CommonExceptionEnum.REQUEST_ERROR.getMessage() + object.get("errcode").toString()); + } + return object.get("userid").toString(); + } + + + /** + * 获取企微token + * @return + */ + private String getWeComToken() { + String cacheObject = redisService.getCacheObject(CacheConstants.WE_COM_TOKEN); + if (StringUtils.isNotEmpty(cacheObject)) { + return cacheObject; + } + String body = HttpUtil.createGet("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + corpid + "&corpsecret=" + weComSecret).execute().body(); + JSONObject object = JSON.parseObject(body); + if(!Constants.ZERO.equals(object.get("errcode").toString())) { + throw new ServiceException(CommonExceptionEnum.REQUEST_ERROR.getCode(), "获取企微token" + CommonExceptionEnum.REQUEST_ERROR.getMessage() + object.get("errcode").toString()); + } + String string = object.get("access_token").toString(); + redisService.setCacheObject(CacheConstants.WE_COM_TOKEN, string, 7000L, TimeUnit.SECONDS); + return string; + + } + + + /** + * 获取时间 + * + * @param startDate + * @param endDate + */ + private List getTime(String startDate, String endDate) throws ParseException { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + LocalDate start = LocalDate.parse(startDate); + LocalDate end = LocalDate.parse(endDate); + List list = new ArrayList<>(); + while (!start.isAfter(end)) { + Visitor gather = new Visitor(); + gather.setCreateTime(sdf.parse(start.toString())); + list.add(gather); + start = start.plusDays(1); + } + return list; + } + + /** + * 新增访客信息 + */ + @Log(title = "访客信息", businessType = BusinessType.INSERT) + @PostMapping("/add") + public AjaxResult addVis(@RequestBody Visitor visitor) { + int i = visitorService.insertVisitor(visitor); + List itemList = visitor.getItemList(); + for (Visitor item : itemList) { + item.setParentId(visitor.getId()); + //随访人员增加人员注册 +// item=admitCreate(item); + visitorService.insertVisitor(item); + } + return toAjax(i); + } + + private Visitor admitCreate(Visitor item) { + String cloud = configService.selectConfigByKey("sys.equipment.cloud"); + if ("true".equals(cloud)) { + String data = sysApiService.admitCreate(item); + JSONObject json = JSONObject.parseObject(data); + if ("1".equals(json.get("result") + "")) { + JSONObject obj = (JSONObject) json.get("data"); + String admitGuid = obj.get("admitGuid") + ""; + item.setGuid(admitGuid); + //人像注册,如果注册失败将人像置空 + if (StringUtils.isNotEmpty(item.getAvatar())) { + String datas = sysApiService.faceRegister(item); + JSONObject jsons = JSONObject.parseObject(datas); + if ("1".equals(jsons.get("result") + "")) { + JSONObject objs = (JSONObject) jsons.get("data"); + String faceGuid = objs.get("faceGuid") + ""; + item.setFaceGuid(faceGuid); + } + } + } + } else { + //判断设备人员是否能注册上设备后再删除掉 + List list = equipmentService.selectSysEquipmentList(new SysEquipment()); + if (list.size() > 0) { + Person person = new Person(); + person.setName(item.getName()); + person.setiDNumber(item.getIdcard()); + person.setPhone(item.getPhone()); + String ip = list.get(0).getIp(); + String pass = list.get(0).getPassword(); + String data = sdkService.personCreate(person, ip, pass); + JSONObject json = JSONObject.parseObject(data); + if ("1".equals(json.get("result") + "")) { + JSONObject obj = (JSONObject) json.get("data"); + String admitGuid = obj.get("id") + ""; + item.setGuid(admitGuid); + String datas = sdkService.imageCreateUrl(admitGuid, item.getAvatar(), ip, pass); + JSONObject jsons = JSONObject.parseObject(datas); + if ("1".equals(jsons.get("result") + "")) { + String faceGuid = jsons.get("data") + ""; + item.setFaceGuid(faceGuid); + sdkService.imageDeletel(faceGuid, ip, pass); + } + //再删除以上的注册信息 + sdkService.personDelete(admitGuid, ip, pass); + } + } + } + return item; + } + + /** + * 修改访客信息 + */ + @Log(title = "访客信息", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody Visitor visitor) throws Exception { + if(!CollectionUtils.isEmpty(visitor.getFileList())) { + saveSysFile(visitor.getFileList(), String.valueOf(visitor.getId())); + } + + // 校验图片 +// checkPhoto(visitor.getAvatar(), visitor.getName()); + + visitorService.deleteVisitorItemByParentId(visitor.getId()); + List itemList = visitor.getItemList(); + for (Visitor item : itemList) { + if (!validatePhoneNumber(item.getPhone())) { + throw new ServiceException("您输入的随访人员手机号格式不正确"); + } + item.setParentId(visitor.getId()); + item.setSource(Constants.ONE); + item.setUserId(visitor.getUserId()); + item.setDeptId(visitor.getDeptId()); + item.setCreateTime(visitor.getCreateTime()); + item.setStartTime(visitor.getStartTime()); + item.setEndTime(visitor.getEndTime()); + visitorService.insertVisitor(item); + } + + return toAjax(visitorService.updateVisitor(visitor)); + } + + /** + * 被访人审核 + */ + @Log(title = "被访人审核", businessType = BusinessType.UPDATE) + @PostMapping("/updateVisitorExamineRespondent") + public AjaxResult updateVisitorExamineRespondent(@RequestBody Visitor visitor) { + List record = visitorService.querySysManageRecord(visitor.getUserId()); + if (CollectionUtils.isEmpty(record)) { + throw new RuntimeException("被访人未授权通行"); + } + VisVisitorExamine examine = visitor.getExamine(); + visitor.setState(examine.getExamine()); + visitor.setReviewer(String.valueOf(visitor.getUserId())); + visitor.setNextStepReviewer(visitor.getReviewer3()); + if(StringUtils.isNotEmpty(visitor.getReviewer2())) { + visitor.setNextStepReviewer(visitor.getReviewer2()); + } + visitorService.saveVisitorAuditRecords(visitor); + + // 1保存审核环节 + if(Constants.ZERO.equals(examine.getExamine())) { + // 1.1保存安环部审核人 + visitor.setType("7529"); + visitor.setReviewer(visitor.getReviewer3()); + visitorService.saveVisitorReviewProcess(visitor); + + // 1.2保存设备部审核人 + visitor.setType("8121"); + visitor.setReviewer(visitor.getReviewer2()); + visitorService.saveVisitorReviewProcess(visitor); + visitor.setType(null); + visitorService.updateVisitor(visitor); + SysPeople people = sysPeopleService.selectSysPeopleById(Long.valueOf(visitor.getReviewer2())); + // 审核通知企微发送消息(小程序来源) + String appletLink = getAppletLink(String.valueOf(visitor.getId()), "pages/visitor/visitor/examineIndex"); + sendWeCom(people.getPhone(), appletLink + " --访客姓名:" + visitor.getName()); + } + + if(Constants.ONE.equals(examine.getExamine())) { + Visitor visitor2 = new Visitor(); + if("1".equals(examine.getExamine())) { + visitor2.setOutTime(new Date()); + } + visitor2.setId(visitor.getId()); + visitor2.setEndTime(visitor.getEndTime()); + visitorService.updateVisitor(visitor2); + examine.setVisitorId(visitor.getId()); + LoginUser user = SecurityUtils.getLoginUser(); + visitor.setUserName(user == null ? visitor.getPeopleName() : user.getUsername()); + examine.setCreateBy(visitor.getUserName()); + return toAjax(visVisitorExamineService.insertVisVisitorExamine(examine)); + } + return toAjax(true); + + } + + /** + * 修改访客信息 + */ + @Log(title = "访客审核", businessType = BusinessType.UPDATE) + @PostMapping("/updateVisitorExamine") + public AjaxResult updateVisitorExamine(@RequestBody Visitor visitor) { + List record = visitorService.querySysManageRecord(visitor.getUserId()); + if (CollectionUtils.isEmpty(record)) { + throw new RuntimeException("被访人未授权通行"); + } + SysPeople sysPeople = visitorService.queryVisitorReviewProcess(visitor.getId()); + // 保存审核记录 + VisVisitorExamine examine = visitor.getExamine(); + visitor.setState(examine.getExamine()); + SysPeople people = sysPeopleService.selectSysPeopleById(sysPeople != null ? sysPeople.getId() : visitor.getUserId()); + visitor.setReviewer(String.valueOf(people.getId())); + visitor.setNextStepReviewer(String.valueOf(people.getId())); + if("8121".equals(people.getPosition())) { + visitor.setPosition("7529"); + } + if("7529".equals(people.getPosition())) { + visitor.setPosition("8121"); + } + String string = visitorService.queryReviewProcess(visitor); + visitor.setNextStepReviewer(StringUtils.isNotEmpty(visitor.getReviewer2()) ? visitor.getReviewer2() : visitor.getReviewer3()); + if(StringUtils.isNotEmpty(string)) { + visitor.setNextStepReviewer(string); + } + if(StringUtils.isEmpty(visitor.getNextStepReviewer())) { + visitor.setNextStepReviewer(String.valueOf(visitor.getUserId())); + } + visitorService.saveVisitorAuditRecords(visitor); + + if(sysPeople == null) { + Visitor visitor2 = new Visitor(); + visitor2.setId(visitor.getId()); + visitor2.setVisitorPosition(visitor.getPosition()); + visitor2.setReviewer2(visitor.getReviewer2()); + visitor2.setReviewer3(visitor.getReviewer3()); + visitorService.updateVisitor(visitor2); + if(Constants.ONE.equals(examine.getExamine())) { + sendMessage(visitor.getPhone(), "1", smsProperties.getTemplate8()); + visitor.setState(examine.getExamine()); + visitorService.updateVisitorReviewProcess(visitor); + + Visitor visitor3 = new Visitor(); + if("1".equals(examine.getExamine())) { + visitor3.setOutTime(new Date()); + } + visitor3.setId(visitor.getId()); + visitor3.setEndTime(visitor.getEndTime()); + visitorService.updateVisitor(visitor3); + examine.setVisitorId(visitor.getId()); + LoginUser user = SecurityUtils.getLoginUser(); + visitor.setUserName(user == null ? visitor.getPeopleName() : user.getUsername()); + examine.setCreateBy(visitor.getUserName()); + return toAjax(visVisitorExamineService.insertVisVisitorExamine(examine)); + } + + // 保存设备部或安环部审核人 + Visitor visitor1 = new Visitor(); + visitor1.setType(visitor.getPosition()); + visitor1.setReviewer(StringUtils.isNotEmpty(visitor.getReviewer2()) ? visitor.getReviewer2() : visitor.getReviewer3()); + visitor1.setId(visitor.getId()); + visitorService.saveVisitorReviewProcess(visitor1); + + // 审核通知企微发送消息(小程序来源) + SysPeople people1 = sysPeopleService.selectSysPeopleById(Long.valueOf(visitor.getNextStepReviewer())); + String appletLink = getAppletLink(String.valueOf(visitor.getId()), "pages/visitor/visitor/examineIndex"); + sendWeCom(people1.getPhone(), appletLink + " --访客姓名:" + visitor.getName()); + return toAjax(true); + } + visitor.setPeoplePhone(sysPeople.getPhone()); + + log.info("修改访客信息:{}", visitor); + Visitor item = new Visitor(); + item.setParentId(visitor.getId()); + List itemList = visitorService.selectVisitorItemList(item); + visitor.setItemList(itemList); + CheckCodeVo codeVo = new CheckCodeVo(); + Visitor visitor1 = visitorService.selectVisitorById(visitor.getId()); + + // 校验黑名单 + checkBlack(visitor, itemList); + + int i = visitorService.queryVisitorReviewProcessCount(visitor.getId()); + // 设备部门审核同意 + if(Constants.ZERO.equals(examine.getExamine()) && i > 1) { + visitor.setState(examine.getExamine()); + visitorService.updateVisitorReviewProcess(visitor); + + OfficialAccountVo officialAccountVo = sysPeopleService.queryPeopleById(string); + // 审核通知企微发送消息(小程序来源) + String appletLink = getAppletLink(String.valueOf(visitor.getId()), "pages/visitor/visitor/examineIndex"); + sendWeCom(officialAccountVo.getPhone(), appletLink + " --访客姓名:" + visitor.getName()); + Visitor visitor2 = new Visitor(); + visitor2.setId(visitor.getId()); + visitor2.setVisitorPosition(people.getPosition()); + visitorService.updateVisitor(visitor2); + return toAjax(true); + } + + // 设备部门审核不同意 + OfficialAccountVo officialAccountVo = sysPeopleService.queryPeopleById(String.valueOf(visitor.getUserId())); + if(Constants.ONE.equals(examine.getExamine()) && i > 1) { + Visitor visitor2 = new Visitor(); + visitor2.setId(visitor.getId()); + visitor2.setState(examine.getExamine()); + visitor2.setReviewer(visitor.getReviewer()); + visitorService.updateVisitorReviewProcess(visitor2); + // 审核通知企微发送消息(小程序来源) + sendWeCom(officialAccountVo.getPhone(), visitor.getName() + "的访客审核被拒绝"); + sendMessage(visitor.getPhone(), "1", smsProperties.getTemplate8()); + Visitor visitor3 = new Visitor(); + if("1".equals(examine.getExamine())) { + visitor3.setOutTime(new Date()); + } + visitor3.setId(visitor.getId()); + visitor3.setEndTime(visitor.getEndTime()); + visitorService.updateVisitor(visitor3); + examine.setVisitorId(visitor.getId()); + LoginUser user = SecurityUtils.getLoginUser(); + visitor.setUserName(user == null ? visitor.getPeopleName() : user.getUsername()); + examine.setCreateBy(visitor.getUserName()); + return toAjax(visVisitorExamineService.insertVisVisitorExamine(examine)); + } + + //审核通过 + if ("0".equals(examine.getExamine())) { + // 保存审核二维码地址信息 + codeVo.setCode(qdUrl + visitor.getId() + "&time=" + new Date().getTime()); + codeVo.setVisitorId(String.valueOf(visitor.getId())); + String replace = UUID.randomUUID().toString().replace("-", ""); + codeVo.setId(replace); + if (StringUtils.isNotEmpty(visitor.getCheckCodeId())) { + codeVo.setId(visitor.getCheckCodeId()); + } + + if (visitor1 != null) { + codeVo.setStartTime(visitor1.getStartTime()); + codeVo.setEndTime(visitor1.getEndTime()); + } + visitorService.saveVisCheckCode(codeVo); + + // 园区人脸下发到设备 + if (visitor1 != null && StringUtils.isEmpty(visitor1.getGuid())) { + List listVisitorId = new ArrayList<>(); + Visitor s = parkDeviceDistribute(visitor, record); + Visitor visitor3 = new Visitor(); + visitor3.setGuid(s.getGuid()); + visitor3.setFaceGuid(s.getFaceGuid()); + visitor3.setId(visitor.getId()); + if (!CollectionUtils.isEmpty(visitor.getItemList())) { + for (Visitor visitor2 : visitor.getItemList()) { + Visitor visitorInfo = new Visitor(); + visitor2.setUserId(visitor.getUserId()); + Visitor visitorId = parkDeviceDistribute(visitor2, record); + visitorInfo.setId(visitor2.getId()); + visitorInfo.setGuid(visitorId.getGuid()); + visitorInfo.setFaceGuid(visitorId.getFaceGuid()); + listVisitorId.add(visitorInfo); + } + } + listVisitorId.add(visitor3); + log.info("更新访客人员信息到设备:" + listVisitorId); + visitorService.updateVisitorInfoGuid(listVisitorId); + } + + // 申请人发送短信(审核通过) + String appletLink = getAppletLink(String.valueOf(visitor.getId()), "pagesC/visExamineEwm/index"); + String[] split = appletLink.split("wxaurl.cn/"); + sendMessage(visitor.getPhone(), split[1], smsProperties.getTemplate5()); + redisService.setCacheObject(CacheConstants.WEIXIN_URL_LINK + visitor.getPhone(), appletLink, 24L, TimeUnit.HOURS); + + // 被访人发送短信(审核通过) + sendMessage(officialAccountVo.getPhone(), visitor.getName() + "访问" + officialAccountVo.getName(), smsProperties.getTemplate9()); + } + + if("1".equals(examine.getExamine())) { + // 申请人发送短信(审核不通过) + SysPeople people1 = sysPeopleService.selectSysPeopleById(visitor.getUserId()); + sendWeCom(people1.getPhone(), visitor.getName() + "的访客审核被拒绝"); + sendMessage(visitor.getPhone(), "1", smsProperties.getTemplate8()); + + // 被访人发送短信(审核不通过) + sendMessage(officialAccountVo.getPhone(), visitor.getName() + "访问" + officialAccountVo.getName(), smsProperties.getTemplate10()); + } + + visitor.setState(examine.getExamine()); + visitorService.updateVisitorReviewProcess(visitor); + + Visitor visitor2 = new Visitor(); + if("1".equals(examine.getExamine())) { + visitor2.setOutTime(new Date()); + } + visitor2.setId(visitor.getId()); + visitor2.setEndTime(visitor.getEndTime()); + visitorService.updateVisitor(visitor2); + examine.setVisitorId(visitor.getId()); + LoginUser user = SecurityUtils.getLoginUser(); + visitor.setUserName(user == null ? visitor.getPeopleName() : user.getUsername()); + examine.setCreateBy(visitor.getUserName()); + return toAjax(visVisitorExamineService.insertVisVisitorExamine(examine)); + } + + /** + * 校验黑名单 + */ + private void checkBlack(Visitor visitor, List itemList) { + //判断是否存在黑名单,存在即审核失败 + SysBlackList sysBlackList = new SysBlackList(); + sysBlackList.setPhone(visitor.getPhone()); + List list = sysBlackListService.selectSysBlackListList(sysBlackList); + if (list.size() > 0) { + throw new ServiceException("存在黑名单无法审核通过"); + } + for (Visitor items : itemList) { + SysBlackList sysBlackLists = new SysBlackList(); + sysBlackLists.setPhone(items.getPhone()); + List lists = sysBlackListService.selectSysBlackListList(sysBlackLists); + if (lists.size() > 0) { + throw new ServiceException("存在黑名单无法审核通过"); + } + } + } + + /** + * 园区人脸设备下发 + */ + private Visitor parkDeviceDistribute(Visitor visitor, List record) { + // 查询被访人授权记录 + Visitor s = new Visitor(); + for (SysManageRecord sysManageRecord : record) { + SysRule rule = sysRuleService.selectSysRuleById(sysManageRecord.getRuleId()); + String[] pointIds = rule.getPointId().split(","); + List equipList = new ArrayList<>(); + if (pointIds != null) { + for (String point : pointIds) { + SysEquipment equipment = new SysEquipment(); + equipment.setPointId(Long.parseLong(point)); + equipment.setFlag("0"); + equipment.setIsCj("0"); + equipment.setProductId(3L); + List equipmentDtoList = equipmentService.selectSysEquipmentList(equipment); + equipList.addAll(equipmentDtoList); + } + } + String guid = IdUtils.simpleUUID(); + String faceId = IdUtils.simpleUUID(); + s.setGuid(guid); + s.setFaceGuid(faceId); + //通过规则获取绑定设备信息 + if (equipList != null) { + for (SysEquipment e : equipList) { + //将人员信息下发到设备 + Person person = new Person(); + person.setName(visitor.getName()); + person.setPhone(visitor.getPhone()); + person.setId(guid); + String ip = e.getIp(); + String pass = e.getPassword(); + sdkService.personCreate(person, ip, pass); + if (StringUtils.isNotEmpty(visitor.getAvatar())) { + sdkService.imageCreateUrl(guid, faceId, visitor.getAvatar(), ip, pass); + } + //保存下发记录 + SysPeopleEquipment sysPeopleEquipment = new SysPeopleEquipment(); + sysPeopleEquipment.setVisitorId(visitor.getId()); + sysPeopleEquipment.setEquipmentId(e.getId()); + sysPeopleEquipment.setGuid(guid); + sysPeopleEquipment.setFaceGuid(faceId); + peopleEquipmentService.insertSysPeopleEquipment(sysPeopleEquipment); + } + } + } + return s; + } + + /** + * 访客签到签退 + */ + @Log(title = "访客签到签退", businessType = BusinessType.UPDATE) + @PostMapping("/updateVisitorInOut") + public AjaxResult updateVisitorInOut(@RequestBody Visitor visitor) { + Visitor item = new Visitor(); + item.setParentId(visitor.getId()); + List itemList = visitorService.selectVisitorItemList(item); + for (Visitor items : itemList) { + if ("in".equals(visitor.getTabFlag())) { + items.setInTime(new Date()); + } else { + items.setOutTime(new Date()); + } + visitorService.updateVisitor(items); + } + if ("in".equals(visitor.getTabFlag())) { + visitor.setInTime(new Date()); + } else { + visitor.setOutTime(new Date()); + } + return toAjax(visitorService.updateVisitor(visitor)); + } + + + private void delVisVisitorItemList(Long id) { + Visitor item = new Visitor(); + item.setParentId(id); + List itemList = visitorService.selectVisitorItemList(item); + String admitGuids = ""; + for (Visitor items : itemList) { + admitGuids += items.getGuid() + ","; + } + if (!"".equals(admitGuids)) { + String cloud = configService.selectConfigByKey("sys.equipment.cloud"); + if ("true".equals(cloud)) { + admitGuids = admitGuids.substring(0, admitGuids.length() - 1); + if (!"null".equals(admitGuids)) { + String data = sysApiService.admitDelete(admitGuids); + } + } else { + List equipmentDtoList = equipmentService.selectSysEquipmentList(new SysEquipment()); + for (SysEquipment eq : equipmentDtoList) { + sdkService.personDelete(admitGuids, eq.getIp(), eq.getPassword()); + } + } + } + } + + /** + * 删除访客信息 + */ + @RequiresPermissions("visitor:visitor:remove") + @Log(title = "访客信息", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) { + String admitGuids = ""; + for (Long visitorId : ids) { + Visitor Visitor = visitorService.selectVisitorById(visitorId); + admitGuids += Visitor.getGuid() + ","; + visitorService.deleteVisitorItemByParentId(visitorId); + //删除子项存在的注册人员信息 + delVisVisitorItemList(visitorId); + } + return toAjax(visitorService.deleteVisitorByIds(ids)); + } + + @Log(title = "访客信息", businessType = BusinessType.DELETE) + @DeleteMapping("/canceVisitor/{id}") + public AjaxResult canceVisitor(@PathVariable Long id) { + Visitor visitor = visitorService.selectVisitorById(id); + Visitor item = new Visitor(); + item.setParentId(visitor.getId()); + List itemList = visitorService.selectVisitorItemList(item); + visitor.setItemList(itemList); + //保存访客通行规则 + String cloud = configService.selectConfigByKey("sys.equipment.cloud"); + try { + if ("true".equals(cloud)) { + sysApiService.authDeviceRevoke(visitor); + } else { + sdkService.authDeviceRevoke(visitor); + } + } catch (Exception e) { + e.printStackTrace(); + } + return toAjax(visVisitorExamineService.deleteVisVisitorExamineByVisitorId(id)); + } + + public AjaxResult sendMessage(String phone, String code, String templateId) { + if (org.apache.commons.lang3.StringUtils.isEmpty(phone)) { + return error("手机号不能为空!"); + } + if (!smsProperties.getEnabled()) { + error("当前系统没有开启短信功能!"); + } + Map map = new HashMap<>(1); + map.put("code", code); + SmsTemplate smsTemplate = SpringUtils.getBean(SmsTemplate.class); + SmsResult result = smsTemplate.send(phone, templateId, map); + if (!result.getIsSuccess()) { + return error(result.getMessage()); + } + return AjaxResult.success(); + } + + /** + * 查询访客记录列表 + * + * @param visitor + * @return + */ + @GetMapping("/queryVisitorRecordList") + public TableDataInfo queryVisitorRecordList(VisitorRecordVo visitor) { + startPage(); + List list = visitorService.queryVisitorRecordList(visitor); + return getDataTable(list); + } + + /** + * 删除访客记录 + * + * @param ids + * @return + */ + @PostMapping("/deleteVisitorRecordList") + public AjaxResult deleteVisitorRecordList(String ids) { + String[] split = ids.split(","); + visitorService.deleteVisitorRecordList(split); + return AjaxResult.success(); + } + + /** + * 新增访客记录 + * + * @return + */ + @PostMapping("/saveVisitorRecord") + public AjaxResult saveVisitorRecord(VisitorRecordVo recordVo) { + Visitor visitor = new Visitor(); + if ("2".equals(recordVo.getType())) { + visitorService.updateVisitorRecord(recordVo); + visitor.setEndTime(recordVo.getEndTime()); + visitorService.updateVisitor(visitor); + return AjaxResult.success(); + } + visitor.setStartTime(recordVo.getStartTime()); + visitorService.saveVisitorRecord(recordVo); + return AjaxResult.success(); + } + + /** + * 校验头像上传宇泛人脸机是否通过 + * + * @param avatar + */ + private void checkPhoto(String avatar, String name) throws Exception { + if (StringUtils.isNotEmpty(avatar)) { + String[] split = avatar.split(minioGwurl); + String s = minioUrl + split[1]; + try { + File file = FileUtils.urlToFile("111", s); + String body = HttpUtil.createPost(upload).form("file", file).execute().body(); + if (!file.delete()) { + log.info("删除临时文件失败成功"); + } + JSONObject object = JSONObject.parseObject(body); + String string = object.get("code").toString(); + if (!"0".equals(string)) { + log.info("来访人头像校验失败:{}", avatar); + throw new ServiceException("来访人" + name + "头像校验失败,请重新上传"); + } + } catch (HttpException e) { + log.error("来访人头像校验失败", e); + } + } + } + + /** + * 查询访客数量(今日,本周,本月) + * + * @param recordVo + * @return + */ + @PostMapping("/queryVisitorCount") + public AjaxResult queryVisitorCount(VisitorRecordVo recordVo) { + return success(visitorService.queryVisitorCount(recordVo)); + } + + /** + * 首页头像展示 + * @param recordVo + * @return + */ + @PostMapping("/queryVisitorAvatar") + public AjaxResult queryVisitorAvatar(VisitorRecordVo recordVo) { + return success(visitorService.queryVisitorAvatar(recordVo)); + } + + @GetMapping("/queryTest") + public AjaxResult queryTest(VisitorRecordVo recordVo) { + return success(visitorService.queryTest(recordVo)); + } + + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/controller/VisitorMachineController.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/controller/VisitorMachineController.java new file mode 100644 index 0000000..7fbc8b1 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/controller/VisitorMachineController.java @@ -0,0 +1,605 @@ +package com.dcsoft.system.visitor.controller; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.thread.ThreadUtil; +import cn.hutool.http.HttpException; +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.dcsoft.common.core.constant.CacheConstants; +import com.dcsoft.common.core.constant.Constants; +import com.dcsoft.common.core.domain.R; +import com.dcsoft.common.core.enums.exception.CommonExceptionEnum; +import com.dcsoft.common.core.exception.ServiceException; +import com.dcsoft.common.core.web.controller.BaseController; +import com.dcsoft.common.core.web.domain.AjaxResult; +import com.dcsoft.common.core.web.page.TableDataInfo; +import com.dcsoft.common.core.web.page.TableDataInfoPage; +import com.dcsoft.common.redis.service.RedisService; +import com.dcsoft.system.api.RemoteFileService; +import com.dcsoft.system.api.domain.SysFile; +import com.dcsoft.system.domain.*; +import com.dcsoft.system.service.*; +import com.dcsoft.system.uniubi.domain.DingtalkMsgVo; +import com.dcsoft.system.uniubi.domain.EwmInfo; +import com.dcsoft.system.uniubi.domain.LadderControlVo; +import com.dcsoft.system.utils.PictureUtils; +import com.dcsoft.system.visitor.domain.*; +import com.dcsoft.system.visitor.service.IVisitorService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.util.CollectionUtils; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import sun.misc.BASE64Decoder; + + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +@Slf4j +@RestController +@RequestMapping("/visitorMachine") +public class VisitorMachineController extends BaseController { + + @Autowired + private IVisitorService visitorService; + + @Autowired + private RemoteFileService remoteFileService; + + @Autowired + protected ISysEquipmentService equipmentService; + + @Autowired + private ISysEmpowerRecordService sysEmpowerRecordService; + + @Autowired + private ISysBranchService sysBranchService; + + @Autowired + private ISysBlackListService sysBlackListService; + + @Autowired + private RemoteFileService fileService; + + @Autowired + private ISysPeopleService sysPeopleService; + + @Autowired + private RedisService redisService; + + @Value("${system.type}") + public String systemType; + + @Value("${sdk.saveVisitorMachine}") + public String saveVisitorMachine; + + @Value("${sdk.updateState}") + public String updateState; + + @Value("${sdk.updateGroupSignOut}") + public String updateGroupSignOut; + + @Value("${sdk.updateParkSignOut}") + public String updateParkSignOut; + + @Value("${dingTalk.agentId}") + public String agentId; + + @Value("${dingTalk.asyncsendV2}") + public String asyncsendV2; + + @Value("${dingTalk.getToken}") + public String getToken; + + @Value("${weCom.corpid}") + public String corpid; + + @Value("${weCom.corpsecret}") + public String weComSecret; + + @Value("${weCom.agentid}") + public String weComAgentid; + + /** + * 访客机新增 + */ + @PostMapping("/saveVisitorMachine") + public AjaxResult saveVisitorMachine(@RequestBody Visitor visitor) throws ParseException { + log.info("访客机新增参数:" + visitor); + // 判断是否是黑名单 + SysBlackList sysBlackList = sysBlackListService.queryBlackById(visitor); + if(sysBlackList != null) { + throw new ServiceException("您已拉入黑名单"); + } + if(visitor.getStartTime().getTime() > visitor.getEndTime().getTime()) { + throw new ServiceException("您输入的开始时间不能大于结束时间"); + } + + // todo 身份证信息获取后推送服务器进行公安比对 + if(StringUtils.isEmpty(visitor.getName())) { + throw new ServiceException("姓名不能为空"); + } + + if (visitorService.queryVisitorByIdCount(visitor.getPhone()) > 0) { + throw new ServiceException("该手机号已存在访客预约信息"); + } + if (visitorService.queryVisitor(visitor) > 0) { + throw new ServiceException("您已预约"); + } + + int i = 0; + Visitor visitor2 = new Visitor(); + BeanUtils.copyProperties(visitor, visitor2); + visitor2.setCreateTime(visitor.getCreateTime()); + visitor2.setStartTime(visitor.getCreateTime()); + visitor2.setSource(Constants.ZERO); +// visitor2.setDeptId("2"); + MultipartFile file = PictureUtils.base64ToMultipartFiles(visitor.getAvatar()); + R sysFileR = fileService.uploadMinio1(file, "true"); + visitor2.setAvatar(sysFileR.getData().getUrl()); + i = visitorService.insertVisitor(visitor2); + List itemList=visitor.getItemList(); + visitor.setId(visitor2.getId()); + // 随访人员 + if(!CollectionUtils.isEmpty(itemList)) { + for (Visitor item:itemList) { + MultipartFile multipartFile = PictureUtils.base64ToMultipartFiles(item.getAvatar()); + R uploadMinio = fileService.uploadMinio1(multipartFile, "true"); + item.setAvatar(uploadMinio.getData().getUrl()); + item.setParentId(visitor2.getId()); + item.setSource(Constants.ZERO); + item.setUserId(item.getUserId()); + item.setDeptId(item.getDeptId()); + item.setCreateTime(new Date()); + item.setStartTime(visitor2.getStartTime()); + item.setEndTime(visitor2.getEndTime()); + visitorService.insertVisitor(item); + } + } + + + SysPeople sysPeople = sysPeopleService.selectSysPeopleByUserId(Long.valueOf(visitor.getUserId())); + String url = "您有新的访客申请,请审核: https://mj.kmlygroup.com/app-fk/#/pages/visitor/visitor/examineDetal?id="+ visitor2.getId(); + if("2".equals(systemType)) { + // 数据同步到总部 + ThreadUtil.execAsync(() -> { + try { + visitor.setDeptId(Constants.TWO); + String body = HttpUtil.createPost(saveVisitorMachine).body(JSON.toJSONString(visitor)).execute().body(); + log.info("数据同步到总部结果:{}", body); + } catch (HttpException e) { + log.error("数据同步到总部失败", e); + } + }); + } + + if(Constants.ONE.equals(systemType)) { + // 钉工牌消息通知 + if(sysPeople != null && StringUtils.isNotEmpty(sysPeople.getGh())) { + try { + asyncsendV2(sysPeople.getPhone(), "text", url); + sendWeCom(sysPeople.getPhone(), url); + } catch (Exception e) { + log.error("钉工牌或企微消息通知失败", e); + } + } + } + return toAjax(i); + } + + + /** + * 企微消息发送 + * @param phone + * @param content + */ + private void sendWeCom(String phone, String content) { + // 获取userId + String weComUserId = getWeComUserId(phone); + DingtalkMsgVo.Text text = new DingtalkMsgVo.Text(); + text.setContent(content); + Map map = new HashMap<>(); + map.put("touser", weComUserId); + map.put("msgtype", "text"); + map.put("agentid", weComAgentid); + map.put("text", text); + map.put("safe", 0); + map.put("enable_id_trans", 0); + map.put("enable_duplicate_check", 0); + map.put("duplicate_check_interval", 1800); + String body = HttpUtil.createPost("https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + getWeComToken()) + .body(JSON.toJSONString(map)) + .execute() + .body(); + JSONObject object = JSON.parseObject(body); + log.info("企微消息发送结果:{}", body); + if(!Constants.ZERO.equals(object.get("errcode").toString())) { + log.error("企微消息发送失败" + object.get("errcode").toString()); + throw new ServiceException(CommonExceptionEnum.REQUEST_ERROR.getCode(), "企微消息发送" + CommonExceptionEnum.REQUEST_ERROR.getMessage() + object.get("errcode").toString()); + } + + } + + /** + * 更具手机号获取userId + * @param phone + * @return + */ + private String getWeComUserId(String phone) { + Map map = new HashMap<>(); + map.put("mobile", phone); + String body = HttpUtil.createPost("https://qyapi.weixin.qq.com/cgi-bin/user/getuserid?access_token=" + getWeComToken()) + .body(JSON.toJSONString(map)) + .execute() + .body(); + JSONObject object = JSON.parseObject(body); + if(!Constants.ZERO.equals(object.get("errcode").toString())) { + throw new ServiceException(CommonExceptionEnum.REQUEST_ERROR.getCode(), "获取企微userId" + CommonExceptionEnum.REQUEST_ERROR.getMessage() + object.get("errcode").toString()); + } + return object.get("userid").toString(); + } + + /** + * 获取企微token + * @return + */ + private String getWeComToken() { + String cacheObject = redisService.getCacheObject(CacheConstants.WE_COM_TOKEN); + if (StringUtils.isNotEmpty(cacheObject)) { + return cacheObject; + } + String body = HttpUtil.createGet("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + corpid + "&corpsecret=" + weComSecret).execute().body(); + JSONObject object = JSON.parseObject(body); + if(!Constants.ZERO.equals(object.get("errcode").toString())) { + throw new ServiceException(CommonExceptionEnum.REQUEST_ERROR.getCode(), "获取企微token" + CommonExceptionEnum.REQUEST_ERROR.getMessage() + object.get("errcode").toString()); + } + String string = object.get("access_token").toString(); + redisService.setCacheObject(CacheConstants.WE_COM_TOKEN, string, 7000L, TimeUnit.SECONDS); + return string; + + } + + /** + * 钉工牌消息通知 + */ + private void asyncsendV2(String phone, String msgType, String content) { + String ddUserId = getDingUserId(phone); + DingtalkMsgVo msgVo = new DingtalkMsgVo(); + DingtalkMsgVo.Text text = new DingtalkMsgVo.Text(); + text.setContent(content); + msgVo.setMsgtype(msgType); + msgVo.setText(text); + Map map = new HashMap<>(); + map.put("agent_id", agentId); + map.put("msg", msgVo); + map.put("userid_list", ddUserId); + String body = HttpUtil.createPost(asyncsendV2 + "?access_token=" + getToken()) + .body(JSON.toJSONString(map)) + .execute() + .body(); + JSONObject object = JSON.parseObject(body); + log.info("钉工牌消息通知结果:{}", body); + if(!Constants.ZERO.equals(object.get("errcode").toString())) { + log.error("钉工牌消息通知接口异常码:" + object.get("errcode").toString()); + //throw new ServiceException(CommonExceptionEnum.REQUEST_ERROR.getCode(), "钉工牌消息通知接口" + CommonExceptionEnum.REQUEST_ERROR.getMessage()); + } + + } + + /** + * 通过手机号获取userId(钉钉) + * @param phone + * @return + */ + private String getDingUserId(String phone) { + Map map = new HashMap<>(); + map.put("mobile", phone); + String body = HttpUtil.createPost("https://oapi.dingtalk.com/topapi/v2/user/getbymobile?access_token=" + getToken()) + .body(JSON.toJSONString(map)) + .execute() + .body(); + JSONObject object = JSON.parseObject(body); + if(!Constants.ZERO.equals(object.get("errcode").toString())) { + throw new ServiceException(CommonExceptionEnum.REQUEST_ERROR.getCode(), "通过手机号获取userId(钉钉)" + CommonExceptionEnum.REQUEST_ERROR.getMessage()); + } + String string = object.get("result").toString(); + JSONObject jsonObject = JSON.parseObject(string); + return jsonObject.get("userid").toString(); + } + + /** + * 获取钉工牌token + */ + private String getToken() { + String body = HttpUtil.createGet(getToken).execute().body(); + JSONObject object = JSON.parseObject(body); + return object.get("access_token").toString(); + + } + + /** + * 获取时间 + * @param startDate + * @param endDate + */ + private List getTime(String startDate, String endDate) throws ParseException { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + LocalDate start = LocalDate.parse(startDate); + LocalDate end = LocalDate.parse(endDate); + List list = new ArrayList<>(); + while (!start.isAfter(end)) { + Visitor gather = new Visitor(); + gather.setCreateTime(sdf.parse(start.toString())); + list.add(gather); + start = start.plusDays(1); + } + return list; + } + + /** + * 查询访客预约信息 + */ + @PostMapping("/queryVisitorAppointment") + public TableDataInfoPage queryVisitorAppointment(@RequestBody VisitorParamVo paramVo) { + log.info("查询访客预约信息(入参):" + paramVo); + TableDataInfoPage tableDataInfoPage = visitorService.queryVisitorAppointment(paramVo); + log.info("查询访客预约信息(出参):" + tableDataInfoPage); + return tableDataInfoPage; + } + + /** + * 查询近七天的访客数据 + * @param paramVo + * @return + */ + @PostMapping("/queryExportVisitorInfo") + public AjaxResult queryExportVisitorInfo(VisitorParamVo paramVo) { + log.info("查询近七天的访客数据(入参):" + paramVo); + List list = visitorService.queryExportVisitorInfo(paramVo); + log.info("查询近七天的访客数据(出参):" + list); + return success(list); + } + + /** + * 查询黑名单 + */ + @PostMapping("/selectSysBlackListList") + public TableDataInfoPage selectSysBlackListList(@RequestBody VisitorParamVo paramVo) { + log.info("查询黑名单(入参):" + paramVo); + TableDataInfoPage tableDataInfoPage = visitorService.selectSysBlackListList(paramVo); + log.info("查询黑名单(出参):" + tableDataInfoPage); + return tableDataInfoPage; + } + + /** + * 二维码校验 + */ + @PostMapping("/checkQrCode") + public AjaxResult checkQrCode(@RequestBody EwmInfoVo info) { + log.info("二维码校验(入参):" + info); + System.out.println("======二维码回调信息============="+info); + CheckCodeVo codeVo = visitorService.queryVisCheckCodeById(info.getQrData()); + if(codeVo == null) { + throw new ServiceException("无效验证码"); + } + if(!codeVo.getCode().contains("/pages/visitor/visitor/visExamineEwm")) { + throw new ServiceException("无效验证码"); + } + String[] ids = codeVo.getCode().split("id="); + String[] split = ids[1].split("&time="); + Visitor visitor = visitorService.selectVisitorById(Long.valueOf(split[0])); + if(visitor == null) { + return success(new Visitor()); + } + if(visitor.getEndTime().getTime() < Long.parseLong(info.getTime())) { + throw new ServiceException("您得验证码已超时"); + } + + log.info("二维码校验(出参):" + visitor); + return success(visitor); + } + + /** + * 修改访客信息 + */ + @PostMapping("/updateVisitor") + public AjaxResult updateVisitor(@RequestBody Visitor paramVo) { + log.info("修改访客信息:" + paramVo); + if(paramVo.getStartTime().getTime() > paramVo.getEndTime().getTime()) { + throw new ServiceException("您输入的开始时间不能大于结束时间"); + } + visitorService.deleteVisitorItemByParentId(paramVo.getId()); + List itemList=paramVo.getItemList(); + if(!CollectionUtils.isEmpty(itemList)) { + for(Visitor item:itemList){ + item.setParentId(paramVo.getId()); + item.setSource(Constants.ZERO); + visitorService.insertVisitor(item); + } + } + + return toAjax(visitorService.updateVisitor(paramVo)); + } + + /** + * 修改状态 + */ + @PostMapping("/updateState") + public AjaxResult updateState(@RequestBody Visitor paramVo) { + log.info("修改状态:" + paramVo); + if("2".equals(systemType)) { + // 数据同步到总部 + ThreadUtil.execAsync(() -> { + try { + String body = HttpUtil.createPost(updateState).body(JSON.toJSONString(paramVo)).execute().body(); + log.info("修改状态同步到总部结果:{}", body); + } catch (HttpException e) { + log.error("修改状态同步到总部失败", e); + } + }); + } + int i = visitorService.updateState(paramVo); + return toAjax(i); + } + + /** + * 修改状态 + */ + @PostMapping("/updateSignOut") + public AjaxResult updateSignOut(@RequestBody Visitor paramVo) { + log.info("修改状态签离:" + paramVo); + // 同步园区签离 + if("1".equals(systemType)) { + ThreadUtil.execAsync(() -> { + try { + String body = HttpUtil.createPost(updateParkSignOut).body(JSON.toJSONString(paramVo)).execute().body(); + log.info("同步园区签离结果:{}", body); + } catch (HttpException e) { + log.error("同步园区签离失败", e); + } + }); + } + + // 同步总部签离 + if("2".equals(systemType)) { + ThreadUtil.execAsync(() -> { + try { + String body = HttpUtil.createPost(updateGroupSignOut).body(JSON.toJSONString(paramVo)).execute().body(); + log.info("同步总部签离结果:{}", body); + } catch (HttpException e) { + log.error("同步总部签离失败", e); + } + }); + } + saveRecord(paramVo.getPeopleId(), paramVo.getDeviceKey()); + return toAjax(visitorService.updateSignOut(paramVo)); + } + + private void saveRecord(String peopleId, String deviceKey) { + insertRecord(peopleId, deviceKey, visitorService); + } + + public static void insertRecord(String peopleId, String deviceKey, IVisitorService visitorService) { + VisitorRecordVo record = new VisitorRecordVo(); + if(StringUtils.isNotEmpty(peopleId)) { + if(visitorService.queryVisitorRecord(Long.valueOf(peopleId)) > 0) { + record.setEndTime(new Date()); + record.setVisitorId(peopleId); + visitorService.updateVisitorRecord(record); + } + } + + record.setVisitorId(peopleId); + record.setSequence(deviceKey); + record.setStartTime(new Date()); + visitorService.saveVisitorRecord(record); + } + + /** + * 查询被访人 + */ + @PostMapping("/queryPeople") + public TableDataInfo queryPeople(Visitor paramVo) { + log.info("查询被访人(入参):" + paramVo); + startPage(); + List infoVos = visitorService.queryPeople(paramVo); + if(!CollectionUtils.isEmpty(infoVos)) { + for (PersonnelInfoVo infoVo : infoVos) { + if(StringUtils.isNotEmpty(infoVo.getPhone())) { + infoVo.setPhone(infoVo.getPhone().replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")); + } + } + } + + log.info("查询被访人(出参):" + infoVos); + return getDataTable(infoVos, 1); + } + + /** + * 查询已审核状态信息 + */ + @PostMapping("/queryAuditedVisitor") + public AjaxResult queryAuditedVisitor(@RequestBody Visitor paramVo) { + log.info("查询已审核状态信息:" + paramVo); + return success(visitorService.queryAuditedVisitor(paramVo)); + } + + /** + * 查询详情 + */ + @PostMapping("/queryVisitorInfo") + public AjaxResult queryVisitorInfo(@RequestBody Visitor paramVo) { + log.info("查询详情(入参):" + paramVo); + VisitorInfoVo visitorInfoVo = visitorService.queryVisitorInfo(paramVo); + log.info("查询详情(出参):" + visitorInfoVo); + return success(visitorInfoVo); + } + + /** + * 查询部门 + */ + @PostMapping("/queryDeptInfo") + public AjaxResult queryDeptInfo(@RequestBody SysBranch paramVo) { + log.info("查询部门:" + paramVo); + return success(sysBranchService.queryDeptInfo(paramVo)); + } + + /** + * 查询未签离列表 + */ + @GetMapping("/queryVisitorUnsigned") + public TableDataInfo queryVisitorUnsigned(VisitorParamVo paramVo) { + log.info("查询未签离列表(入参):" + paramVo); + List list = visitorService.queryVisitorUnsigned(paramVo); + log.info("查询未签离列表(出参):" + list); + return getDataTable(list); + } + + + /** + * 查询访客二维码 码值 + * @param visitorId + * @return + */ + @PostMapping("/queryVisCheckCode") + public AjaxResult queryVisCheckCode(String visitorId) { + log.info("访客id(参数):" + visitorId); + return success(visitorService.queryVisCheckCode(visitorId)); + } + + /** + * 通过手机号查询访客id + * @param phone + * @return + */ + @PostMapping("/queryVisitorById") + public AjaxResult queryVisitorById(String phone) { + log.info("手机号(参数):" + phone); + return success(visitorService.queryVisitorById(phone)); + } + + /** + * 保存访客机断线数据 + * @param visitor + * @return + * @throws ParseException + */ + @PostMapping("/saveDisconnect") + public AjaxResult saveDisconnect(@RequestBody Visitor visitor) throws ParseException { + visitorService.saveDisconnect(visitor.getVisitor()); + return success(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/CheckCodeVo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/CheckCodeVo.java new file mode 100644 index 0000000..8b5ca7f --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/CheckCodeVo.java @@ -0,0 +1,20 @@ +package com.dcsoft.system.visitor.domain; + +import lombok.Data; + +import java.util.Date; + +@Data +public class CheckCodeVo { + private String id; + + private String code; + + private Date startTime; + + private Date endTime; + + private String visitorId; + + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/EwmInfoVo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/EwmInfoVo.java new file mode 100644 index 0000000..5a83572 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/EwmInfoVo.java @@ -0,0 +1,19 @@ +package com.dcsoft.system.visitor.domain; + +import lombok.Data; + +@Data +public class EwmInfoVo { + + /** 设备序列号 **/ + protected String deviceKey; + + /** 识别记录毫秒级时间戳*/ + protected String time; + + /** 设备当前 IP 地址 "*/ + protected String ip; + + /** 现场照保存路径 "*/ + protected String qrData; +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/PersonnelInfoVo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/PersonnelInfoVo.java new file mode 100644 index 0000000..45050df --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/PersonnelInfoVo.java @@ -0,0 +1,64 @@ +package com.dcsoft.system.visitor.domain; + +import lombok.Data; + +import java.util.List; + +@Data +public class PersonnelInfoVo { + + /** + * 主键id + */ + private String id; + + /** + * 姓名 + */ + private String name; + + /** + * 身份证 + */ + private String idcard; + + /** + * 车辆 + */ + private String carNo; + + /** + * 电话号码 + */ + private String phone; + + /** + * 头像地址 + */ + private String avatar; + + /** + * 进入时间 + */ + private String inTime; + + /** + * 离开时间 + */ + private String outTime; + + /** + * 部门id + */ + private String branchId; + + /** + * 部门名称 + */ + private String branchName; + + + + private List list; + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisVisitorExamine.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisVisitorExamine.java new file mode 100644 index 0000000..cd55be7 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisVisitorExamine.java @@ -0,0 +1,203 @@ +package com.dcsoft.system.visitor.domain; + +import com.dcsoft.common.core.annotation.Excel; +import com.dcsoft.common.core.web.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 访客审核对象 vis_visitor_examine + * + * @author nichun + * @date 2023-03-11 + */ +public class VisVisitorExamine extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 审核Id */ + private Long id; + + /** 随访人 */ + @Excel(name = "随访人") + private String name; + + /** 联系电话 */ + @Excel(name = "联系电话") + private String phone; + + /** 访客id */ + @Excel(name = "访客id") + private Long visitorId; + + /** 准入时间起 */ + @Excel(name = "准入时间起") + private String admittanceStart; + + /** 准入时间止 */ + @Excel(name = "准入时间止") + private String admittanceEnd; + + /** 设备空间 */ + @Excel(name = "设备空间") + private Long spaceId; + + /** 设备位置 */ + @Excel(name = "设备位置") + private String pointId; + + /** 1:本地库 2:云端库 默认本地 */ + @Excel(name = "1:本地库 2:云端库 默认本地") + private String type; + + /** facePermission 刷脸权限 idCardPermission 刷卡权限 faceAndCardPermission 人卡合一权限 idCardFacePermission 人证比对权限 +passwordPermission 密码权限 */ + private String permission; + + /** 审核意见 */ + private String examine; + + protected String[] pointIds; + + private Long ruleId; + + + + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setPhone(String phone) + { + this.phone = phone; + } + + public String getPhone() + { + return phone; + } + public void setVisitorId(Long visitorId) + { + this.visitorId = visitorId; + } + + public Long getVisitorId() + { + return visitorId; + } + public void setAdmittanceStart(String admittanceStart) + { + this.admittanceStart = admittanceStart; + } + + public String getAdmittanceStart() + { + return admittanceStart; + } + public void setAdmittanceEnd(String admittanceEnd) + { + this.admittanceEnd = admittanceEnd; + } + + public String getAdmittanceEnd() + { + return admittanceEnd; + } + public void setSpaceId(Long spaceId) + { + this.spaceId = spaceId; + } + + public Long getSpaceId() + { + return spaceId; + } + public void setPointId(String pointId) + { + this.pointId = pointId; + } + + public String getPointId() + { + return pointId; + } + public void setType(String type) + { + this.type = type; + } + + public String getType() + { + return type; + } + public void setPermission(String permission) + { + this.permission = permission; + } + + public String getPermission() + { + return permission; + } + + + public String getExamine() { + return examine; + } + + public void setExamine(String examine) { + this.examine = examine; + } + + public String[] getPointIds() { + return pointIds; + } + + public void setPointIds(String[] pointIds) { + this.pointIds = pointIds; + } + + public Long getRuleId() { + return ruleId; + } + + public void setRuleId(Long ruleId) { + this.ruleId = ruleId; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("phone", getPhone()) + .append("visitorId", getVisitorId()) + .append("admittanceStart", getAdmittanceStart()) + .append("admittanceEnd", getAdmittanceEnd()) + .append("spaceId", getSpaceId()) + .append("pointId", getPointId()) + .append("type", getType()) + .append("permission", getPermission()) + .append("remark", getRemark()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisVisitorLogisticsVo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisVisitorLogisticsVo.java new file mode 100644 index 0000000..f310931 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisVisitorLogisticsVo.java @@ -0,0 +1,46 @@ +package com.dcsoft.system.visitor.domain; + +import lombok.Data; + +import java.util.Date; + +@Data +public class VisVisitorLogisticsVo { + /** + * 主键id + */ + private String id; + /** + * 访客id + */ + private String visitorId; + /** + * 驾驶证 + */ + private String driver; + /** + * 危化品运输许可证 + */ + private String transportPermit; + /** + * 当值保安 + */ + private String security; + /** + * 创建人 + */ + private String createdBy; + /** + * 创建时间 + */ + private Date createdTime; + /** + * 更新人 + */ + private String updatedBy; + /** + * 更新时间 + */ + private Date updatedTime; +} + diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisVisitorRegister.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisVisitorRegister.java new file mode 100644 index 0000000..291d63a --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisVisitorRegister.java @@ -0,0 +1,176 @@ +package com.dcsoft.system.visitor.domain; + +import java.util.Date; + +import com.dcsoft.common.core.web.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.dcsoft.common.core.annotation.Excel; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 访客注册对象 vis_visitor_register + * + * @author dcsoft + * @date 2024-05-21 + */ +public class VisVisitorRegister extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + private String id; + + /** + * 用户名 + */ + @Excel(name = "用户名") + private String userName; + + /** + * 用户昵称 + */ + @Excel(name = "用户昵称") + private String nickName; + + /** + * 用户手机号 + */ + @Excel(name = "用户手机号") + private String phone; + + /** + * 微信公众号用户id + */ + @Excel(name = "微信公众号用户id") + private String openid; + + /** + * 删除状态 0.否;1.是 + */ + @Excel(name = "删除状态 0.否;1.是") + private String deleteState; + + /** + * 创建人 + */ + @Excel(name = "创建人") + private String createdBy; + + /** + * 创建时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date createdTime; + + /** + * 更新人 + */ + @Excel(name = "更新人") + private String updatedBy; + + /** + * 更新时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date updatedTime; + + public void setId(String id) { + this.id = id; + } + + public String getId() { + return id; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getUserName() { + return userName; + } + + public void setNickName(String nickName) { + this.nickName = nickName; + } + + public String getNickName() { + return nickName; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPhone() { + return phone; + } + + public void setOpenid(String openid) { + this.openid = openid; + } + + public String getOpenid() { + return openid; + } + + public void setDeleteState(String deleteState) { + this.deleteState = deleteState; + } + + public String getDeleteState() { + return deleteState; + } + + public void setCreatedBy(String createdBy) { + this.createdBy = createdBy; + } + + public String getCreatedBy() { + return createdBy; + } + + public void setCreatedTime(Date createdTime) { + this.createdTime = createdTime; + } + + public Date getCreatedTime() { + return createdTime; + } + + public void setUpdatedBy(String updatedBy) { + this.updatedBy = updatedBy; + } + + public String getUpdatedBy() { + return updatedBy; + } + + public void setUpdatedTime(Date updatedTime) { + this.updatedTime = updatedTime; + } + + public Date getUpdatedTime() { + return updatedTime; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("userName", getUserName()) + .append("nickName", getNickName()) + .append("phone", getPhone()) + .append("openid", getOpenid()) + .append("deleteState", getDeleteState()) + .append("createdBy", getCreatedBy()) + .append("createdTime", getCreatedTime()) + .append("updatedBy", getUpdatedBy()) + .append("updatedTime", getUpdatedTime()) + .toString(); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/Visitor.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/Visitor.java new file mode 100644 index 0000000..80e7b7d --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/Visitor.java @@ -0,0 +1,245 @@ +package com.dcsoft.system.visitor.domain; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import com.dcsoft.common.core.annotation.Excels; +import com.dcsoft.common.core.web.domain.BaseEntity; +import com.dcsoft.system.domain.SysBranch; +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.domain.vo.SysFileVo; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.dcsoft.common.core.annotation.Excel; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 访客信息对象 vis_visitor + * + * @author 倪春 + * @date 2023-03-09 + */ +@Data +public class Visitor extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * 访客Id + */ + private Long id; + + /** + * 来访人 + */ + @Excel(name = "来访人") + private String name; + + /** + * 联系电话 + */ + private String phone; + + /** + * 用户性别(0男 1女 2保密) + */ + @Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=保密") + private String sex; + + /** + * 头像地址 + */ + private String avatar; + + /** + * 身份证号码 + */ + private String idcard; + + /** + * 车牌号码 + */ + private String carNo; + + /** + * 被访人 + */ + private Long userId; + + /** + * 访问部门 + */ + private String deptId; + + /** + * 访问部门名称 + */ + private String deptName; + + /** + * 访客类型 + */ + private String flag; + + /** + * 预约时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "预约时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date startTime; + + /** + * 来访结束时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "结束时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date endTime; + + /** + * 来访事由 + */ + private String matter; + + /** + * 携带物品 + */ + private String res; + + /** + * 人员编号对接 + */ + private String guid; + + /** + * 人像对接 + */ + private String faceGuid; + + private Long parentId; + + private List itemList; + + /** + * 审核状态 + */ + private String tabFlag; + + private VisVisitorExamine examine; + + @Excels({ + @Excel(name = "访问部门", targetAttr = "name", type = Excel.Type.EXPORT), + }) + private SysBranch branch; + + @Excels({ + @Excel(name = "访问人员", targetAttr = "name", type = Excel.Type.EXPORT), + }) + private SysPeople people; + + private Long time; + + /** + * 进入时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "进入时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date inTime; + + /** + * 离开时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "离开时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date outTime; + + /** + * 是否推送预约访客0.未推送 1已推送 + */ + private String pushType; + + /** + * 访客来源 0.访客机;1.小程序;2.后台端 + */ + private String source; + + private String state; + + private String idcardPhoto; + + private String type; + + /** + * 来访单位 + */ + private String visitingUnit; + + private String ruleId; + + private String userName; + + private String peopleId; + + private String ladderRuleId; + + private String peopleName; + + private String peoplePhone; + + private String checkCodeId; + + private String idCardStartTime; + + private String idCardEndTime; + + private String idCardAddress; + + /** + * 设备序列号 + **/ + private String deviceKey; + + private List visitor; + + /** + * 离开时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + + /** + * 职位标签 + */ + private String position; + + /** + * 审核人 + */ + private String reviewer; + + /** + * 设备部审核人 + */ + private String reviewer2; + + /** + * 安环部审核人 + */ + private String reviewer3; + + private String visitorPosition; + + /** + * 下一环节审核人 + */ + private String nextStepReviewer; + + /** + * 附件 + */ + private List fileList; + + private List reviewProcessList; +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisitorCountVo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisitorCountVo.java new file mode 100644 index 0000000..a7d9ad2 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisitorCountVo.java @@ -0,0 +1,24 @@ +package com.dcsoft.system.visitor.domain; + +import lombok.Data; + +@Data +public class VisitorCountVo { + + /** + * 访客天数据 + */ + private Integer dayCount; + + /** + * 访客本周数据 + */ + private Integer weekCount; + + /** + * 访客本月数据 + */ + private Integer monthCount; + + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisitorInfoVo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisitorInfoVo.java new file mode 100644 index 0000000..c881341 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisitorInfoVo.java @@ -0,0 +1,37 @@ +package com.dcsoft.system.visitor.domain; + +import lombok.Data; + +import java.util.List; + +@Data +public class VisitorInfoVo { + private Long id; + private String avatar; + private String name; + private String phone; + private String sex; + private String idcard; + private String carNo; + private String flag; + private String deptId; + private String deptName; + private String userId; + private String userName; + private String startTime; + private String endTime; + private String matter; + private String res; + private String remark; + private String source; + private String inTime; + private String outTime; + private String state; + private String type; + private String idCardStartTime; + private String idCardEndTime; + private String idCardAddress; + private String visitingUnit; + private List itemList; + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisitorParamVo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisitorParamVo.java new file mode 100644 index 0000000..0c58c83 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisitorParamVo.java @@ -0,0 +1,32 @@ +package com.dcsoft.system.visitor.domain; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.util.Date; + +@Data +public class VisitorParamVo { + + /** 当前记录起始索引 */ + private Integer pageNum = 1; + + /** 每页显示记录数 */ + private Integer pageSize = 10; + + /** 身份证 */ + private String idcard; + + /** 姓名 */ + private String name; + + /** + * 审核状态 0 未审核,1 已审核 + */ + private String reviewStatus; + + private String inTime; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date endTime; +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisitorRecordVo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisitorRecordVo.java new file mode 100644 index 0000000..8c19350 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisitorRecordVo.java @@ -0,0 +1,91 @@ +package com.dcsoft.system.visitor.domain; + +import com.dcsoft.common.core.web.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.util.Date; + +@Data +public class VisitorRecordVo extends BaseEntity { + /** + * 主键id + */ + private String id; + /** + * 访客id + */ + private String visitorId; + /** + * 设备序列号 + */ + private String sequence; + /** + * 来访时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date startTime; + /** + * 结束时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date endTime; + + /** + * 来访人 + */ + private String name; + + /** + * 被访人 + */ + private String peopleName; + + /** + * 创建人 + */ + private String createdBy; + /** + * 创建时间 + */ + private Date createdTime; + /** + * 更新人 + */ + private String updatedBy; + /** + * 更新时间 + */ + private Date updatedTime; + /** + * 删除状态 0.否;1.是 + */ + private String deleteState; + + /** + * 更具状态判断新增还是修改 1.新增; 2.修改 + */ + private String type; + + private Integer pageNum; + + /** 每页显示记录数 */ + private Integer pageSize; + + /** + * 开始时间 + */ + private String startTimeTxt; + /** + * 结束时间 + */ + private String endTimeTxt; + + /** + * 访客头像 + */ + private String visitorAvatar; + + + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisitorReviewProcessVo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisitorReviewProcessVo.java new file mode 100644 index 0000000..6ec3100 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisitorReviewProcessVo.java @@ -0,0 +1,31 @@ +package com.dcsoft.system.visitor.domain; + +import lombok.Data; + +@Data +public class VisitorReviewProcessVo { + /** + * 审核人 + */ + private String reviewer; + + /** + * 审核状态 0 同意;1 不同意 + */ + private String state; + + /** + * 审核人类型 + */ + private String type; + + /** + * 审核人姓名 + */ + private String reviewerName; + + /** + * 审核时间 + */ + private String createdTime; +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisitorVo.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisitorVo.java new file mode 100644 index 0000000..e657ad9 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/domain/VisitorVo.java @@ -0,0 +1,33 @@ +package com.dcsoft.system.visitor.domain; + +import lombok.Data; + +@Data +public class VisitorVo { + + /** + * 访客姓名 + */ + private String name; + + /** + * 来访事由 + */ + private String matter; + + /** + * 来访时间 + */ + private String inTime; + + /** + * 离开时间 + */ + private String outTime; + + /** + * 1已签离;2.未签离;3.今日预约的 + */ + private String state; + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/mapper/VisVisitorExamineMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/mapper/VisVisitorExamineMapper.java new file mode 100644 index 0000000..7e874b4 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/mapper/VisVisitorExamineMapper.java @@ -0,0 +1,64 @@ +package com.dcsoft.system.visitor.mapper; + +import com.dcsoft.system.visitor.domain.VisVisitorExamine; + +import java.util.List; + +/** + * 访客审核Mapper接口 + * + * @author nichun + * @date 2023-03-11 + */ +public interface VisVisitorExamineMapper +{ + /** + * 查询访客审核 + * + * @param id 访客审核主键 + * @return 访客审核 + */ + public VisVisitorExamine selectVisVisitorExamineById(Long id); + + /** + * 查询访客审核列表 + * + * @param visVisitorExamine 访客审核 + * @return 访客审核集合 + */ + public List selectVisVisitorExamineList(VisVisitorExamine visVisitorExamine); + + /** + * 新增访客审核 + * + * @param visVisitorExamine 访客审核 + * @return 结果 + */ + public int insertVisVisitorExamine(VisVisitorExamine visVisitorExamine); + + /** + * 修改访客审核 + * + * @param visVisitorExamine 访客审核 + * @return 结果 + */ + public int updateVisVisitorExamine(VisVisitorExamine visVisitorExamine); + + /** + * 删除访客审核 + * + * @param id 访客审核主键 + * @return 结果 + */ + public int deleteVisVisitorExamineById(Long id); + + /** + * 批量删除访客审核 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteVisVisitorExamineByIds(Long[] ids); + + public int deleteVisVisitorExamineByVisitorId(Long visitorId); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/mapper/VisVisitorRegisterMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/mapper/VisVisitorRegisterMapper.java new file mode 100644 index 0000000..0ffa183 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/mapper/VisVisitorRegisterMapper.java @@ -0,0 +1,68 @@ +package com.dcsoft.system.visitor.mapper; + +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.visitor.domain.VisVisitorRegister; + +import java.util.List; + +/** + * 访客注册Mapper接口 + * + * @author dcsoft + * @date 2024-05-21 + */ +public interface VisVisitorRegisterMapper { + /** + * 查询访客注册 + * + * @param id 访客注册主键 + * @return 访客注册 + */ + public VisVisitorRegister selectVisVisitorRegisterById(String id); + + /** + * 查询访客注册列表 + * + * @param visVisitorRegister 访客注册 + * @return 访客注册集合 + */ + public List selectVisVisitorRegisterList(VisVisitorRegister visVisitorRegister); + + /** + * 新增访客注册 + * + * @param visVisitorRegister 访客注册 + * @return 结果 + */ + public int insertVisVisitorRegister(VisVisitorRegister visVisitorRegister); + + /** + * 修改访客注册 + * + * @param visVisitorRegister 访客注册 + * @return 结果 + */ + public int updateVisVisitorRegister(VisVisitorRegister visVisitorRegister); + + /** + * 删除访客注册 + * + * @param id 访客注册主键 + * @return 结果 + */ + public int deleteVisVisitorRegisterById(String id); + + /** + * 批量删除访客注册 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteVisVisitorRegisterByIds(String[] ids); + + String queryVisitorRegister(SysPeople sysPeople); + + void saveVisitorRegister(SysPeople people1); + + void updateVisitorRegisterByOpenid(SysPeople sysPeople); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/mapper/VisitorMapper.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/mapper/VisitorMapper.java new file mode 100644 index 0000000..7dbd3ec --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/mapper/VisitorMapper.java @@ -0,0 +1,235 @@ +package com.dcsoft.system.visitor.mapper; + +import java.util.List; + +import com.dcsoft.common.core.web.page.TableDataInfoPage; +import com.dcsoft.system.domain.SysBranch; +import com.dcsoft.system.domain.SysManageRecord; +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.domain.vo.SysFileVo; +import com.dcsoft.system.visitor.domain.*; + +/** + * 访客信息Mapper接口 + * + * @author 倪春 + * @date 2023-03-09 + */ +public interface VisitorMapper +{ + /** + * 查询访客信息 + * + * @param id 访客信息主键 + * @return 访客信息 + */ + public Visitor selectVisitorById(Long id); + + /** + * 查询访客信息列表 + * + * @param visitor 访客信息 + * @return 访客信息集合 + */ + public List selectVisitorList(Visitor visitor); + + /** + * 新增访客信息 + * + * @param visitor 访客信息 + * @return 结果 + */ + public int insertVisitor(Visitor visitor); + + /** + * 修改访客信息 + * + * @param visitor 访客信息 + * @return 结果 + */ + public int updateVisitor(Visitor visitor); + + /** + * 删除访客信息 + * + * @param id 访客信息主键 + * @return 结果 + */ + public int deleteVisitorById(Long id); + + /** + * 批量删除访客信息 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteVisitorByIds(Long[] ids); + + public List selectVisitorItemList(Visitor visitor); + + public int deleteVisitorItemByParentId(Long parentId); + + public Visitor selectByGuid(String guid); + + public Visitor selectVisitorByPhone(String phone); + + /** + * 查询访客预约信息 + */ + List queryVisitorAppointment(VisitorParamVo paramVo); + + /** + * 修改推送状态 + */ + void updateVisitorPushType(List list); + + int queryVisitor(Visitor visitor); + + /** + * + */ + int updateVisitorInfo(Visitor paramVo); + + /** + * 查询访客信息 + */ + PersonnelInfoVo queryVisitorInfoById(String id); + + /** + * 查询未签离列表 + */ + List queryVisitorUnsigned(VisitorParamVo paramVo); + + void saveVisCheckCode(CheckCodeVo codeVo); + + CheckCodeVo queryVisCheckCodeById(String qrData); + + String queryVisCheckCode(String visitorId); + + Visitor selectVisitorInfo(SysPeople people); + + /** + * querySysManageRecord + * @return + */ + List querySysManageRecord(Long userId); + + void updateVisitorInfoGuid(List listVisitorId); + + Visitor queryVisitorGuid(String guid); + + /** + * 查询是否进入 + * @param id + * @return + */ + int queryVisitorRecord(Long id); + + /** + * 更新离开时间 + * @param record + */ + void updateVisitorRecord(VisitorRecordVo record); + + /** + * 新增访客识别记录 + * @param record + */ + void saveVisitorRecord(VisitorRecordVo record); + + /** + * 查询访客记录列表 + * @param visitor + * @return + */ + List queryVisitorRecordList(VisitorRecordVo visitor); + + /** + * 删除访客记录 + * @param ids + */ + void deleteVisitorRecordList(String[] ids); + + List querySysBranch(String deptType); + + /** + * 今日访客数 + * @param recordVo + * @return + */ + int queryVisitorDayCount(VisitorRecordVo recordVo); + + /** + * 本周访客数 + * @param recordVo + * @return + */ + int queryVisitorWeekCount(VisitorRecordVo recordVo); + + /** + * 本月访客数 + * @param recordVo + * @return + */ + int queryVisitorMonthCount(VisitorRecordVo recordVo); + + /** + * 首页头像展示 + * @param recordVo + * @return + */ + List queryVisitorAvatar(VisitorRecordVo recordVo); + + /** + * 通过手机号查询访客id + * @param phone + * @return + */ + VisitorRecordVo queryVisitorById(String phone); + + int queryVisitorByIdCount(String phone); + + /** + * 查询近七天的访客数据 + * @param paramVo + * @return + */ + List queryExportVisitorInfo(VisitorParamVo paramVo); + + List queryBranch(); + + String queryBranch1(String s); + + void updateDisconnect(Visitor visitor1); + + /** + * 保存审核记录 + * @param visitor + */ + void saveVisitorAuditRecords(Visitor visitor); + + /** + * 查询物业子部门访客审核人员 + * @param deptId + * @return + */ + List queryPropertyExaminePeople(String deptId); + + void deleteFile(SysFileVo sysFile); + + void saveFile(List sysFiles); + + List querySysFile(SysFileVo fileVo); + + void saveVisitorReviewProcess(Visitor visitor); + + SysPeople queryVisitorReviewProcess(Long id); + + void updateVisitorReviewProcess(Visitor visitor); + + String queryReviewProcess(Visitor visitor); + + int queryVisitorReviewProcessCount(Long id); + + List queryVisitorReviewProcessList(Long id); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/service/IVisVisitorExamineService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/service/IVisVisitorExamineService.java new file mode 100644 index 0000000..de03d5d --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/service/IVisVisitorExamineService.java @@ -0,0 +1,71 @@ +package com.dcsoft.system.visitor.service; + +import com.dcsoft.system.visitor.domain.VisVisitorExamine; + +import java.util.List; + +/** + * 访客审核Service接口 + * + * @author nichun + * @date 2023-03-11 + */ +public interface IVisVisitorExamineService +{ + /** + * 查询访客审核 + * + * @param id 访客审核主键 + * @return 访客审核 + */ + public VisVisitorExamine selectVisVisitorExamineById(Long id); + + /** + * 查询访客审核列表 + * + * @param visVisitorExamine 访客审核 + * @return 访客审核集合 + */ + public List selectVisVisitorExamineList(VisVisitorExamine visVisitorExamine); + + /** + * 新增访客审核 + * + * @param visVisitorExamine 访客审核 + * @return 结果 + */ + public int insertVisVisitorExamine(VisVisitorExamine visVisitorExamine); + + /** + * 修改访客审核 + * + * @param visVisitorExamine 访客审核 + * @return 结果 + */ + public int updateVisVisitorExamine(VisVisitorExamine visVisitorExamine); + + /** + * 批量删除访客审核 + * + * @param ids 需要删除的访客审核主键集合 + * @return 结果 + */ + public int deleteVisVisitorExamineByIds(Long[] ids); + + /** + * 删除访客审核信息 + * + * @param id 访客审核主键 + * @return 结果 + */ + public int deleteVisVisitorExamineById(Long id); + + /** + * 删除访客审核信息 + * + * @param visitorId 访客审核主键 + * @return 结果 + */ + public int deleteVisVisitorExamineByVisitorId(Long visitorId); + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/service/IVisVisitorRegisterService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/service/IVisVisitorRegisterService.java new file mode 100644 index 0000000..3d6b3f3 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/service/IVisVisitorRegisterService.java @@ -0,0 +1,69 @@ +package com.dcsoft.system.visitor.service; + +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.visitor.domain.VisVisitorRegister; + +import java.util.List; + +/** + * 访客注册Service接口 + * + * @author dcsoft + * @date 2024-05-21 + */ +public interface IVisVisitorRegisterService +{ + /** + * 查询访客注册 + * + * @param id 访客注册主键 + * @return 访客注册 + */ + public VisVisitorRegister selectVisVisitorRegisterById(String id); + + /** + * 查询访客注册列表 + * + * @param visVisitorRegister 访客注册 + * @return 访客注册集合 + */ + public List selectVisVisitorRegisterList(VisVisitorRegister visVisitorRegister); + + /** + * 新增访客注册 + * + * @param visVisitorRegister 访客注册 + * @return 结果 + */ + public int insertVisVisitorRegister(VisVisitorRegister visVisitorRegister); + + /** + * 修改访客注册 + * + * @param visVisitorRegister 访客注册 + * @return 结果 + */ + public int updateVisVisitorRegister(VisVisitorRegister visVisitorRegister); + + /** + * 批量删除访客注册 + * + * @param ids 需要删除的访客注册主键集合 + * @return 结果 + */ + public int deleteVisVisitorRegisterByIds(String[] ids); + + /** + * 删除访客注册信息 + * + * @param id 访客注册主键 + * @return 结果 + */ + public int deleteVisVisitorRegisterById(String id); + + String queryVisitorRegister(SysPeople sysPeople); + + void saveVisitorRegister(SysPeople people1); + + void updateVisitorRegisterByOpenid(SysPeople sysPeople); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/service/IVisitorService.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/service/IVisitorService.java new file mode 100644 index 0000000..27e625c --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/service/IVisitorService.java @@ -0,0 +1,250 @@ +package com.dcsoft.system.visitor.service; + +import java.util.List; + +import com.dcsoft.common.core.web.page.TableDataInfoPage; +import com.dcsoft.system.domain.SysBranch; +import com.dcsoft.system.domain.SysEmpowerRecord; +import com.dcsoft.system.domain.SysManageRecord; +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.domain.vo.SysFileVo; +import com.dcsoft.system.visitor.domain.*; + +/** + * 访客信息Service接口 + * + * @author 倪春 + * @date 2023-03-09 + */ +public interface IVisitorService +{ + /** + * 查询访客信息 + * + * @param id 访客信息主键 + * @return 访客信息 + */ + public Visitor selectVisitorById(Long id); + + /** + * 查询访客信息列表 + * + * @param visitor 访客信息 + * @return 访客信息集合 + */ + public List selectVisitorList(Visitor visitor); + + /** + * 新增访客信息 + * + * @param visitor 访客信息 + * @return 结果 + */ + public int insertVisitor(Visitor visitor); + + /** + * 修改访客信息 + * + * @param visitor 访客信息 + * @return 结果 + */ + public int updateVisitor(Visitor visitor); + + /** + * 批量删除访客信息 + * + * @param ids 需要删除的访客信息主键集合 + * @return 结果 + */ + public int deleteVisitorByIds(Long[] ids); + + /** + * 删除访客信息信息 + * + * @param id 访客信息主键 + * @return 结果 + */ + public int deleteVisitorById(Long id); + + public List selectVisitorItemList(Visitor item); + + public int deleteVisitorItemByParentId(Long id); + + Visitor selectByGuid(String guid); + + Visitor selectVisitorByPhone(String phone); + + /** + * 查询访客预约信息 + */ + TableDataInfoPage queryVisitorAppointment(VisitorParamVo paramVo); + + /** + * 查询黑名单 + */ + TableDataInfoPage selectSysBlackListList(VisitorParamVo paramVo); + + /** + * 查询访客人员信息 + */ + PersonnelInfoVo queryPersonnelInfo(List list); + + /** + * 查询被访人 + */ + List queryPeople(Visitor paramVo); + + /** + * 查询已审核状态信息 + */ + VisitorParamVo queryAuditedVisitor(Visitor paramVo); + + /** + * 查询详情 + */ + VisitorInfoVo queryVisitorInfo(Visitor paramVo); + + /** + * 修改状态 + */ + int updateState(Visitor paramVo); + + int queryVisitor(Visitor visitor); + + /** + * 查询访客信息 + */ + PersonnelInfoVo queryVisitorInfoById(String id); + + /** + * 查询未签离列表 + */ + List queryVisitorUnsigned(VisitorParamVo paramVo); + + /** + * + * @param paramVo + * @return + */ + int updateSignOut(Visitor paramVo); + + void saveVisCheckCode(CheckCodeVo codeVo); + + CheckCodeVo queryVisCheckCodeById(String qrData); + + String queryVisCheckCode(String visitorId); + + Visitor selectVisitorInfo(SysPeople people); + + /** + * 查询被访人授权记录 + * @param userId + * @return + */ + List querySysManageRecord(Long userId); + + /** + * 保存访客guid + */ + void updateVisitorInfoGuid(List listVisitorId); + + /** + * 查询访客guid + * @param personId + * @return + */ + Visitor queryVisitorGuid(String personId); + + /** + * 查询是否进入 + * @param id + */ + int queryVisitorRecord(Long id); + + /** + * 更新离开时间 + * @param record + */ + void updateVisitorRecord(VisitorRecordVo record); + + /** + * 新增访客识别记录 + * @param record + */ + void saveVisitorRecord(VisitorRecordVo record); + + /** + * 查询访客记录列表 + * @param visitor + * @return + */ + List queryVisitorRecordList(VisitorRecordVo visitor); + + /** + * 删除访客记录 + * @param ids + */ + void deleteVisitorRecordList(String[] ids); + + List querySysBranch(String deptType); + + /** + * 查询访客数量(今日,本周,本月) + * @param recordVo + * @return + */ + VisitorCountVo queryVisitorCount(VisitorRecordVo recordVo); + + /** + * 首页头像展示 + * @param recordVo + * @return + */ + List queryVisitorAvatar(VisitorRecordVo recordVo); + + VisitorRecordVo queryVisitorById(String phone); + + int queryVisitorByIdCount(String phone); + + /** + * 查询近七天的访客数据 + * @param paramVo + * @return + */ + List queryExportVisitorInfo(VisitorParamVo paramVo); + + String queryTest(VisitorRecordVo recordVo); + + /** + * 保存访客机断线数据 + * @param visitor + */ + void saveDisconnect(List visitor); + + /** + * 保存审核记录 + * @param visitor + */ + void saveVisitorAuditRecords(Visitor visitor); + + /** + * 查询物业子部门访客审核人员 + * @param deptId + * @return + */ + List queryPropertyExaminePeople(String deptId); + + void deleteFile(SysFileVo sysFile); + + void saveFile(List sysFiles); + + void saveVisitorReviewProcess(Visitor visitor); + + SysPeople queryVisitorReviewProcess(Long id); + + void updateVisitorReviewProcess(Visitor visitor); + + String queryReviewProcess(Visitor visitor); + + int queryVisitorReviewProcessCount(Long id); +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/service/impl/VisVisitorExamineServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/service/impl/VisVisitorExamineServiceImpl.java new file mode 100644 index 0000000..1938177 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/service/impl/VisVisitorExamineServiceImpl.java @@ -0,0 +1,105 @@ +package com.dcsoft.system.visitor.service.impl; + +import java.util.List; +import com.dcsoft.common.core.utils.DateUtils; +import com.dcsoft.common.security.utils.SecurityUtils; +import com.dcsoft.system.visitor.domain.VisVisitorExamine; +import com.dcsoft.system.visitor.mapper.VisVisitorExamineMapper; +import com.dcsoft.system.visitor.service.IVisVisitorExamineService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + + +/** + * 访客审核Service业务层处理 + * + * @author nichun + * @date 2023-03-11 + */ +@Service +public class VisVisitorExamineServiceImpl implements IVisVisitorExamineService +{ + @Autowired + private VisVisitorExamineMapper visVisitorExamineMapper; + + /** + * 查询访客审核 + * + * @param id 访客审核主键 + * @return 访客审核 + */ + @Override + public VisVisitorExamine selectVisVisitorExamineById(Long id) + { + return visVisitorExamineMapper.selectVisVisitorExamineById(id); + } + + /** + * 查询访客审核列表 + * + * @param visVisitorExamine 访客审核 + * @return 访客审核 + */ + @Override + public List selectVisVisitorExamineList(VisVisitorExamine visVisitorExamine) + { + return visVisitorExamineMapper.selectVisVisitorExamineList(visVisitorExamine); + } + + /** + * 新增访客审核 + * + * @param visVisitorExamine 访客审核 + * @return 结果 + */ + @Override + public int insertVisVisitorExamine(VisVisitorExamine visVisitorExamine) + { + visVisitorExamine.setCreateTime(DateUtils.getNowDate()); + return visVisitorExamineMapper.insertVisVisitorExamine(visVisitorExamine); + } + + /** + * 修改访客审核 + * + * @param visVisitorExamine 访客审核 + * @return 结果 + */ + @Override + public int updateVisVisitorExamine(VisVisitorExamine visVisitorExamine) + { + visVisitorExamine.setUpdateTime(DateUtils.getNowDate()); + return visVisitorExamineMapper.updateVisVisitorExamine(visVisitorExamine); + } + + /** + * 批量删除访客审核 + * + * @param ids 需要删除的访客审核主键 + * @return 结果 + */ + @Override + public int deleteVisVisitorExamineByIds(Long[] ids) + { + return visVisitorExamineMapper.deleteVisVisitorExamineByIds(ids); + } + + /** + * 删除访客审核信息 + * + * @param id 访客审核主键 + * @return 结果 + */ + @Override + public int deleteVisVisitorExamineById(Long id) + { + return visVisitorExamineMapper.deleteVisVisitorExamineById(id); + } + + @Override + public int deleteVisVisitorExamineByVisitorId(Long visitorId) { + return visVisitorExamineMapper.deleteVisVisitorExamineByVisitorId(visitorId); + } + + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/service/impl/VisVisitorRegisterServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/service/impl/VisVisitorRegisterServiceImpl.java new file mode 100644 index 0000000..9c159a9 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/service/impl/VisVisitorRegisterServiceImpl.java @@ -0,0 +1,103 @@ +package com.dcsoft.system.visitor.service.impl; + +import java.util.List; + +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.visitor.domain.VisVisitorRegister; +import com.dcsoft.system.visitor.mapper.VisVisitorRegisterMapper; +import com.dcsoft.system.visitor.service.IVisVisitorRegisterService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * 访客注册Service业务层处理 + * + * @author dcsoft + * @date 2024-05-21 + */ +@Service +public class VisVisitorRegisterServiceImpl implements IVisVisitorRegisterService { + @Autowired + private VisVisitorRegisterMapper visVisitorRegisterMapper; + + /** + * 查询访客注册 + * + * @param id 访客注册主键 + * @return 访客注册 + */ + @Override + public VisVisitorRegister selectVisVisitorRegisterById(String id) { + return visVisitorRegisterMapper.selectVisVisitorRegisterById(id); + } + + /** + * 查询访客注册列表 + * + * @param visVisitorRegister 访客注册 + * @return 访客注册 + */ + @Override + public List selectVisVisitorRegisterList(VisVisitorRegister visVisitorRegister) { + return visVisitorRegisterMapper.selectVisVisitorRegisterList(visVisitorRegister); + } + + /** + * 新增访客注册 + * + * @param visVisitorRegister 访客注册 + * @return 结果 + */ + @Override + public int insertVisVisitorRegister(VisVisitorRegister visVisitorRegister) { + return visVisitorRegisterMapper.insertVisVisitorRegister(visVisitorRegister); + } + + /** + * 修改访客注册 + * + * @param visVisitorRegister 访客注册 + * @return 结果 + */ + @Override + public int updateVisVisitorRegister(VisVisitorRegister visVisitorRegister) { + return visVisitorRegisterMapper.updateVisVisitorRegister(visVisitorRegister); + } + + /** + * 批量删除访客注册 + * + * @param ids 需要删除的访客注册主键 + * @return 结果 + */ + @Override + public int deleteVisVisitorRegisterByIds(String[] ids) { + return visVisitorRegisterMapper.deleteVisVisitorRegisterByIds(ids); + } + + /** + * 删除访客注册信息 + * + * @param id 访客注册主键 + * @return 结果 + */ + @Override + public int deleteVisVisitorRegisterById(String id) { + return visVisitorRegisterMapper.deleteVisVisitorRegisterById(id); + } + + @Override + public String queryVisitorRegister(SysPeople sysPeople) { + return visVisitorRegisterMapper.queryVisitorRegister(sysPeople); + } + + @Override + public void saveVisitorRegister(SysPeople people1) { + visVisitorRegisterMapper.saveVisitorRegister(people1); + } + + @Override + public void updateVisitorRegisterByOpenid(SysPeople sysPeople) { + visVisitorRegisterMapper.updateVisitorRegisterByOpenid(sysPeople); + } +} diff --git a/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/service/impl/VisitorServiceImpl.java b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/service/impl/VisitorServiceImpl.java new file mode 100644 index 0000000..11f5f5c --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/java/com/dcsoft/system/visitor/service/impl/VisitorServiceImpl.java @@ -0,0 +1,671 @@ +package com.dcsoft.system.visitor.service.impl; + +import com.dcsoft.common.core.constant.Constants; +import com.dcsoft.common.core.domain.R; +import com.dcsoft.common.core.exception.ServiceException; +import com.dcsoft.common.core.web.page.TableDataInfoPage; +import com.dcsoft.common.datascope.annotation.DataScope; +import com.dcsoft.system.api.RemoteFileService; +import com.dcsoft.system.api.domain.SysFile; +import com.dcsoft.system.domain.SysBlackList; +import com.dcsoft.system.domain.SysBranch; +import com.dcsoft.system.domain.SysManageRecord; +import com.dcsoft.system.domain.SysPeople; +import com.dcsoft.system.domain.vo.SysFileVo; +import com.dcsoft.system.mapper.SysBlackListMapper; +import com.dcsoft.system.mapper.SysDictDataMapper; +import com.dcsoft.system.utils.PictureUtils; +import com.dcsoft.system.visitor.domain.*; +import com.dcsoft.system.visitor.mapper.VisitorMapper; +import com.dcsoft.system.visitor.service.IVisitorService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +import static com.dcsoft.common.core.utils.PageUtils.startPage; + +/** + * 访客信息Service业务层处理 + * + * @author 倪春 + * @date 2023-03-09 + */ +@Slf4j +@Service +public class VisitorServiceImpl implements IVisitorService { + @Resource + private VisitorMapper visitorMapper; + + @Resource + private SysBlackListMapper sysBlackListMapper; + + @Autowired + private SysDictDataMapper dictDataMapper; + + @Autowired + private RemoteFileService fileService; + + @Value("${system.type}") + public String systemType; + + /** + * 卡权限创建接口 + */ + public static final String create = "/cardinfo/create"; + + /** + * 查询访客信息 + * + * @param id 访客信息主键 + * @return 访客信息 + */ + @Override + public Visitor selectVisitorById(Long id) { + Visitor visitor = visitorMapper.selectVisitorById(id); + if (visitor == null) { + return new Visitor(); + } + if(StringUtils.isNotEmpty(visitor.getVisitorPosition())) { + visitor.setPosition(visitor.getVisitorPosition()); + } + Visitor item = new Visitor(); + item.setParentId(id); + List itemList = visitorMapper.selectVisitorItemList(item); + visitor.setItemList(itemList); + + SysFileVo fileVo = new SysFileVo(); + fileVo.setBusinessId(String.valueOf(id)); + fileVo.setBusinessType("sys_visitor_insurance"); + List list = visitorMapper.querySysFile(fileVo); + if(!CollectionUtils.isEmpty(list)) { + try { + for (SysFileVo sysFileVo : list) { + sysFileVo.setFileName(URLDecoder.decode(sysFileVo.getFileName(), "utf-8")); + } + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + visitor.setFileList(list); + } + List reviewProcess = visitorMapper.queryVisitorReviewProcessList(id); + if(!CollectionUtils.isEmpty(reviewProcess)) { + boolean flag = true; + for (VisitorReviewProcessVo process : reviewProcess) { + if(!flag) { + process.setState(null); + } + if(Constants.ONE.equals(process.getState())) { + flag = false; + } + } + visitor.setReviewProcessList(reviewProcess); + } + return visitor; + } + + /** + * 查询访客信息列表 + * + * @param visitor 访客信息 + * @return 访客信息 + */ + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List selectVisitorList(Visitor visitor) { + return visitorMapper.selectVisitorList(visitor); + } + + /** + * 新增访客信息 + * + * @param visitor 访客信息 + * @return 结果 + */ + @Override + public int insertVisitor(Visitor visitor) { + return visitorMapper.insertVisitor(visitor); + } + + /** + * 修改访客信息 + * + * @param visitor 访客信息 + * @return 结果 + */ + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public int updateVisitor(Visitor visitor) { + visitor.setUpdateTime(new Date()); + return visitorMapper.updateVisitor(visitor); + } + + /** + * 批量删除访客信息 + * + * @param ids 需要删除的访客信息主键 + * @return 结果 + */ + @Override + public int deleteVisitorByIds(Long[] ids) { + return visitorMapper.deleteVisitorByIds(ids); + } + + /** + * 删除访客信息信息 + * + * @param id 访客信息主键 + * @return 结果 + */ + @Override + public int deleteVisitorById(Long id) { + return visitorMapper.deleteVisitorById(id); + } + + @Override + public List selectVisitorItemList(Visitor visitor) { + return visitorMapper.selectVisitorItemList(visitor); + } + + @Override + public int deleteVisitorItemByParentId(Long parentId) { + return visitorMapper.deleteVisitorItemByParentId(parentId); + } + + @Override + public Visitor selectByGuid(String guid) { + return visitorMapper.selectByGuid(guid); + } + + @Override + public Visitor selectVisitorByPhone(String phone) { + return visitorMapper.selectVisitorByPhone(phone); + } + + /** + * 查询访客预约信息 + */ + @Override + public TableDataInfoPage queryVisitorAppointment(VisitorParamVo paramVo) { + List visitors = visitorMapper.queryVisitorAppointment(paramVo); + List result = visitors.stream() + .skip((long) (paramVo.getPageNum() - 1) * paramVo.getPageSize()) + .limit(paramVo.getPageSize()) + .collect(Collectors.toList()); + return new TableDataInfoPage(result, visitors.size(), paramVo.getPageNum(), result.size()); + } + + /** + * 查询黑名单 + */ + @Override + public TableDataInfoPage selectSysBlackListList(VisitorParamVo paramVo) { + List sysBlackLists = sysBlackListMapper.selectSysBlackListList(new SysBlackList()); + List result = sysBlackLists.stream() + .skip((long) (paramVo.getPageNum() - 1) * paramVo.getPageSize()) + .limit(paramVo.getPageSize()) + .collect(Collectors.toList()); + return new TableDataInfoPage(result, sysBlackLists.size(), paramVo.getPageNum(), result.size()); + } + + /** + * 查询访客人员信息 + */ + @Override + public PersonnelInfoVo queryPersonnelInfo(List list) { + PersonnelInfoVo sysEmpowerRecords = sysBlackListMapper.queryPersonnelInfo(list); + List infoVos = sysBlackListMapper.queryGeneralInfo(sysEmpowerRecords.getId()); + sysEmpowerRecords.setList(infoVos); + return sysEmpowerRecords; + } + + /** + * 查询被访人 + */ + @Override + public List queryPeople(Visitor paramVo) { + return sysBlackListMapper.queryPeople(paramVo); + } + + /** + * 查询已审核状态信息 + */ + @Override + public VisitorParamVo queryAuditedVisitor(Visitor paramVo) { + return sysBlackListMapper.queryAuditedVisitor(paramVo); + } + + /** + * 查询详情 + */ + @Override + public VisitorInfoVo queryVisitorInfo(Visitor paramVo) { + VisitorParamVo visitorParamVo = sysBlackListMapper.queryAuditedVisitor(paramVo); + if (visitorParamVo != null) { + checkVisitor(visitorParamVo); + } + + VisitorInfoVo visitorInfoVo = sysBlackListMapper.queryVisitorInfo(paramVo); + if (visitorInfoVo != null) { + Visitor infoVo = new Visitor(); + infoVo.setId(visitorInfoVo.getId()); + visitorInfoVo.setItemList(sysBlackListMapper.queryFollowUp(infoVo)); + String s = dictDataMapper.selectDictLabel("vis_info_reason", visitorInfoVo.getMatter()); + visitorInfoVo.setMatter(s); + visitorInfoVo.setDeptName(dictDataMapper.selectDictLabel("sys_company_type", visitorInfoVo.getDeptId())); + } + + + return visitorInfoVo; + } + + /** + * 修改状态 + */ + @Override + public int updateState(Visitor paramVo) { + VisitorParamVo visitorParamVo = sysBlackListMapper.queryAuditedVisitor(paramVo); + if (visitorParamVo != null) { + checkVisitor(visitorParamVo); + } + + VisitorInfoVo visitorInfo = sysBlackListMapper.queryVisitorType(paramVo); + if ("2".equals(paramVo.getType()) && StringUtils.isEmpty(visitorInfo.getInTime())) { + throw new ServiceException("您未签到"); + } + if ("2".equals(paramVo.getType()) && "2".equals(visitorInfo.getType())) { + throw new ServiceException("您已经签离"); + } + if ("1".equals(paramVo.getType()) && "2".equals(visitorInfo.getType())) { + throw new ServiceException("您已经签离"); + } + + List visitorInfoVos = sysBlackListMapper.queryFollowUp(paramVo); + // 修改同行人 + for (VisitorInfoVo visitorInfoVo : visitorInfoVos) { + Visitor visitor = new Visitor(); + visitor.setId(visitorInfoVo.getId()); + if (Constants.ONE.equals(paramVo.getType())) { + visitor.setInTime(new Date()); + visitor.setType("1"); + } + if (Constants.TWO.equals(paramVo.getType())) { + visitor.setType("2"); + visitor.setOutTime(new Date()); + } + visitorMapper.updateVisitor(visitor); + } + if ("1".equals(paramVo.getType())) { + paramVo.setInTime(new Date()); + } + if ("2".equals(paramVo.getType())) { + paramVo.setOutTime(new Date()); + } + return visitorMapper.updateVisitorInfo(paramVo); + } + + /** + * 查询访客预约数 + */ + @Override + public int queryVisitor(Visitor visitor) { + return visitorMapper.queryVisitor(visitor); + } + + /** + * 访客信息 + */ + @Override + public PersonnelInfoVo queryVisitorInfoById(String id) { + return visitorMapper.queryVisitorInfoById(id); + } + + /** + * 查询未签离列表 + */ + @Override + public List queryVisitorUnsigned(VisitorParamVo paramVo) { + startPage(); + return visitorMapper.queryVisitorUnsigned(paramVo); + } + + @Override + public int updateSignOut(Visitor paramVo) { + List visitorInfoVos = sysBlackListMapper.queryFollowUp(paramVo); + Visitor visitorInfo = new Visitor(); + // 修改同行人 + for (VisitorInfoVo visitorInfoVo : visitorInfoVos) { + Visitor visitor = new Visitor(); + visitor.setId(visitorInfoVo.getId()); + if (Constants.ONE.equals(paramVo.getType())) { + visitor.setInTime(new Date()); + } + if (Constants.TWO.equals(paramVo.getType())) { + visitor.setOutTime(new Date()); + } + visitorMapper.updateVisitor(visitor); + } + if ("1".equals(paramVo.getType())) { + visitorInfo.setInTime(new Date()); + } + if ("2".equals(paramVo.getType())) { + visitorInfo.setOutTime(new Date()); + } + visitorInfo.setId(paramVo.getId()); + return visitorMapper.updateVisitor(visitorInfo); + } + + @Override + public void saveVisCheckCode(CheckCodeVo codeVo) { + visitorMapper.saveVisCheckCode(codeVo); + } + + @Override + public CheckCodeVo queryVisCheckCodeById(String qrData) { + return visitorMapper.queryVisCheckCodeById(qrData); + } + + @Override + public String queryVisCheckCode(String visitorId) { + return visitorMapper.queryVisCheckCode(visitorId); + } + + @Override + public Visitor selectVisitorInfo(SysPeople people) { + return visitorMapper.selectVisitorInfo(people); + } + + /** + * 查询被访人授权记录 + * + * @param userId + * @return + */ + @Override + public List querySysManageRecord(Long userId) { + return visitorMapper.querySysManageRecord(userId); + } + + /** + * 保存访客guid + */ + @Override + public void updateVisitorInfoGuid(List listVisitorId) { + visitorMapper.updateVisitorInfoGuid(listVisitorId); + } + + @Override + public Visitor queryVisitorGuid(String guid) { + return visitorMapper.queryVisitorGuid(guid); + } + + /** + * 查询是否进入 + * + * @param id + */ + @Override + public int queryVisitorRecord(Long id) { + return visitorMapper.queryVisitorRecord(id); + } + + /** + * 更新离开时间 + * + * @param record + */ + @Override + public void updateVisitorRecord(VisitorRecordVo record) { + visitorMapper.updateVisitorRecord(record); + } + + /** + * 新增访客识别记录 + * + * @param record + */ + @Override + public void saveVisitorRecord(VisitorRecordVo record) { + visitorMapper.saveVisitorRecord(record); + } + + /** + * 查询访客记录列表 + * + * @param visitor + * @return + */ + @Override + public List queryVisitorRecordList(VisitorRecordVo visitor) { + return visitorMapper.queryVisitorRecordList(visitor); + } + + /** + * 删除访客记录 + * + * @param ids + */ + @Override + public void deleteVisitorRecordList(String[] ids) { + visitorMapper.deleteVisitorRecordList(ids); + } + + @Override + public List querySysBranch(String deptType) { + return visitorMapper.querySysBranch(deptType); + } + + /** + * 查询访客数量(今日,本周,本月) + * + * @param recordVo + * @return + */ + @Override + public VisitorCountVo queryVisitorCount(VisitorRecordVo recordVo) { + VisitorCountVo visitorCountVo = new VisitorCountVo(); + recordVo.setType(systemType); + int dayCount = visitorMapper.queryVisitorDayCount(recordVo); + int weekCount = visitorMapper.queryVisitorWeekCount(recordVo); + int monthCount = visitorMapper.queryVisitorMonthCount(recordVo); + visitorCountVo.setDayCount(dayCount); + visitorCountVo.setWeekCount(weekCount); + visitorCountVo.setMonthCount(monthCount); + return visitorCountVo; + } + + /** + * 首页头像展示 + * + * @param recordVo + * @return + */ + @Override + public List queryVisitorAvatar(VisitorRecordVo recordVo) { + return visitorMapper.queryVisitorAvatar(recordVo); + } + + /** + * 通过手机号查询访客id + * + * @param phone + * @return + */ + @Override + public VisitorRecordVo queryVisitorById(String phone) { + return visitorMapper.queryVisitorById(phone); + } + + @Override + public int queryVisitorByIdCount(String phone) { + return visitorMapper.queryVisitorByIdCount(phone); + } + + /** + * 查询近七天的访客数据 + * + * @param paramVo + * @return + */ + @Override + public List queryExportVisitorInfo(VisitorParamVo paramVo) { + return visitorMapper.queryExportVisitorInfo(paramVo); + } + + + @Override + public String queryTest(VisitorRecordVo recordVo) { + List list = visitorMapper.queryBranch(); + for (String s : list) { + String branch = visitorMapper.queryBranch1(s); + System.out.println(branch); + } + return null; + } + + /** + * 访客校验 + */ + private void checkVisitor(VisitorParamVo visitorParamVo) { +// if(visitorParamVo == null) { +// throw new ServiceException("未查询到预约信息"); +// } + if (Constants.ZERO.equals(visitorParamVo.getReviewStatus())) { + throw new ServiceException("您未审核"); + } + if (Constants.TWO.equals(visitorParamVo.getReviewStatus())) { + throw new ServiceException("您审核未通过"); + } + + if (visitorParamVo.getEndTime().getTime() < new Date().getTime()) { + throw new ServiceException("您得预约时间已超时"); + } + + } + + /** + * 保存访客机断线数据 + * + * @param visitor + */ + @Override + @Transactional + public void saveDisconnect(List visitor) { + for (Visitor visitor1 : visitor) { + log.info("保存断线数据:" + visitor1); + if (visitorMapper.queryVisitor(visitor1) > 0) { + MultipartFile file = PictureUtils.base64ToMultipartFiles(visitor1.getAvatar()); + R sysFileR = fileService.uploadMinio1(file, "true"); + visitor1.setAvatar(sysFileR.getData().getUrl()); + visitorMapper.updateDisconnect(visitor1); + } else { + MultipartFile file = PictureUtils.base64ToMultipartFiles(visitor1.getAvatar()); + R sysFileR = fileService.uploadMinio1(file, "true"); + visitor1.setCreateTime(visitor1.getCreateTime()); + visitor1.setStartTime(visitor1.getCreateTime()); + visitor1.setSource(Constants.ZERO); + visitor1.setAvatar(sysFileR.getData().getUrl()); + visitor1.setState(Constants.ONE); + visitor1.setType(visitor1.getOutTime() == null ? Constants.ONE : Constants.TWO); + visitorMapper.insertVisitor(visitor1); + } + List itemList = visitor1.getItemList(); + // 随访人员 + if (!CollectionUtils.isEmpty(itemList)) { + for (Visitor item : itemList) { + log.info("保存断线随访人数据:" + item); + if (visitorMapper.queryVisitor(item) > 0) { + MultipartFile file = PictureUtils.base64ToMultipartFiles(item.getAvatar()); + R sysFileR = fileService.uploadMinio1(file, "true"); + item.setAvatar(sysFileR.getData().getUrl()); + visitorMapper.updateDisconnect(item); + } else { + if (StringUtils.isNotEmpty(item.getAvatar())) { + MultipartFile multipartFile = PictureUtils.base64ToMultipartFiles(item.getAvatar()); + R uploadMinio = fileService.uploadMinio1(multipartFile, "true"); + item.setAvatar(uploadMinio.getData().getUrl()); + } + item.setParentId(visitor1.getId()); + item.setSource(Constants.ZERO); + item.setUserId(item.getUserId()); + item.setDeptId(item.getDeptId()); + item.setCreateTime(visitor1.getCreateTime()); + item.setStartTime(visitor1.getStartTime()); + item.setEndTime(visitor1.getEndTime()); + item.setState(Constants.ONE); + item.setType(item.getOutTime() == null ? Constants.ONE : Constants.TWO); + visitorMapper.insertVisitor(item); + } + } + } + } + } + + /** + * 保存审核记录 + * + * @param visitor + */ + @Override + public void saveVisitorAuditRecords(Visitor visitor) { + visitorMapper.saveVisitorAuditRecords(visitor); + } + + /** + * 查询物业子部门访客审核人员 + * + * @param deptId + * @return + */ + @Override + public List queryPropertyExaminePeople(String deptId) { + return visitorMapper.queryPropertyExaminePeople(deptId); + } + + @Override + public void deleteFile(SysFileVo sysFile) { + visitorMapper.deleteFile(sysFile); + } + + @Override + public void saveFile(List sysFiles) { + visitorMapper.saveFile(sysFiles); + } + + @Override + public void saveVisitorReviewProcess(Visitor visitor) { + visitorMapper.saveVisitorReviewProcess(visitor); + } + + @Override + public SysPeople queryVisitorReviewProcess(Long id) { + return visitorMapper.queryVisitorReviewProcess(id); + } + + @Override + public void updateVisitorReviewProcess(Visitor visitor) { + visitorMapper.updateVisitorReviewProcess(visitor); + } + + @Override + public String queryReviewProcess(Visitor visitor) { + return visitorMapper.queryReviewProcess(visitor); + } + + @Override + public int queryVisitorReviewProcessCount(Long id) { + return visitorMapper.queryVisitorReviewProcessCount(id); + } + +} diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/banner.txt b/dcsoft-modules/dcsoft-system/src/main/resources/banner.txt new file mode 100644 index 0000000..7f07076 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/banner.txt @@ -0,0 +1,7 @@ +Spring Boot Version: ${spring-boot.version} +Spring Application Name: ${spring.application.name} + + ___ ___ ___ ___ __ __ ___ _____ ___ __ __ + | \ / __| / __| ___ / __| \ \ / / / __| |_ _| | __| | \/ | + | |) | | (__ \__ \ |___| \__ \ \ V / \__ \ | | | _| | |\/| | + |___/ \___| |___/ _____ |___/ _|_|_ |___/ _|_|_ |___| |_|__|_| diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/bootstrap.yml b/dcsoft-modules/dcsoft-system/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..e2f3528 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/bootstrap.yml @@ -0,0 +1,59 @@ +# Tomcat +server: + port: 9201 + +# Spring +spring: + application: + # 应用名称 + name: dcsoft-system + profiles: + # 环境配置 + active: dev + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: 127.0.0.1:8848 + config: + # 配置中心地址 + server-addr: 127.0.0.1:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + + +## Tomcat +#server: +# port: 9201 +# +## Spring +#spring: +# application: +# # 应用名称 +# name: dcsoft-system +# profiles: +# # 环境配置 +# active: dev +# cloud: +# nacos: +# discovery: +# # 服务注册地址 +# server-addr: 127.0.0.1:8848 +# config: +# # 配置中心地址 +# server-addr: 192.168.1.183:8848 +# # 配置文件格式 +# file-extension: yml +# group: jinjiang-system +# namespace: b06abbf2-ec74-4e57-8848-32885956fec7 +# prefix: dev +# config: +# import: +# - optional:nacos:${spring.cloud.nacos.config.prefix}.${spring.cloud.nacos.config.file-extension} +# # 共享配置 +# shared-configs: +# - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/logback.xml b/dcsoft-modules/dcsoft-system/src/main/resources/logback.xml new file mode 100644 index 0000000..95526a4 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/logback.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/info.log + + + + ${log.path}/info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/error.log + + + + ${log.path}/error.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + + + + + + + + + + + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/car/TbCarMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/car/TbCarMapper.xml new file mode 100644 index 0000000..7c91ccb --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/car/TbCarMapper.xml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + select id, car_no, plate_type,user_id,car_type,driving_url, plate_color, card_no, stru_start_time, stru_stop_time, person_no, is_del, sync,owner_name,owner_phone from tb_car + + + + + + + + insert into tb_car + + id, + user_id, + car_type, + driving_url, + car_no, + plate_type, + plate_color, + card_no, + stru_start_time, + stru_stop_time, + person_no, + is_del, + sync, + owner_name, + owner_phone, + + + #{id}, + #{userId}, + #{carType}, + #{drivingUrl}, + #{carNo}, + #{plateType}, + #{plateColor}, + #{cardNo}, + #{struStartTime}, + #{struStopTime}, + #{personNo}, + #{isDel}, + #{sync}, + #{ownerName}, + #{ownerPhone}, + + + + + update tb_car + + car_no = #{carNo}, + plate_type = #{plateType}, + plate_color = #{plateColor}, + card_no = #{cardNo}, + stru_start_time = #{struStartTime}, + stru_stop_time = #{struStopTime}, + person_no = #{personNo}, + is_del = #{isDel}, + sync = #{sync}, + owner_name = #{ownerName}, + owner_phone = #{ownerPhone}, + user_id = #{userId}, + car_type = #{carType}, + driving_url = #{drivingUrl}, + + where id = #{id} + + + + delete from tb_car where id = #{id} + + + + delete from tb_car where id in + + #{id} + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/car/TbCarRecordMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/car/TbCarRecordMapper.xml new file mode 100644 index 0000000..92fb084 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/car/TbCarRecordMapper.xml @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, park_code, unique_no, direction, plate_no, card_no, pass_time, veh_type, veh_color, operator_name, terminal_no, gate_name, lane_name, in_pass_time, in_unique_no, should_pay, actual_pay, pic_file_path, pic_plate_file_path, pic_vehicle_file_data, pic_plate_file_data, data_type from tb_car_record + + + + + + + + insert into tb_car_record + + id, + park_code, + unique_no, + direction, + plate_no, + card_no, + pass_time, + veh_type, + veh_color, + operator_name, + terminal_no, + gate_name, + lane_name, + in_pass_time, + in_unique_no, + should_pay, + actual_pay, + pic_file_path, + pic_plate_file_path, + pic_vehicle_file_data, + pic_plate_file_data, + data_type, + + + #{id}, + #{parkCode}, + #{uniqueNo}, + #{direction}, + #{plateNo}, + #{cardNo}, + #{passTime}, + #{vehType}, + #{vehColor}, + #{operatorName}, + #{terminalNo}, + #{gateName}, + #{laneName}, + #{inPassTime}, + #{inUniqueNo}, + #{shouldPay}, + #{actualPay}, + #{picFilePath}, + #{picPlateFilePath}, + #{picVehicleFileData}, + #{picPlateFileData}, + #{dataType}, + + + + + update tb_car_record + + park_code = #{parkCode}, + unique_no = #{uniqueNo}, + direction = #{direction}, + plate_no = #{plateNo}, + card_no = #{cardNo}, + pass_time = #{passTime}, + veh_type = #{vehType}, + veh_color = #{vehColor}, + operator_name = #{operatorName}, + terminal_no = #{terminalNo}, + gate_name = #{gateName}, + lane_name = #{laneName}, + in_pass_time = #{inPassTime}, + in_unique_no = #{inUniqueNo}, + should_pay = #{shouldPay}, + actual_pay = #{actualPay}, + pic_file_path = #{picFilePath}, + pic_plate_file_path = #{picPlateFilePath}, + pic_vehicle_file_data = #{picVehicleFileData}, + pic_plate_file_data = #{picPlateFileData}, + data_type = #{dataType}, + + where id = #{id} + + + + delete from tb_car_record where id = #{id} + + + + delete from tb_car_record where id in + + #{id} + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysBackGroupMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysBackGroupMapper.xml new file mode 100644 index 0000000..e39f62b --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysBackGroupMapper.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + select id, name, avatar,logo from sys_back_group + + + + + + + + insert into sys_back_group + + name, + avatar, + logo, + + + #{name}, + #{avatar}, + #{logo}, + + + + + + update sys_back_group + + name = #{name}, + avatar = #{avatar}, + logo = #{logo}, + + where id = #{id} + + + + delete from sys_back_group where id = #{id} + + + + delete from sys_back_group where id in + + #{id} + + + + + delete from sys_back_group + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysBlackListMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysBlackListMapper.xml new file mode 100644 index 0000000..3b8684f --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysBlackListMapper.xml @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + select id, name, phone, sex, idcard, car_no, remark, create_by, create_time, update_by, update_time from sys_black_list + + + + + + + + + + + + + + + + insert into sys_black_list + + name, + phone, + sex, + idcard, + car_no, + remark, + create_by, + create_time, + update_by, + update_time, + + + #{name}, + #{phone}, + #{sex}, + #{idcard}, + #{carNo}, + #{remark}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update sys_black_list + + name = #{name}, + phone = #{phone}, + sex = #{sex}, + idcard = #{idcard}, + car_no = #{carNo}, + remark = #{remark}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from sys_black_list where id = #{id} + + + + delete from sys_black_list where id in + + #{id} + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysBranchMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysBranchMapper.xml new file mode 100644 index 0000000..76830b4 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysBranchMapper.xml @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + select b.id, b.name, b.leader, b.phone, b.parent_id, b.ancestors, b.space_id,b.dept_id, b.remark, b.create_by, + b.create_time, b.update_by, b.update_time, b.rule_id, b.ladder_rule_id, b.is_examine isExamine + from sys_branch b + left join sys_dept d on b.dept_id = d.dept_id + + + + + + + + insert into sys_branch + + id, + name, + leader, + phone, + parent_id, + ancestors, + space_id, + remark, + create_by, + create_time, + update_by, + update_time, + dept_id, + rule_id, + ladder_rule_id, + + + #{id}, + #{name}, + #{leader}, + #{phone}, + #{parentId}, + #{ancestors}, + #{spaceId}, + #{remark}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{deptId}, + #{ruleId}, + #{ladderRuleId}, + + + + insert into sys_branch (id, name, parent_id, level, ancestors) + values + + ( + #{i.deptcode}, + #{i.name}, + #{i.parentcode}, + #{i.level}, + #{i.ancestors} + ) + + ON DUPLICATE KEY UPDATE + name = values(name), + parent_id = values(parent_id), + level = values(level), + ancestors = values(ancestors); + + + insert into sys_people (sex, branch_id, position, name, phone, gh, guid, del_flag) + VALUES + + ( + #{i.sex}, + #{i.ssbm}, + #{i.posts}, + #{i.lastname}, + #{i.telphone}, + #{i.workcode}, + REPLACE(uuid(), '-', ''), + #{i.delFlag} + ) + + ON DUPLICATE KEY UPDATE + sex = values(sex), + branch_id = values(branch_id), + position = values(position), + name = values(name), + phone = values(phone), + del_flag = values(del_flag) + + + insert into jj_station(id, postid, deptcode, postname, postcode, begindate) + VALUES + + ( + REPLACE(uuid(), '-', ''), + #{i.postid}, + #{i.deptcode}, + #{i.postname}, + #{i.postcode}, + #{i.begindate} + ) + + + + + update sys_branch + + name = #{name}, + leader = #{leader}, + phone = #{phone}, + parent_id = #{parentId}, + ancestors = #{ancestors}, + space_id = #{spaceId}, + remark = #{remark}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + dept_id = #{deptId}, + rule_id = #{ruleId}, + ladder_rule_id = #{ladderRuleId}, + is_examine = #{isExamine}, + + where id = #{id} + + + update sys_branch + + + + + WHEN ID=#{item.id} THEN #{item.ancestors} + + + + + WHERE + ID IN + + #{item.id} + + + + + delete from sys_branch where id = #{id} + + + + delete from sys_branch where id = #{id} + + + + delete from sys_branch where id in + + #{id} + + + + + + + + + + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysConfigMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysConfigMapper.xml new file mode 100644 index 0000000..5d9308d --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysConfigMapper.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + select config_id, config_name, config_key, config_value, config_type, create_by, create_time, update_by, update_time, remark + from sys_config + + + + + + + and config_id = #{configId} + + + and config_key = #{configKey} + + + + + + + + + + + + + + insert into sys_config ( + config_name, + config_key, + config_value, + config_type, + create_by, + remark, + create_time + )values( + #{configName}, + #{configKey}, + #{configValue}, + #{configType}, + #{createBy}, + #{remark}, + sysdate() + ) + + + + update sys_config + + config_name = #{configName}, + config_key = #{configKey}, + config_value = #{configValue}, + config_type = #{configType}, + update_by = #{updateBy}, + remark = #{remark}, + update_time = sysdate() + + where config_id = #{configId} + + + + delete from sys_config where config_id = #{configId} + + + + delete from sys_config where config_id in + + #{configId} + + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysDeptMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysDeptMapper.xml new file mode 100644 index 0000000..5f661d0 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysDeptMapper.xml @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + + + + select d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.status, d.del_flag, d.create_by, d.create_time,d.external_id + from sys_dept d + + + + + + + + + + + + + + + + + + + + insert into sys_dept( + dept_id, + parent_id, + dept_name, + ancestors, + order_num, + leader, + phone, + email, + status, + create_by, + external_id, + create_time + )values( + #{deptId}, + #{parentId}, + #{deptName}, + #{ancestors}, + #{orderNum}, + #{leader}, + #{phone}, + #{email}, + #{status}, + #{createBy}, + #{externalId}, + sysdate() + ) + + + + update sys_dept + + parent_id = #{parentId}, + dept_name = #{deptName}, + ancestors = #{ancestors}, + order_num = #{orderNum}, + leader = #{leader}, + phone = #{phone}, + email = #{email}, + status = #{status}, + update_by = #{updateBy}, + external_id = #{externalId}, + update_time = sysdate() + + where dept_id = #{deptId} + + + + update sys_dept set ancestors = + + when #{item.deptId} then #{item.ancestors} + + where dept_id in + + #{item.deptId} + + + + + update sys_dept set status = '0' where dept_id in + + #{deptId} + + + + + update sys_dept set del_flag = '2' where dept_id = #{deptId} + + + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysDictDataMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysDictDataMapper.xml new file mode 100644 index 0000000..26fd378 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysDictDataMapper.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + select dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remark + from sys_dict_data + + + + + + + + + + + + + + delete from sys_dict_data where dict_code = #{dictCode} + + + + delete from sys_dict_data where dict_code in + + #{dictCode} + + + + + update sys_dict_data + + dict_sort = #{dictSort}, + dict_label = #{dictLabel}, + dict_value = #{dictValue}, + dict_type = #{dictType}, + css_class = #{cssClass}, + list_class = #{listClass}, + is_default = #{isDefault}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = sysdate() + + where dict_code = #{dictCode} + + + + update sys_dict_data set dict_type = #{newDictType} where dict_type = #{oldDictType} + + + + insert into sys_dict_data( + dict_sort, + dict_label, + dict_value, + dict_type, + css_class, + list_class, + is_default, + status, + remark, + create_by, + create_time + )values( + #{dictSort}, + #{dictLabel}, + #{dictValue}, + #{dictType}, + #{cssClass}, + #{listClass}, + #{isDefault}, + #{status}, + #{remark}, + #{createBy}, + sysdate() + ) + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysDictTypeMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysDictTypeMapper.xml new file mode 100644 index 0000000..04aeb4f --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysDictTypeMapper.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + select dict_id, dict_name, dict_type, status, create_by, create_time, remark + from sys_dict_type + + + + + + + + + + + + + + delete from sys_dict_type where dict_id = #{dictId} + + + + delete from sys_dict_type where dict_id in + + #{dictId} + + + + + update sys_dict_type + + dict_name = #{dictName}, + dict_type = #{dictType}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = sysdate() + + where dict_id = #{dictId} + + + + insert into sys_dict_type( + dict_name, + dict_type, + status, + remark, + create_by, + create_time + )values( + #{dictName}, + #{dictType}, + #{status}, + #{remark}, + #{createBy}, + sysdate() + ) + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysEmpowerRecordMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysEmpowerRecordMapper.xml new file mode 100644 index 0000000..4218163 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysEmpowerRecordMapper.xml @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select ser.id, ser.name, ser.people_id, ser.info_down, ser.empower, ser.equipment_id, ser.status, ser.remark, ser.create_by, + ser.create_time, ser.update_by, ser.update_time, ser.rule_id, p.name peopleName,p.avatar peopleAvatar,e.name equipmentName, + e.entry_exit_type + from sys_empower_record ser + left join sys_people p on ser.people_id=p.id + left join sys_equipment e on ser.equipment_id=e.id + + + + + + + + insert into sys_empower_record + + name, + people_id, + info_down, + empower, + equipment_id, + status, + remark, + create_by, + create_time, + update_by, + update_time, + rule_id, + + + #{name}, + #{peopleId}, + #{infoDown}, + #{empower}, + #{equipmentId}, + #{status}, + #{remark}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{ruleId}, + + + + + update sys_empower_record + + name = #{name}, + people_id = #{peopleId}, + info_down = #{infoDown}, + empower = #{empower}, + equipment_id = #{equipmentId}, + status = #{status}, + remark = #{remark}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + rule_id = #{ruleId}, + + where id = #{id} + + + + delete from sys_empower_record where id = #{id} + + + + delete from sys_empower_record where id in + + #{id} + + + + + delete from sys_empower_record where people_id = #{peopleId} + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysEquipmentMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysEquipmentMapper.xml new file mode 100644 index 0000000..3211c2a --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysEquipmentMapper.xml @@ -0,0 +1,522 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select e.id, e.product_id, e.name, e.sequence, e.ip, e.password, e.space_id, e.point_id, e.remark, e.create_by, e.create_time, e.update_by, e.update_time, e.state, + e.flag, e.com_rec_time_window, e.com_rec_rank, e.com_rec_dist_mode_type, e.language_type, e.com_relay_time, e.time_zone, e.face_enable, e.face_score, e.face_detection_type, + e.repeat_reg_enable, e.reg_interval,e.card_enable, e.rec_suc_tts_mode_type, e.rec_suc_tts_mode_content, e.rec_suc_display_text1_type, e.rec_suc_display_text1_content, + e.rec_suc_display_text2_type, e.rec_suc_display_text2_content, e.rec_suc_com_mode_type, e.rec_suc_com_mode_content, e.rec_suc_wiegand_type, e.rec_suc_wiegand_content, + e.rec_suc_relay_type, e.rec_fail_enable, e.rec_fail_times_threshold, e.rec_fail_tts_mode_type, e.rec_fail_tts_mode_content, e.rec_fail_display_text_type, e.rec_fail_display_text_content, + e.rec_fail_com_mode_type,e.rec_fail_com_mode_content, e.rec_fail_wiegand_type, e.rec_fail_wiegand_content, e.rec_fail_relay_type, e.rec_no_per_tts_mode_type, e.rec_no_per_tts_mode_content, + e.rec_no_per_display_text1_type, e.rec_no_per_display_text1_content, e.rec_no_per_display_text2_type, e.rec_no_per_display_text2_content, e.rec_no_per_com_mode_type, e.rec_no_per_com_mode_content, + e.rec_no_per_wiegand_type, e.rec_no_per_wiegand_content, e.rec_no_per_relay_type, e.scr_display_text1_type, e.scr_display_text1_content, e.scr_display_text2_type, e.scr_display_text2_content, + e.is_show_device_key, e.is_show_ip, e.is_show_person_count, e.scr_image1_url, e.scr_image2_url, e.is_temperature_open, e.temperature_compensation, e.temperature_measure_max, e.temperature_measure_min, + e.temp_map_switch, e.temp_unit, e.is_mask_open, e.error_temperature,p.avatar productAvatar,p.name productName,pt.name pointName,e.back_url,e.is_cj, + e.entry_exit_type, p.bigtype, e.file_type + from sys_equipment e + left join sys_product p on e.product_id = p.id + left join sys_point pt on e.point_id = pt.id + + + + + + + + + insert into sys_equipment + + id, + product_id, + name, + sequence, + ip, + password, + space_id, + point_id, + remark, + create_by, + create_time, + update_by, + update_time, + state, + flag, + com_rec_time_window, + com_rec_rank, + com_rec_dist_mode_type, + language_type, + com_relay_time, + time_zone, + face_enable, + face_score, + face_detection_type, + repeat_reg_enable, + reg_interval, + card_enable, + rec_suc_tts_mode_type, + rec_suc_tts_mode_content, + rec_suc_display_text1_type, + rec_suc_display_text1_content, + rec_suc_display_text2_type, + rec_suc_display_text2_content, + rec_suc_com_mode_type, + rec_suc_com_mode_content, + rec_suc_wiegand_type, + rec_suc_wiegand_content, + rec_suc_relay_type, + rec_fail_enable, + rec_fail_times_threshold, + rec_fail_tts_mode_type, + rec_fail_tts_mode_content, + rec_fail_display_text_type, + rec_fail_display_text_content, + rec_fail_com_mode_type, + rec_fail_com_mode_content, + rec_fail_wiegand_type, + rec_fail_wiegand_content, + rec_fail_relay_type, + rec_no_per_tts_mode_type, + rec_no_per_tts_mode_content, + rec_no_per_display_text1_type, + rec_no_per_display_text1_content, + rec_no_per_display_text2_type, + rec_no_per_display_text2_content, + rec_no_per_com_mode_type, + rec_no_per_com_mode_content, + rec_no_per_wiegand_type, + rec_no_per_wiegand_content, + rec_no_per_relay_type, + scr_display_text1_type, + scr_display_text1_content, + scr_display_text2_type, + scr_display_text2_content, + is_show_device_key, + is_show_ip, + is_show_person_count, + scr_image1_url, + scr_image2_url, + is_temperature_open, + temperature_compensation, + temperature_measure_max, + temperature_measure_min, + temp_map_switch, + temp_unit, + is_mask_open, + error_temperature, + back_url, + is_cj, + entry_exit_type, + + + + #{id}, + #{productId}, + #{name}, + #{sequence}, + #{ip}, + #{password}, + #{spaceId}, + #{pointId}, + #{remark}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{state}, + #{flag}, + #{comRecTimeWindow}, + #{comRecRank}, + #{comRecDistModeType}, + #{languageType}, + #{comRelayTime}, + #{timeZone}, + #{faceEnable}, + #{faceScore}, + #{faceDetectionType}, + #{repeatRegEnable}, + #{regInterval}, + #{cardEnable}, + #{recSucTtsModeType}, + #{recSucTtsModeContent}, + #{recSucDisplayText1Type}, + #{recSucDisplayText1Content}, + #{recSucDisplayText2Type}, + #{recSucDisplayText2Content}, + #{recSucComModeType}, + #{recSucComModeContent}, + #{recSucWiegandType}, + #{recSucWiegandContent}, + #{recSucRelayType}, + #{recFailEnable}, + #{recFailTimesThreshold}, + #{recFailTtsModeType}, + #{recFailTtsModeContent}, + #{recFailDisplayTextType}, + #{recFailDisplayTextContent}, + #{recFailComModeType}, + #{recFailComModeContent}, + #{recFailWiegandType}, + #{recFailWiegandContent}, + #{recFailRelayType}, + #{recNoPerTtsModeType}, + #{recNoPerTtsModeContent}, + #{recNoPerDisplayText1Type}, + #{recNoPerDisplayText1Content}, + #{recNoPerDisplayText2Type}, + #{recNoPerDisplayText2Content}, + #{recNoPerComModeType}, + #{recNoPerComModeContent}, + #{recNoPerWiegandType}, + #{recNoPerWiegandContent}, + #{recNoPerRelayType}, + #{scrDisplayText1Type}, + #{scrDisplayText1Content}, + #{scrDisplayText2Type}, + #{scrDisplayText2Content}, + #{isShowDeviceKey}, + #{isShowIp}, + #{isShowPersonCount}, + #{scrImage1Url}, + #{scrImage2Url}, + #{isTemperatureOpen}, + #{temperatureCompensation}, + #{temperatureMeasureMax}, + #{temperatureMeasureMin}, + #{tempMapSwitch}, + #{tempUnit}, + #{isMaskOpen}, + #{errorTemperature}, + #{backUrl}, + #{isCj}, + #{entryExitType}, + + + + insert into sys_file (id, business_id, business_type, url, file_name) VALUES + + ( + #{i.id}, + #{i.businessId}, + #{i.businessType}, + #{i.url}, + #{i.fileName} + ) + + + + + update sys_equipment + + product_id = #{productId}, + name = #{name}, + sequence = #{sequence}, + ip = #{ip}, + password = #{password}, + space_id = #{spaceId}, + point_id = #{pointId}, + remark = #{remark}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + state = #{state}, + flag = #{flag}, + com_rec_time_window = #{comRecTimeWindow}, + com_rec_rank = #{comRecRank}, + com_rec_dist_mode_type = #{comRecDistModeType}, + language_type = #{languageType}, + com_relay_time = #{comRelayTime}, + time_zone = #{timeZone}, + face_enable = #{faceEnable}, + face_score = #{faceScore}, + face_detection_type = #{faceDetectionType}, + repeat_reg_enable = #{repeatRegEnable}, + reg_interval = #{regInterval}, + card_enable = #{cardEnable}, + rec_suc_tts_mode_type = #{recSucTtsModeType}, + rec_suc_tts_mode_content = #{recSucTtsModeContent}, + rec_suc_display_text1_type = #{recSucDisplayText1Type}, + rec_suc_display_text1_content = #{recSucDisplayText1Content}, + rec_suc_display_text2_type = #{recSucDisplayText2Type}, + rec_suc_display_text2_content = #{recSucDisplayText2Content}, + rec_suc_com_mode_type = #{recSucComModeType}, + rec_suc_com_mode_content = #{recSucComModeContent}, + rec_suc_wiegand_type = #{recSucWiegandType}, + rec_suc_wiegand_content = #{recSucWiegandContent}, + rec_suc_relay_type = #{recSucRelayType}, + rec_fail_enable = #{recFailEnable}, + rec_fail_times_threshold = #{recFailTimesThreshold}, + rec_fail_tts_mode_type = #{recFailTtsModeType}, + rec_fail_tts_mode_content = #{recFailTtsModeContent}, + rec_fail_display_text_type = #{recFailDisplayTextType}, + rec_fail_display_text_content = #{recFailDisplayTextContent}, + rec_fail_com_mode_type = #{recFailComModeType}, + rec_fail_com_mode_content = #{recFailComModeContent}, + rec_fail_wiegand_type = #{recFailWiegandType}, + rec_fail_wiegand_content = #{recFailWiegandContent}, + rec_fail_relay_type = #{recFailRelayType}, + rec_no_per_tts_mode_type = #{recNoPerTtsModeType}, + rec_no_per_tts_mode_content = #{recNoPerTtsModeContent}, + rec_no_per_display_text1_type = #{recNoPerDisplayText1Type}, + rec_no_per_display_text1_content = #{recNoPerDisplayText1Content}, + rec_no_per_display_text2_type = #{recNoPerDisplayText2Type}, + rec_no_per_display_text2_content = #{recNoPerDisplayText2Content}, + rec_no_per_com_mode_type = #{recNoPerComModeType}, + rec_no_per_com_mode_content = #{recNoPerComModeContent}, + rec_no_per_wiegand_type = #{recNoPerWiegandType}, + rec_no_per_wiegand_content = #{recNoPerWiegandContent}, + rec_no_per_relay_type = #{recNoPerRelayType}, + scr_display_text1_type = #{scrDisplayText1Type}, + scr_display_text1_content = #{scrDisplayText1Content}, + scr_display_text2_type = #{scrDisplayText2Type}, + scr_display_text2_content = #{scrDisplayText2Content}, + is_show_device_key = #{isShowDeviceKey}, + is_show_ip = #{isShowIp}, + is_show_person_count = #{isShowPersonCount}, + scr_image1_url = #{scrImage1Url}, + scr_image2_url = #{scrImage2Url}, + is_temperature_open = #{isTemperatureOpen}, + temperature_compensation = #{temperatureCompensation}, + temperature_measure_max = #{temperatureMeasureMax}, + temperature_measure_min = #{temperatureMeasureMin}, + temp_map_switch = #{tempMapSwitch}, + temp_unit = #{tempUnit}, + is_mask_open = #{isMaskOpen}, + error_temperature = #{errorTemperature}, + back_url = #{backUrl}, + is_cj = #{isCj}, + entry_exit_type = #{entryExitType}, + file_type = #{fileType}, + + where id = #{id} + + + update sys_equipment + + password = #{password}, + ip = #{deviceIp}, + name = #{name}, + file_type = #{fileType}, + + where sequence = #{deviceKey} + + + + delete from sys_equipment where id = #{id} + + + + delete from sys_equipment where id in + + #{id} + + + + delete from sys_file where business_id = #{businessId} and business_type = #{businessType} + + + + + + + + + + + + + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysLogininforMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysLogininforMapper.xml new file mode 100644 index 0000000..e1f7368 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysLogininforMapper.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + insert into sys_logininfor (user_name, status, ipaddr, msg, access_time) + values (#{userName}, #{status}, #{ipaddr}, #{msg}, sysdate()) + + + + + + delete from sys_logininfor where info_id in + + #{infoId} + + + + + truncate table sys_logininfor + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysManageRecordMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysManageRecordMapper.xml new file mode 100644 index 0000000..60f8089 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysManageRecordMapper.xml @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select smr.id, smr.type, smr.people_id, smr.branch_id, smr.rule_id, smr.remark, smr.create_by, smr.create_time, smr.update_by, smr.update_time, + b.name branchName ,p.name peopleName ,r.name ruleName + from sys_manage_record smr + left join sys_branch b on smr.branch_id=b.id + left join sys_people p on smr.people_id=p.id + left join sys_rule r on smr.rule_id=r.id + + + + + + + + insert into sys_manage_record + + type, + people_id, + branch_id, + rule_id, + remark, + create_by, + create_time, + update_by, + update_time, + + + #{type}, + #{peopleId}, + #{branchId}, + #{ruleId}, + #{remark}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update sys_manage_record + + type = #{type}, + people_id = #{peopleId}, + branch_id = #{branchId}, + rule_id = #{ruleId}, + remark = #{remark}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from sys_manage_record where id = #{id} + + + + delete from sys_manage_record where id in + + #{id} + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysMenuMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysMenuMapper.xml new file mode 100644 index 0000000..3268e07 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysMenuMapper.xml @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select menu_id, menu_name, parent_id, order_num, path, component, `query`, is_frame, is_cache, menu_type, visible, status, ifnull(perms,'') as perms, icon, create_time + from sys_menu + + + + + + + + + + + + + + + + + + + + + + + + + + update sys_menu + + menu_name = #{menuName}, + parent_id = #{parentId}, + order_num = #{orderNum}, + path = #{path}, + component = #{component}, + `query` = #{query}, + is_frame = #{isFrame}, + is_cache = #{isCache}, + menu_type = #{menuType}, + visible = #{visible}, + status = #{status}, + perms = #{perms}, + icon = #{icon}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = sysdate() + + where menu_id = #{menuId} + + + + insert into sys_menu( + menu_id, + parent_id, + menu_name, + order_num, + path, + component, + `query`, + is_frame, + is_cache, + menu_type, + visible, + status, + perms, + icon, + remark, + create_by, + create_time + )values( + #{menuId}, + #{parentId}, + #{menuName}, + #{orderNum}, + #{path}, + #{component}, + #{query}, + #{isFrame}, + #{isCache}, + #{menuType}, + #{visible}, + #{status}, + #{perms}, + #{icon}, + #{remark}, + #{createBy}, + sysdate() + ) + + + + delete from sys_menu where menu_id = #{menuId} + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysNoticeMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysNoticeMapper.xml new file mode 100644 index 0000000..7ab8b17 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysNoticeMapper.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + select notice_id, notice_title, notice_type, cast(notice_content as char) as notice_content, status, create_by, create_time, update_by, update_time, remark + from sys_notice + + + + + + + + insert into sys_notice ( + notice_title, + notice_type, + notice_content, + status, + remark, + create_by, + create_time + )values( + #{noticeTitle}, + #{noticeType}, + #{noticeContent}, + #{status}, + #{remark}, + #{createBy}, + sysdate() + ) + + + + update sys_notice + + notice_title = #{noticeTitle}, + notice_type = #{noticeType}, + notice_content = #{noticeContent}, + status = #{status}, + update_by = #{updateBy}, + update_time = sysdate() + + where notice_id = #{noticeId} + + + + delete from sys_notice where notice_id = #{noticeId} + + + + delete from sys_notice where notice_id in + + #{noticeId} + + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysOperLogMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysOperLogMapper.xml new file mode 100644 index 0000000..720e0a7 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysOperLogMapper.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + select oper_id, title, business_type, method, request_method, operator_type, oper_name, dept_name, oper_url, oper_ip, oper_param, json_result, status, error_msg, oper_time, cost_time + from sys_oper_log + + + + insert into sys_oper_log(title, business_type, method, request_method, operator_type, oper_name, dept_name, oper_url, oper_ip, oper_param, json_result, status, error_msg, cost_time, oper_time) + values (#{title}, #{businessType}, #{method}, #{requestMethod}, #{operatorType}, #{operName}, #{deptName}, #{operUrl}, #{operIp}, #{operParam}, #{jsonResult}, #{status}, #{errorMsg}, #{costTime}, sysdate()) + + + + + + delete from sys_oper_log where oper_id in + + #{operId} + + + + + + + truncate table sys_oper_log + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPeopleEquipmentMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPeopleEquipmentMapper.xml new file mode 100644 index 0000000..0c9d26e --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPeopleEquipmentMapper.xml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + select id, people_id, equipment_id, guid, face_guid,visitor_id,other_id from sys_people_equipment + + + + + + + + insert into sys_people_equipment + + people_id, + equipment_id, + guid, + face_guid, + visitor_id, + other_id, + + + + #{peopleId}, + #{equipmentId}, + #{guid}, + #{faceGuid}, + #{visitorId}, + #{otherId}, + + + + + + update sys_people_equipment + + people_id = #{peopleId}, + equipment_id = #{equipmentId}, + guid = #{guid}, + face_guid = #{faceGuid}, + + where id = #{id} + + + + delete from sys_people_equipment where id = #{id} + + + + delete from sys_people_equipment where id in + + #{id} + + + + + + + + + + + delete from sys_people_equipment where other_id = #{otherId} + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPeopleLeaveMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPeopleLeaveMapper.xml new file mode 100644 index 0000000..f0f940c --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPeopleLeaveMapper.xml @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + select spl.id, spl.gh, spl.name, spl.sex, spl.branch_id, spl.idcard, spl.leave_time, spl.people_id, + spl.leave_reason, spl.remark, spl.create_by, spl.create_time, spl.update_by, spl.update_time,b.name branch_name,spl.status + from sys_people_leave spl + left join sys_branch b on spl.branch_id = b.id + + + + + + + + + + insert into sys_people_leave + + gh, + name, + sex, + branch_id, + idcard, + leave_time, + people_id, + leave_reason, + remark, + create_by, + create_time, + update_by, + update_time, + status, + + + #{gh}, + #{name}, + #{sex}, + #{branchId}, + #{idcard}, + #{leaveTime}, + #{peopleId}, + #{leaveReason}, + #{remark}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{status}, + + + + insert into sys_people_leave (gh, name, sex, branch_id, leave_time, people_id, leave_reason, status) + VALUES + + ( + #{i.gh}, + #{i.name}, + #{i.sex}, + #{i.branchId}, + #{i.leaveTime}, + #{i.peopleId}, + #{i.leaveReason}, + #{i.status} + ) + + + + + update sys_people_leave + + gh = #{gh}, + name = #{name}, + sex = #{sex}, + branch_id = #{branchId}, + idcard = #{idcard}, + leave_time = #{leaveTime}, + people_id = #{peopleId}, + leave_reason = #{leaveReason}, + remark = #{remark}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + status = #{status}, + + where id = #{id} + + + UPDATE sys_people_leave + + + + + WHEN gh=#{item.gh} THEN #{item.name} + + + + + + + WHEN gh=#{item.gh} THEN #{item.sex} + + + + + + + WHEN gh=#{item.gh} THEN #{item.branchId} + + + + + + + WHEN gh=#{item.gh} THEN #{item.leaveTime} + + + + + + + WHEN gh=#{item.gh} THEN #{item.peopleId} + + + + + + + WHEN gh=#{item.gh} THEN #{item.leaveReason} + + + + + + + WHEN gh=#{item.gh} THEN #{item.status} + + + + + WHERE + gh IN + + #{item.gh} + + + + + delete from sys_people_leave where id = #{id} + + + + delete from sys_people_leave where id in + + #{id} + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPeopleMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPeopleMapper.xml new file mode 100644 index 0000000..d1ed2ae --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPeopleMapper.xml @@ -0,0 +1,322 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select p.id, p.name, p.phone, p.sex, p.avatar, p.branch_id, p.position, p.idcard, p.car_no,p.door_no, p.guid, p.face_guid, p.openid, b.is_examine, + p.user_id, p.remark, p.create_by, p.create_time, p.update_by, p.update_time ,b.name branchName,p.gh,p.fingerprint,p.join_time,p.down,p.del_flag,b.rule_id + from sys_people p left join sys_branch b on p.branch_id=b.id + left join sys_user u on u.user_id = p.user_id + left join sys_dept d on u.dept_id = d.dept_id + + + + + + + + insert into sys_people + + name, + phone, + sex, + avatar, + branch_id, + position, + idcard, + car_no, + door_no, + guid, + face_guid, + user_id, + remark, + create_by, + create_time, + update_by, + update_time, + gh, + fingerprint, + join_time, + down, + del_flag, + + + #{name}, + #{phone}, + #{sex}, + #{avatar}, + #{branchId}, + #{position}, + #{idcard}, + #{carNo}, + #{doorNo}, + #{guid}, + #{faceGuid}, + #{userId}, + #{remark}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{gh}, + #{fingerprint}, + #{joinTime}, + #{down}, + #{delFlag}, + + + + + update sys_people + + name = #{name}, + phone = #{phone}, + sex = #{sex}, + avatar = #{avatar}, + branch_id = #{branchId}, + position = #{position}, + idcard = #{idcard}, + car_no = #{carNo}, + door_no = #{doorNo}, + guid = #{guid}, + face_guid = #{faceGuid}, + user_id = #{userId}, + remark = #{remark}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + gh = #{gh}, + fingerprint = #{fingerprint}, + join_time = #{joinTime}, + down = #{down}, + del_flag = #{delFlag}, + openid = #{openid}, + + where id = #{id} + + + + update sys_people set del_flag='2' where id = #{id} + + + + update sys_people set del_flag='2' where id in + + #{id} + + + + + update sys_people set del_flag='2' where guid = #{guid} + + + update sys_people set del_flag='2', update_time = now() where gh = #{gh} + + + update sys_people set openid= #{openid} where phone = #{phone} and name = #{name} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPeopleOtherMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPeopleOtherMapper.xml new file mode 100644 index 0000000..b8a59d5 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPeopleOtherMapper.xml @@ -0,0 +1,291 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select p.id, p.name, p.phone, p.sex, p.avatar, p.branch_id, p.position, p.idcard, p.car_no, p.guid, p.face_guid,p.valid_time_start,p.valid_time_end, + p.remark, p.create_by, p.create_time, p.update_by, p.update_time ,b.name branchName,p.down,p.del_flag,b.rule_id,p.file1,p.file2,p.file3 + from sys_people_other p + left join sys_branch b on p.branch_id=b.id + left join sys_dept d on b.dept_id = d.dept_id + + + + + + + + insert into sys_people_other + + name, + phone, + sex, + avatar, + branch_id, + position, + idcard, + car_no, + guid, + face_guid, + remark, + create_by, + create_time, + update_by, + update_time, + down, + del_flag, + valid_time_start, + valid_time_end, + file1, + file2, + file3, + + + #{name}, + #{phone}, + #{sex}, + #{avatar}, + #{branchId}, + #{position}, + #{idcard}, + #{carNo}, + #{guid}, + #{faceGuid}, + #{remark}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{down}, + #{delFlag}, + #{validTimeStart}, + #{validTimeEnd}, + #{file1}, + #{file2}, + #{file3}, + + + + + update sys_people_other + + name = #{name}, + phone = #{phone}, + sex = #{sex}, + avatar = #{avatar}, + branch_id = #{branchId}, + position = #{position}, + idcard = #{idcard}, + car_no = #{carNo}, + guid = #{guid}, + face_guid = #{faceGuid}, + remark = #{remark}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + down = #{down}, + del_flag = #{delFlag}, + valid_time_start = #{validTimeStart}, + valid_time_end = #{validTimeEnd}, + file1 = #{file1}, + file2 = #{file2}, + file3 = #{file3}, + + where id = #{id} + + + + update sys_people_other set del_flag='2' where id = #{id} + + + + update sys_people_other set del_flag='2' where id in + + #{id} + + + + + update sys_people_other set del_flag='2' where guid = #{guid} + + + update sys_people_other set del_flag='2', update_time = now() where gh = #{gh} + + + update sys_people_other set openid= #{openid} where phone = #{phone} and name = #{name} + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPeopleRecordMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPeopleRecordMapper.xml new file mode 100644 index 0000000..d6f9575 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPeopleRecordMapper.xml @@ -0,0 +1,307 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select spr.id, spr.people_id, spr.equipment_id, spr.device_ip, spr.admit_guid, spr.rec_mode, spr.file_path, spr.show_time, spr.show_date, spr.alive_type, + spr.rec_score, spr.device_no, spr.device_version, spr.source, spr.type, spr.card_no, spr.device_name, spr.rec_type, spr.result, spr.permission_time_type, + spr.pass_time_type, spr.rec_mode_type, spr.storage_id, spr.timestamp, spr.admit_name, spr.remark, spr.create_by, spr.create_time, spr.update_by, spr.update_time, + e.name equipmentName,spr.flag,spr.group_id,p.name people_name,p.gh,spr.sign + from sys_people_record spr + left join sys_equipment e on spr.equipment_id=e.id + left join sys_people p on spr.people_id=p.id + + + + + + + + + + + insert into sys_people_record + + people_id, + equipment_id, + device_ip, + admit_guid, + rec_mode, + file_path, + show_time, + show_date, + alive_type, + rec_score, + device_no, + device_version, + source, + type, + card_no, + device_name, + rec_type, + result, + permission_time_type, + pass_time_type, + rec_mode_type, + storage_id, + timestamp, + admit_name, + remark, + create_by, + create_time, + update_by, + update_time, + group_id, + flag, + sign, + + + + #{peopleId}, + #{equipmentId}, + #{deviceIp}, + #{admitGuid}, + #{recMode}, + #{filePath}, + #{showTime}, + #{showDate}, + #{aliveType}, + #{recScore}, + #{deviceNo}, + #{deviceVersion}, + #{source}, + #{type}, + #{cardNo}, + #{deviceName}, + #{recType}, + #{result}, + #{permissionTimeType}, + #{passTimeType}, + #{recModeType}, + #{storageId}, + #{timestamp}, + #{admitName}, + #{remark}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{groupId}, + #{flag}, + #{sign}, + + + + + update sys_people_record + + people_id = #{peopleId}, + equipment_id = #{equipmentId}, + device_ip = #{deviceIp}, + admit_guid = #{admitGuid}, + rec_mode = #{recMode}, + file_path = #{filePath}, + show_time = #{showTime}, + show_date = #{showDate}, + alive_type = #{aliveType}, + rec_score = #{recScore}, + device_no = #{deviceNo}, + device_version = #{deviceVersion}, + source = #{source}, + type = #{type}, + card_no = #{cardNo}, + device_name = #{deviceName}, + rec_type = #{recType}, + result = #{result}, + permission_time_type = #{permissionTimeType}, + pass_time_type = #{passTimeType}, + rec_mode_type = #{recModeType}, + storage_id = #{storageId}, + timestamp = #{timestamp}, + admit_name = #{admitName}, + remark = #{remark}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + group_id = #{groupId}, + flag = #{flag}, + sign = #{sign}, + + where id = #{id} + + + + delete from sys_people_record where id = #{id} + + + + delete from sys_people_record where id in + + #{id} + + + + + + + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPeopleRuleMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPeopleRuleMapper.xml new file mode 100644 index 0000000..75a9d36 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPeopleRuleMapper.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + select id, people_id, rule_id,equipment_id, sync, remark, create_by, create_time, update_by, update_time from sys_people_rule + + + + + + + + insert into sys_people_rule + + people_id, + rule_id, + equipment_id, + sync, + remark, + create_by, + create_time, + update_by, + update_time, + + + #{peopleId}, + #{ruleId}, + #{equipmentId}, + #{sync}, + #{remark}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update sys_people_rule + + people_id = #{peopleId}, + rule_id = #{ruleId}, + equipment_id = #{equipmentId}, + sync = #{sync}, + remark = #{remark}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from sys_people_rule where id = #{id} + + + + delete from sys_people_rule where id in + + #{id} + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPointMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPointMapper.xml new file mode 100644 index 0000000..54fed73 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPointMapper.xml @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + select p.id, p.name, p.space_id, p.remark, p.create_by, p.create_time, p.update_by, p.update_time,s.name spaceName,p.sort + from sys_point p + left join sys_space s on s.id=p.space_id + + + + + + + + + insert into sys_point + + id, + name, + space_id, + remark, + create_by, + create_time, + update_by, + update_time, + sort, + + + #{id}, + #{name}, + #{spaceId}, + #{remark}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{sort}, + + + + + update sys_point + + name = #{name}, + space_id = #{spaceId}, + remark = #{remark}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + sort = #{sort}, + + where id = #{id} + + + + delete from sys_point where id = #{id} + + + + delete from sys_point where id in + + #{id} + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPostMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPostMapper.xml new file mode 100644 index 0000000..8345879 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysPostMapper.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + select post_id, post_code, post_name, post_sort, status, create_by, create_time, remark + from sys_post + + + + + + + + + + + + + + + + + + update sys_post + + post_code = #{postCode}, + post_name = #{postName}, + post_sort = #{postSort}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = sysdate() + + where post_id = #{postId} + + + + insert into sys_post( + post_id, + post_code, + post_name, + post_sort, + status, + remark, + create_by, + create_time + )values( + #{postId}, + #{postCode}, + #{postName}, + #{postSort}, + #{status}, + #{remark}, + #{createBy}, + sysdate() + ) + + + + delete from sys_post where post_id = #{postId} + + + + delete from sys_post where post_id in + + #{postId} + + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysProductMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysProductMapper.xml new file mode 100644 index 0000000..982be94 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysProductMapper.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + select id, avatar, name, version, bigtype, subtype, genre, describes, network, data_format, scale, attestation, create_by, create_time, update_by, update_time from sys_product + + + + + + + + insert into sys_product + + id, + avatar, + name, + version, + bigtype, + subtype, + genre, + describes, + network, + data_format, + scale, + attestation, + create_by, + create_time, + update_by, + update_time, + + + #{id}, + #{avatar}, + #{name}, + #{version}, + #{bigtype}, + #{subtype}, + #{genre}, + #{describes}, + #{network}, + #{dataFormat}, + #{scale}, + #{attestation}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update sys_product + + avatar = #{avatar}, + name = #{name}, + version = #{version}, + bigtype = #{bigtype}, + subtype = #{subtype}, + genre = #{genre}, + describes = #{describes}, + network = #{network}, + data_format = #{dataFormat}, + scale = #{scale}, + attestation = #{attestation}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from sys_product where id = #{id} + + + + delete from sys_product where id in + + #{id} + + + \ No newline at end of file diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml new file mode 100644 index 0000000..5bc8422 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + delete from sys_role_dept where role_id=#{roleId} + + + + + + delete from sys_role_dept where role_id in + + #{roleId} + + + + + insert into sys_role_dept(role_id, dept_id) values + + (#{item.roleId},#{item.deptId}) + + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysRoleMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysRoleMapper.xml new file mode 100644 index 0000000..3039bda --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysRoleMapper.xml @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + select distinct r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.menu_check_strictly, r.dept_check_strictly, + r.status, r.del_flag, r.create_time, r.remark + from sys_role r + left join sys_user_role ur on ur.role_id = r.role_id + left join sys_user u on u.user_id = ur.user_id + left join sys_dept d on u.dept_id = d.dept_id + + + + + + + + + + + + + + + + + + + + insert into sys_role( + role_id, + role_name, + role_key, + role_sort, + data_scope, + menu_check_strictly, + dept_check_strictly, + status, + remark, + create_by, + create_time + )values( + #{roleId}, + #{roleName}, + #{roleKey}, + #{roleSort}, + #{dataScope}, + #{menuCheckStrictly}, + #{deptCheckStrictly}, + #{status}, + #{remark}, + #{createBy}, + sysdate() + ) + + + + update sys_role + + role_name = #{roleName}, + role_key = #{roleKey}, + role_sort = #{roleSort}, + data_scope = #{dataScope}, + menu_check_strictly = #{menuCheckStrictly}, + dept_check_strictly = #{deptCheckStrictly}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = sysdate() + + where role_id = #{roleId} + + + + update sys_role set del_flag = '2' where role_id = #{roleId} + + + + update sys_role set del_flag = '2' where role_id in + + #{roleId} + + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml new file mode 100644 index 0000000..457ac81 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + delete from sys_role_menu where role_id=#{roleId} + + + + delete from sys_role_menu where role_id in + + #{roleId} + + + + + insert into sys_role_menu(role_id, menu_id) values + + (#{item.roleId},#{item.menuId}) + + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysRuleMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysRuleMapper.xml new file mode 100644 index 0000000..9bc99f2 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysRuleMapper.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + select sr.id, sr.name, sr.start_time, sr.end_time, sr.admittance_start, sr.admittance_end, sr.space_id, sr.point_id, + sr.remark, sr.create_by, sr.create_time, sr.update_by, sr.update_time, sr.type, sr.permission,ss.name space_name + from sys_rule sr + left join sys_space ss on sr.space_id =ss.id + + + + + + + + insert into sys_rule + + name, + start_time, + end_time, + admittance_start, + admittance_end, + space_id, + point_id, + remark, + create_by, + create_time, + update_by, + update_time, + type, + permission, + + + #{name}, + #{startTime}, + #{endTime}, + #{admittanceStart}, + #{admittanceEnd}, + #{spaceId}, + #{pointId}, + #{remark}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{type}, + #{permission}, + + + + + update sys_rule + + name = #{name}, + start_time = #{startTime}, + end_time = #{endTime}, + admittance_start = #{admittanceStart}, + admittance_end = #{admittanceEnd}, + space_id = #{spaceId}, + point_id = #{pointId}, + remark = #{remark}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + type = #{type}, + permission = #{permission}, + + where id = #{id} + + + + delete from sys_rule where id = #{id} + + + + delete from sys_rule where id in + + #{id} + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysSpaceMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysSpaceMapper.xml new file mode 100644 index 0000000..6b7ba29 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysSpaceMapper.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + select id, name, parent_id, ancestors, type, remark, create_by, create_time, update_by, update_time from sys_space + + + + + + + + + insert into sys_space + + id, + name, + parent_id, + ancestors, + type, + remark, + create_by, + create_time, + update_by, + update_time, + + + #{id}, + #{name}, + #{parentId}, + #{ancestors}, + #{type}, + #{remark}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update sys_space + + name = #{name}, + parent_id = #{parentId}, + ancestors = #{ancestors}, + type = #{type}, + remark = #{remark}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from sys_space where id = #{id} + + + + delete from sys_space where id in + + #{id} + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysSyncRuleMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysSyncRuleMapper.xml new file mode 100644 index 0000000..fc0a91e --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysSyncRuleMapper.xml @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + select id, name, guid, all_dept_url, add_dept_url, all_people_url, add_people_url, remark, create_by, create_time, update_by, update_time from sys_sync_rule + + + + + + + + insert into sys_sync_rule + + name, + guid, + all_dept_url, + add_dept_url, + all_people_url, + add_people_url, + remark, + create_by, + create_time, + update_by, + update_time, + + + #{name}, + #{guid}, + #{allDeptUrl}, + #{addDeptUrl}, + #{allPeopleUrl}, + #{addPeopleUrl}, + #{remark}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update sys_sync_rule + + name = #{name}, + guid = #{guid}, + all_dept_url = #{allDeptUrl}, + add_dept_url = #{addDeptUrl}, + all_people_url = #{allPeopleUrl}, + add_people_url = #{addPeopleUrl}, + remark = #{remark}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from sys_sync_rule where id = #{id} + + + + delete from sys_sync_rule where id in + + #{id} + + + + + insert into sys_sync_item + + dept, + rule_id, + + + #{dept}, + #{ruleId}, + + + + + delete from sys_sync_item where rule_id = #{id} + + + + + + + + + + + + select id, dept,rule_id from sys_sync_item + + + + + + + select ssr.id, ssr.name,ssr.guid, ssr.all_dept_url, ssr.add_dept_url, ssr.all_people_url, ssr.add_people_url, ssr.remark, ssr.create_by, ssr.create_time, ssr.update_by, ssr.update_time + from sys_sync_rule ssr + left join sys_sync_item ssi on ssr.id=ssi.rule_id + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysUserMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysUserMapper.xml new file mode 100644 index 0000000..4a6ae55 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysUserMapper.xml @@ -0,0 +1,256 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, + d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.status as dept_status, + r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status,u.openid,u.external_id,u.equipment_id + from sys_user u + left join sys_dept d on u.dept_id = d.dept_id + left join sys_user_role ur on u.user_id = ur.user_id + left join sys_role r on r.role_id = ur.role_id + + + + + + + + + + + + + + + + + + + + insert into sys_user( + user_id, + dept_id, + user_name, + nick_name, + email, + avatar, + phonenumber, + sex, + password, + status, + create_by, + remark, + openid, + external_id, + equipment_id, + + create_time + )values( + #{userId}, + #{deptId}, + #{userName}, + #{nickName}, + #{email}, + #{avatar}, + #{phonenumber}, + #{sex}, + #{password}, + #{status}, + #{createBy}, + #{remark}, + #{openid}, + #{externalId}, + #{equipmentId}, + + sysdate() + ) + + + + update sys_user + + dept_id = #{deptId}, + user_name = #{userName}, + nick_name = #{nickName}, + email = #{email}, + phonenumber = #{phonenumber}, + sex = #{sex}, + avatar = #{avatar}, + password = #{password}, + status = #{status}, + login_ip = #{loginIp}, + login_date = #{loginDate}, + update_by = #{updateBy}, + remark = #{remark}, + openid = #{openid}, + external_id = #{externalId}, + equipment_id = #{equipmentId}, + update_time = sysdate() + + where user_id = #{userId} + + + + update sys_user set status = #{status} where user_id = #{userId} + + + + update sys_user set avatar = #{avatar} where user_name = #{userName} + + + + update sys_user set password = #{password} where user_name = #{userName} + + + + update sys_user set del_flag = '2' where user_id = #{userId} + + + + update sys_user set del_flag = '2' where user_id in + + #{userId} + + + + + + + update sys_user set openid = #{openid} where user_id = #{userId} + + + update sys_user set avatar = #{avatar} where user_name = #{userName} + + + + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysUserPostMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysUserPostMapper.xml new file mode 100644 index 0000000..e8a762a --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysUserPostMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + delete from sys_user_post where user_id=#{userId} + + + + + + delete from sys_user_post where user_id in + + #{userId} + + + + + insert into sys_user_post(user_id, post_id) values + + (#{item.userId},#{item.postId}) + + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysUserRoleMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysUserRoleMapper.xml new file mode 100644 index 0000000..5dc40d8 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/SysUserRoleMapper.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + delete from sys_user_role where user_id=#{userId} + + + + + + delete from sys_user_role where user_id in + + #{userId} + + + + + insert into sys_user_role(user_id, role_id) values + + (#{item.userId},#{item.roleId}) + + + + + delete from sys_user_role where user_id=#{userId} and role_id=#{roleId} + + + + delete from sys_user_role where role_id=#{roleId} and user_id in + + #{userId} + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/visitor/VisVisitorExamineMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/visitor/VisVisitorExamineMapper.xml new file mode 100644 index 0000000..bc03896 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/visitor/VisVisitorExamineMapper.xml @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, name, phone, visitor_id, admittance_start, admittance_end, space_id, point_id, type, permission, remark, create_by, create_time, update_by, update_time,examine,rule_id from vis_visitor_examine + + + + + + + + insert into vis_visitor_examine + + name, + phone, + visitor_id, + admittance_start, + admittance_end, + space_id, + point_id, + type, + permission, + remark, + create_by, + create_time, + update_by, + update_time, + examine, + rule_id, + + + + #{name}, + #{phone}, + #{visitorId}, + #{admittanceStart}, + #{admittanceEnd}, + #{spaceId}, + #{pointId}, + #{type}, + #{permission}, + #{remark}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{examine}, + #{ruleId}, + + + + + + update vis_visitor_examine + + name = #{name}, + phone = #{phone}, + visitor_id = #{visitorId}, + admittance_start = #{admittanceStart}, + admittance_end = #{admittanceEnd}, + space_id = #{spaceId}, + point_id = #{pointId}, + type = #{type}, + permission = #{permission}, + remark = #{remark}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + examine = #{examine}, + rule_id = #{ruleId}, + + + where id = #{id} + + + + delete from vis_visitor_examine where id = #{id} + + + + delete from vis_visitor_examine where id in + + #{id} + + + + + delete from vis_visitor_examine where visitor_id = #{visitorId} + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/visitor/VisVisitorRegisterMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/visitor/VisVisitorRegisterMapper.xml new file mode 100644 index 0000000..7ebede3 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/visitor/VisVisitorRegisterMapper.xml @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + select id, user_name, nick_name, phone, openid, delete_state, created_by, created_time, updated_by, updated_time from vis_visitor_register + + + + + + + + insert into vis_visitor_register + + id, + user_name, + nick_name, + phone, + openid, + delete_state, + created_by, + created_time, + updated_by, + updated_time, + + + #{id}, + #{userName}, + #{nickName}, + #{phone}, + #{openid}, + #{deleteState}, + #{createdBy}, + #{createdTime}, + #{updatedBy}, + #{updatedTime}, + + + + + update vis_visitor_register + + user_name = #{userName}, + nick_name = #{nickName}, + phone = #{phone}, + openid = #{openid}, + delete_state = #{deleteState}, + created_by = #{createdBy}, + created_time = #{createdTime}, + updated_by = #{updatedBy}, + updated_time = #{updatedTime}, + + where id = #{id} + + + + delete from vis_visitor_register where id = #{id} + + + + delete from vis_visitor_register where id in + + #{id} + + + + + insert into vis_visitor_register (id, user_name, nick_name, phone, openid) + values (#{visitorRegisterId}, #{name}, #{name}, #{phone}, #{openid}) + + + + update vis_visitor_register set openid = #{openid} where user_name = #{name} and phone = #{phone} + + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/visitor/VisitorMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/visitor/VisitorMapper.xml new file mode 100644 index 0000000..0b9b891 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/system/visitor/VisitorMapper.xml @@ -0,0 +1,811 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select distinct + vv.id, + vv.name, + vv.phone, + vv.sex, + vv.avatar, + vv.idcard, + vv.car_no, + vv.user_id, + vv.dept_id, + vv.flag, + vv.start_time, + vv.end_time, + vv.matter, + vv.res, + vv.guid, + vv.face_guid, + vv.remark, + vv.create_by, + vv.create_time, + vv.update_by, + vv.parent_id, + vv.update_time, + vve.admittance_start, + vve.admittance_end, + vve.point_id, + sb.name branch_name, + if(sp.name is not null, sp.name, vv.user_name) people_name, + vve.examine, + vv.in_time, + vv.out_time, + vve.create_by examine_name, + sp.phone people_phone, + vv.source, + sp.position, + vv.position visitorPosition, + vv.visiting_unit, + vv.reviewer2, + vv.reviewer3 + from vis_visitor vv + left join vis_visitor_examine vve on vv.id = vve.visitor_id + left join sys_branch sb on vv.dept_id = sb.id + left join sys_people sp on vv.user_id = sp.id + left join sys_dept d on d.dept_id = sb.dept_id + left join sys_user u on u.user_id = sp.user_id + left join vis_visitor_audit_records vvar on vvar.visitor_id = vv.id + + + + + + + + + + + insert into vis_visitor + + id, + name, + phone, + sex, + avatar, + idcard, + car_no, + user_id, + dept_id, + flag, + start_time, + end_time, + matter, + res, + guid, + face_guid, + remark, + create_by, + create_time, + update_by, + update_time, + parent_id, + in_time, + out_time, + source, + id_card_start_time, + id_card_end_time, + id_card_address, + visiting_unit, + user_name, + + + + #{id}, + #{name}, + #{phone}, + #{sex}, + #{avatar}, + #{idcard}, + #{carNo}, + #{userId}, + #{deptId}, + #{flag}, + #{startTime}, + #{endTime}, + #{matter}, + #{res}, + #{guid}, + #{faceGuid}, + #{remark}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{parentId}, + #{inTime}, + #{outTime}, + #{source}, + #{idCardStartTime}, + #{idCardEndTime}, + #{idCardAddress}, + #{visitingUnit}, + #{userName}, + + + + + insert into vis_check_code (id, code, start_time, end_time, visitor_id) + VALUES (#{id}, #{code}, #{startTime}, #{endTime}, #{visitorId}) + + + insert into vis_visitor_record (id, visitor_id, sequence, start_time) + VALUES (REPLACE(uuid(), '-', ''), #{visitorId}, #{sequence}, #{startTime}) + + + insert into vis_visitor_audit_records (id, visitor_id, reviewer, state, next_step_reviewer) + VALUES (REPLACE(uuid(), '-', ''), #{id}, #{reviewer}, #{state}, #{nextStepReviewer}) + + + insert into sys_file (id, business_id, business_type, url, file_name) VALUES + + ( + #{i.id}, + #{i.businessId}, + #{i.businessType}, + #{i.url}, + #{i.fileName} + ) + + + + insert into vis_visitor_review_process (id, visitor_id, reviewer, type) + VALUES (REPLACE(uuid(), '-', ''), #{id}, #{reviewer}, #{type}) + + + + update vis_visitor + + name = #{name}, + phone = #{phone}, + sex = #{sex}, + avatar = #{avatar}, + idcard = #{idcard}, + car_no = #{carNo}, + user_id = #{userId}, + dept_id = #{deptId}, + flag = #{flag}, + start_time = #{startTime}, + end_time = #{endTime}, + matter = #{matter}, + res = #{res}, + guid = #{guid}, + face_guid = #{faceGuid}, + remark = #{remark}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + parent_id = #{parentId}, + in_time = #{inTime}, + out_time = #{outTime}, + type = #{type}, + id_card_start_time = #{idCardStartTime}, + id_card_end_time = #{idCardEndTime}, + id_card_address = #{idCardAddress}, + visiting_unit = #{visitingUnit}, + user_name = #{userName}, + position = #{visitorPosition}, + reviewer2 = #{reviewer2}, + reviewer3 = #{reviewer3}, + + where id = #{id} + + + update vis_visitor + set push_type = '1' + where 1=1 + and id in + + #{item.id} + + + + update vis_visitor + + in_time = #{inTime}, + out_time = #{outTime}, + type = #{type}, + + where idcard = #{idcard} + and date_format(create_time, '%Y-%m-%d') = date_format(now(), '%Y-%m-%d') + + + UPDATE vis_visitor + + + + + WHEN ID=#{item.id} THEN #{item.guid} + + + + + + + WHEN ID=#{item.id} THEN #{item.faceGuid} + + + + + WHERE + ID IN + + #{item.id} + + + + update vis_visitor_record + set end_time = #{endTime} + where visitor_id = #{visitorId} + + + update vis_visitor + + name = #{name}, + phone = #{phone}, + sex = #{sex}, + avatar = #{avatar}, + idcard = #{idcard}, + car_no = #{carNo}, + user_id = #{userId}, + dept_id = #{deptId}, + flag = #{flag}, + start_time = #{startTime}, + end_time = #{endTime}, + matter = #{matter}, + res = #{res}, + guid = #{guid}, + face_guid = #{faceGuid}, + remark = #{remark}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + parent_id = #{parentId}, + in_time = #{inTime}, + out_time = #{outTime}, + type = #{type}, + id_card_start_time = #{idCardStartTime}, + id_card_end_time = #{idCardEndTime}, + id_card_address = #{idCardAddress}, + visiting_unit = #{visitingUnit}, + user_name = #{userName}, + + where idcard = #{idcard} and out_time is null + + + update vis_visitor_review_process + set state = #{state} + where visitor_id = #{id} + + and reviewer = #{reviewer} + + + + + delete + from vis_visitor + where id = #{id} + + + + delete from vis_visitor where id in + + #{id} + + + + + delete + from vis_visitor + where parent_id = #{parentId} + + + update vis_visitor_record set delete_state = '1' where id in + + #{id} + + + + delete from sys_file where business_id = #{businessId} and business_type = #{businessType} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarChargeItemMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarChargeItemMapper.xml new file mode 100644 index 0000000..1d94cfa --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarChargeItemMapper.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + select id, charge_id, start_long, end_long, charge_money from car_charge_item + + + + + + + + insert into car_charge_item + + charge_id, + start_long, + end_long, + charge_money, + + + #{chargeId}, + #{startLong}, + #{endLong}, + #{chargeMoney}, + + + + + update car_charge_item + + charge_id = #{chargeId}, + start_long = #{startLong}, + end_long = #{endLong}, + charge_money = #{chargeMoney}, + + where id = #{id} + + + + delete from car_charge_item where id = #{id} + + + + delete from car_charge_item where id in + + #{id} + + + + + delete from car_charge_item where charge_id = #{id} + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarChargeMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarChargeMapper.xml new file mode 100644 index 0000000..e3182ae --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarChargeMapper.xml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + select cc.id, cc.park_id, cc.name, cc.type, cc.time_long, cc.charge_money, cc.status, cc.remark, cc.create_by, + cc.create_time, cc.update_by, cc.update_time ,cp.name park_name + from car_charge cc + left join car_park cp on cc.park_id=cp.id + + + + + + + + insert into car_charge + + park_id, + name, + type, + time_long, + charge_money, + status, + remark, + create_by, + create_time, + update_by, + update_time, + + + #{parkId}, + #{name}, + #{type}, + #{timeLong}, + #{chargeMoney}, + #{status}, + #{remark}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update car_charge + + park_id = #{parkId}, + name = #{name}, + type = #{type}, + time_long = #{timeLong}, + charge_money = #{chargeMoney}, + status = #{status}, + remark = #{remark}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from car_charge where id = #{id} + + + + delete from car_charge where id in + + #{id} + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarInfoMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarInfoMapper.xml new file mode 100644 index 0000000..a1ac455 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarInfoMapper.xml @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select ci.customer_id, ci.enable_time, ci.overdue_time, ci.enable, ci.plate, ci.time_seg_enable, ci.seg_time, ci.need_alarm, + ci.vehicle_code, ci.vehicle_comment, ci.people_id, ci.del_flag, ci.sync, ci.remark, + ci.create_by, ci.create_time, ci.update_by, ci.update_time,ci.park_id, cp.name park_name,p.name people_name, + ci.num,ci.car_type,ci.unit,ci.phone + from car_info ci + left join car_park cp on ci.park_id=cp.id + left join sys_people p on ci.people_id=p.id + + + + + + + + + insert into car_info + + customer_id, + enable_time, + overdue_time, + enable, + plate, + time_seg_enable, + seg_time, + need_alarm, + vehicle_code, + vehicle_comment, + people_id, + del_flag, + sync, + remark, + create_by, + create_time, + update_by, + update_time, + park_id, + num, + car_type, + unit, + phone, + + + #{customerId}, + #{enableTime}, + #{overdueTime}, + #{enable}, + #{plate}, + #{timeSegEnable}, + #{segTime}, + #{needAlarm}, + #{vehicleCode}, + #{vehicleComment}, + #{peopleId}, + #{delFlag}, + #{sync}, + #{remark}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{parkId}, + #{num}, + #{carType}, + #{unit}, + #{phone}, + + + + + update car_info + + enable_time = #{enableTime}, + overdue_time = #{overdueTime}, + enable = #{enable}, + plate = #{plate}, + time_seg_enable = #{timeSegEnable}, + seg_time = #{segTime}, + need_alarm = #{needAlarm}, + vehicle_code = #{vehicleCode}, + vehicle_comment = #{vehicleComment}, + people_id = #{peopleId}, + del_flag = #{delFlag}, + sync = #{sync}, + remark = #{remark}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + park_id = #{parkId}, + num = #{num}, + car_type = #{carType}, + unit = #{unit}, + phone = #{phone}, + + + where customer_id = #{customerId} + + + + update car_info set del_flag=2 where customer_id = #{customerId} + + + + update car_info set del_flag=2 where customer_id in + + #{customerId} + + + + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarParkItemMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarParkItemMapper.xml new file mode 100644 index 0000000..2bcac52 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarParkItemMapper.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + select id, equipment_id, park_id, way,area from car_park_item + + + + + + + + insert into car_park_item + + id, + equipment_id, + park_id, + way, + area, + + + #{id}, + #{equipmentId}, + #{parkId}, + #{way}, + #{area}, + + + + + update car_park_item + + equipment_id = #{equipmentId}, + park_id = #{parkId}, + way = #{way}, + area = #{area}, + + where id = #{id} + + + + delete from car_park_item where id = #{id} + + + + delete from car_park_item where id in + + #{id} + + + + + delete from car_park_item where park_id = #{parkId} + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarParkMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarParkMapper.xml new file mode 100644 index 0000000..a377942 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarParkMapper.xml @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + select cp.id, cp.name, cp.space_id, cp.cars_num, cp.surplus_num, cp.remark, cp.create_by, cp.create_time, + cp.update_by, cp.update_time,ss.name space_name + from car_park cp + left join sys_space ss on cp.space_id=ss.id + + + + + + + + + insert into car_park + + id, + name, + space_id, + cars_num, + surplus_num, + remark, + create_by, + create_time, + update_by, + update_time, + + + #{id}, + #{name}, + #{spaceId}, + #{carsNum}, + #{surplusNum}, + #{remark}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update car_park + + name = #{name}, + space_id = #{spaceId}, + cars_num = #{carsNum}, + surplus_num = #{surplusNum}, + remark = #{remark}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from car_park where id = #{id} + + + + delete from car_park where id in + + #{id} + + + + + + + + + + delete from car_equipment_open where equipment_id = #{id} + + + + insert into car_equipment_open (equipment_id,io) values(#{id},#{flag}) + + + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarParkRecordMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarParkRecordMapper.xml new file mode 100644 index 0000000..7409cac --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarParkRecordMapper.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + select cpr.id, cpr.equipment_id, cpr.park_id, cpr.customer_id, cpr.sync, + se.name equipment_name,cp.name park_name,ci.plate customer_name + from car_park_record cpr + left join sys_equipment se on cpr.equipment_id=se.id + left join car_park cp on cpr.park_id=cp.id + left join car_info ci on cpr.customer_id=ci.customer_id + + + + + + + + insert into car_park_record + + equipment_id, + park_id, + customer_id, + sync, + + + #{equipmentId}, + #{parkId}, + #{customerId}, + #{sync}, + + + + + update car_park_record + + equipment_id = #{equipmentId}, + park_id = #{parkId}, + customer_id = #{customerId}, + sync = #{sync}, + + where id = #{id} + + + + delete from car_park_record where id = #{id} + + + + delete from car_park_record where id in + + #{id} + + + + + delete from car_park_record where park_id = #{parkId} + + + + + update car_park_record set sync=0 where customer_id in + + #{id} + + + + + delete from car_park_record where customer_id = #{customerId} + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarPassGatherMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarPassGatherMapper.xml new file mode 100644 index 0000000..f5fd4ee --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarPassGatherMapper.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + select cpg.id, cpg.park_id, cpg.area, cpg.license, cpg.join_time, cpg.sn,cp.name park_name,se.name equipment_name,HOUR(TIMEDIFF(NOW(),cpg.join_time)) AS time_long + from car_pass_gather cpg + left join car_park cp on cp.id=cpg.park_id + left join sys_equipment se on se.sequence=cpg.sn + + + + + + + + insert into car_pass_gather + + park_id, + area, + license, + join_time, + sn, + + + #{parkId}, + #{area}, + #{license}, + #{joinTime}, + #{sn}, + + + + + update car_pass_gather + + park_id = #{parkId}, + area = #{area}, + license = #{license}, + join_time = #{joinTime}, + sn = #{sn}, + + where id = #{id} + + + + delete from car_pass_gather where id = #{id} + + + + delete from car_pass_gather where id in + + #{id} + + + + + + diff --git a/dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarPassRecordMapper.xml b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarPassRecordMapper.xml new file mode 100644 index 0000000..edecd92 --- /dev/null +++ b/dcsoft-modules/dcsoft-system/src/main/resources/mapper/vehicle/CarPassRecordMapper.xml @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + select cpr.id, cpr.park_id, cpr.unique_no, cpr.direction, cpr.license, cpr.pass_time, cpr.trigger_type, cpr.color_type, + cpr.car_color, cpr.url, cpr.data_type, cpr.sn,cpi.way,cp.name park_name,se.name equipment_name,ci.unit,cpr.type + from car_pass_record cpr + left join sys_equipment se on cpr.sn=se.sequence + left join car_park_item cpi on cpi.equipment_id=se.id + left join car_park cp on cp.id=cpi.park_id + left join car_info ci on cpr.license=ci.plate + + + + + + + + insert into car_pass_record + + id, + park_id, + unique_no, + direction, + license, + pass_time, + trigger_type, + color_type, + car_color, + url, + data_type, + sn, + + + #{id}, + #{parkId}, + #{uniqueNo}, + #{direction}, + #{license}, + #{passTime}, + #{triggerType}, + #{colorType}, + #{carColor}, + #{url}, + #{dataType}, + #{sn}, + + + + + update car_pass_record + + park_id = #{parkId}, + unique_no = #{uniqueNo}, + direction = #{direction}, + license = #{license}, + pass_time = #{passTime}, + trigger_type = #{triggerType}, + color_type = #{colorType}, + car_color = #{carColor}, + url = #{url}, + data_type = #{dataType}, + sn = #{sn}, + + where id = #{id} + + + + delete from car_pass_record where id = #{id} + + + + delete from car_pass_record where id in + + #{id} + + + diff --git a/dcsoft-modules/pom.xml b/dcsoft-modules/pom.xml new file mode 100644 index 0000000..19fa3f5 --- /dev/null +++ b/dcsoft-modules/pom.xml @@ -0,0 +1,25 @@ + + + + com.dcsoft + dcsoft + 3.6.2 + + 4.0.0 + + + dcsoft-system + dcsoft-gen + dcsoft-job + dcsoft-file + + + dcsoft-modules + pom + + + dcsoft-modules业务模块 + + + diff --git a/dcsoft-visual/dcsoft-monitor/pom.xml b/dcsoft-visual/dcsoft-monitor/pom.xml new file mode 100644 index 0000000..7d1ce20 --- /dev/null +++ b/dcsoft-visual/dcsoft-monitor/pom.xml @@ -0,0 +1,75 @@ + + + com.dcsoft + dcsoft-visual + 3.6.2 + + 4.0.0 + + dcsoft-visual-monitor + + + dcsoft-visual-monitor监控中心 + + + + + + + de.codecentric + spring-boot-admin-starter-server + ${spring-boot-admin.version} + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-security + + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + diff --git a/dcsoft-visual/dcsoft-monitor/src/main/java/com/dcsoft/modules/monitor/DCSMonitorApplication.java b/dcsoft-visual/dcsoft-monitor/src/main/java/com/dcsoft/modules/monitor/DCSMonitorApplication.java new file mode 100644 index 0000000..3fcf048 --- /dev/null +++ b/dcsoft-visual/dcsoft-monitor/src/main/java/com/dcsoft/modules/monitor/DCSMonitorApplication.java @@ -0,0 +1,30 @@ +package com.dcsoft.modules.monitor; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import de.codecentric.boot.admin.server.config.EnableAdminServer; + +/** + * 监控中心 + * + * @author dcsoft + */ +@EnableAdminServer +@SpringBootApplication +public class DCSMonitorApplication +{ + public static void main(String[] args) + { + SpringApplication.run(com.dcsoft.modules.monitor.DCSMonitorApplication.class, args); + System.out.println("(♥◠‿◠)ノ゙ 监控中心启动成功 ლ(´ڡ`ლ)゙ \n" + + " .-------. ____ __ \n" + + " | _ _ \\ \\ \\ / / \n" + + " | ( ' ) | \\ _. / ' \n" + + " |(_ o _) / _( )_ .' \n" + + " | (_,_).' __ ___(_ o _)' \n" + + " | |\\ \\ | || |(_,_)' \n" + + " | | \\ `' /| `-' / \n" + + " | | \\ / \\ / \n" + + " ''-' `'-' `-..-' "); + } +} diff --git a/dcsoft-visual/dcsoft-monitor/src/main/java/com/dcsoft/modules/monitor/config/WebSecurityConfigurer.java b/dcsoft-visual/dcsoft-monitor/src/main/java/com/dcsoft/modules/monitor/config/WebSecurityConfigurer.java new file mode 100644 index 0000000..7236401 --- /dev/null +++ b/dcsoft-visual/dcsoft-monitor/src/main/java/com/dcsoft/modules/monitor/config/WebSecurityConfigurer.java @@ -0,0 +1,51 @@ +package com.dcsoft.modules.monitor.config; + +import de.codecentric.boot.admin.server.config.AdminServerProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; + +/** + * 监控权限配置 + * + * @author dcsoft + */ +@EnableWebSecurity +public class WebSecurityConfigurer +{ + private final String adminContextPath; + + public WebSecurityConfigurer(AdminServerProperties adminServerProperties) + { + this.adminContextPath = adminServerProperties.getContextPath(); + } + + @Bean + public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception + { + SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler(); + successHandler.setTargetUrlParameter("redirectTo"); + successHandler.setDefaultTargetUrl(adminContextPath + "/"); + + return httpSecurity + .headers().frameOptions().disable() + .and().authorizeRequests() + .antMatchers(adminContextPath + "/assets/**" + , adminContextPath + "/login" + , adminContextPath + "/actuator/**" + , adminContextPath + "/instances/**" + ).permitAll() + .anyRequest().authenticated() + .and() + .formLogin().loginPage(adminContextPath + "/login") + .successHandler(successHandler).and() + .logout().logoutUrl(adminContextPath + "/logout") + .and() + .httpBasic().and() + .csrf() + .disable() + .build(); + } +} diff --git a/dcsoft-visual/dcsoft-monitor/src/main/resources/banner.txt b/dcsoft-visual/dcsoft-monitor/src/main/resources/banner.txt new file mode 100644 index 0000000..ecaf8a4 --- /dev/null +++ b/dcsoft-visual/dcsoft-monitor/src/main/resources/banner.txt @@ -0,0 +1,10 @@ +Spring Boot Version: ${spring-boot.version} +Spring Application Name: ${spring.application.name} + _ _ _ + (_) (_)| | + _ __ _ _ ___ _ _ _ ______ _ __ ___ ___ _ __ _ | |_ ___ _ __ +| '__|| | | | / _ \ | | | || ||______|| '_ ` _ \ / _ \ | '_ \ | || __| / _ \ | '__| +| | | |_| || (_) || |_| || | | | | | | || (_) || | | || || |_ | (_) || | +|_| \__,_| \___/ \__, ||_| |_| |_| |_| \___/ |_| |_||_| \__| \___/ |_| + __/ | + |___/ \ No newline at end of file diff --git a/dcsoft-visual/dcsoft-monitor/src/main/resources/bootstrap.yml b/dcsoft-visual/dcsoft-monitor/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..37196de --- /dev/null +++ b/dcsoft-visual/dcsoft-monitor/src/main/resources/bootstrap.yml @@ -0,0 +1,25 @@ +# Tomcat +server: + port: 9100 + +# Spring +spring: + application: + # 应用名称 + name: dcsoft-monitor + profiles: + # 环境配置 + active: dev + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: 127.0.0.1:8848 + config: + # 配置中心地址 + server-addr: 127.0.0.1:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} diff --git a/dcsoft-visual/dcsoft-monitor/src/main/resources/logback.xml b/dcsoft-visual/dcsoft-monitor/src/main/resources/logback.xml new file mode 100644 index 0000000..6496cd2 --- /dev/null +++ b/dcsoft-visual/dcsoft-monitor/src/main/resources/logback.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/info.log + + + + ${log.path}/info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/error.log + + + + ${log.path}/error.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + + + + + + + + + + + + + diff --git a/dcsoft-visual/pom.xml b/dcsoft-visual/pom.xml new file mode 100644 index 0000000..b458196 --- /dev/null +++ b/dcsoft-visual/pom.xml @@ -0,0 +1,22 @@ + + + + com.dcsoft + dcsoft + 3.6.2 + + 4.0.0 + + + dcsoft-monitor + + + dcsoft-visual + pom + + + dcsoft-visual图形化管理模块 + + + diff --git a/license.xml b/license.xml new file mode 100644 index 0000000..00400f3 --- /dev/null +++ b/license.xml @@ -0,0 +1,8 @@ + + + + + + + PXVnqRD54Gd4f0cEECwqpL0KYlN40lDtUTQRhpSURSqYg+QzDF4/9mYLcu0JNMxsy1O5ZrsAhSLjNzf0TGO05w== + diff --git a/logs/dcsoft-auth/error.log b/logs/dcsoft-auth/error.log new file mode 100644 index 0000000..e69de29 diff --git a/logs/dcsoft-auth/info.2025-03-21.log b/logs/dcsoft-auth/info.2025-03-21.log new file mode 100644 index 0000000..1e96076 --- /dev/null +++ b/logs/dcsoft-auth/info.2025-03-21.log @@ -0,0 +1,106 @@ +22:25:16.575 [background-preinit] INFO o.h.v.i.util.Version - [,21] - HV000001: Hibernate Validator 6.2.5.Final +22:25:17.347 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of ac1a39dc-5abb-41d9-88ff-db247677aa6a_config-0 +22:25:17.382 [main] INFO o.r.Reflections - [scan,232] - Reflections took 19 ms to scan 1 urls, producing 3 keys and 6 values +22:25:17.408 [main] INFO o.r.Reflections - [scan,232] - Reflections took 8 ms to scan 1 urls, producing 4 keys and 9 values +22:25:17.417 [main] INFO o.r.Reflections - [scan,232] - Reflections took 7 ms to scan 1 urls, producing 3 keys and 10 values +22:25:17.518 [main] INFO o.r.Reflections - [scan,232] - Reflections took 99 ms to scan 180 urls, producing 0 keys and 0 values +22:25:17.528 [main] INFO o.r.Reflections - [scan,232] - Reflections took 6 ms to scan 1 urls, producing 1 keys and 5 values +22:25:17.537 [main] INFO o.r.Reflections - [scan,232] - Reflections took 7 ms to scan 1 urls, producing 1 keys and 7 values +22:25:17.549 [main] INFO o.r.Reflections - [scan,232] - Reflections took 10 ms to scan 1 urls, producing 2 keys and 8 values +22:25:17.651 [main] INFO o.r.Reflections - [scan,232] - Reflections took 100 ms to scan 180 urls, producing 0 keys and 0 values +22:25:17.652 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [ac1a39dc-5abb-41d9-88ff-db247677aa6a_config-0] RpcClient init label, labels = {module=config, Vipserver-Tag=null, source=sdk, Amory-Tag=null, Location-Tag=null, taskId=0, AppName=unknown} +22:25:17.652 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [ac1a39dc-5abb-41d9-88ff-db247677aa6a_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$336/1532554556 +22:25:17.653 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [ac1a39dc-5abb-41d9-88ff-db247677aa6a_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$337/620423816 +22:25:17.653 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [ac1a39dc-5abb-41d9-88ff-db247677aa6a_config-0] Registry connection listener to current client:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$1 +22:25:17.653 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [ac1a39dc-5abb-41d9-88ff-db247677aa6a_config-0] RpcClient init, ServerListFactory = com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$2 +22:25:17.659 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [ac1a39dc-5abb-41d9-88ff-db247677aa6a_config-0] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +22:25:19.390 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [ac1a39dc-5abb-41d9-88ff-db247677aa6a_config-0] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1742567119133_127.0.0.1_49271 +22:25:19.391 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [ac1a39dc-5abb-41d9-88ff-db247677aa6a_config-0] Notify connected event to listeners. +22:25:19.391 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [ac1a39dc-5abb-41d9-88ff-db247677aa6a_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +22:25:19.391 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [ac1a39dc-5abb-41d9-88ff-db247677aa6a_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$345/1729734072 +22:25:19.529 [main] INFO c.d.a.DCSAuthApplication - [logStartupProfileInfo,637] - The following 1 profile is active: "dev" +22:25:20.932 [main] INFO o.a.c.h.Http11NioProtocol - [log,173] - Initializing ProtocolHandler ["http-nio-9200"] +22:25:20.932 [main] INFO o.a.c.c.StandardService - [log,173] - Starting service [Tomcat] +22:25:20.933 [main] INFO o.a.c.c.StandardEngine - [log,173] - Starting Servlet engine: [Apache Tomcat/9.0.70] +22:25:21.084 [main] INFO o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring embedded WebApplicationContext +22:25:22.027 [main] INFO c.a.c.s.SentinelWebMvcConfigurer - [addInterceptors,52] - [Sentinel Starter] register SentinelWebInterceptor with urlPatterns: [/**]. +22:25:23.805 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of 835ace5f-c105-4bd1-9e70-14c08cc81525 +22:25:23.806 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [835ace5f-c105-4bd1-9e70-14c08cc81525] RpcClient init label, labels = {module=naming, source=sdk} +22:25:23.807 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [835ace5f-c105-4bd1-9e70-14c08cc81525] RpcClient init, ServerListFactory = com.alibaba.nacos.client.naming.core.ServerListManager +22:25:23.807 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [835ace5f-c105-4bd1-9e70-14c08cc81525] Registry connection listener to current client:com.alibaba.nacos.client.naming.remote.gprc.redo.NamingGrpcRedoService +22:25:23.807 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [835ace5f-c105-4bd1-9e70-14c08cc81525] Register server push request handler:com.alibaba.nacos.client.naming.remote.gprc.NamingPushRequestHandler +22:25:23.807 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [835ace5f-c105-4bd1-9e70-14c08cc81525] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +22:25:23.918 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [835ace5f-c105-4bd1-9e70-14c08cc81525] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1742567123811_127.0.0.1_49325 +22:25:23.918 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [835ace5f-c105-4bd1-9e70-14c08cc81525] Notify connected event to listeners. +22:25:23.918 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [835ace5f-c105-4bd1-9e70-14c08cc81525] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +22:25:23.918 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [835ace5f-c105-4bd1-9e70-14c08cc81525] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$345/1729734072 +22:25:23.967 [main] INFO o.a.c.h.Http11NioProtocol - [log,173] - Starting ProtocolHandler ["http-nio-9200"] +22:25:23.994 [main] INFO c.a.c.n.r.NacosServiceRegistry - [register,75] - nacos registry, DEFAULT_GROUP dcsoft-auth 192.168.0.104:9200 register finished +22:25:24.612 [main] INFO c.d.a.DCSAuthApplication - [logStarted,61] - Started DCSAuthApplication in 8.791 seconds (JVM running for 9.748) +22:25:24.619 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-auth, group=DEFAULT_GROUP +22:25:24.620 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-auth.yml, group=DEFAULT_GROUP +22:25:24.620 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-auth-dev.yml, group=DEFAULT_GROUP +22:25:25.974 [RMI TCP Connection(3)-192.168.0.104] INFO o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring DispatcherServlet 'dispatcherServlet' +22:25:26.355 [nacos-grpc-client-executor-11] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [835ace5f-c105-4bd1-9e70-14c08cc81525] Receive server push request, request = NotifySubscriberRequest, requestId = 1 +22:25:26.356 [nacos-grpc-client-executor-11] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [835ace5f-c105-4bd1-9e70-14c08cc81525] Ack server push request, request = NotifySubscriberRequest, requestId = 1 +22:29:09.027 [nacos-grpc-client-executor-68] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [ac1a39dc-5abb-41d9-88ff-db247677aa6a_config-0] Receive server push request, request = ConfigChangeNotifyRequest, requestId = 7 +22:29:09.027 [nacos-grpc-client-executor-68] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [ac1a39dc-5abb-41d9-88ff-db247677aa6a_config-0] Ack server push request, request = ConfigChangeNotifyRequest, requestId = 7 +22:30:01.736 [SpringApplicationShutdownHook] INFO c.a.c.n.r.NacosServiceRegistry - [deregister,94] - De-registering from Nacos Server now... +22:30:01.747 [SpringApplicationShutdownHook] INFO c.a.c.n.r.NacosServiceRegistry - [deregister,114] - De-registration finished. +22:30:02.080 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [shutdown,454] - Shutdown rpc client, set status to shutdown +22:30:02.080 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [shutdown,456] - Shutdown client event executor java.util.concurrent.ScheduledThreadPoolExecutor@7172a0a8[Running, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 0] +22:30:02.080 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [closeConnection,591] - Close current connection 1742567123811_127.0.0.1_49325 +22:30:02.081 [nacos-grpc-client-executor-77] INFO c.a.n.c.r.c.g.GrpcClient - [printIfInfoEnabled,60] - [1742567123811_127.0.0.1_49325]Ignore complete event,isRunning:false,isAbandon=false +22:30:02.083 [SpringApplicationShutdownHook] INFO c.a.n.c.r.c.g.GrpcClient - [shutdown,85] - Shutdown grpc executor java.util.concurrent.ThreadPoolExecutor@6ea2db0[Running, pool size = 6, active threads = 0, queued tasks = 0, completed tasks = 78] +22:39:17.143 [background-preinit] INFO o.h.v.i.util.Version - [,21] - HV000001: Hibernate Validator 6.2.5.Final +22:39:17.944 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of b29d427d-4c1a-4ce2-b8d2-d6698df89101_config-0 +22:39:17.979 [main] INFO o.r.Reflections - [scan,232] - Reflections took 21 ms to scan 1 urls, producing 3 keys and 6 values +22:39:18.001 [main] INFO o.r.Reflections - [scan,232] - Reflections took 9 ms to scan 1 urls, producing 4 keys and 9 values +22:39:18.010 [main] INFO o.r.Reflections - [scan,232] - Reflections took 7 ms to scan 1 urls, producing 3 keys and 10 values +22:39:18.127 [main] INFO o.r.Reflections - [scan,232] - Reflections took 114 ms to scan 180 urls, producing 0 keys and 0 values +22:39:18.136 [main] INFO o.r.Reflections - [scan,232] - Reflections took 6 ms to scan 1 urls, producing 1 keys and 5 values +22:39:18.146 [main] INFO o.r.Reflections - [scan,232] - Reflections took 9 ms to scan 1 urls, producing 1 keys and 7 values +22:39:18.154 [main] INFO o.r.Reflections - [scan,232] - Reflections took 7 ms to scan 1 urls, producing 2 keys and 8 values +22:39:18.246 [main] INFO o.r.Reflections - [scan,232] - Reflections took 89 ms to scan 180 urls, producing 0 keys and 0 values +22:39:18.247 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b29d427d-4c1a-4ce2-b8d2-d6698df89101_config-0] RpcClient init label, labels = {module=config, Vipserver-Tag=null, source=sdk, Amory-Tag=null, Location-Tag=null, taskId=0, AppName=unknown} +22:39:18.247 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b29d427d-4c1a-4ce2-b8d2-d6698df89101_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$336/1532554556 +22:39:18.248 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b29d427d-4c1a-4ce2-b8d2-d6698df89101_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$337/620423816 +22:39:18.248 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b29d427d-4c1a-4ce2-b8d2-d6698df89101_config-0] Registry connection listener to current client:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$1 +22:39:18.249 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b29d427d-4c1a-4ce2-b8d2-d6698df89101_config-0] RpcClient init, ServerListFactory = com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$2 +22:39:18.254 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b29d427d-4c1a-4ce2-b8d2-d6698df89101_config-0] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +22:39:19.860 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b29d427d-4c1a-4ce2-b8d2-d6698df89101_config-0] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1742567959641_127.0.0.1_50337 +22:39:19.860 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b29d427d-4c1a-4ce2-b8d2-d6698df89101_config-0] Notify connected event to listeners. +22:39:19.860 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b29d427d-4c1a-4ce2-b8d2-d6698df89101_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +22:39:19.861 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b29d427d-4c1a-4ce2-b8d2-d6698df89101_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$345/1729734072 +22:39:19.922 [main] INFO c.d.a.DCSAuthApplication - [logStartupProfileInfo,637] - The following 1 profile is active: "dev" +22:39:20.957 [main] INFO o.a.c.h.Http11NioProtocol - [log,173] - Initializing ProtocolHandler ["http-nio-9200"] +22:39:20.958 [main] INFO o.a.c.c.StandardService - [log,173] - Starting service [Tomcat] +22:39:20.958 [main] INFO o.a.c.c.StandardEngine - [log,173] - Starting Servlet engine: [Apache Tomcat/9.0.70] +22:39:21.069 [main] INFO o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring embedded WebApplicationContext +22:39:21.899 [main] INFO c.a.c.s.SentinelWebMvcConfigurer - [addInterceptors,52] - [Sentinel Starter] register SentinelWebInterceptor with urlPatterns: [/**]. +22:39:23.525 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of f3e731dc-c38f-4ec8-8fb5-b60f685fb81c +22:39:23.525 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [f3e731dc-c38f-4ec8-8fb5-b60f685fb81c] RpcClient init label, labels = {module=naming, source=sdk} +22:39:23.526 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [f3e731dc-c38f-4ec8-8fb5-b60f685fb81c] RpcClient init, ServerListFactory = com.alibaba.nacos.client.naming.core.ServerListManager +22:39:23.527 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [f3e731dc-c38f-4ec8-8fb5-b60f685fb81c] Registry connection listener to current client:com.alibaba.nacos.client.naming.remote.gprc.redo.NamingGrpcRedoService +22:39:23.527 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [f3e731dc-c38f-4ec8-8fb5-b60f685fb81c] Register server push request handler:com.alibaba.nacos.client.naming.remote.gprc.NamingPushRequestHandler +22:39:23.527 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [f3e731dc-c38f-4ec8-8fb5-b60f685fb81c] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +22:39:23.638 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [f3e731dc-c38f-4ec8-8fb5-b60f685fb81c] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1742567963532_127.0.0.1_50391 +22:39:23.638 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [f3e731dc-c38f-4ec8-8fb5-b60f685fb81c] Notify connected event to listeners. +22:39:23.638 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [f3e731dc-c38f-4ec8-8fb5-b60f685fb81c] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +22:39:23.638 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [f3e731dc-c38f-4ec8-8fb5-b60f685fb81c] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$345/1729734072 +22:39:23.660 [main] INFO o.a.c.h.Http11NioProtocol - [log,173] - Starting ProtocolHandler ["http-nio-9200"] +22:39:23.674 [main] INFO c.a.c.n.r.NacosServiceRegistry - [register,75] - nacos registry, DEFAULT_GROUP dcsoft-auth 192.168.0.104:9200 register finished +22:39:24.242 [nacos-grpc-client-executor-7] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [f3e731dc-c38f-4ec8-8fb5-b60f685fb81c] Receive server push request, request = NotifySubscriberRequest, requestId = 11 +22:39:24.248 [nacos-grpc-client-executor-7] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [f3e731dc-c38f-4ec8-8fb5-b60f685fb81c] Ack server push request, request = NotifySubscriberRequest, requestId = 11 +22:39:24.287 [main] INFO c.d.a.DCSAuthApplication - [logStarted,61] - Started DCSAuthApplication in 7.957 seconds (JVM running for 8.835) +22:39:24.297 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-auth, group=DEFAULT_GROUP +22:39:24.298 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-auth.yml, group=DEFAULT_GROUP +22:39:24.300 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-auth-dev.yml, group=DEFAULT_GROUP +22:39:25.815 [RMI TCP Connection(3)-192.168.0.104] INFO o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring DispatcherServlet 'dispatcherServlet' +23:00:20.650 [SpringApplicationShutdownHook] INFO c.a.c.n.r.NacosServiceRegistry - [deregister,94] - De-registering from Nacos Server now... +23:00:20.654 [SpringApplicationShutdownHook] INFO c.a.c.n.r.NacosServiceRegistry - [deregister,114] - De-registration finished. +23:00:20.984 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [shutdown,454] - Shutdown rpc client, set status to shutdown +23:00:20.984 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [shutdown,456] - Shutdown client event executor java.util.concurrent.ScheduledThreadPoolExecutor@1c77f19b[Running, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 0] +23:00:20.984 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [closeConnection,591] - Close current connection 1742567963532_127.0.0.1_50391 +23:00:20.985 [nacos-grpc-client-executor-272] INFO c.a.n.c.r.c.g.GrpcClient - [printIfInfoEnabled,60] - [1742567963532_127.0.0.1_50391]Ignore complete event,isRunning:false,isAbandon=false +23:00:20.987 [SpringApplicationShutdownHook] INFO c.a.n.c.r.c.g.GrpcClient - [shutdown,85] - Shutdown grpc executor java.util.concurrent.ThreadPoolExecutor@5c84af72[Running, pool size = 7, active threads = 0, queued tasks = 0, completed tasks = 273] diff --git a/logs/dcsoft-auth/info.2025-03-22.log b/logs/dcsoft-auth/info.2025-03-22.log new file mode 100644 index 0000000..e169810 --- /dev/null +++ b/logs/dcsoft-auth/info.2025-03-22.log @@ -0,0 +1,60 @@ +17:37:51.005 [background-preinit] INFO o.h.v.i.util.Version - [,21] - HV000001: Hibernate Validator 6.2.5.Final +17:37:51.782 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of 76604a69-c3db-47c3-bbcd-98f91b141048_config-0 +17:37:51.825 [main] INFO o.r.Reflections - [scan,232] - Reflections took 23 ms to scan 1 urls, producing 3 keys and 6 values +17:37:51.848 [main] INFO o.r.Reflections - [scan,232] - Reflections took 15 ms to scan 1 urls, producing 4 keys and 9 values +17:37:51.859 [main] INFO o.r.Reflections - [scan,232] - Reflections took 9 ms to scan 1 urls, producing 3 keys and 10 values +17:37:51.968 [main] INFO o.r.Reflections - [scan,232] - Reflections took 106 ms to scan 180 urls, producing 0 keys and 0 values +17:37:51.977 [main] INFO o.r.Reflections - [scan,232] - Reflections took 7 ms to scan 1 urls, producing 1 keys and 5 values +17:37:51.988 [main] INFO o.r.Reflections - [scan,232] - Reflections took 9 ms to scan 1 urls, producing 1 keys and 7 values +17:37:52.001 [main] INFO o.r.Reflections - [scan,232] - Reflections took 11 ms to scan 1 urls, producing 2 keys and 8 values +17:37:52.095 [main] INFO o.r.Reflections - [scan,232] - Reflections took 93 ms to scan 180 urls, producing 0 keys and 0 values +17:37:52.096 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [76604a69-c3db-47c3-bbcd-98f91b141048_config-0] RpcClient init label, labels = {module=config, Vipserver-Tag=null, source=sdk, Amory-Tag=null, Location-Tag=null, taskId=0, AppName=unknown} +17:37:52.096 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [76604a69-c3db-47c3-bbcd-98f91b141048_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$336/1985028494 +17:37:52.097 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [76604a69-c3db-47c3-bbcd-98f91b141048_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$337/830863979 +17:37:52.097 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [76604a69-c3db-47c3-bbcd-98f91b141048_config-0] Registry connection listener to current client:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$1 +17:37:52.098 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [76604a69-c3db-47c3-bbcd-98f91b141048_config-0] RpcClient init, ServerListFactory = com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$2 +17:37:52.102 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [76604a69-c3db-47c3-bbcd-98f91b141048_config-0] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +17:37:53.764 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [76604a69-c3db-47c3-bbcd-98f91b141048_config-0] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1742636273550_127.0.0.1_56753 +17:37:53.764 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [76604a69-c3db-47c3-bbcd-98f91b141048_config-0] Notify connected event to listeners. +17:37:53.764 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [76604a69-c3db-47c3-bbcd-98f91b141048_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +17:37:53.764 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [76604a69-c3db-47c3-bbcd-98f91b141048_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$345/1774589469 +17:37:53.847 [main] INFO c.d.a.DCSAuthApplication - [logStartupProfileInfo,637] - The following 1 profile is active: "dev" +17:37:55.201 [main] INFO o.a.c.h.Http11NioProtocol - [log,173] - Initializing ProtocolHandler ["http-nio-9200"] +17:37:55.202 [main] INFO o.a.c.c.StandardService - [log,173] - Starting service [Tomcat] +17:37:55.202 [main] INFO o.a.c.c.StandardEngine - [log,173] - Starting Servlet engine: [Apache Tomcat/9.0.70] +17:37:55.333 [main] INFO o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring embedded WebApplicationContext +17:37:56.163 [main] INFO c.a.c.s.SentinelWebMvcConfigurer - [addInterceptors,52] - [Sentinel Starter] register SentinelWebInterceptor with urlPatterns: [/**]. +17:37:57.850 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of de2ded54-9530-46e9-b55c-e98b58d34ada +17:37:57.850 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [de2ded54-9530-46e9-b55c-e98b58d34ada] RpcClient init label, labels = {module=naming, source=sdk} +17:37:57.852 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [de2ded54-9530-46e9-b55c-e98b58d34ada] RpcClient init, ServerListFactory = com.alibaba.nacos.client.naming.core.ServerListManager +17:37:57.852 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [de2ded54-9530-46e9-b55c-e98b58d34ada] Registry connection listener to current client:com.alibaba.nacos.client.naming.remote.gprc.redo.NamingGrpcRedoService +17:37:57.853 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [de2ded54-9530-46e9-b55c-e98b58d34ada] Register server push request handler:com.alibaba.nacos.client.naming.remote.gprc.NamingPushRequestHandler +17:37:57.853 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [de2ded54-9530-46e9-b55c-e98b58d34ada] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +17:37:57.977 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [de2ded54-9530-46e9-b55c-e98b58d34ada] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1742636277856_127.0.0.1_56758 +17:37:57.977 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [de2ded54-9530-46e9-b55c-e98b58d34ada] Notify connected event to listeners. +17:37:57.977 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [de2ded54-9530-46e9-b55c-e98b58d34ada] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +17:37:57.977 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [de2ded54-9530-46e9-b55c-e98b58d34ada] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$345/1774589469 +17:37:58.025 [main] INFO o.a.c.h.Http11NioProtocol - [log,173] - Starting ProtocolHandler ["http-nio-9200"] +17:37:58.055 [main] INFO c.a.c.n.r.NacosServiceRegistry - [register,75] - nacos registry, DEFAULT_GROUP dcsoft-auth 192.168.0.104:9200 register finished +17:37:58.693 [main] INFO c.d.a.DCSAuthApplication - [logStarted,61] - Started DCSAuthApplication in 8.621 seconds (JVM running for 9.57) +17:37:58.700 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-auth, group=DEFAULT_GROUP +17:37:58.701 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-auth.yml, group=DEFAULT_GROUP +17:37:58.702 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-auth-dev.yml, group=DEFAULT_GROUP +17:38:00.955 [nacos-grpc-client-executor-11] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [de2ded54-9530-46e9-b55c-e98b58d34ada] Receive server push request, request = NotifySubscriberRequest, requestId = 1 +17:38:00.956 [nacos-grpc-client-executor-11] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [de2ded54-9530-46e9-b55c-e98b58d34ada] Ack server push request, request = NotifySubscriberRequest, requestId = 1 +17:38:00.981 [RMI TCP Connection(3)-192.168.0.104] INFO o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring DispatcherServlet 'dispatcherServlet' +17:39:51.384 [http-nio-9200-exec-1] INFO o.a.t.u.h.p.Cookie - [log,173] - A cookie header was received [Hm_lvt_be968d539e394cf45975b5117965eb10=1742280385,1742366828,1742451210,1742550106] that contained an invalid cookie. That cookie will be ignored. + Note: further occurrences of this error will be logged at DEBUG level. +17:39:52.634 [nacos-grpc-client-executor-45] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [de2ded54-9530-46e9-b55c-e98b58d34ada] Receive server push request, request = NotifySubscriberRequest, requestId = 7 +17:39:52.634 [nacos-grpc-client-executor-45] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [de2ded54-9530-46e9-b55c-e98b58d34ada] Ack server push request, request = NotifySubscriberRequest, requestId = 7 +17:42:36.385 [nacos-grpc-client-executor-85] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [de2ded54-9530-46e9-b55c-e98b58d34ada] Receive server push request, request = NotifySubscriberRequest, requestId = 8 +17:42:36.389 [nacos-grpc-client-executor-85] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [de2ded54-9530-46e9-b55c-e98b58d34ada] Ack server push request, request = NotifySubscriberRequest, requestId = 8 +17:42:54.265 [nacos-grpc-client-executor-91] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [de2ded54-9530-46e9-b55c-e98b58d34ada] Receive server push request, request = NotifySubscriberRequest, requestId = 11 +17:42:54.268 [nacos-grpc-client-executor-91] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [de2ded54-9530-46e9-b55c-e98b58d34ada] Ack server push request, request = NotifySubscriberRequest, requestId = 11 +17:50:39.900 [SpringApplicationShutdownHook] INFO c.a.c.n.r.NacosServiceRegistry - [deregister,94] - De-registering from Nacos Server now... +17:50:39.916 [SpringApplicationShutdownHook] INFO c.a.c.n.r.NacosServiceRegistry - [deregister,114] - De-registration finished. +17:50:40.235 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [shutdown,454] - Shutdown rpc client, set status to shutdown +17:50:40.235 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [shutdown,456] - Shutdown client event executor java.util.concurrent.ScheduledThreadPoolExecutor@7f3b2a3c[Running, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 0] +17:50:40.235 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [closeConnection,591] - Close current connection 1742636277856_127.0.0.1_56758 +17:50:40.244 [nacos-grpc-client-executor-191] INFO c.a.n.c.r.c.g.GrpcClient - [printIfInfoEnabled,60] - [1742636277856_127.0.0.1_56758]Ignore complete event,isRunning:false,isAbandon=false +17:50:40.246 [SpringApplicationShutdownHook] INFO c.a.n.c.r.c.g.GrpcClient - [shutdown,85] - Shutdown grpc executor java.util.concurrent.ThreadPoolExecutor@15dd1a4d[Running, pool size = 5, active threads = 0, queued tasks = 0, completed tasks = 192] diff --git a/logs/dcsoft-auth/info.log b/logs/dcsoft-auth/info.log new file mode 100644 index 0000000..95ea73b --- /dev/null +++ b/logs/dcsoft-auth/info.log @@ -0,0 +1,56 @@ +15:34:39.739 [background-preinit] INFO o.h.v.i.util.Version - [,21] - HV000001: Hibernate Validator 6.2.5.Final +15:34:40.605 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of 7f2f3a5c-57a0-4e0f-bb16-4618881394a6_config-0 +15:34:40.633 [main] INFO o.r.Reflections - [scan,232] - Reflections took 18 ms to scan 1 urls, producing 3 keys and 6 values +15:34:40.651 [main] INFO o.r.Reflections - [scan,232] - Reflections took 10 ms to scan 1 urls, producing 4 keys and 9 values +15:34:40.660 [main] INFO o.r.Reflections - [scan,232] - Reflections took 7 ms to scan 1 urls, producing 3 keys and 10 values +15:34:40.767 [main] INFO o.r.Reflections - [scan,232] - Reflections took 104 ms to scan 180 urls, producing 0 keys and 0 values +15:34:40.780 [main] INFO o.r.Reflections - [scan,232] - Reflections took 6 ms to scan 1 urls, producing 1 keys and 5 values +15:34:40.790 [main] INFO o.r.Reflections - [scan,232] - Reflections took 9 ms to scan 1 urls, producing 1 keys and 7 values +15:34:40.801 [main] INFO o.r.Reflections - [scan,232] - Reflections took 9 ms to scan 1 urls, producing 2 keys and 8 values +15:34:40.909 [main] INFO o.r.Reflections - [scan,232] - Reflections took 107 ms to scan 180 urls, producing 0 keys and 0 values +15:34:40.910 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7f2f3a5c-57a0-4e0f-bb16-4618881394a6_config-0] RpcClient init label, labels = {module=config, Vipserver-Tag=null, source=sdk, Amory-Tag=null, Location-Tag=null, taskId=0, AppName=unknown} +15:34:40.911 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7f2f3a5c-57a0-4e0f-bb16-4618881394a6_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$336/1985028494 +15:34:40.911 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7f2f3a5c-57a0-4e0f-bb16-4618881394a6_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$337/830863979 +15:34:40.911 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7f2f3a5c-57a0-4e0f-bb16-4618881394a6_config-0] Registry connection listener to current client:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$1 +15:34:40.912 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7f2f3a5c-57a0-4e0f-bb16-4618881394a6_config-0] RpcClient init, ServerListFactory = com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$2 +15:34:40.919 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7f2f3a5c-57a0-4e0f-bb16-4618881394a6_config-0] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +15:34:42.493 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7f2f3a5c-57a0-4e0f-bb16-4618881394a6_config-0] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1745825682292_127.0.0.1_59557 +15:34:42.494 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7f2f3a5c-57a0-4e0f-bb16-4618881394a6_config-0] Notify connected event to listeners. +15:34:42.494 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7f2f3a5c-57a0-4e0f-bb16-4618881394a6_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +15:34:42.495 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7f2f3a5c-57a0-4e0f-bb16-4618881394a6_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$345/1774589469 +15:34:42.589 [main] INFO c.d.a.DCSAuthApplication - [logStartupProfileInfo,637] - The following 1 profile is active: "dev" +15:34:44.026 [main] INFO o.a.c.h.Http11NioProtocol - [log,173] - Initializing ProtocolHandler ["http-nio-9200"] +15:34:44.026 [main] INFO o.a.c.c.StandardService - [log,173] - Starting service [Tomcat] +15:34:44.027 [main] INFO o.a.c.c.StandardEngine - [log,173] - Starting Servlet engine: [Apache Tomcat/9.0.70] +15:34:44.189 [main] INFO o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring embedded WebApplicationContext +15:34:45.133 [main] INFO c.a.c.s.SentinelWebMvcConfigurer - [addInterceptors,52] - [Sentinel Starter] register SentinelWebInterceptor with urlPatterns: [/**]. +15:34:47.003 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of b6ceb628-d8df-468d-94d3-22464e44a647 +15:34:47.003 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b6ceb628-d8df-468d-94d3-22464e44a647] RpcClient init label, labels = {module=naming, source=sdk} +15:34:47.004 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b6ceb628-d8df-468d-94d3-22464e44a647] RpcClient init, ServerListFactory = com.alibaba.nacos.client.naming.core.ServerListManager +15:34:47.005 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b6ceb628-d8df-468d-94d3-22464e44a647] Registry connection listener to current client:com.alibaba.nacos.client.naming.remote.gprc.redo.NamingGrpcRedoService +15:34:47.005 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b6ceb628-d8df-468d-94d3-22464e44a647] Register server push request handler:com.alibaba.nacos.client.naming.remote.gprc.NamingPushRequestHandler +15:34:47.005 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b6ceb628-d8df-468d-94d3-22464e44a647] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +15:34:47.167 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b6ceb628-d8df-468d-94d3-22464e44a647] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1745825687048_127.0.0.1_59589 +15:34:47.167 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b6ceb628-d8df-468d-94d3-22464e44a647] Notify connected event to listeners. +15:34:47.167 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b6ceb628-d8df-468d-94d3-22464e44a647] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +15:34:47.167 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b6ceb628-d8df-468d-94d3-22464e44a647] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$345/1774589469 +15:34:47.199 [main] INFO o.a.c.h.Http11NioProtocol - [log,173] - Starting ProtocolHandler ["http-nio-9200"] +15:34:47.231 [main] INFO c.a.c.n.r.NacosServiceRegistry - [register,75] - nacos registry, DEFAULT_GROUP dcsoft-auth 192.168.2.21:9200 register finished +15:34:47.768 [nacos-grpc-client-executor-7] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b6ceb628-d8df-468d-94d3-22464e44a647] Receive server push request, request = NotifySubscriberRequest, requestId = 23 +15:34:47.775 [nacos-grpc-client-executor-7] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b6ceb628-d8df-468d-94d3-22464e44a647] Ack server push request, request = NotifySubscriberRequest, requestId = 23 +15:34:47.792 [main] INFO c.d.a.DCSAuthApplication - [logStarted,61] - Started DCSAuthApplication in 9.099 seconds (JVM running for 10.169) +15:34:47.799 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-auth, group=DEFAULT_GROUP +15:34:47.800 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-auth.yml, group=DEFAULT_GROUP +15:34:47.800 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-auth-dev.yml, group=DEFAULT_GROUP +15:34:48.377 [RMI TCP Connection(1)-192.168.2.21] INFO o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring DispatcherServlet 'dispatcherServlet' +15:36:55.520 [http-nio-9200-exec-2] INFO o.a.t.u.h.p.Cookie - [log,173] - A cookie header was received [Hm_lvt_be968d539e394cf45975b5117965eb10=1744178737,1744208190,1744250909,1744265525;] that contained an invalid cookie. That cookie will be ignored. + Note: further occurrences of this error will be logged at DEBUG level. +15:36:57.047 [nacos-grpc-client-executor-40] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b6ceb628-d8df-468d-94d3-22464e44a647] Receive server push request, request = NotifySubscriberRequest, requestId = 29 +15:36:57.050 [nacos-grpc-client-executor-40] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b6ceb628-d8df-468d-94d3-22464e44a647] Ack server push request, request = NotifySubscriberRequest, requestId = 29 +15:38:42.161 [SpringApplicationShutdownHook] INFO c.a.c.n.r.NacosServiceRegistry - [deregister,94] - De-registering from Nacos Server now... +15:38:42.181 [SpringApplicationShutdownHook] INFO c.a.c.n.r.NacosServiceRegistry - [deregister,114] - De-registration finished. +15:38:42.583 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [shutdown,454] - Shutdown rpc client, set status to shutdown +15:38:42.584 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [shutdown,456] - Shutdown client event executor java.util.concurrent.ScheduledThreadPoolExecutor@3a80f2fc[Running, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 0] +15:38:42.584 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [closeConnection,591] - Close current connection 1745825687048_127.0.0.1_59589 +15:38:42.590 [nacos-grpc-client-executor-64] INFO c.a.n.c.r.c.g.GrpcClient - [printIfInfoEnabled,60] - [1745825687048_127.0.0.1_59589]Ignore complete event,isRunning:false,isAbandon=false +15:38:42.597 [SpringApplicationShutdownHook] INFO c.a.n.c.r.c.g.GrpcClient - [shutdown,85] - Shutdown grpc executor java.util.concurrent.ThreadPoolExecutor@59533360[Running, pool size = 6, active threads = 0, queued tasks = 0, completed tasks = 65] diff --git a/logs/dcsoft-file/error.log b/logs/dcsoft-file/error.log new file mode 100644 index 0000000..e69de29 diff --git a/logs/dcsoft-file/info.log b/logs/dcsoft-file/info.log new file mode 100644 index 0000000..e69de29 diff --git a/logs/dcsoft-gateway/error.2025-03-21.log b/logs/dcsoft-gateway/error.2025-03-21.log new file mode 100644 index 0000000..e69de29 diff --git a/logs/dcsoft-gateway/error.log b/logs/dcsoft-gateway/error.log new file mode 100644 index 0000000..6d49693 --- /dev/null +++ b/logs/dcsoft-gateway/error.log @@ -0,0 +1,22 @@ +15:34:50.120 [main] ERROR o.s.b.d.LoggingFailureAnalysisReporter - [report,40] - + +*************************** +APPLICATION FAILED TO START +*************************** + +Description: + +Web server failed to start. Port 6609 was already in use. + +Action: + +Identify and stop the process that's listening on port 6609 or configure this application to listen on another port. + +15:36:03.129 [reactor-http-nio-2] ERROR c.d.g.h.GatewayExceptionHandler - [handle,52] - [网关异常处理]请求路径:/sockjs-node/info,异常信息:404 NOT_FOUND +15:36:12.002 [reactor-http-nio-2] ERROR c.d.g.h.GatewayExceptionHandler - [handle,52] - [网关异常处理]请求路径:/sockjs-node/info,异常信息:404 NOT_FOUND +15:36:29.000 [reactor-http-nio-2] ERROR c.d.g.h.GatewayExceptionHandler - [handle,52] - [网关异常处理]请求路径:/sockjs-node/info,异常信息:404 NOT_FOUND +15:36:42.893 [reactor-http-nio-7] ERROR c.d.g.h.GatewayExceptionHandler - [handle,52] - [网关异常处理]请求路径:/,异常信息:404 NOT_FOUND +15:36:42.949 [reactor-http-nio-7] ERROR c.d.g.h.GatewayExceptionHandler - [handle,52] - [网关异常处理]请求路径:/favicon.ico,异常信息:404 NOT_FOUND +15:36:44.693 [reactor-http-nio-7] ERROR c.d.g.h.GatewayExceptionHandler - [handle,52] - [网关异常处理]请求路径:/,异常信息:404 NOT_FOUND +15:36:44.737 [reactor-http-nio-7] ERROR c.d.g.h.GatewayExceptionHandler - [handle,52] - [网关异常处理]请求路径:/favicon.ico,异常信息:404 NOT_FOUND +15:36:55.315 [reactor-http-nio-9] ERROR c.d.g.f.AuthFilter - [unauthorizedResponse,120] - [鉴权异常处理]请求路径:/system/user/getInfo diff --git a/logs/dcsoft-gateway/info.2025-03-21.log b/logs/dcsoft-gateway/info.2025-03-21.log new file mode 100644 index 0000000..a21f243 --- /dev/null +++ b/logs/dcsoft-gateway/info.2025-03-21.log @@ -0,0 +1,134 @@ +22:25:21.897 [background-preinit] INFO o.h.v.i.util.Version - [,21] - HV000001: Hibernate Validator 6.2.5.Final +22:25:22.873 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of 4f20d557-1226-45d1-9920-4368f57a7b45_config-0 +22:25:22.905 [main] INFO o.r.Reflections - [scan,232] - Reflections took 21 ms to scan 1 urls, producing 3 keys and 6 values +22:25:22.929 [main] INFO o.r.Reflections - [scan,232] - Reflections took 15 ms to scan 1 urls, producing 4 keys and 9 values +22:25:22.938 [main] INFO o.r.Reflections - [scan,232] - Reflections took 7 ms to scan 1 urls, producing 3 keys and 10 values +22:25:23.045 [main] INFO o.r.Reflections - [scan,232] - Reflections took 105 ms to scan 211 urls, producing 0 keys and 0 values +22:25:23.057 [main] INFO o.r.Reflections - [scan,232] - Reflections took 6 ms to scan 1 urls, producing 1 keys and 5 values +22:25:23.064 [main] INFO o.r.Reflections - [scan,232] - Reflections took 6 ms to scan 1 urls, producing 1 keys and 7 values +22:25:23.072 [main] INFO o.r.Reflections - [scan,232] - Reflections took 6 ms to scan 1 urls, producing 2 keys and 8 values +22:25:23.201 [main] INFO o.r.Reflections - [scan,232] - Reflections took 128 ms to scan 211 urls, producing 0 keys and 0 values +22:25:23.202 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [4f20d557-1226-45d1-9920-4368f57a7b45_config-0] RpcClient init label, labels = {module=config, Vipserver-Tag=null, source=sdk, Amory-Tag=null, Location-Tag=null, taskId=0, AppName=unknown} +22:25:23.203 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [4f20d557-1226-45d1-9920-4368f57a7b45_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$337/1108706191 +22:25:23.203 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [4f20d557-1226-45d1-9920-4368f57a7b45_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$338/1160487387 +22:25:23.204 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [4f20d557-1226-45d1-9920-4368f57a7b45_config-0] Registry connection listener to current client:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$1 +22:25:23.205 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [4f20d557-1226-45d1-9920-4368f57a7b45_config-0] RpcClient init, ServerListFactory = com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$2 +22:25:23.212 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [4f20d557-1226-45d1-9920-4368f57a7b45_config-0] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +22:25:25.073 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [4f20d557-1226-45d1-9920-4368f57a7b45_config-0] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1742567124865_127.0.0.1_49328 +22:25:25.073 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [4f20d557-1226-45d1-9920-4368f57a7b45_config-0] Notify connected event to listeners. +22:25:25.073 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [4f20d557-1226-45d1-9920-4368f57a7b45_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +22:25:25.074 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [4f20d557-1226-45d1-9920-4368f57a7b45_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$346/332498651 +22:25:25.162 [main] INFO c.d.g.DCSGatewayApplication - [logStartupProfileInfo,637] - The following 1 profile is active: "dev" +22:25:28.707 [main] INFO c.a.c.s.g.s.SentinelSCGAutoConfiguration - [sentinelGatewayFilter,144] - [Sentinel SpringCloudGateway] register SentinelGatewayFilter with order: -2147483648 +22:25:29.020 [main] INFO c.a.c.s.g.s.SentinelSCGAutoConfiguration - [sentinelGatewayBlockExceptionHandler,134] - [Sentinel SpringCloudGateway] register SentinelGatewayBlockExceptionHandler +22:25:29.415 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of 97d5b7b3-a2af-485c-82a0-1fc37305e7e9_config-0 +22:25:29.415 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [97d5b7b3-a2af-485c-82a0-1fc37305e7e9_config-0] RpcClient init label, labels = {module=config, Vipserver-Tag=null, source=sdk, Amory-Tag=null, Location-Tag=null, taskId=0, AppName=unknown} +22:25:29.415 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [97d5b7b3-a2af-485c-82a0-1fc37305e7e9_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$337/1108706191 +22:25:29.416 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [97d5b7b3-a2af-485c-82a0-1fc37305e7e9_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$338/1160487387 +22:25:29.416 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [97d5b7b3-a2af-485c-82a0-1fc37305e7e9_config-0] Registry connection listener to current client:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$1 +22:25:29.416 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [97d5b7b3-a2af-485c-82a0-1fc37305e7e9_config-0] RpcClient init, ServerListFactory = com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$2 +22:25:29.417 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [97d5b7b3-a2af-485c-82a0-1fc37305e7e9_config-0] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +22:25:29.532 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [97d5b7b3-a2af-485c-82a0-1fc37305e7e9_config-0] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1742567129420_127.0.0.1_49361 +22:25:29.533 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [97d5b7b3-a2af-485c-82a0-1fc37305e7e9_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +22:25:29.533 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [97d5b7b3-a2af-485c-82a0-1fc37305e7e9_config-0] Notify connected event to listeners. +22:25:29.534 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [97d5b7b3-a2af-485c-82a0-1fc37305e7e9_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$346/332498651 +22:25:29.619 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of 661d2b34-e952-4f9c-8547-2940c8b94648 +22:25:29.619 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [661d2b34-e952-4f9c-8547-2940c8b94648] RpcClient init label, labels = {module=naming, source=sdk} +22:25:29.620 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [661d2b34-e952-4f9c-8547-2940c8b94648] RpcClient init, ServerListFactory = com.alibaba.nacos.client.naming.core.ServerListManager +22:25:29.621 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [661d2b34-e952-4f9c-8547-2940c8b94648] Registry connection listener to current client:com.alibaba.nacos.client.naming.remote.gprc.redo.NamingGrpcRedoService +22:25:29.621 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [661d2b34-e952-4f9c-8547-2940c8b94648] Register server push request handler:com.alibaba.nacos.client.naming.remote.gprc.NamingPushRequestHandler +22:25:29.622 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [661d2b34-e952-4f9c-8547-2940c8b94648] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +22:25:29.736 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [661d2b34-e952-4f9c-8547-2940c8b94648] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1742567129629_127.0.0.1_49362 +22:25:29.736 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [661d2b34-e952-4f9c-8547-2940c8b94648] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +22:25:29.736 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [661d2b34-e952-4f9c-8547-2940c8b94648] Notify connected event to listeners. +22:25:29.737 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [661d2b34-e952-4f9c-8547-2940c8b94648] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$346/332498651 +22:25:30.335 [nacos-grpc-client-executor-16] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [661d2b34-e952-4f9c-8547-2940c8b94648] Receive server push request, request = NotifySubscriberRequest, requestId = 2 +22:25:30.336 [nacos-grpc-client-executor-16] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [661d2b34-e952-4f9c-8547-2940c8b94648] Ack server push request, request = NotifySubscriberRequest, requestId = 2 +22:25:30.339 [nacos-grpc-client-executor-17] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [661d2b34-e952-4f9c-8547-2940c8b94648] Receive server push request, request = NotifySubscriberRequest, requestId = 3 +22:25:30.339 [nacos-grpc-client-executor-17] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [661d2b34-e952-4f9c-8547-2940c8b94648] Ack server push request, request = NotifySubscriberRequest, requestId = 3 +22:25:30.815 [main] INFO c.a.c.n.r.NacosServiceRegistry - [register,75] - nacos registry, DEFAULT_GROUP dcsoft-gateway 192.168.0.104:6609 register finished +22:25:30.837 [main] INFO c.d.g.DCSGatewayApplication - [logStarted,61] - Started DCSGatewayApplication in 9.789 seconds (JVM running for 10.711) +22:25:30.845 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-gateway-dev.yml, group=DEFAULT_GROUP +22:25:30.848 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-gateway, group=DEFAULT_GROUP +22:25:30.848 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-gateway.yml, group=DEFAULT_GROUP +22:25:31.413 [nacos-grpc-client-executor-32] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [661d2b34-e952-4f9c-8547-2940c8b94648] Receive server push request, request = NotifySubscriberRequest, requestId = 4 +22:25:31.413 [nacos-grpc-client-executor-32] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [661d2b34-e952-4f9c-8547-2940c8b94648] Ack server push request, request = NotifySubscriberRequest, requestId = 4 +22:27:29.339 [nacos-grpc-client-executor-49] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [4f20d557-1226-45d1-9920-4368f57a7b45_config-0] Receive server push request, request = ConfigChangeNotifyRequest, requestId = 5 +22:27:29.341 [nacos-grpc-client-executor-49] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [4f20d557-1226-45d1-9920-4368f57a7b45_config-0] Ack server push request, request = ConfigChangeNotifyRequest, requestId = 5 +22:28:57.195 [nacos-grpc-client-executor-72] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [4f20d557-1226-45d1-9920-4368f57a7b45_config-0] Receive server push request, request = ConfigChangeNotifyRequest, requestId = 6 +22:28:57.195 [nacos-grpc-client-executor-72] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [4f20d557-1226-45d1-9920-4368f57a7b45_config-0] Ack server push request, request = ConfigChangeNotifyRequest, requestId = 6 +22:30:00.531 [nacos-grpc-client-executor-133] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [661d2b34-e952-4f9c-8547-2940c8b94648] Receive server push request, request = NotifySubscriberRequest, requestId = 10 +22:30:00.532 [nacos-grpc-client-executor-133] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [661d2b34-e952-4f9c-8547-2940c8b94648] Ack server push request, request = NotifySubscriberRequest, requestId = 10 +22:30:01.319 [SpringApplicationShutdownHook] INFO c.a.c.n.r.NacosServiceRegistry - [deregister,94] - De-registering from Nacos Server now... +22:30:01.324 [SpringApplicationShutdownHook] INFO c.a.c.n.r.NacosServiceRegistry - [deregister,114] - De-registration finished. +22:30:01.654 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [shutdown,454] - Shutdown rpc client, set status to shutdown +22:30:01.654 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [shutdown,456] - Shutdown client event executor java.util.concurrent.ScheduledThreadPoolExecutor@46137bb3[Running, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 0] +22:30:01.654 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [closeConnection,591] - Close current connection 1742567129629_127.0.0.1_49362 +22:30:01.656 [nacos-grpc-client-executor-137] INFO c.a.n.c.r.c.g.GrpcClient - [printIfInfoEnabled,60] - [1742567129629_127.0.0.1_49362]Ignore complete event,isRunning:false,isAbandon=false +22:30:01.658 [SpringApplicationShutdownHook] INFO c.a.n.c.r.c.g.GrpcClient - [shutdown,85] - Shutdown grpc executor java.util.concurrent.ThreadPoolExecutor@410c6c1b[Running, pool size = 10, active threads = 0, queued tasks = 0, completed tasks = 138] +22:39:18.785 [background-preinit] INFO o.h.v.i.util.Version - [,21] - HV000001: Hibernate Validator 6.2.5.Final +22:39:19.550 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of 6dc66efc-5b0d-48e3-8071-c2060cdeaf00_config-0 +22:39:19.579 [main] INFO o.r.Reflections - [scan,232] - Reflections took 19 ms to scan 1 urls, producing 3 keys and 6 values +22:39:19.607 [main] INFO o.r.Reflections - [scan,232] - Reflections took 16 ms to scan 1 urls, producing 4 keys and 9 values +22:39:19.617 [main] INFO o.r.Reflections - [scan,232] - Reflections took 8 ms to scan 1 urls, producing 3 keys and 10 values +22:39:19.745 [main] INFO o.r.Reflections - [scan,232] - Reflections took 125 ms to scan 211 urls, producing 0 keys and 0 values +22:39:19.753 [main] INFO o.r.Reflections - [scan,232] - Reflections took 7 ms to scan 1 urls, producing 1 keys and 5 values +22:39:19.762 [main] INFO o.r.Reflections - [scan,232] - Reflections took 8 ms to scan 1 urls, producing 1 keys and 7 values +22:39:19.770 [main] INFO o.r.Reflections - [scan,232] - Reflections took 6 ms to scan 1 urls, producing 2 keys and 8 values +22:39:19.873 [main] INFO o.r.Reflections - [scan,232] - Reflections took 100 ms to scan 211 urls, producing 0 keys and 0 values +22:39:19.874 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [6dc66efc-5b0d-48e3-8071-c2060cdeaf00_config-0] RpcClient init label, labels = {module=config, Vipserver-Tag=null, source=sdk, Amory-Tag=null, Location-Tag=null, taskId=0, AppName=unknown} +22:39:19.875 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [6dc66efc-5b0d-48e3-8071-c2060cdeaf00_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$337/1267042315 +22:39:19.875 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [6dc66efc-5b0d-48e3-8071-c2060cdeaf00_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$338/1335061928 +22:39:19.875 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [6dc66efc-5b0d-48e3-8071-c2060cdeaf00_config-0] Registry connection listener to current client:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$1 +22:39:19.876 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [6dc66efc-5b0d-48e3-8071-c2060cdeaf00_config-0] RpcClient init, ServerListFactory = com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$2 +22:39:19.880 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [6dc66efc-5b0d-48e3-8071-c2060cdeaf00_config-0] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +22:39:21.343 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [6dc66efc-5b0d-48e3-8071-c2060cdeaf00_config-0] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1742567961129_127.0.0.1_50387 +22:39:21.343 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [6dc66efc-5b0d-48e3-8071-c2060cdeaf00_config-0] Notify connected event to listeners. +22:39:21.344 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [6dc66efc-5b0d-48e3-8071-c2060cdeaf00_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +22:39:21.344 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [6dc66efc-5b0d-48e3-8071-c2060cdeaf00_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$346/353891891 +22:39:21.413 [main] INFO c.d.g.DCSGatewayApplication - [logStartupProfileInfo,637] - The following 1 profile is active: "dev" +22:39:25.909 [main] INFO c.a.c.s.g.s.SentinelSCGAutoConfiguration - [sentinelGatewayFilter,144] - [Sentinel SpringCloudGateway] register SentinelGatewayFilter with order: -2147483648 +22:39:26.288 [main] INFO c.a.c.s.g.s.SentinelSCGAutoConfiguration - [sentinelGatewayBlockExceptionHandler,134] - [Sentinel SpringCloudGateway] register SentinelGatewayBlockExceptionHandler +22:39:26.661 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of 3a7104bb-633b-4e10-8e3d-cf0132900851_config-0 +22:39:26.661 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [3a7104bb-633b-4e10-8e3d-cf0132900851_config-0] RpcClient init label, labels = {module=config, Vipserver-Tag=null, source=sdk, Amory-Tag=null, Location-Tag=null, taskId=0, AppName=unknown} +22:39:26.661 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [3a7104bb-633b-4e10-8e3d-cf0132900851_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$337/1267042315 +22:39:26.661 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [3a7104bb-633b-4e10-8e3d-cf0132900851_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$338/1335061928 +22:39:26.661 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [3a7104bb-633b-4e10-8e3d-cf0132900851_config-0] Registry connection listener to current client:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$1 +22:39:26.662 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [3a7104bb-633b-4e10-8e3d-cf0132900851_config-0] RpcClient init, ServerListFactory = com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$2 +22:39:26.662 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [3a7104bb-633b-4e10-8e3d-cf0132900851_config-0] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +22:39:26.781 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [3a7104bb-633b-4e10-8e3d-cf0132900851_config-0] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1742567966665_127.0.0.1_50425 +22:39:26.781 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [3a7104bb-633b-4e10-8e3d-cf0132900851_config-0] Notify connected event to listeners. +22:39:26.781 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [3a7104bb-633b-4e10-8e3d-cf0132900851_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +22:39:26.781 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [3a7104bb-633b-4e10-8e3d-cf0132900851_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$346/353891891 +22:39:26.857 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of 31120925-851c-4c76-ad05-733c23eccdb4 +22:39:26.858 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [31120925-851c-4c76-ad05-733c23eccdb4] RpcClient init label, labels = {module=naming, source=sdk} +22:39:26.859 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [31120925-851c-4c76-ad05-733c23eccdb4] RpcClient init, ServerListFactory = com.alibaba.nacos.client.naming.core.ServerListManager +22:39:26.859 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [31120925-851c-4c76-ad05-733c23eccdb4] Registry connection listener to current client:com.alibaba.nacos.client.naming.remote.gprc.redo.NamingGrpcRedoService +22:39:26.859 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [31120925-851c-4c76-ad05-733c23eccdb4] Register server push request handler:com.alibaba.nacos.client.naming.remote.gprc.NamingPushRequestHandler +22:39:26.860 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [31120925-851c-4c76-ad05-733c23eccdb4] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +22:39:26.981 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [31120925-851c-4c76-ad05-733c23eccdb4] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1742567966864_127.0.0.1_50427 +22:39:26.982 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [31120925-851c-4c76-ad05-733c23eccdb4] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +22:39:26.982 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [31120925-851c-4c76-ad05-733c23eccdb4] Notify connected event to listeners. +22:39:26.982 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [31120925-851c-4c76-ad05-733c23eccdb4] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$346/353891891 +22:39:27.513 [nacos-grpc-client-executor-10] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [31120925-851c-4c76-ad05-733c23eccdb4] Receive server push request, request = NotifySubscriberRequest, requestId = 12 +22:39:27.513 [nacos-grpc-client-executor-10] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [31120925-851c-4c76-ad05-733c23eccdb4] Ack server push request, request = NotifySubscriberRequest, requestId = 12 +22:39:27.608 [nacos-grpc-client-executor-11] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [31120925-851c-4c76-ad05-733c23eccdb4] Receive server push request, request = NotifySubscriberRequest, requestId = 13 +22:39:27.609 [nacos-grpc-client-executor-11] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [31120925-851c-4c76-ad05-733c23eccdb4] Ack server push request, request = NotifySubscriberRequest, requestId = 13 +22:39:28.734 [main] INFO c.a.c.n.r.NacosServiceRegistry - [register,75] - nacos registry, DEFAULT_GROUP dcsoft-gateway 192.168.0.104:6609 register finished +22:39:28.772 [main] INFO c.d.g.DCSGatewayApplication - [logStarted,61] - Started DCSGatewayApplication in 10.826 seconds (JVM running for 11.747) +22:39:28.778 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-gateway-dev.yml, group=DEFAULT_GROUP +22:39:28.779 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-gateway, group=DEFAULT_GROUP +22:39:28.779 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-gateway.yml, group=DEFAULT_GROUP +22:39:29.247 [nacos-grpc-client-executor-27] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [31120925-851c-4c76-ad05-733c23eccdb4] Receive server push request, request = NotifySubscriberRequest, requestId = 14 +22:39:29.247 [nacos-grpc-client-executor-27] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [31120925-851c-4c76-ad05-733c23eccdb4] Ack server push request, request = NotifySubscriberRequest, requestId = 14 +22:39:57.699 [nacos-grpc-client-executor-43] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [31120925-851c-4c76-ad05-733c23eccdb4] Receive server push request, request = NotifySubscriberRequest, requestId = 16 +22:39:57.700 [nacos-grpc-client-executor-43] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [31120925-851c-4c76-ad05-733c23eccdb4] Ack server push request, request = NotifySubscriberRequest, requestId = 16 +22:40:30.127 [nacos-grpc-client-executor-57] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [31120925-851c-4c76-ad05-733c23eccdb4] Receive server push request, request = NotifySubscriberRequest, requestId = 17 +22:40:30.130 [nacos-grpc-client-executor-57] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [31120925-851c-4c76-ad05-733c23eccdb4] Ack server push request, request = NotifySubscriberRequest, requestId = 17 +23:00:20.311 [SpringApplicationShutdownHook] INFO c.a.c.n.r.NacosServiceRegistry - [deregister,94] - De-registering from Nacos Server now... +23:00:20.316 [SpringApplicationShutdownHook] INFO c.a.c.n.r.NacosServiceRegistry - [deregister,114] - De-registration finished. +23:00:20.643 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [shutdown,454] - Shutdown rpc client, set status to shutdown +23:00:20.644 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [shutdown,456] - Shutdown client event executor java.util.concurrent.ScheduledThreadPoolExecutor@63991f56[Running, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 0] +23:00:20.644 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [closeConnection,591] - Close current connection 1742567966864_127.0.0.1_50427 +23:00:20.646 [nacos-grpc-client-executor-384] INFO c.a.n.c.r.c.g.GrpcClient - [printIfInfoEnabled,60] - [1742567966864_127.0.0.1_50427]Ignore complete event,isRunning:false,isAbandon=false +23:00:20.648 [SpringApplicationShutdownHook] INFO c.a.n.c.r.c.g.GrpcClient - [shutdown,85] - Shutdown grpc executor java.util.concurrent.ThreadPoolExecutor@51694fb0[Running, pool size = 5, active threads = 0, queued tasks = 0, completed tasks = 385] diff --git a/logs/dcsoft-gateway/info.2025-03-22.log b/logs/dcsoft-gateway/info.2025-03-22.log new file mode 100644 index 0000000..b8e96dd --- /dev/null +++ b/logs/dcsoft-gateway/info.2025-03-22.log @@ -0,0 +1,68 @@ +17:37:49.475 [background-preinit] INFO o.h.v.i.util.Version - [,21] - HV000001: Hibernate Validator 6.2.5.Final +17:37:50.530 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of a2776078-aae3-4d09-ade1-4ef488601249_config-0 +17:37:50.575 [main] INFO o.r.Reflections - [scan,232] - Reflections took 26 ms to scan 1 urls, producing 3 keys and 6 values +17:37:50.599 [main] INFO o.r.Reflections - [scan,232] - Reflections took 10 ms to scan 1 urls, producing 4 keys and 9 values +17:37:50.612 [main] INFO o.r.Reflections - [scan,232] - Reflections took 11 ms to scan 1 urls, producing 3 keys and 10 values +17:37:50.787 [main] INFO o.r.Reflections - [scan,232] - Reflections took 173 ms to scan 211 urls, producing 0 keys and 0 values +17:37:50.806 [main] INFO o.r.Reflections - [scan,232] - Reflections took 6 ms to scan 1 urls, producing 1 keys and 5 values +17:37:50.813 [main] INFO o.r.Reflections - [scan,232] - Reflections took 6 ms to scan 1 urls, producing 1 keys and 7 values +17:37:50.820 [main] INFO o.r.Reflections - [scan,232] - Reflections took 5 ms to scan 1 urls, producing 2 keys and 8 values +17:37:50.908 [main] INFO o.r.Reflections - [scan,232] - Reflections took 86 ms to scan 211 urls, producing 0 keys and 0 values +17:37:50.911 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a2776078-aae3-4d09-ade1-4ef488601249_config-0] RpcClient init label, labels = {module=config, Vipserver-Tag=null, source=sdk, Amory-Tag=null, Location-Tag=null, taskId=0, AppName=unknown} +17:37:50.911 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a2776078-aae3-4d09-ade1-4ef488601249_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$337/1160487387 +17:37:50.912 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a2776078-aae3-4d09-ade1-4ef488601249_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$338/579447973 +17:37:50.912 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a2776078-aae3-4d09-ade1-4ef488601249_config-0] Registry connection listener to current client:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$1 +17:37:50.912 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a2776078-aae3-4d09-ade1-4ef488601249_config-0] RpcClient init, ServerListFactory = com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$2 +17:37:50.919 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a2776078-aae3-4d09-ade1-4ef488601249_config-0] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +17:37:52.803 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a2776078-aae3-4d09-ade1-4ef488601249_config-0] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1742636272469_127.0.0.1_56752 +17:37:52.803 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a2776078-aae3-4d09-ade1-4ef488601249_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +17:37:52.803 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a2776078-aae3-4d09-ade1-4ef488601249_config-0] Notify connected event to listeners. +17:37:52.804 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a2776078-aae3-4d09-ade1-4ef488601249_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$346/1869177530 +17:37:52.969 [main] INFO c.d.g.DCSGatewayApplication - [logStartupProfileInfo,637] - The following 1 profile is active: "dev" +17:37:57.214 [main] INFO c.a.c.s.g.s.SentinelSCGAutoConfiguration - [sentinelGatewayFilter,144] - [Sentinel SpringCloudGateway] register SentinelGatewayFilter with order: -2147483648 +17:37:57.659 [main] INFO c.a.c.s.g.s.SentinelSCGAutoConfiguration - [sentinelGatewayBlockExceptionHandler,134] - [Sentinel SpringCloudGateway] register SentinelGatewayBlockExceptionHandler +17:37:57.947 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of f969b92c-9c8b-4311-956a-c3005dd75ef4_config-0 +17:37:57.948 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [f969b92c-9c8b-4311-956a-c3005dd75ef4_config-0] RpcClient init label, labels = {module=config, Vipserver-Tag=null, source=sdk, Amory-Tag=null, Location-Tag=null, taskId=0, AppName=unknown} +17:37:57.948 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [f969b92c-9c8b-4311-956a-c3005dd75ef4_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$337/1160487387 +17:37:57.948 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [f969b92c-9c8b-4311-956a-c3005dd75ef4_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$338/579447973 +17:37:57.948 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [f969b92c-9c8b-4311-956a-c3005dd75ef4_config-0] Registry connection listener to current client:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$1 +17:37:57.948 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [f969b92c-9c8b-4311-956a-c3005dd75ef4_config-0] RpcClient init, ServerListFactory = com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$2 +17:37:57.948 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [f969b92c-9c8b-4311-956a-c3005dd75ef4_config-0] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +17:37:58.069 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [f969b92c-9c8b-4311-956a-c3005dd75ef4_config-0] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1742636277952_127.0.0.1_56759 +17:37:58.069 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [f969b92c-9c8b-4311-956a-c3005dd75ef4_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +17:37:58.069 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [f969b92c-9c8b-4311-956a-c3005dd75ef4_config-0] Notify connected event to listeners. +17:37:58.069 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [f969b92c-9c8b-4311-956a-c3005dd75ef4_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$346/1869177530 +17:37:58.147 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of a62d2582-c1c8-46fb-8d4a-3b04b7c62a05 +17:37:58.148 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a62d2582-c1c8-46fb-8d4a-3b04b7c62a05] RpcClient init label, labels = {module=naming, source=sdk} +17:37:58.149 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a62d2582-c1c8-46fb-8d4a-3b04b7c62a05] RpcClient init, ServerListFactory = com.alibaba.nacos.client.naming.core.ServerListManager +17:37:58.149 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a62d2582-c1c8-46fb-8d4a-3b04b7c62a05] Registry connection listener to current client:com.alibaba.nacos.client.naming.remote.gprc.redo.NamingGrpcRedoService +17:37:58.149 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a62d2582-c1c8-46fb-8d4a-3b04b7c62a05] Register server push request handler:com.alibaba.nacos.client.naming.remote.gprc.NamingPushRequestHandler +17:37:58.149 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a62d2582-c1c8-46fb-8d4a-3b04b7c62a05] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +17:37:58.269 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a62d2582-c1c8-46fb-8d4a-3b04b7c62a05] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1742636278154_127.0.0.1_56762 +17:37:58.269 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a62d2582-c1c8-46fb-8d4a-3b04b7c62a05] Notify connected event to listeners. +17:37:58.269 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a62d2582-c1c8-46fb-8d4a-3b04b7c62a05] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +17:37:58.269 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a62d2582-c1c8-46fb-8d4a-3b04b7c62a05] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$346/1869177530 +17:38:01.298 [nacos-grpc-client-executor-15] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a62d2582-c1c8-46fb-8d4a-3b04b7c62a05] Receive server push request, request = NotifySubscriberRequest, requestId = 2 +17:38:01.298 [nacos-grpc-client-executor-15] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a62d2582-c1c8-46fb-8d4a-3b04b7c62a05] Ack server push request, request = NotifySubscriberRequest, requestId = 2 +17:38:01.301 [nacos-grpc-client-executor-16] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a62d2582-c1c8-46fb-8d4a-3b04b7c62a05] Receive server push request, request = NotifySubscriberRequest, requestId = 3 +17:38:01.302 [nacos-grpc-client-executor-16] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a62d2582-c1c8-46fb-8d4a-3b04b7c62a05] Ack server push request, request = NotifySubscriberRequest, requestId = 3 +17:38:01.834 [main] INFO c.a.c.n.r.NacosServiceRegistry - [register,75] - nacos registry, DEFAULT_GROUP dcsoft-gateway 192.168.0.104:6609 register finished +17:38:01.865 [main] INFO c.d.g.DCSGatewayApplication - [logStarted,61] - Started DCSGatewayApplication in 13.263 seconds (JVM running for 14.438) +17:38:01.876 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-gateway-dev.yml, group=DEFAULT_GROUP +17:38:01.877 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-gateway, group=DEFAULT_GROUP +17:38:01.879 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-gateway.yml, group=DEFAULT_GROUP +17:38:02.382 [nacos-grpc-client-executor-29] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a62d2582-c1c8-46fb-8d4a-3b04b7c62a05] Receive server push request, request = NotifySubscriberRequest, requestId = 4 +17:38:02.382 [nacos-grpc-client-executor-29] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a62d2582-c1c8-46fb-8d4a-3b04b7c62a05] Ack server push request, request = NotifySubscriberRequest, requestId = 4 +17:39:28.962 [nacos-grpc-client-executor-66] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a62d2582-c1c8-46fb-8d4a-3b04b7c62a05] Receive server push request, request = NotifySubscriberRequest, requestId = 6 +17:39:28.962 [nacos-grpc-client-executor-66] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a62d2582-c1c8-46fb-8d4a-3b04b7c62a05] Ack server push request, request = NotifySubscriberRequest, requestId = 6 +17:42:36.385 [nacos-grpc-client-executor-129] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a62d2582-c1c8-46fb-8d4a-3b04b7c62a05] Receive server push request, request = NotifySubscriberRequest, requestId = 9 +17:42:36.389 [nacos-grpc-client-executor-129] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a62d2582-c1c8-46fb-8d4a-3b04b7c62a05] Ack server push request, request = NotifySubscriberRequest, requestId = 9 +17:42:54.265 [nacos-grpc-client-executor-134] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a62d2582-c1c8-46fb-8d4a-3b04b7c62a05] Receive server push request, request = NotifySubscriberRequest, requestId = 12 +17:42:54.267 [nacos-grpc-client-executor-134] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a62d2582-c1c8-46fb-8d4a-3b04b7c62a05] Ack server push request, request = NotifySubscriberRequest, requestId = 12 +17:50:39.562 [SpringApplicationShutdownHook] INFO c.a.c.n.r.NacosServiceRegistry - [deregister,94] - De-registering from Nacos Server now... +17:50:39.564 [SpringApplicationShutdownHook] INFO c.a.c.n.r.NacosServiceRegistry - [deregister,114] - De-registration finished. +17:50:39.900 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [shutdown,454] - Shutdown rpc client, set status to shutdown +17:50:39.900 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [shutdown,456] - Shutdown client event executor java.util.concurrent.ScheduledThreadPoolExecutor@36b0e18e[Running, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 0] +17:50:39.900 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [closeConnection,591] - Close current connection 1742636278154_127.0.0.1_56762 +17:50:39.900 [nacos-grpc-client-executor-266] INFO c.a.n.c.r.c.g.GrpcClient - [printIfInfoEnabled,60] - [1742636278154_127.0.0.1_56762]Ignore complete event,isRunning:false,isAbandon=false +17:50:39.900 [SpringApplicationShutdownHook] INFO c.a.n.c.r.c.g.GrpcClient - [shutdown,85] - Shutdown grpc executor java.util.concurrent.ThreadPoolExecutor@8475653[Running, pool size = 4, active threads = 0, queued tasks = 0, completed tasks = 267] diff --git a/logs/dcsoft-gateway/info.log b/logs/dcsoft-gateway/info.log new file mode 100644 index 0000000..4818383 --- /dev/null +++ b/logs/dcsoft-gateway/info.log @@ -0,0 +1,115 @@ +15:34:37.703 [background-preinit] INFO o.h.v.i.util.Version - [,21] - HV000001: Hibernate Validator 6.2.5.Final +15:34:38.708 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of e23dbcb5-799f-41c3-9e81-04dd4dca6831_config-0 +15:34:38.768 [main] INFO o.r.Reflections - [scan,232] - Reflections took 30 ms to scan 1 urls, producing 3 keys and 6 values +15:34:38.802 [main] INFO o.r.Reflections - [scan,232] - Reflections took 14 ms to scan 1 urls, producing 4 keys and 9 values +15:34:38.819 [main] INFO o.r.Reflections - [scan,232] - Reflections took 13 ms to scan 1 urls, producing 3 keys and 10 values +15:34:39.009 [main] INFO o.r.Reflections - [scan,232] - Reflections took 186 ms to scan 211 urls, producing 0 keys and 0 values +15:34:39.018 [main] INFO o.r.Reflections - [scan,232] - Reflections took 8 ms to scan 1 urls, producing 1 keys and 5 values +15:34:39.032 [main] INFO o.r.Reflections - [scan,232] - Reflections took 12 ms to scan 1 urls, producing 1 keys and 7 values +15:34:39.050 [main] INFO o.r.Reflections - [scan,232] - Reflections took 13 ms to scan 1 urls, producing 2 keys and 8 values +15:34:39.184 [main] INFO o.r.Reflections - [scan,232] - Reflections took 132 ms to scan 211 urls, producing 0 keys and 0 values +15:34:39.185 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [e23dbcb5-799f-41c3-9e81-04dd4dca6831_config-0] RpcClient init label, labels = {module=config, Vipserver-Tag=null, source=sdk, Amory-Tag=null, Location-Tag=null, taskId=0, AppName=unknown} +15:34:39.185 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [e23dbcb5-799f-41c3-9e81-04dd4dca6831_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$337/1160487387 +15:34:39.186 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [e23dbcb5-799f-41c3-9e81-04dd4dca6831_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$338/579447973 +15:34:39.188 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [e23dbcb5-799f-41c3-9e81-04dd4dca6831_config-0] Registry connection listener to current client:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$1 +15:34:39.188 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [e23dbcb5-799f-41c3-9e81-04dd4dca6831_config-0] RpcClient init, ServerListFactory = com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$2 +15:34:39.194 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [e23dbcb5-799f-41c3-9e81-04dd4dca6831_config-0] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +15:34:41.020 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [e23dbcb5-799f-41c3-9e81-04dd4dca6831_config-0] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1745825680837_127.0.0.1_59506 +15:34:41.021 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [e23dbcb5-799f-41c3-9e81-04dd4dca6831_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +15:34:41.021 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [e23dbcb5-799f-41c3-9e81-04dd4dca6831_config-0] Notify connected event to listeners. +15:34:41.023 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [e23dbcb5-799f-41c3-9e81-04dd4dca6831_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$346/1869177530 +15:34:41.309 [main] INFO c.d.g.DCSGatewayApplication - [logStartupProfileInfo,637] - The following 1 profile is active: "dev" +15:34:45.702 [main] INFO c.a.c.s.g.s.SentinelSCGAutoConfiguration - [sentinelGatewayFilter,144] - [Sentinel SpringCloudGateway] register SentinelGatewayFilter with order: -2147483648 +15:34:46.115 [main] INFO c.a.c.s.g.s.SentinelSCGAutoConfiguration - [sentinelGatewayBlockExceptionHandler,134] - [Sentinel SpringCloudGateway] register SentinelGatewayBlockExceptionHandler +15:34:46.583 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of 99ce233c-1623-41f3-adaa-973c07eba9b5_config-0 +15:34:46.583 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [99ce233c-1623-41f3-adaa-973c07eba9b5_config-0] RpcClient init label, labels = {module=config, Vipserver-Tag=null, source=sdk, Amory-Tag=null, Location-Tag=null, taskId=0, AppName=unknown} +15:34:46.583 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [99ce233c-1623-41f3-adaa-973c07eba9b5_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$337/1160487387 +15:34:46.583 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [99ce233c-1623-41f3-adaa-973c07eba9b5_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$338/579447973 +15:34:46.583 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [99ce233c-1623-41f3-adaa-973c07eba9b5_config-0] Registry connection listener to current client:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$1 +15:34:46.583 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [99ce233c-1623-41f3-adaa-973c07eba9b5_config-0] RpcClient init, ServerListFactory = com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$2 +15:34:46.583 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [99ce233c-1623-41f3-adaa-973c07eba9b5_config-0] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +15:34:46.706 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [99ce233c-1623-41f3-adaa-973c07eba9b5_config-0] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1745825686590_127.0.0.1_59563 +15:34:46.706 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [99ce233c-1623-41f3-adaa-973c07eba9b5_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +15:34:46.706 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [99ce233c-1623-41f3-adaa-973c07eba9b5_config-0] Notify connected event to listeners. +15:34:46.706 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [99ce233c-1623-41f3-adaa-973c07eba9b5_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$346/1869177530 +15:34:46.811 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of 38777a66-4c72-4375-a506-f9d3d7af557c +15:34:46.811 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [38777a66-4c72-4375-a506-f9d3d7af557c] RpcClient init label, labels = {module=naming, source=sdk} +15:34:46.816 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [38777a66-4c72-4375-a506-f9d3d7af557c] RpcClient init, ServerListFactory = com.alibaba.nacos.client.naming.core.ServerListManager +15:34:46.816 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [38777a66-4c72-4375-a506-f9d3d7af557c] Registry connection listener to current client:com.alibaba.nacos.client.naming.remote.gprc.redo.NamingGrpcRedoService +15:34:46.817 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [38777a66-4c72-4375-a506-f9d3d7af557c] Register server push request handler:com.alibaba.nacos.client.naming.remote.gprc.NamingPushRequestHandler +15:34:46.818 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [38777a66-4c72-4375-a506-f9d3d7af557c] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +15:34:46.935 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [38777a66-4c72-4375-a506-f9d3d7af557c] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1745825686826_127.0.0.1_59564 +15:34:46.936 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [38777a66-4c72-4375-a506-f9d3d7af557c] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +15:34:46.936 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [38777a66-4c72-4375-a506-f9d3d7af557c] Notify connected event to listeners. +15:34:46.936 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [38777a66-4c72-4375-a506-f9d3d7af557c] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$346/1869177530 +15:34:47.560 [nacos-grpc-client-executor-10] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [38777a66-4c72-4375-a506-f9d3d7af557c] Receive server push request, request = NotifySubscriberRequest, requestId = 22 +15:34:47.561 [nacos-grpc-client-executor-10] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [38777a66-4c72-4375-a506-f9d3d7af557c] Ack server push request, request = NotifySubscriberRequest, requestId = 22 +15:34:47.965 [main] INFO c.a.n.c.r.client - [shutdown,454] - Shutdown rpc client, set status to shutdown +15:34:47.965 [main] INFO c.a.n.c.r.client - [shutdown,456] - Shutdown client event executor java.util.concurrent.ScheduledThreadPoolExecutor@279e1422[Running, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 0] +15:34:47.965 [main] INFO c.a.n.c.r.client - [closeConnection,591] - Close current connection 1745825686826_127.0.0.1_59564 +15:34:47.973 [main] INFO c.a.n.c.r.c.g.GrpcClient - [shutdown,85] - Shutdown grpc executor java.util.concurrent.ThreadPoolExecutor@d3d5094[Running, pool size = 12, active threads = 1, queued tasks = 0, completed tasks = 11] +15:34:47.973 [nacos-grpc-client-executor-11] INFO c.a.n.c.r.c.g.GrpcClient - [printIfInfoEnabled,60] - [1745825686826_127.0.0.1_59564]Ignore complete event,isRunning:false,isAbandon=false +15:35:55.187 [background-preinit] INFO o.h.v.i.util.Version - [,21] - HV000001: Hibernate Validator 6.2.5.Final +15:35:55.929 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of b58fe309-9c5d-4b4d-b792-b6628624bae0_config-0 +15:35:55.956 [main] INFO o.r.Reflections - [scan,232] - Reflections took 16 ms to scan 1 urls, producing 3 keys and 6 values +15:35:55.981 [main] INFO o.r.Reflections - [scan,232] - Reflections took 16 ms to scan 1 urls, producing 4 keys and 9 values +15:35:55.991 [main] INFO o.r.Reflections - [scan,232] - Reflections took 8 ms to scan 1 urls, producing 3 keys and 10 values +15:35:56.087 [main] INFO o.r.Reflections - [scan,232] - Reflections took 94 ms to scan 211 urls, producing 0 keys and 0 values +15:35:56.093 [main] INFO o.r.Reflections - [scan,232] - Reflections took 5 ms to scan 1 urls, producing 1 keys and 5 values +15:35:56.102 [main] INFO o.r.Reflections - [scan,232] - Reflections took 6 ms to scan 1 urls, producing 1 keys and 7 values +15:35:56.109 [main] INFO o.r.Reflections - [scan,232] - Reflections took 6 ms to scan 1 urls, producing 2 keys and 8 values +15:35:56.198 [main] INFO o.r.Reflections - [scan,232] - Reflections took 87 ms to scan 211 urls, producing 0 keys and 0 values +15:35:56.199 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b58fe309-9c5d-4b4d-b792-b6628624bae0_config-0] RpcClient init label, labels = {module=config, Vipserver-Tag=null, source=sdk, Amory-Tag=null, Location-Tag=null, taskId=0, AppName=unknown} +15:35:56.200 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b58fe309-9c5d-4b4d-b792-b6628624bae0_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$337/1267042315 +15:35:56.200 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b58fe309-9c5d-4b4d-b792-b6628624bae0_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$338/1335061928 +15:35:56.200 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b58fe309-9c5d-4b4d-b792-b6628624bae0_config-0] Registry connection listener to current client:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$1 +15:35:56.201 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b58fe309-9c5d-4b4d-b792-b6628624bae0_config-0] RpcClient init, ServerListFactory = com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$2 +15:35:56.207 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b58fe309-9c5d-4b4d-b792-b6628624bae0_config-0] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +15:35:57.953 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b58fe309-9c5d-4b4d-b792-b6628624bae0_config-0] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1745825757716_127.0.0.1_59722 +15:35:57.955 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b58fe309-9c5d-4b4d-b792-b6628624bae0_config-0] Notify connected event to listeners. +15:35:57.955 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b58fe309-9c5d-4b4d-b792-b6628624bae0_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +15:35:57.956 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b58fe309-9c5d-4b4d-b792-b6628624bae0_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$346/1402333753 +15:35:58.059 [main] INFO c.d.g.DCSGatewayApplication - [logStartupProfileInfo,637] - The following 1 profile is active: "dev" +15:36:01.313 [main] INFO c.a.c.s.g.s.SentinelSCGAutoConfiguration - [sentinelGatewayFilter,144] - [Sentinel SpringCloudGateway] register SentinelGatewayFilter with order: -2147483648 +15:36:01.639 [main] INFO c.a.c.s.g.s.SentinelSCGAutoConfiguration - [sentinelGatewayBlockExceptionHandler,134] - [Sentinel SpringCloudGateway] register SentinelGatewayBlockExceptionHandler +15:36:02.112 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of 32f3e3d7-b74a-472e-a438-adcd23487017_config-0 +15:36:02.113 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [32f3e3d7-b74a-472e-a438-adcd23487017_config-0] RpcClient init label, labels = {module=config, Vipserver-Tag=null, source=sdk, Amory-Tag=null, Location-Tag=null, taskId=0, AppName=unknown} +15:36:02.113 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [32f3e3d7-b74a-472e-a438-adcd23487017_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$337/1267042315 +15:36:02.113 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [32f3e3d7-b74a-472e-a438-adcd23487017_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$338/1335061928 +15:36:02.113 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [32f3e3d7-b74a-472e-a438-adcd23487017_config-0] Registry connection listener to current client:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$1 +15:36:02.113 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [32f3e3d7-b74a-472e-a438-adcd23487017_config-0] RpcClient init, ServerListFactory = com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$2 +15:36:02.114 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [32f3e3d7-b74a-472e-a438-adcd23487017_config-0] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +15:36:02.238 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [32f3e3d7-b74a-472e-a438-adcd23487017_config-0] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1745825762124_127.0.0.1_59729 +15:36:02.238 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [32f3e3d7-b74a-472e-a438-adcd23487017_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +15:36:02.239 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [32f3e3d7-b74a-472e-a438-adcd23487017_config-0] Notify connected event to listeners. +15:36:02.239 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [32f3e3d7-b74a-472e-a438-adcd23487017_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$346/1402333753 +15:36:02.351 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of 7e52aba6-4921-41ea-a33a-0d4aabbe6e16 +15:36:02.352 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7e52aba6-4921-41ea-a33a-0d4aabbe6e16] RpcClient init label, labels = {module=naming, source=sdk} +15:36:02.353 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7e52aba6-4921-41ea-a33a-0d4aabbe6e16] RpcClient init, ServerListFactory = com.alibaba.nacos.client.naming.core.ServerListManager +15:36:02.353 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7e52aba6-4921-41ea-a33a-0d4aabbe6e16] Registry connection listener to current client:com.alibaba.nacos.client.naming.remote.gprc.redo.NamingGrpcRedoService +15:36:02.353 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7e52aba6-4921-41ea-a33a-0d4aabbe6e16] Register server push request handler:com.alibaba.nacos.client.naming.remote.gprc.NamingPushRequestHandler +15:36:02.354 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7e52aba6-4921-41ea-a33a-0d4aabbe6e16] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +15:36:02.469 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7e52aba6-4921-41ea-a33a-0d4aabbe6e16] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1745825762359_127.0.0.1_59731 +15:36:02.469 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7e52aba6-4921-41ea-a33a-0d4aabbe6e16] Notify connected event to listeners. +15:36:02.469 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7e52aba6-4921-41ea-a33a-0d4aabbe6e16] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +15:36:02.470 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7e52aba6-4921-41ea-a33a-0d4aabbe6e16] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$346/1402333753 +15:36:03.075 [nacos-grpc-client-executor-15] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7e52aba6-4921-41ea-a33a-0d4aabbe6e16] Receive server push request, request = NotifySubscriberRequest, requestId = 24 +15:36:03.076 [nacos-grpc-client-executor-15] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7e52aba6-4921-41ea-a33a-0d4aabbe6e16] Ack server push request, request = NotifySubscriberRequest, requestId = 24 +15:36:03.180 [nacos-grpc-client-executor-16] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7e52aba6-4921-41ea-a33a-0d4aabbe6e16] Receive server push request, request = NotifySubscriberRequest, requestId = 25 +15:36:03.181 [nacos-grpc-client-executor-16] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7e52aba6-4921-41ea-a33a-0d4aabbe6e16] Ack server push request, request = NotifySubscriberRequest, requestId = 25 +15:36:03.667 [main] INFO c.a.c.n.r.NacosServiceRegistry - [register,75] - nacos registry, DEFAULT_GROUP dcsoft-gateway 192.168.2.21:6609 register finished +15:36:03.693 [main] INFO c.d.g.DCSGatewayApplication - [logStarted,61] - Started DCSGatewayApplication in 9.379 seconds (JVM running for 10.299) +15:36:03.697 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-gateway-dev.yml, group=DEFAULT_GROUP +15:36:03.698 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-gateway, group=DEFAULT_GROUP +15:36:03.699 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-gateway.yml, group=DEFAULT_GROUP +15:36:04.256 [nacos-grpc-client-executor-28] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7e52aba6-4921-41ea-a33a-0d4aabbe6e16] Receive server push request, request = NotifySubscriberRequest, requestId = 26 +15:36:04.256 [nacos-grpc-client-executor-28] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7e52aba6-4921-41ea-a33a-0d4aabbe6e16] Ack server push request, request = NotifySubscriberRequest, requestId = 26 +15:36:33.213 [nacos-grpc-client-executor-42] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7e52aba6-4921-41ea-a33a-0d4aabbe6e16] Receive server push request, request = NotifySubscriberRequest, requestId = 28 +15:36:33.213 [nacos-grpc-client-executor-42] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [7e52aba6-4921-41ea-a33a-0d4aabbe6e16] Ack server push request, request = NotifySubscriberRequest, requestId = 28 +15:38:41.049 [SpringApplicationShutdownHook] INFO c.a.c.n.r.NacosServiceRegistry - [deregister,94] - De-registering from Nacos Server now... +15:38:41.084 [SpringApplicationShutdownHook] INFO c.a.c.n.r.NacosServiceRegistry - [deregister,114] - De-registration finished. +15:38:41.494 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [shutdown,454] - Shutdown rpc client, set status to shutdown +15:38:41.495 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [shutdown,456] - Shutdown client event executor java.util.concurrent.ScheduledThreadPoolExecutor@e804fe4[Running, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 0] +15:38:41.496 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [closeConnection,591] - Close current connection 1745825762359_127.0.0.1_59731 +15:38:41.498 [nacos-grpc-client-executor-88] INFO c.a.n.c.r.c.g.GrpcClient - [printIfInfoEnabled,60] - [1745825762359_127.0.0.1_59731]Ignore complete event,isRunning:false,isAbandon=false +15:38:41.505 [SpringApplicationShutdownHook] INFO c.a.n.c.r.c.g.GrpcClient - [shutdown,85] - Shutdown grpc executor java.util.concurrent.ThreadPoolExecutor@3c3ec590[Running, pool size = 6, active threads = 0, queued tasks = 0, completed tasks = 89] diff --git a/logs/dcsoft-system/error.2025-03-21.log b/logs/dcsoft-system/error.2025-03-21.log new file mode 100644 index 0000000..eec72ad --- /dev/null +++ b/logs/dcsoft-system/error.2025-03-21.log @@ -0,0 +1,85 @@ +22:26:12.430 [main] ERROR o.s.b.SpringApplication - [reportFailure,821] - Application run failed +org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'sysConfigController': Unsatisfied dependency expressed through field 'configService'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sysConfigServiceImpl': Invocation of init method failed; nested exception is org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to 192.168.2.30:6379 + at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:660) + at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640) + at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119) + at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1431) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:619) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) + at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) + at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) + at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) + at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955) + at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) + at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) + at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) + at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731) + at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) + at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) + at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303) + at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292) + at com.dcsoft.system.DCSSystemApplication.main(DCSSystemApplication.java:22) +Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sysConfigServiceImpl': Invocation of init method failed; nested exception is org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to 192.168.2.30:6379 + at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:160) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:440) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) + at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) + at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) + at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) + at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) + at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1391) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311) + at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:657) + ... 20 common frames omitted +Caused by: org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to 192.168.2.30:6379 + at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.translateException(LettuceConnectionFactory.java:1689) + at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.getConnection(LettuceConnectionFactory.java:1597) + at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getNativeConnection(LettuceConnectionFactory.java:1383) + at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getConnection(LettuceConnectionFactory.java:1366) + at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getSharedConnection(LettuceConnectionFactory.java:1093) + at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getConnection(LettuceConnectionFactory.java:421) + at org.springframework.data.redis.core.RedisConnectionUtils.fetchConnection(RedisConnectionUtils.java:193) + at org.springframework.data.redis.core.RedisConnectionUtils.doGetConnection(RedisConnectionUtils.java:144) + at org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:105) + at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:211) + at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:191) + at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:97) + at org.springframework.data.redis.core.DefaultValueOperations.set(DefaultValueOperations.java:305) + at com.dcsoft.common.redis.service.RedisService.setCacheObject(RedisService.java:36) + at com.dcsoft.system.service.impl.SysConfigServiceImpl.loadingConfigCache(SysConfigServiceImpl.java:174) + at com.dcsoft.system.service.impl.SysConfigServiceImpl.init(SysConfigServiceImpl.java:51) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:389) + at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:333) + at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:157) + ... 32 common frames omitted +Caused by: io.lettuce.core.RedisConnectionException: Unable to connect to 192.168.2.30:6379 + at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:78) + at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:56) + at io.lettuce.core.AbstractRedisClient.getConnection(AbstractRedisClient.java:330) + at io.lettuce.core.RedisClient.connect(RedisClient.java:216) + at org.springframework.data.redis.connection.lettuce.StandaloneConnectionProvider.lambda$getConnection$1(StandaloneConnectionProvider.java:115) + at java.util.Optional.orElseGet(Optional.java:267) + at org.springframework.data.redis.connection.lettuce.StandaloneConnectionProvider.getConnection(StandaloneConnectionProvider.java:115) + at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.getConnection(LettuceConnectionFactory.java:1595) + ... 53 common frames omitted +Caused by: io.netty.channel.ConnectTimeoutException: connection timed out: /192.168.2.30:6379 + at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe$1.run(AbstractNioChannel.java:261) + at io.netty.util.concurrent.PromiseTask.runTask(PromiseTask.java:98) + at io.netty.util.concurrent.ScheduledFutureTask.run(ScheduledFutureTask.java:153) + at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174) + at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167) + at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470) + at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569) + at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) + at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) + at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) + at java.lang.Thread.run(Thread.java:750) diff --git a/logs/dcsoft-system/error.log b/logs/dcsoft-system/error.log new file mode 100644 index 0000000..00e5b5c --- /dev/null +++ b/logs/dcsoft-system/error.log @@ -0,0 +1,1663 @@ +17:38:17.589 [main] ERROR c.a.d.p.DruidDataSource - [init,929] - init datasource error, url: jdbc:mysql://127.0.0.1:3306/jj_cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 +com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure + +The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server. + at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:828) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:448) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:198) + at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:118) + at com.alibaba.druid.filter.FilterAdapter.connection_connect(FilterAdapter.java:764) + at com.alibaba.druid.filter.FilterEventAdapter.connection_connect(FilterEventAdapter.java:33) + at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:112) + at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:232) + at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:112) + at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1703) + at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1786) + at com.alibaba.druid.pool.DruidDataSource.init(DruidDataSource.java:925) + at com.baomidou.dynamic.datasource.creator.DruidDataSourceCreator.doCreateDataSource(DruidDataSourceCreator.java:85) + at com.baomidou.dynamic.datasource.creator.AbstractDataSourceCreator.createDataSource(AbstractDataSourceCreator.java:70) + at com.baomidou.dynamic.datasource.creator.DefaultDataSourceCreator.createDataSource(DefaultDataSourceCreator.java:48) + at com.baomidou.dynamic.datasource.provider.AbstractDataSourceProvider.createDataSourceMap(AbstractDataSourceProvider.java:47) + at com.baomidou.dynamic.datasource.provider.YmlDynamicDataSourceProvider.loadDataSources(YmlDynamicDataSourceProvider.java:42) + at com.baomidou.dynamic.datasource.DynamicRoutingDataSource.afterPropertiesSet(DynamicRoutingDataSource.java:225) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) + at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) + at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) + at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) + at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) + at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.addCandidateEntry(DefaultListableBeanFactory.java:1609) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1573) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveMultipleBeans(DefaultListableBeanFactory.java:1492) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1349) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311) + at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) + at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) + at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:541) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) + at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) + at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) + at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) + at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) + at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.addCandidateEntry(DefaultListableBeanFactory.java:1616) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1573) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveMultipleBeans(DefaultListableBeanFactory.java:1417) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1349) + at org.springframework.beans.factory.support.DefaultListableBeanFactory$DependencyObjectProvider.resolveStream(DefaultListableBeanFactory.java:2119) + at org.springframework.beans.factory.support.DefaultListableBeanFactory$DependencyObjectProvider.orderedStream(DefaultListableBeanFactory.java:2113) + at org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryConfigurer.addBinders(MeterRegistryConfigurer.java:86) + at org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryConfigurer.configure(MeterRegistryConfigurer.java:68) + at org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryPostProcessor.postProcessAfterInitialization(MeterRegistryPostProcessor.java:64) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:455) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1808) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) + at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) + at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) + at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) + at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) + at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1391) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311) + at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) + at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) + at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:541) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) + at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) + at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) + at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) + at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:213) + at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:212) + at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:203) + at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addServletContextInitializerBeans(ServletContextInitializerBeans.java:97) + at org.springframework.boot.web.servlet.ServletContextInitializerBeans.(ServletContextInitializerBeans.java:86) + at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getServletContextInitializerBeans(ServletWebServerApplicationContext.java:262) + at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.selfInitialize(ServletWebServerApplicationContext.java:236) + at org.springframework.boot.web.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:53) + at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5211) + at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) + at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393) + at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1383) + at java.util.concurrent.FutureTask.run(FutureTask.java:266) + at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) + at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134) + at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:916) + at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:835) + at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) + at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393) + at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1383) + at java.util.concurrent.FutureTask.run(FutureTask.java:266) + at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) + at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134) + at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:916) + at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:265) + at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) + at org.apache.catalina.core.StandardService.startInternal(StandardService.java:430) + at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) + at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:930) + at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) + at org.apache.catalina.startup.Tomcat.start(Tomcat.java:486) + at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:123) + at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.(TomcatWebServer.java:104) + at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:479) + at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:211) + at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:184) + at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:162) + at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:577) + at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) + at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731) + at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) + at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) + at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303) + at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292) + at com.dcsoft.system.DCSSystemApplication.main(DCSSystemApplication.java:22) +Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure + +The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server. + at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) + at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) + at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) + at java.lang.reflect.Constructor.newInstance(Constructor.java:423) + at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61) + at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105) + at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151) + at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167) + at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:89) + at com.mysql.cj.NativeSession.connect(NativeSession.java:120) + at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:948) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:818) + ... 119 common frames omitted +Caused by: java.net.ConnectException: Connection refused: connect + at java.net.DualStackPlainSocketImpl.connect0(Native Method) + at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:75) + at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:476) + at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:218) + at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:200) + at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:162) + at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:394) + at java.net.Socket.connect(Socket.java:606) + at com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:153) + at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:63) + ... 122 common frames omitted +17:38:17.597 [main] ERROR c.a.d.p.DruidDataSource - [init,971] - {dataSource-1} init error +com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure + +The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server. + at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:828) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:448) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:198) + at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:118) + at com.alibaba.druid.filter.FilterAdapter.connection_connect(FilterAdapter.java:764) + at com.alibaba.druid.filter.FilterEventAdapter.connection_connect(FilterEventAdapter.java:33) + at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:112) + at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:232) + at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:112) + at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1703) + at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1786) + at com.alibaba.druid.pool.DruidDataSource.init(DruidDataSource.java:925) + at com.baomidou.dynamic.datasource.creator.DruidDataSourceCreator.doCreateDataSource(DruidDataSourceCreator.java:85) + at com.baomidou.dynamic.datasource.creator.AbstractDataSourceCreator.createDataSource(AbstractDataSourceCreator.java:70) + at com.baomidou.dynamic.datasource.creator.DefaultDataSourceCreator.createDataSource(DefaultDataSourceCreator.java:48) + at com.baomidou.dynamic.datasource.provider.AbstractDataSourceProvider.createDataSourceMap(AbstractDataSourceProvider.java:47) + at com.baomidou.dynamic.datasource.provider.YmlDynamicDataSourceProvider.loadDataSources(YmlDynamicDataSourceProvider.java:42) + at com.baomidou.dynamic.datasource.DynamicRoutingDataSource.afterPropertiesSet(DynamicRoutingDataSource.java:225) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) + at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) + at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) + at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) + at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) + at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.addCandidateEntry(DefaultListableBeanFactory.java:1609) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1573) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveMultipleBeans(DefaultListableBeanFactory.java:1492) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1349) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311) + at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) + at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) + at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:541) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) + at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) + at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) + at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) + at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) + at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.addCandidateEntry(DefaultListableBeanFactory.java:1616) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1573) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveMultipleBeans(DefaultListableBeanFactory.java:1417) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1349) + at org.springframework.beans.factory.support.DefaultListableBeanFactory$DependencyObjectProvider.resolveStream(DefaultListableBeanFactory.java:2119) + at org.springframework.beans.factory.support.DefaultListableBeanFactory$DependencyObjectProvider.orderedStream(DefaultListableBeanFactory.java:2113) + at org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryConfigurer.addBinders(MeterRegistryConfigurer.java:86) + at org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryConfigurer.configure(MeterRegistryConfigurer.java:68) + at org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryPostProcessor.postProcessAfterInitialization(MeterRegistryPostProcessor.java:64) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:455) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1808) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) + at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) + at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) + at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) + at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) + at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1391) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311) + at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) + at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) + at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:541) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) + at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) + at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) + at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) + at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:213) + at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:212) + at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:203) + at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addServletContextInitializerBeans(ServletContextInitializerBeans.java:97) + at org.springframework.boot.web.servlet.ServletContextInitializerBeans.(ServletContextInitializerBeans.java:86) + at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getServletContextInitializerBeans(ServletWebServerApplicationContext.java:262) + at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.selfInitialize(ServletWebServerApplicationContext.java:236) + at org.springframework.boot.web.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:53) + at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5211) + at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) + at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393) + at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1383) + at java.util.concurrent.FutureTask.run(FutureTask.java:266) + at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) + at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134) + at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:916) + at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:835) + at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) + at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393) + at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1383) + at java.util.concurrent.FutureTask.run(FutureTask.java:266) + at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) + at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134) + at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:916) + at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:265) + at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) + at org.apache.catalina.core.StandardService.startInternal(StandardService.java:430) + at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) + at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:930) + at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) + at org.apache.catalina.startup.Tomcat.start(Tomcat.java:486) + at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:123) + at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.(TomcatWebServer.java:104) + at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:479) + at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:211) + at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:184) + at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:162) + at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:577) + at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) + at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731) + at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) + at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) + at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303) + at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292) + at com.dcsoft.system.DCSSystemApplication.main(DCSSystemApplication.java:22) +Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure + +The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server. + at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) + at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) + at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) + at java.lang.reflect.Constructor.newInstance(Constructor.java:423) + at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61) + at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105) + at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151) + at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167) + at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:89) + at com.mysql.cj.NativeSession.connect(NativeSession.java:120) + at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:948) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:818) + ... 119 common frames omitted +Caused by: java.net.ConnectException: Connection refused: connect + at java.net.DualStackPlainSocketImpl.connect0(Native Method) + at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:75) + at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:476) + at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:218) + at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:200) + at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:162) + at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:394) + at java.net.Socket.connect(Socket.java:606) + at com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:153) + at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:63) + ... 122 common frames omitted +17:38:17.601 [main] ERROR o.s.b.w.e.t.TomcatStarter - [onStartup,61] - Error starting Tomcat context. Exception: org.springframework.beans.factory.UnsatisfiedDependencyException. Message: Error creating bean with name 'webMvcMetricsFilter' defined in class path resource [org/springframework/boot/actuate/autoconfigure/metrics/web/servlet/WebMvcMetricsAutoConfiguration.class]: Unsatisfied dependency expressed through method 'webMvcMetricsFilter' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'simpleMeterRegistry' defined in class path resource [org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimpleMetricsExportAutoConfiguration.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataSourcePoolMetadataMeterBinder' defined in class path resource [org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfiguration$DataSourcePoolMetadataMetricsConfiguration.class]: Unsatisfied dependency expressed through method 'dataSourcePoolMetadataMeterBinder' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [com/baomidou/dynamic/datasource/spring/boot/autoconfigure/DynamicDataSourceAutoConfiguration.class]: Invocation of init method failed; nested exception is com.baomidou.dynamic.datasource.exception.ErrorCreateDataSourceException: druid create error +17:38:17.785 [main] ERROR o.s.b.SpringApplication - [reportFailure,821] - Application run failed +org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat + at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:165) + at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:577) + at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) + at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731) + at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) + at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) + at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303) + at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292) + at com.dcsoft.system.DCSSystemApplication.main(DCSSystemApplication.java:22) +Caused by: org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat + at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:142) + at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.(TomcatWebServer.java:104) + at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:479) + at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:211) + at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:184) + at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:162) + ... 8 common frames omitted +Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webMvcMetricsFilter' defined in class path resource [org/springframework/boot/actuate/autoconfigure/metrics/web/servlet/WebMvcMetricsAutoConfiguration.class]: Unsatisfied dependency expressed through method 'webMvcMetricsFilter' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'simpleMeterRegistry' defined in class path resource [org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimpleMetricsExportAutoConfiguration.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataSourcePoolMetadataMeterBinder' defined in class path resource [org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfiguration$DataSourcePoolMetadataMetricsConfiguration.class]: Unsatisfied dependency expressed through method 'dataSourcePoolMetadataMeterBinder' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [com/baomidou/dynamic/datasource/spring/boot/autoconfigure/DynamicDataSourceAutoConfiguration.class]: Invocation of init method failed; nested exception is com.baomidou.dynamic.datasource.exception.ErrorCreateDataSourceException: druid create error + at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) + at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:541) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) + at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) + at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) + at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) + at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:213) + at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:212) + at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:203) + at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addServletContextInitializerBeans(ServletContextInitializerBeans.java:97) + at org.springframework.boot.web.servlet.ServletContextInitializerBeans.(ServletContextInitializerBeans.java:86) + at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getServletContextInitializerBeans(ServletWebServerApplicationContext.java:262) + at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.selfInitialize(ServletWebServerApplicationContext.java:236) + at org.springframework.boot.web.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:53) + at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5211) + at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) + at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393) + at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1383) + at java.util.concurrent.FutureTask.run(FutureTask.java:266) + at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) + at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134) + at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:916) + at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:835) + at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) + at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393) + at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1383) + at java.util.concurrent.FutureTask.run(FutureTask.java:266) + at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) + at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134) + at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:916) + at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:265) + at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) + at org.apache.catalina.core.StandardService.startInternal(StandardService.java:430) + at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) + at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:930) + at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) + at org.apache.catalina.startup.Tomcat.start(Tomcat.java:486) + at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:123) + ... 13 common frames omitted +Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'simpleMeterRegistry' defined in class path resource [org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimpleMetricsExportAutoConfiguration.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataSourcePoolMetadataMeterBinder' defined in class path resource [org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfiguration$DataSourcePoolMetadataMetricsConfiguration.class]: Unsatisfied dependency expressed through method 'dataSourcePoolMetadataMeterBinder' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [com/baomidou/dynamic/datasource/spring/boot/autoconfigure/DynamicDataSourceAutoConfiguration.class]: Invocation of init method failed; nested exception is com.baomidou.dynamic.datasource.exception.ErrorCreateDataSourceException: druid create error + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:628) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) + at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) + at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) + at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) + at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) + at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1391) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311) + at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) + at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) + ... 53 common frames omitted +Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataSourcePoolMetadataMeterBinder' defined in class path resource [org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfiguration$DataSourcePoolMetadataMetricsConfiguration.class]: Unsatisfied dependency expressed through method 'dataSourcePoolMetadataMeterBinder' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [com/baomidou/dynamic/datasource/spring/boot/autoconfigure/DynamicDataSourceAutoConfiguration.class]: Invocation of init method failed; nested exception is com.baomidou.dynamic.datasource.exception.ErrorCreateDataSourceException: druid create error + at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) + at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:541) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) + at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) + at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) + at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) + at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) + at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.addCandidateEntry(DefaultListableBeanFactory.java:1616) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1573) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveMultipleBeans(DefaultListableBeanFactory.java:1417) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1349) + at org.springframework.beans.factory.support.DefaultListableBeanFactory$DependencyObjectProvider.resolveStream(DefaultListableBeanFactory.java:2119) + at org.springframework.beans.factory.support.DefaultListableBeanFactory$DependencyObjectProvider.orderedStream(DefaultListableBeanFactory.java:2113) + at org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryConfigurer.addBinders(MeterRegistryConfigurer.java:86) + at org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryConfigurer.configure(MeterRegistryConfigurer.java:68) + at org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryPostProcessor.postProcessAfterInitialization(MeterRegistryPostProcessor.java:64) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:455) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1808) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) + ... 63 common frames omitted +Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [com/baomidou/dynamic/datasource/spring/boot/autoconfigure/DynamicDataSourceAutoConfiguration.class]: Invocation of init method failed; nested exception is com.baomidou.dynamic.datasource.exception.ErrorCreateDataSourceException: druid create error + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) + at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) + at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) + at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) + at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) + at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.addCandidateEntry(DefaultListableBeanFactory.java:1609) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1573) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveMultipleBeans(DefaultListableBeanFactory.java:1492) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1349) + at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311) + at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) + at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) + ... 85 common frames omitted +Caused by: com.baomidou.dynamic.datasource.exception.ErrorCreateDataSourceException: druid create error + at com.baomidou.dynamic.datasource.creator.DruidDataSourceCreator.doCreateDataSource(DruidDataSourceCreator.java:87) + at com.baomidou.dynamic.datasource.creator.AbstractDataSourceCreator.createDataSource(AbstractDataSourceCreator.java:70) + at com.baomidou.dynamic.datasource.creator.DefaultDataSourceCreator.createDataSource(DefaultDataSourceCreator.java:48) + at com.baomidou.dynamic.datasource.provider.AbstractDataSourceProvider.createDataSourceMap(AbstractDataSourceProvider.java:47) + at com.baomidou.dynamic.datasource.provider.YmlDynamicDataSourceProvider.loadDataSources(YmlDynamicDataSourceProvider.java:42) + at com.baomidou.dynamic.datasource.DynamicRoutingDataSource.afterPropertiesSet(DynamicRoutingDataSource.java:225) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863) + at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800) + ... 99 common frames omitted +Caused by: com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure + +The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server. + at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:828) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:448) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:198) + at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:118) + at com.alibaba.druid.filter.FilterAdapter.connection_connect(FilterAdapter.java:764) + at com.alibaba.druid.filter.FilterEventAdapter.connection_connect(FilterEventAdapter.java:33) + at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:112) + at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:232) + at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:112) + at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1703) + at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1786) + at com.alibaba.druid.pool.DruidDataSource.init(DruidDataSource.java:925) + at com.baomidou.dynamic.datasource.creator.DruidDataSourceCreator.doCreateDataSource(DruidDataSourceCreator.java:85) + ... 106 common frames omitted +Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure + +The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server. + at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) + at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) + at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) + at java.lang.reflect.Constructor.newInstance(Constructor.java:423) + at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61) + at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105) + at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151) + at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167) + at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:89) + at com.mysql.cj.NativeSession.connect(NativeSession.java:120) + at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:948) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:818) + ... 119 common frames omitted +Caused by: java.net.ConnectException: Connection refused: connect + at java.net.DualStackPlainSocketImpl.connect0(Native Method) + at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:75) + at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:476) + at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:218) + at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:200) + at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:162) + at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:394) + at java.net.Socket.connect(Socket.java:606) + at com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:153) + at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:63) + ... 122 common frames omitted +17:40:21.411 [http-nio-9201-exec-4] ERROR druid.sql.Statement - [statementLogError,148] - {conn-10004, pstmt-20027} execute error. insert into car_info + ( enable_time, + overdue_time, + enable, + plate, + time_seg_enable, + + need_alarm, + + + + + + remark, + create_by, + create_time, + + + + num, + car_type, + unit, + phone ) + values ( ?, + ?, + ?, + ?, + ?, + + ?, + + + + + + ?, + ?, + ?, + + + + ?, + ?, + ?, + ? ) +java.sql.SQLException: Incorrect integer value: 'admin' for column 'create_by' at row 1 + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:916) + at com.mysql.cj.jdbc.ClientPreparedStatement.execute(ClientPreparedStatement.java:354) + at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_execute(FilterChainImpl.java:3446) + at com.alibaba.druid.filter.FilterEventAdapter.preparedStatement_execute(FilterEventAdapter.java:434) + at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_execute(FilterChainImpl.java:3444) + at com.alibaba.druid.filter.FilterEventAdapter.preparedStatement_execute(FilterEventAdapter.java:434) + at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_execute(FilterChainImpl.java:3444) + at com.alibaba.druid.proxy.jdbc.PreparedStatementProxyImpl.execute(PreparedStatementProxyImpl.java:152) + at com.alibaba.druid.pool.DruidPooledPreparedStatement.execute(DruidPooledPreparedStatement.java:483) + at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:47) + at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:74) + at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:50) + at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117) + at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:64) + at com.sun.proxy.$Proxy281.update(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:194) + at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:181) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:427) + at com.sun.proxy.$Proxy135.insert(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:272) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:62) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:145) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at com.sun.proxy.$Proxy213.insertCarInfo(Unknown Source) + at com.dcsoft.system.vehicle.service.impl.CarInfoServiceImpl.insertCarInfo(CarInfoServiceImpl.java:83) + at com.dcsoft.system.vehicle.service.impl.CarInfoServiceImpl.importData(CarInfoServiceImpl.java:267) + at com.dcsoft.system.vehicle.controller.CarInfoController.importData(CarInfoController.java:78) + at com.dcsoft.system.vehicle.controller.CarInfoController$$FastClassBySpringCGLIB$$6da77215.invoke() + at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:89) + at com.dcsoft.common.security.aspect.PreAuthorizeAspect.around(PreAuthorizeAspect.java:62) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:634) + at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:624) + at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:72) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:64) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:57) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:58) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708) + at com.dcsoft.system.vehicle.controller.CarInfoController$$EnhancerBySpringCGLIB$$6a889eb4.importData() + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) + at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) + at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) + at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071) + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964) + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) + at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) + at javax.servlet.http.HttpServlet.service(HttpServlet.java:696) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) + at javax.servlet.http.HttpServlet.service(HttpServlet.java:779) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:891) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.lang.Thread.run(Thread.java:750) +17:40:21.560 [http-nio-9201-exec-4] ERROR c.d.c.s.h.GlobalExceptionHandler - [handleServiceException,70] - 很抱歉,导入失败!共 1 条数据格式不正确,错误如下:
1、车牌信息 皖B77898 导入失败: +### Error updating database. Cause: java.sql.SQLException: Incorrect integer value: 'admin' for column 'create_by' at row 1 +### The error may exist in file [D:\xa-prod\xa-master-prod\dcsoft-modules\dcsoft-system\target\classes\mapper\vehicle\CarInfoMapper.xml] +### The error may involve com.dcsoft.system.vehicle.mapper.CarInfoMapper.insertCarInfo-Inline +### The error occurred while setting parameters +### SQL: insert into car_info ( enable_time, overdue_time, enable, plate, time_seg_enable, need_alarm, remark, create_by, create_time, num, car_type, unit, phone ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) +### Cause: java.sql.SQLException: Incorrect integer value: 'admin' for column 'create_by' at row 1 +; uncategorized SQLException; SQL state [HY000]; error code [1366]; Incorrect integer value: 'admin' for column 'create_by' at row 1; nested exception is java.sql.SQLException: Incorrect integer value: 'admin' for column 'create_by' at row 1 +com.dcsoft.common.core.exception.ServiceException: 很抱歉,导入失败!共 1 条数据格式不正确,错误如下:
1、车牌信息 皖B77898 导入失败: +### Error updating database. Cause: java.sql.SQLException: Incorrect integer value: 'admin' for column 'create_by' at row 1 +### The error may exist in file [D:\xa-prod\xa-master-prod\dcsoft-modules\dcsoft-system\target\classes\mapper\vehicle\CarInfoMapper.xml] +### The error may involve com.dcsoft.system.vehicle.mapper.CarInfoMapper.insertCarInfo-Inline +### The error occurred while setting parameters +### SQL: insert into car_info ( enable_time, overdue_time, enable, plate, time_seg_enable, need_alarm, remark, create_by, create_time, num, car_type, unit, phone ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) +### Cause: java.sql.SQLException: Incorrect integer value: 'admin' for column 'create_by' at row 1 +; uncategorized SQLException; SQL state [HY000]; error code [1366]; Incorrect integer value: 'admin' for column 'create_by' at row 1; nested exception is java.sql.SQLException: Incorrect integer value: 'admin' for column 'create_by' at row 1 + at com.dcsoft.system.vehicle.service.impl.CarInfoServiceImpl.importData(CarInfoServiceImpl.java:326) + at com.dcsoft.system.vehicle.controller.CarInfoController.importData(CarInfoController.java:78) + at com.dcsoft.system.vehicle.controller.CarInfoController$$FastClassBySpringCGLIB$$6da77215.invoke() + at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:89) + at com.dcsoft.common.security.aspect.PreAuthorizeAspect.around(PreAuthorizeAspect.java:62) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:634) + at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:624) + at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:72) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:64) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:57) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:58) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708) + at com.dcsoft.system.vehicle.controller.CarInfoController$$EnhancerBySpringCGLIB$$6a889eb4.importData() + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) + at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) + at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) + at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071) + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964) + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) + at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) + at javax.servlet.http.HttpServlet.service(HttpServlet.java:696) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) + at javax.servlet.http.HttpServlet.service(HttpServlet.java:779) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:891) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.lang.Thread.run(Thread.java:750) +17:40:21.570 [http-nio-9201-exec-4] ERROR o.a.c.h.Http11Processor - [log,175] - Error processing request +java.io.UncheckedIOException: Cannot delete C:\Users\jingy\AppData\Local\Temp\tomcat.9201.6979368381763412530\work\Tomcat\localhost\ROOT\upload_995d96ee_ae19_4e0a_949d_e9c9b82d4d56_00000000.tmp + at org.apache.tomcat.util.http.fileupload.disk.DiskFileItem.delete(DiskFileItem.java:431) + at org.apache.catalina.core.ApplicationPart.delete(ApplicationPart.java:54) + at org.apache.catalina.connector.Request.recycle(Request.java:483) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:441) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:891) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.lang.Thread.run(Thread.java:750) +Caused by: java.io.IOException: Cannot delete C:\Users\jingy\AppData\Local\Temp\tomcat.9201.6979368381763412530\work\Tomcat\localhost\ROOT\upload_995d96ee_ae19_4e0a_949d_e9c9b82d4d56_00000000.tmp + ... 13 common frames omitted +17:40:21.592 [http-nio-9201-exec-4] ERROR o.a.c.h.Http11NioProtocol - [log,175] - Error reading request, ignored +java.io.UncheckedIOException: Cannot delete C:\Users\jingy\AppData\Local\Temp\tomcat.9201.6979368381763412530\work\Tomcat\localhost\ROOT\upload_995d96ee_ae19_4e0a_949d_e9c9b82d4d56_00000000.tmp + at org.apache.tomcat.util.http.fileupload.disk.DiskFileItem.delete(DiskFileItem.java:431) + at org.apache.catalina.core.ApplicationPart.delete(ApplicationPart.java:54) + at org.apache.catalina.connector.Request.recycle(Request.java:483) + at org.apache.catalina.connector.CoyoteAdapter.log(CoyoteAdapter.java:515) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:429) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:891) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.lang.Thread.run(Thread.java:750) +Caused by: java.io.IOException: Cannot delete C:\Users\jingy\AppData\Local\Temp\tomcat.9201.6979368381763412530\work\Tomcat\localhost\ROOT\upload_995d96ee_ae19_4e0a_949d_e9c9b82d4d56_00000000.tmp + ... 13 common frames omitted +17:40:21.599 [http-nio-9201-exec-4] ERROR o.a.t.u.n.NioEndpoint - [log,175] - Error running socket processor +java.io.UncheckedIOException: Cannot delete C:\Users\jingy\AppData\Local\Temp\tomcat.9201.6979368381763412530\work\Tomcat\localhost\ROOT\upload_995d96ee_ae19_4e0a_949d_e9c9b82d4d56_00000000.tmp + at org.apache.tomcat.util.http.fileupload.disk.DiskFileItem.delete(DiskFileItem.java:431) + at org.apache.catalina.core.ApplicationPart.delete(ApplicationPart.java:54) + at org.apache.catalina.connector.Request.recycle(Request.java:483) + at org.apache.catalina.connector.CoyoteAdapter.log(CoyoteAdapter.java:515) + at org.apache.catalina.connector.CoyoteAdapter.checkRecycled(CoyoteAdapter.java:539) + at org.apache.coyote.http11.Http11Processor.recycle(Http11Processor.java:1426) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.release(AbstractProtocol.java:1098) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:1056) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.lang.Thread.run(Thread.java:750) +Caused by: java.io.IOException: Cannot delete C:\Users\jingy\AppData\Local\Temp\tomcat.9201.6979368381763412530\work\Tomcat\localhost\ROOT\upload_995d96ee_ae19_4e0a_949d_e9c9b82d4d56_00000000.tmp + ... 14 common frames omitted +17:40:21.900 [http-nio-9201-exec-8] ERROR c.d.c.s.h.GlobalExceptionHandler - [handleRuntimeException,82] - 请求地址'/operlog',发生未知异常. +org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\r, \n, \t) is allowed between tokens; nested exception is com.fasterxml.jackson.core.JsonParseException: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\r, \n, \t) is allowed between tokens + at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 2] + at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:391) + at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:343) + at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:185) + at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:160) + at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:133) + at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:122) + at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:179) + at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:146) + at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) + at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071) + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964) + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) + at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) + at javax.servlet.http.HttpServlet.service(HttpServlet.java:696) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) + at javax.servlet.http.HttpServlet.service(HttpServlet.java:779) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:891) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.lang.Thread.run(Thread.java:750) +Caused by: com.fasterxml.jackson.core.JsonParseException: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\r, \n, \t) is allowed between tokens + at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 2] + at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:2391) + at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:735) + at com.fasterxml.jackson.core.base.ParserMinimalBase._throwInvalidSpace(ParserMinimalBase.java:713) + at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._skipWSOrEnd(UTF8StreamJsonParser.java:3057) + at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.nextToken(UTF8StreamJsonParser.java:756) + at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:4761) + at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4667) + at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3682) + at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:380) + ... 55 common frames omitted +17:42:19.015 [http-nio-9201-exec-6] ERROR druid.sql.Statement - [statementLogError,148] - {conn-10003, pstmt-20037} execute error. insert into car_info + ( enable_time, + overdue_time, + enable, + plate, + time_seg_enable, + + need_alarm, + + + + + + remark, + create_by, + create_time, + + + + num, + car_type, + unit, + phone ) + values ( ?, + ?, + ?, + ?, + ?, + + ?, + + + + + + ?, + ?, + ?, + + + + ?, + ?, + ?, + ? ) +java.sql.SQLException: Incorrect integer value: 'admin' for column 'create_by' at row 1 + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:916) + at com.mysql.cj.jdbc.ClientPreparedStatement.execute(ClientPreparedStatement.java:354) + at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_execute(FilterChainImpl.java:3446) + at com.alibaba.druid.filter.FilterEventAdapter.preparedStatement_execute(FilterEventAdapter.java:434) + at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_execute(FilterChainImpl.java:3444) + at com.alibaba.druid.filter.FilterEventAdapter.preparedStatement_execute(FilterEventAdapter.java:434) + at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_execute(FilterChainImpl.java:3444) + at com.alibaba.druid.proxy.jdbc.PreparedStatementProxyImpl.execute(PreparedStatementProxyImpl.java:152) + at com.alibaba.druid.pool.DruidPooledPreparedStatement.execute(DruidPooledPreparedStatement.java:483) + at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:47) + at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:74) + at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:50) + at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117) + at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:64) + at com.sun.proxy.$Proxy281.update(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:194) + at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:181) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:427) + at com.sun.proxy.$Proxy135.insert(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:272) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:62) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:145) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at com.sun.proxy.$Proxy213.insertCarInfo(Unknown Source) + at com.dcsoft.system.vehicle.service.impl.CarInfoServiceImpl.insertCarInfo(CarInfoServiceImpl.java:83) + at com.dcsoft.system.vehicle.service.impl.CarInfoServiceImpl.importData(CarInfoServiceImpl.java:267) + at com.dcsoft.system.vehicle.controller.CarInfoController.importData(CarInfoController.java:78) + at com.dcsoft.system.vehicle.controller.CarInfoController$$FastClassBySpringCGLIB$$6da77215.invoke() + at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:89) + at com.dcsoft.common.security.aspect.PreAuthorizeAspect.around(PreAuthorizeAspect.java:62) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:634) + at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:624) + at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:72) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:64) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:57) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:58) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708) + at com.dcsoft.system.vehicle.controller.CarInfoController$$EnhancerBySpringCGLIB$$6a889eb4.importData() + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) + at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) + at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) + at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071) + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964) + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) + at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) + at javax.servlet.http.HttpServlet.service(HttpServlet.java:696) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) + at javax.servlet.http.HttpServlet.service(HttpServlet.java:779) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:891) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.lang.Thread.run(Thread.java:750) +17:42:19.018 [http-nio-9201-exec-6] ERROR c.d.c.s.h.GlobalExceptionHandler - [handleServiceException,70] - 很抱歉,导入失败!共 1 条数据格式不正确,错误如下:
1、车牌信息 皖B77898 导入失败: +### Error updating database. Cause: java.sql.SQLException: Incorrect integer value: 'admin' for column 'create_by' at row 1 +### The error may exist in file [D:\xa-prod\xa-master-prod\dcsoft-modules\dcsoft-system\target\classes\mapper\vehicle\CarInfoMapper.xml] +### The error may involve com.dcsoft.system.vehicle.mapper.CarInfoMapper.insertCarInfo-Inline +### The error occurred while setting parameters +### SQL: insert into car_info ( enable_time, overdue_time, enable, plate, time_seg_enable, need_alarm, remark, create_by, create_time, num, car_type, unit, phone ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) +### Cause: java.sql.SQLException: Incorrect integer value: 'admin' for column 'create_by' at row 1 +; uncategorized SQLException; SQL state [HY000]; error code [1366]; Incorrect integer value: 'admin' for column 'create_by' at row 1; nested exception is java.sql.SQLException: Incorrect integer value: 'admin' for column 'create_by' at row 1 +com.dcsoft.common.core.exception.ServiceException: 很抱歉,导入失败!共 1 条数据格式不正确,错误如下:
1、车牌信息 皖B77898 导入失败: +### Error updating database. Cause: java.sql.SQLException: Incorrect integer value: 'admin' for column 'create_by' at row 1 +### The error may exist in file [D:\xa-prod\xa-master-prod\dcsoft-modules\dcsoft-system\target\classes\mapper\vehicle\CarInfoMapper.xml] +### The error may involve com.dcsoft.system.vehicle.mapper.CarInfoMapper.insertCarInfo-Inline +### The error occurred while setting parameters +### SQL: insert into car_info ( enable_time, overdue_time, enable, plate, time_seg_enable, need_alarm, remark, create_by, create_time, num, car_type, unit, phone ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) +### Cause: java.sql.SQLException: Incorrect integer value: 'admin' for column 'create_by' at row 1 +; uncategorized SQLException; SQL state [HY000]; error code [1366]; Incorrect integer value: 'admin' for column 'create_by' at row 1; nested exception is java.sql.SQLException: Incorrect integer value: 'admin' for column 'create_by' at row 1 + at com.dcsoft.system.vehicle.service.impl.CarInfoServiceImpl.importData(CarInfoServiceImpl.java:326) + at com.dcsoft.system.vehicle.controller.CarInfoController.importData(CarInfoController.java:78) + at com.dcsoft.system.vehicle.controller.CarInfoController$$FastClassBySpringCGLIB$$6da77215.invoke() + at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:89) + at com.dcsoft.common.security.aspect.PreAuthorizeAspect.around(PreAuthorizeAspect.java:62) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:634) + at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:624) + at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:72) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:64) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:57) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:58) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708) + at com.dcsoft.system.vehicle.controller.CarInfoController$$EnhancerBySpringCGLIB$$6a889eb4.importData() + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) + at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) + at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) + at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071) + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964) + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) + at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) + at javax.servlet.http.HttpServlet.service(HttpServlet.java:696) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) + at javax.servlet.http.HttpServlet.service(HttpServlet.java:779) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:891) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.lang.Thread.run(Thread.java:750) +17:42:19.027 [http-nio-9201-exec-6] ERROR o.a.c.h.Http11Processor - [log,175] - Error processing request +java.io.UncheckedIOException: Cannot delete C:\Users\jingy\AppData\Local\Temp\tomcat.9201.6979368381763412530\work\Tomcat\localhost\ROOT\upload_995d96ee_ae19_4e0a_949d_e9c9b82d4d56_00000001.tmp + at org.apache.tomcat.util.http.fileupload.disk.DiskFileItem.delete(DiskFileItem.java:431) + at org.apache.catalina.core.ApplicationPart.delete(ApplicationPart.java:54) + at org.apache.catalina.connector.Request.recycle(Request.java:483) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:441) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:891) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.lang.Thread.run(Thread.java:750) +Caused by: java.io.IOException: Cannot delete C:\Users\jingy\AppData\Local\Temp\tomcat.9201.6979368381763412530\work\Tomcat\localhost\ROOT\upload_995d96ee_ae19_4e0a_949d_e9c9b82d4d56_00000001.tmp + ... 13 common frames omitted +17:42:19.029 [http-nio-9201-exec-6] ERROR o.a.c.h.Http11NioProtocol - [log,175] - Error reading request, ignored +java.io.UncheckedIOException: Cannot delete C:\Users\jingy\AppData\Local\Temp\tomcat.9201.6979368381763412530\work\Tomcat\localhost\ROOT\upload_995d96ee_ae19_4e0a_949d_e9c9b82d4d56_00000001.tmp + at org.apache.tomcat.util.http.fileupload.disk.DiskFileItem.delete(DiskFileItem.java:431) + at org.apache.catalina.core.ApplicationPart.delete(ApplicationPart.java:54) + at org.apache.catalina.connector.Request.recycle(Request.java:483) + at org.apache.catalina.connector.CoyoteAdapter.log(CoyoteAdapter.java:515) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:429) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:891) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.lang.Thread.run(Thread.java:750) +Caused by: java.io.IOException: Cannot delete C:\Users\jingy\AppData\Local\Temp\tomcat.9201.6979368381763412530\work\Tomcat\localhost\ROOT\upload_995d96ee_ae19_4e0a_949d_e9c9b82d4d56_00000001.tmp + ... 13 common frames omitted +17:42:19.031 [http-nio-9201-exec-9] ERROR c.d.c.s.h.GlobalExceptionHandler - [handleRuntimeException,82] - 请求地址'/operlog',发生未知异常. +org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\r, \n, \t) is allowed between tokens; nested exception is com.fasterxml.jackson.core.JsonParseException: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\r, \n, \t) is allowed between tokens + at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 2] + at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:391) + at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:343) + at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:185) + at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:160) + at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:133) + at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:122) + at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:179) + at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:146) + at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) + at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071) + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964) + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) + at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) + at javax.servlet.http.HttpServlet.service(HttpServlet.java:696) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) + at javax.servlet.http.HttpServlet.service(HttpServlet.java:779) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:891) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.lang.Thread.run(Thread.java:750) +Caused by: com.fasterxml.jackson.core.JsonParseException: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\r, \n, \t) is allowed between tokens + at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 2] + at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:2391) + at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:735) + at com.fasterxml.jackson.core.base.ParserMinimalBase._throwInvalidSpace(ParserMinimalBase.java:713) + at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._skipWSOrEnd(UTF8StreamJsonParser.java:3057) + at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.nextToken(UTF8StreamJsonParser.java:756) + at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:4761) + at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4667) + at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3682) + at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:380) + ... 55 common frames omitted +17:42:19.032 [http-nio-9201-exec-6] ERROR o.a.t.u.n.NioEndpoint - [log,175] - Error running socket processor +java.io.UncheckedIOException: Cannot delete C:\Users\jingy\AppData\Local\Temp\tomcat.9201.6979368381763412530\work\Tomcat\localhost\ROOT\upload_995d96ee_ae19_4e0a_949d_e9c9b82d4d56_00000001.tmp + at org.apache.tomcat.util.http.fileupload.disk.DiskFileItem.delete(DiskFileItem.java:431) + at org.apache.catalina.core.ApplicationPart.delete(ApplicationPart.java:54) + at org.apache.catalina.connector.Request.recycle(Request.java:483) + at org.apache.catalina.connector.CoyoteAdapter.log(CoyoteAdapter.java:515) + at org.apache.catalina.connector.CoyoteAdapter.checkRecycled(CoyoteAdapter.java:539) + at org.apache.coyote.http11.Http11Processor.recycle(Http11Processor.java:1426) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.release(AbstractProtocol.java:1098) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:1056) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.lang.Thread.run(Thread.java:750) +Caused by: java.io.IOException: Cannot delete C:\Users\jingy\AppData\Local\Temp\tomcat.9201.6979368381763412530\work\Tomcat\localhost\ROOT\upload_995d96ee_ae19_4e0a_949d_e9c9b82d4d56_00000001.tmp + ... 14 common frames omitted +17:43:21.665 [http-nio-9201-exec-5] ERROR druid.sql.Statement - [statementLogError,148] - {conn-10005, pstmt-20010} execute error. insert into car_info + ( enable_time, + overdue_time, + enable, + plate, + time_seg_enable, + + need_alarm, + + + + + + remark, + create_by, + create_time, + + + + num, + car_type, + unit, + phone ) + values ( ?, + ?, + ?, + ?, + ?, + + ?, + + + + + + ?, + ?, + ?, + + + + ?, + ?, + ?, + ? ) +java.sql.SQLException: Incorrect integer value: 'admin' for column 'create_by' at row 1 + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:916) + at com.mysql.cj.jdbc.ClientPreparedStatement.execute(ClientPreparedStatement.java:354) + at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_execute(FilterChainImpl.java:3446) + at com.alibaba.druid.filter.FilterEventAdapter.preparedStatement_execute(FilterEventAdapter.java:434) + at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_execute(FilterChainImpl.java:3444) + at com.alibaba.druid.filter.FilterEventAdapter.preparedStatement_execute(FilterEventAdapter.java:434) + at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_execute(FilterChainImpl.java:3444) + at com.alibaba.druid.proxy.jdbc.PreparedStatementProxyImpl.execute(PreparedStatementProxyImpl.java:152) + at com.alibaba.druid.pool.DruidPooledPreparedStatement.execute(DruidPooledPreparedStatement.java:483) + at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:47) + at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:74) + at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:50) + at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117) + at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:64) + at com.sun.proxy.$Proxy281.update(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:194) + at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:181) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:427) + at com.sun.proxy.$Proxy135.insert(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:272) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:62) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:145) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at com.sun.proxy.$Proxy213.insertCarInfo(Unknown Source) + at com.dcsoft.system.vehicle.service.impl.CarInfoServiceImpl.insertCarInfo(CarInfoServiceImpl.java:83) + at com.dcsoft.system.vehicle.service.impl.CarInfoServiceImpl.importData(CarInfoServiceImpl.java:267) + at com.dcsoft.system.vehicle.controller.CarInfoController.importData(CarInfoController.java:79) + at com.dcsoft.system.vehicle.controller.CarInfoController$$FastClassBySpringCGLIB$$6da77215.invoke() + at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:89) + at com.dcsoft.common.security.aspect.PreAuthorizeAspect.around(PreAuthorizeAspect.java:62) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:634) + at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:624) + at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:72) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:64) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:57) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:58) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708) + at com.dcsoft.system.vehicle.controller.CarInfoController$$EnhancerBySpringCGLIB$$b01191d7.importData() + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) + at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) + at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) + at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071) + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964) + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) + at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) + at javax.servlet.http.HttpServlet.service(HttpServlet.java:696) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) + at javax.servlet.http.HttpServlet.service(HttpServlet.java:779) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:891) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.lang.Thread.run(Thread.java:750) +17:43:21.702 [http-nio-9201-exec-5] ERROR c.d.c.s.h.GlobalExceptionHandler - [handleServiceException,70] - 很抱歉,导入失败!共 1 条数据格式不正确,错误如下:
1、车牌信息 皖B77898 导入失败: +### Error updating database. Cause: java.sql.SQLException: Incorrect integer value: 'admin' for column 'create_by' at row 1 +### The error may exist in file [D:\xa-prod\xa-master-prod\dcsoft-modules\dcsoft-system\target\classes\mapper\vehicle\CarInfoMapper.xml] +### The error may involve com.dcsoft.system.vehicle.mapper.CarInfoMapper.insertCarInfo-Inline +### The error occurred while setting parameters +### SQL: insert into car_info ( enable_time, overdue_time, enable, plate, time_seg_enable, need_alarm, remark, create_by, create_time, num, car_type, unit, phone ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) +### Cause: java.sql.SQLException: Incorrect integer value: 'admin' for column 'create_by' at row 1 +; uncategorized SQLException; SQL state [HY000]; error code [1366]; Incorrect integer value: 'admin' for column 'create_by' at row 1; nested exception is java.sql.SQLException: Incorrect integer value: 'admin' for column 'create_by' at row 1 +com.dcsoft.common.core.exception.ServiceException: 很抱歉,导入失败!共 1 条数据格式不正确,错误如下:
1、车牌信息 皖B77898 导入失败: +### Error updating database. Cause: java.sql.SQLException: Incorrect integer value: 'admin' for column 'create_by' at row 1 +### The error may exist in file [D:\xa-prod\xa-master-prod\dcsoft-modules\dcsoft-system\target\classes\mapper\vehicle\CarInfoMapper.xml] +### The error may involve com.dcsoft.system.vehicle.mapper.CarInfoMapper.insertCarInfo-Inline +### The error occurred while setting parameters +### SQL: insert into car_info ( enable_time, overdue_time, enable, plate, time_seg_enable, need_alarm, remark, create_by, create_time, num, car_type, unit, phone ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) +### Cause: java.sql.SQLException: Incorrect integer value: 'admin' for column 'create_by' at row 1 +; uncategorized SQLException; SQL state [HY000]; error code [1366]; Incorrect integer value: 'admin' for column 'create_by' at row 1; nested exception is java.sql.SQLException: Incorrect integer value: 'admin' for column 'create_by' at row 1 + at com.dcsoft.system.vehicle.service.impl.CarInfoServiceImpl.importData(CarInfoServiceImpl.java:326) + at com.dcsoft.system.vehicle.controller.CarInfoController.importData(CarInfoController.java:79) + at com.dcsoft.system.vehicle.controller.CarInfoController$$FastClassBySpringCGLIB$$6da77215.invoke() + at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:89) + at com.dcsoft.common.security.aspect.PreAuthorizeAspect.around(PreAuthorizeAspect.java:62) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:634) + at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:624) + at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:72) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:64) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:57) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:58) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) + at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708) + at com.dcsoft.system.vehicle.controller.CarInfoController$$EnhancerBySpringCGLIB$$b01191d7.importData() + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) + at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) + at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) + at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071) + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964) + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) + at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) + at javax.servlet.http.HttpServlet.service(HttpServlet.java:696) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) + at javax.servlet.http.HttpServlet.service(HttpServlet.java:779) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:891) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.lang.Thread.run(Thread.java:750) +17:43:21.742 [http-nio-9201-exec-5] ERROR o.a.c.h.Http11Processor - [log,175] - Error processing request +java.io.UncheckedIOException: Cannot delete C:\Users\jingy\AppData\Local\Temp\tomcat.9201.3224933836524553325\work\Tomcat\localhost\ROOT\upload_457f6bd9_c065_474f_a723_a978f70799c8_00000000.tmp + at org.apache.tomcat.util.http.fileupload.disk.DiskFileItem.delete(DiskFileItem.java:431) + at org.apache.catalina.core.ApplicationPart.delete(ApplicationPart.java:54) + at org.apache.catalina.connector.Request.recycle(Request.java:483) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:441) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:891) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.lang.Thread.run(Thread.java:750) +Caused by: java.io.IOException: Cannot delete C:\Users\jingy\AppData\Local\Temp\tomcat.9201.3224933836524553325\work\Tomcat\localhost\ROOT\upload_457f6bd9_c065_474f_a723_a978f70799c8_00000000.tmp + ... 13 common frames omitted +17:43:21.745 [http-nio-9201-exec-5] ERROR o.a.c.h.Http11NioProtocol - [log,175] - Error reading request, ignored +java.io.UncheckedIOException: Cannot delete C:\Users\jingy\AppData\Local\Temp\tomcat.9201.3224933836524553325\work\Tomcat\localhost\ROOT\upload_457f6bd9_c065_474f_a723_a978f70799c8_00000000.tmp + at org.apache.tomcat.util.http.fileupload.disk.DiskFileItem.delete(DiskFileItem.java:431) + at org.apache.catalina.core.ApplicationPart.delete(ApplicationPart.java:54) + at org.apache.catalina.connector.Request.recycle(Request.java:483) + at org.apache.catalina.connector.CoyoteAdapter.log(CoyoteAdapter.java:515) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:429) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:891) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.lang.Thread.run(Thread.java:750) +Caused by: java.io.IOException: Cannot delete C:\Users\jingy\AppData\Local\Temp\tomcat.9201.3224933836524553325\work\Tomcat\localhost\ROOT\upload_457f6bd9_c065_474f_a723_a978f70799c8_00000000.tmp + ... 13 common frames omitted +17:43:21.745 [http-nio-9201-exec-5] ERROR o.a.t.u.n.NioEndpoint - [log,175] - Error running socket processor +java.io.UncheckedIOException: Cannot delete C:\Users\jingy\AppData\Local\Temp\tomcat.9201.3224933836524553325\work\Tomcat\localhost\ROOT\upload_457f6bd9_c065_474f_a723_a978f70799c8_00000000.tmp + at org.apache.tomcat.util.http.fileupload.disk.DiskFileItem.delete(DiskFileItem.java:431) + at org.apache.catalina.core.ApplicationPart.delete(ApplicationPart.java:54) + at org.apache.catalina.connector.Request.recycle(Request.java:483) + at org.apache.catalina.connector.CoyoteAdapter.log(CoyoteAdapter.java:515) + at org.apache.catalina.connector.CoyoteAdapter.checkRecycled(CoyoteAdapter.java:539) + at org.apache.coyote.http11.Http11Processor.recycle(Http11Processor.java:1426) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.release(AbstractProtocol.java:1098) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:1056) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.lang.Thread.run(Thread.java:750) +Caused by: java.io.IOException: Cannot delete C:\Users\jingy\AppData\Local\Temp\tomcat.9201.3224933836524553325\work\Tomcat\localhost\ROOT\upload_457f6bd9_c065_474f_a723_a978f70799c8_00000000.tmp + ... 14 common frames omitted +17:43:21.825 [http-nio-9201-exec-2] ERROR c.d.c.s.h.GlobalExceptionHandler - [handleRuntimeException,82] - 请求地址'/operlog',发生未知异常. +org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\r, \n, \t) is allowed between tokens; nested exception is com.fasterxml.jackson.core.JsonParseException: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\r, \n, \t) is allowed between tokens + at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 2] + at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:391) + at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:343) + at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:185) + at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:160) + at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:133) + at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:122) + at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:179) + at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:146) + at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) + at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071) + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964) + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) + at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) + at javax.servlet.http.HttpServlet.service(HttpServlet.java:696) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) + at javax.servlet.http.HttpServlet.service(HttpServlet.java:779) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:891) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.lang.Thread.run(Thread.java:750) +Caused by: com.fasterxml.jackson.core.JsonParseException: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\r, \n, \t) is allowed between tokens + at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 2] + at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:2391) + at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:735) + at com.fasterxml.jackson.core.base.ParserMinimalBase._throwInvalidSpace(ParserMinimalBase.java:713) + at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._skipWSOrEnd(UTF8StreamJsonParser.java:3057) + at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.nextToken(UTF8StreamJsonParser.java:756) + at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:4761) + at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4667) + at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3682) + at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:380) + ... 55 common frames omitted diff --git a/logs/dcsoft-system/info.2025-03-21.log b/logs/dcsoft-system/info.2025-03-21.log new file mode 100644 index 0000000..9037d0c --- /dev/null +++ b/logs/dcsoft-system/info.2025-03-21.log @@ -0,0 +1,153 @@ +22:25:55.134 [background-preinit] INFO o.h.v.i.util.Version - [,21] - HV000001: Hibernate Validator 6.2.5.Final +22:25:55.772 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of 1566228b-1985-423b-8b43-b96d51607ca9_config-0 +22:25:55.796 [main] INFO o.r.Reflections - [scan,232] - Reflections took 15 ms to scan 1 urls, producing 3 keys and 6 values +22:25:55.814 [main] INFO o.r.Reflections - [scan,232] - Reflections took 10 ms to scan 1 urls, producing 4 keys and 9 values +22:25:55.826 [main] INFO o.r.Reflections - [scan,232] - Reflections took 10 ms to scan 1 urls, producing 3 keys and 10 values +22:25:55.932 [main] INFO o.r.Reflections - [scan,232] - Reflections took 104 ms to scan 226 urls, producing 0 keys and 0 values +22:25:55.942 [main] INFO o.r.Reflections - [scan,232] - Reflections took 6 ms to scan 1 urls, producing 1 keys and 5 values +22:25:55.950 [main] INFO o.r.Reflections - [scan,232] - Reflections took 6 ms to scan 1 urls, producing 1 keys and 7 values +22:25:55.957 [main] INFO o.r.Reflections - [scan,232] - Reflections took 6 ms to scan 1 urls, producing 2 keys and 8 values +22:25:56.077 [main] INFO o.r.Reflections - [scan,232] - Reflections took 116 ms to scan 226 urls, producing 0 keys and 0 values +22:25:56.077 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [1566228b-1985-423b-8b43-b96d51607ca9_config-0] RpcClient init label, labels = {module=config, Vipserver-Tag=null, source=sdk, Amory-Tag=null, Location-Tag=null, taskId=0, AppName=unknown} +22:25:56.078 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [1566228b-1985-423b-8b43-b96d51607ca9_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$336/1267042315 +22:25:56.078 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [1566228b-1985-423b-8b43-b96d51607ca9_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$337/1335061928 +22:25:56.078 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [1566228b-1985-423b-8b43-b96d51607ca9_config-0] Registry connection listener to current client:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$1 +22:25:56.079 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [1566228b-1985-423b-8b43-b96d51607ca9_config-0] RpcClient init, ServerListFactory = com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$2 +22:25:56.084 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [1566228b-1985-423b-8b43-b96d51607ca9_config-0] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +22:25:57.447 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [1566228b-1985-423b-8b43-b96d51607ca9_config-0] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1742567157232_127.0.0.1_49758 +22:25:57.447 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [1566228b-1985-423b-8b43-b96d51607ca9_config-0] Notify connected event to listeners. +22:25:57.447 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [1566228b-1985-423b-8b43-b96d51607ca9_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +22:25:57.448 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [1566228b-1985-423b-8b43-b96d51607ca9_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$345/353891891 +22:25:57.529 [main] INFO c.d.s.DCSSystemApplication - [logStartupProfileInfo,637] - The following 1 profile is active: "dev" +22:25:59.332 [main] INFO o.a.c.h.Http11NioProtocol - [log,173] - Initializing ProtocolHandler ["http-nio-9201"] +22:25:59.332 [main] INFO o.a.c.c.StandardService - [log,173] - Starting service [Tomcat] +22:25:59.333 [main] INFO o.a.c.c.StandardEngine - [log,173] - Starting Servlet engine: [Apache Tomcat/9.0.70] +22:25:59.510 [main] INFO o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring embedded WebApplicationContext +22:26:00.348 [main] INFO c.a.d.p.DruidDataSource - [init,996] - {dataSource-1,master} inited +22:26:00.349 [main] INFO c.b.d.d.DynamicRoutingDataSource - [addDataSource,154] - dynamic-datasource - add a datasource named [master] success +22:26:00.349 [main] INFO c.b.d.d.DynamicRoutingDataSource - [afterPropertiesSet,234] - dynamic-datasource initial loaded [1] datasource,primary datasource named [master] +22:26:12.385 [main] INFO c.b.d.d.DynamicRoutingDataSource - [destroy,211] - dynamic-datasource start closing .... +22:26:12.389 [main] INFO c.a.d.p.DruidDataSource - [close,2138] - {dataSource-1} closing ... +22:26:12.394 [main] INFO c.a.d.p.DruidDataSource - [close,2211] - {dataSource-1} closed +22:26:12.394 [main] INFO c.b.d.d.DynamicRoutingDataSource - [destroy,215] - dynamic-datasource all closed success,bye +22:26:12.395 [main] INFO o.a.c.c.StandardService - [log,173] - Stopping service [Tomcat] +22:29:40.395 [background-preinit] INFO o.h.v.i.util.Version - [,21] - HV000001: Hibernate Validator 6.2.5.Final +22:29:41.080 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of d0c8e5f7-7805-4d09-874c-b07c3bfec394_config-0 +22:29:41.113 [main] INFO o.r.Reflections - [scan,232] - Reflections took 22 ms to scan 1 urls, producing 3 keys and 6 values +22:29:41.128 [main] INFO o.r.Reflections - [scan,232] - Reflections took 8 ms to scan 1 urls, producing 4 keys and 9 values +22:29:41.137 [main] INFO o.r.Reflections - [scan,232] - Reflections took 7 ms to scan 1 urls, producing 3 keys and 10 values +22:29:41.245 [main] INFO o.r.Reflections - [scan,232] - Reflections took 106 ms to scan 226 urls, producing 0 keys and 0 values +22:29:41.251 [main] INFO o.r.Reflections - [scan,232] - Reflections took 6 ms to scan 1 urls, producing 1 keys and 5 values +22:29:41.258 [main] INFO o.r.Reflections - [scan,232] - Reflections took 6 ms to scan 1 urls, producing 1 keys and 7 values +22:29:41.266 [main] INFO o.r.Reflections - [scan,232] - Reflections took 6 ms to scan 1 urls, producing 2 keys and 8 values +22:29:41.438 [main] INFO o.r.Reflections - [scan,232] - Reflections took 171 ms to scan 226 urls, producing 0 keys and 0 values +22:29:41.440 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [d0c8e5f7-7805-4d09-874c-b07c3bfec394_config-0] RpcClient init label, labels = {module=config, Vipserver-Tag=null, source=sdk, Amory-Tag=null, Location-Tag=null, taskId=0, AppName=unknown} +22:29:41.441 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [d0c8e5f7-7805-4d09-874c-b07c3bfec394_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$336/1335061928 +22:29:41.441 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [d0c8e5f7-7805-4d09-874c-b07c3bfec394_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$337/1108706191 +22:29:41.441 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [d0c8e5f7-7805-4d09-874c-b07c3bfec394_config-0] Registry connection listener to current client:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$1 +22:29:41.442 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [d0c8e5f7-7805-4d09-874c-b07c3bfec394_config-0] RpcClient init, ServerListFactory = com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$2 +22:29:41.450 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [d0c8e5f7-7805-4d09-874c-b07c3bfec394_config-0] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +22:29:43.423 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [d0c8e5f7-7805-4d09-874c-b07c3bfec394_config-0] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1742567383168_127.0.0.1_50001 +22:29:43.424 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [d0c8e5f7-7805-4d09-874c-b07c3bfec394_config-0] Notify connected event to listeners. +22:29:43.424 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [d0c8e5f7-7805-4d09-874c-b07c3bfec394_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +22:29:43.425 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [d0c8e5f7-7805-4d09-874c-b07c3bfec394_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$345/1340086275 +22:29:43.555 [main] INFO c.d.s.DCSSystemApplication - [logStartupProfileInfo,637] - The following 1 profile is active: "dev" +22:29:45.279 [main] INFO o.a.c.h.Http11NioProtocol - [log,173] - Initializing ProtocolHandler ["http-nio-9201"] +22:29:45.280 [main] INFO o.a.c.c.StandardService - [log,173] - Starting service [Tomcat] +22:29:45.280 [main] INFO o.a.c.c.StandardEngine - [log,173] - Starting Servlet engine: [Apache Tomcat/9.0.70] +22:29:45.455 [main] INFO o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring embedded WebApplicationContext +22:29:46.347 [main] INFO c.a.d.p.DruidDataSource - [init,996] - {dataSource-1,master} inited +22:29:46.348 [main] INFO c.b.d.d.DynamicRoutingDataSource - [addDataSource,154] - dynamic-datasource - add a datasource named [master] success +22:29:46.348 [main] INFO c.b.d.d.DynamicRoutingDataSource - [afterPropertiesSet,234] - dynamic-datasource initial loaded [1] datasource,primary datasource named [master] +22:29:49.016 [main] INFO c.a.c.s.SentinelWebMvcConfigurer - [addInterceptors,52] - [Sentinel Starter] register SentinelWebInterceptor with urlPatterns: [/**]. +22:29:50.959 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of a626541d-6152-446d-8fb5-f6bddf3ed46c +22:29:50.960 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a626541d-6152-446d-8fb5-f6bddf3ed46c] RpcClient init label, labels = {module=naming, source=sdk} +22:29:50.961 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a626541d-6152-446d-8fb5-f6bddf3ed46c] RpcClient init, ServerListFactory = com.alibaba.nacos.client.naming.core.ServerListManager +22:29:50.961 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a626541d-6152-446d-8fb5-f6bddf3ed46c] Registry connection listener to current client:com.alibaba.nacos.client.naming.remote.gprc.redo.NamingGrpcRedoService +22:29:50.962 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a626541d-6152-446d-8fb5-f6bddf3ed46c] Register server push request handler:com.alibaba.nacos.client.naming.remote.gprc.NamingPushRequestHandler +22:29:50.962 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a626541d-6152-446d-8fb5-f6bddf3ed46c] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +22:29:51.080 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a626541d-6152-446d-8fb5-f6bddf3ed46c] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1742567390967_127.0.0.1_50037 +22:29:51.080 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a626541d-6152-446d-8fb5-f6bddf3ed46c] Notify connected event to listeners. +22:29:51.080 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a626541d-6152-446d-8fb5-f6bddf3ed46c] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +22:29:51.081 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a626541d-6152-446d-8fb5-f6bddf3ed46c] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$345/1340086275 +22:29:51.111 [main] INFO o.a.c.h.Http11NioProtocol - [log,173] - Starting ProtocolHandler ["http-nio-9201"] +22:29:51.127 [main] INFO c.a.c.n.r.NacosServiceRegistry - [register,75] - nacos registry, DEFAULT_GROUP dcsoft-system 192.168.0.104:9201 register finished +22:29:51.693 [nacos-grpc-client-executor-8] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a626541d-6152-446d-8fb5-f6bddf3ed46c] Receive server push request, request = NotifySubscriberRequest, requestId = 8 +22:29:51.697 [nacos-grpc-client-executor-8] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a626541d-6152-446d-8fb5-f6bddf3ed46c] Ack server push request, request = NotifySubscriberRequest, requestId = 8 +22:29:52.332 [main] INFO c.d.s.DCSSystemApplication - [logStarted,61] - Started DCSSystemApplication in 12.611 seconds (JVM running for 13.509) +22:29:52.341 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-system-dev.yml, group=DEFAULT_GROUP +22:29:52.341 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-system, group=DEFAULT_GROUP +22:29:52.342 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-system.yml, group=DEFAULT_GROUP +22:29:53.363 [RMI TCP Connection(5)-192.168.0.104] INFO o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring DispatcherServlet 'dispatcherServlet' +22:29:57.680 [SpringApplicationShutdownHook] INFO c.a.c.n.r.NacosServiceRegistry - [deregister,94] - De-registering from Nacos Server now... +22:29:57.695 [SpringApplicationShutdownHook] INFO c.a.c.n.r.NacosServiceRegistry - [deregister,114] - De-registration finished. +22:29:58.237 [nacos-grpc-client-executor-14] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a626541d-6152-446d-8fb5-f6bddf3ed46c] Receive server push request, request = NotifySubscriberRequest, requestId = 9 +22:29:58.239 [nacos-grpc-client-executor-14] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [a626541d-6152-446d-8fb5-f6bddf3ed46c] Ack server push request, request = NotifySubscriberRequest, requestId = 9 +22:29:58.347 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [shutdown,454] - Shutdown rpc client, set status to shutdown +22:29:58.348 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [shutdown,456] - Shutdown client event executor java.util.concurrent.ScheduledThreadPoolExecutor@239f678b[Running, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 0] +22:29:58.348 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [closeConnection,591] - Close current connection 1742567390967_127.0.0.1_50037 +22:29:58.351 [nacos-grpc-client-executor-15] INFO c.a.n.c.r.c.g.GrpcClient - [printIfInfoEnabled,60] - [1742567390967_127.0.0.1_50037]Ignore complete event,isRunning:false,isAbandon=false +22:29:58.357 [SpringApplicationShutdownHook] INFO c.a.n.c.r.c.g.GrpcClient - [shutdown,85] - Shutdown grpc executor java.util.concurrent.ThreadPoolExecutor@1a6bb898[Running, pool size = 16, active threads = 0, queued tasks = 0, completed tasks = 16] +22:29:58.537 [SpringApplicationShutdownHook] INFO c.b.d.d.DynamicRoutingDataSource - [destroy,211] - dynamic-datasource start closing .... +22:29:58.553 [SpringApplicationShutdownHook] INFO c.a.d.p.DruidDataSource - [close,2138] - {dataSource-1} closing ... +22:29:58.578 [SpringApplicationShutdownHook] INFO c.a.d.p.DruidDataSource - [close,2211] - {dataSource-1} closed +22:29:58.579 [SpringApplicationShutdownHook] INFO c.b.d.d.DynamicRoutingDataSource - [destroy,215] - dynamic-datasource all closed success,bye +22:39:39.438 [background-preinit] INFO o.h.v.i.util.Version - [,21] - HV000001: Hibernate Validator 6.2.5.Final +22:39:40.217 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of b5ee788f-a92b-4e87-9c4f-b00cd9da5f79_config-0 +22:39:40.245 [main] INFO o.r.Reflections - [scan,232] - Reflections took 18 ms to scan 1 urls, producing 3 keys and 6 values +22:39:40.262 [main] INFO o.r.Reflections - [scan,232] - Reflections took 9 ms to scan 1 urls, producing 4 keys and 9 values +22:39:40.273 [main] INFO o.r.Reflections - [scan,232] - Reflections took 10 ms to scan 1 urls, producing 3 keys and 10 values +22:39:40.374 [main] INFO o.r.Reflections - [scan,232] - Reflections took 99 ms to scan 226 urls, producing 0 keys and 0 values +22:39:40.381 [main] INFO o.r.Reflections - [scan,232] - Reflections took 6 ms to scan 1 urls, producing 1 keys and 5 values +22:39:40.388 [main] INFO o.r.Reflections - [scan,232] - Reflections took 5 ms to scan 1 urls, producing 1 keys and 7 values +22:39:40.395 [main] INFO o.r.Reflections - [scan,232] - Reflections took 5 ms to scan 1 urls, producing 2 keys and 8 values +22:39:40.500 [main] INFO o.r.Reflections - [scan,232] - Reflections took 103 ms to scan 226 urls, producing 0 keys and 0 values +22:39:40.501 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b5ee788f-a92b-4e87-9c4f-b00cd9da5f79_config-0] RpcClient init label, labels = {module=config, Vipserver-Tag=null, source=sdk, Amory-Tag=null, Location-Tag=null, taskId=0, AppName=unknown} +22:39:40.501 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b5ee788f-a92b-4e87-9c4f-b00cd9da5f79_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$336/2024711353 +22:39:40.501 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b5ee788f-a92b-4e87-9c4f-b00cd9da5f79_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$337/711310213 +22:39:40.502 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b5ee788f-a92b-4e87-9c4f-b00cd9da5f79_config-0] Registry connection listener to current client:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$1 +22:39:40.502 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b5ee788f-a92b-4e87-9c4f-b00cd9da5f79_config-0] RpcClient init, ServerListFactory = com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$2 +22:39:40.506 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b5ee788f-a92b-4e87-9c4f-b00cd9da5f79_config-0] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +22:39:41.745 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b5ee788f-a92b-4e87-9c4f-b00cd9da5f79_config-0] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1742567981544_127.0.0.1_50557 +22:39:41.746 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b5ee788f-a92b-4e87-9c4f-b00cd9da5f79_config-0] Notify connected event to listeners. +22:39:41.747 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b5ee788f-a92b-4e87-9c4f-b00cd9da5f79_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +22:39:41.748 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [b5ee788f-a92b-4e87-9c4f-b00cd9da5f79_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$345/70978270 +22:39:41.814 [main] INFO c.d.s.DCSSystemApplication - [logStartupProfileInfo,637] - The following 1 profile is active: "dev" +22:39:43.350 [main] INFO o.a.c.h.Http11NioProtocol - [log,173] - Initializing ProtocolHandler ["http-nio-9201"] +22:39:43.350 [main] INFO o.a.c.c.StandardService - [log,173] - Starting service [Tomcat] +22:39:43.350 [main] INFO o.a.c.c.StandardEngine - [log,173] - Starting Servlet engine: [Apache Tomcat/9.0.70] +22:39:43.473 [main] INFO o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring embedded WebApplicationContext +22:39:44.323 [main] INFO c.a.d.p.DruidDataSource - [init,996] - {dataSource-1,master} inited +22:39:44.324 [main] INFO c.b.d.d.DynamicRoutingDataSource - [addDataSource,154] - dynamic-datasource - add a datasource named [master] success +22:39:44.324 [main] INFO c.b.d.d.DynamicRoutingDataSource - [afterPropertiesSet,234] - dynamic-datasource initial loaded [1] datasource,primary datasource named [master] +22:39:46.782 [main] INFO c.a.c.s.SentinelWebMvcConfigurer - [addInterceptors,52] - [Sentinel Starter] register SentinelWebInterceptor with urlPatterns: [/**]. +22:39:48.556 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of 99060f22-f218-4a4a-923a-05197324ee84 +22:39:48.557 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [99060f22-f218-4a4a-923a-05197324ee84] RpcClient init label, labels = {module=naming, source=sdk} +22:39:48.558 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [99060f22-f218-4a4a-923a-05197324ee84] RpcClient init, ServerListFactory = com.alibaba.nacos.client.naming.core.ServerListManager +22:39:48.558 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [99060f22-f218-4a4a-923a-05197324ee84] Registry connection listener to current client:com.alibaba.nacos.client.naming.remote.gprc.redo.NamingGrpcRedoService +22:39:48.558 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [99060f22-f218-4a4a-923a-05197324ee84] Register server push request handler:com.alibaba.nacos.client.naming.remote.gprc.NamingPushRequestHandler +22:39:48.558 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [99060f22-f218-4a4a-923a-05197324ee84] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +22:39:48.679 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [99060f22-f218-4a4a-923a-05197324ee84] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1742567988564_127.0.0.1_50591 +22:39:48.680 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [99060f22-f218-4a4a-923a-05197324ee84] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +22:39:48.681 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [99060f22-f218-4a4a-923a-05197324ee84] Notify connected event to listeners. +22:39:48.682 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [99060f22-f218-4a4a-923a-05197324ee84] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$345/70978270 +22:39:48.713 [main] INFO o.a.c.h.Http11NioProtocol - [log,173] - Starting ProtocolHandler ["http-nio-9201"] +22:39:48.729 [main] INFO c.a.c.n.r.NacosServiceRegistry - [register,75] - nacos registry, DEFAULT_GROUP dcsoft-system 192.168.0.104:9201 register finished +22:39:49.205 [nacos-grpc-client-executor-6] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [99060f22-f218-4a4a-923a-05197324ee84] Receive server push request, request = NotifySubscriberRequest, requestId = 15 +22:39:49.209 [nacos-grpc-client-executor-6] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [99060f22-f218-4a4a-923a-05197324ee84] Ack server push request, request = NotifySubscriberRequest, requestId = 15 +22:39:49.933 [main] INFO c.d.s.DCSSystemApplication - [logStarted,61] - Started DCSSystemApplication in 11.46 seconds (JVM running for 12.359) +22:39:49.939 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-system-dev.yml, group=DEFAULT_GROUP +22:39:49.940 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-system, group=DEFAULT_GROUP +22:39:49.940 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-system.yml, group=DEFAULT_GROUP +22:39:50.907 [RMI TCP Connection(3)-192.168.0.104] INFO o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring DispatcherServlet 'dispatcherServlet' +22:40:29.586 [SpringApplicationShutdownHook] INFO c.a.c.n.r.NacosServiceRegistry - [deregister,94] - De-registering from Nacos Server now... +22:40:29.591 [SpringApplicationShutdownHook] INFO c.a.c.n.r.NacosServiceRegistry - [deregister,114] - De-registration finished. +22:40:29.922 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [shutdown,454] - Shutdown rpc client, set status to shutdown +22:40:29.922 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [shutdown,456] - Shutdown client event executor java.util.concurrent.ScheduledThreadPoolExecutor@2bc641e4[Running, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 0] +22:40:29.922 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [closeConnection,591] - Close current connection 1742567988564_127.0.0.1_50591 +22:40:29.924 [nacos-grpc-client-executor-21] INFO c.a.n.c.r.c.g.GrpcClient - [printIfInfoEnabled,60] - [1742567988564_127.0.0.1_50591]Ignore complete event,isRunning:false,isAbandon=false +22:40:29.927 [SpringApplicationShutdownHook] INFO c.a.n.c.r.c.g.GrpcClient - [shutdown,85] - Shutdown grpc executor java.util.concurrent.ThreadPoolExecutor@184fb3f5[Running, pool size = 6, active threads = 0, queued tasks = 0, completed tasks = 22] +22:40:30.091 [SpringApplicationShutdownHook] INFO c.b.d.d.DynamicRoutingDataSource - [destroy,211] - dynamic-datasource start closing .... +22:40:30.094 [SpringApplicationShutdownHook] INFO c.a.d.p.DruidDataSource - [close,2138] - {dataSource-1} closing ... +22:40:30.100 [SpringApplicationShutdownHook] INFO c.a.d.p.DruidDataSource - [close,2211] - {dataSource-1} closed +22:40:30.100 [SpringApplicationShutdownHook] INFO c.b.d.d.DynamicRoutingDataSource - [destroy,215] - dynamic-datasource all closed success,bye diff --git a/logs/dcsoft-system/info.2025-03-22.log b/logs/dcsoft-system/info.2025-03-22.log new file mode 100644 index 0000000..3b5ac99 --- /dev/null +++ b/logs/dcsoft-system/info.2025-03-22.log @@ -0,0 +1,149 @@ +17:38:10.718 [background-preinit] INFO o.h.v.i.util.Version - [,21] - HV000001: Hibernate Validator 6.2.5.Final +17:38:11.429 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of 05a7ea6b-9b07-4905-8a19-736ef0c1bbff_config-0 +17:38:11.461 [main] INFO o.r.Reflections - [scan,232] - Reflections took 20 ms to scan 1 urls, producing 3 keys and 6 values +17:38:11.485 [main] INFO o.r.Reflections - [scan,232] - Reflections took 12 ms to scan 1 urls, producing 4 keys and 9 values +17:38:11.493 [main] INFO o.r.Reflections - [scan,232] - Reflections took 6 ms to scan 1 urls, producing 3 keys and 10 values +17:38:11.637 [main] INFO o.r.Reflections - [scan,232] - Reflections took 142 ms to scan 227 urls, producing 0 keys and 0 values +17:38:11.646 [main] INFO o.r.Reflections - [scan,232] - Reflections took 6 ms to scan 1 urls, producing 1 keys and 5 values +17:38:11.657 [main] INFO o.r.Reflections - [scan,232] - Reflections took 9 ms to scan 1 urls, producing 1 keys and 7 values +17:38:11.665 [main] INFO o.r.Reflections - [scan,232] - Reflections took 6 ms to scan 1 urls, producing 2 keys and 8 values +17:38:11.779 [main] INFO o.r.Reflections - [scan,232] - Reflections took 112 ms to scan 227 urls, producing 0 keys and 0 values +17:38:11.782 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [05a7ea6b-9b07-4905-8a19-736ef0c1bbff_config-0] RpcClient init label, labels = {module=config, Vipserver-Tag=null, source=sdk, Amory-Tag=null, Location-Tag=null, taskId=0, AppName=unknown} +17:38:11.782 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [05a7ea6b-9b07-4905-8a19-736ef0c1bbff_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$336/1960514242 +17:38:11.782 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [05a7ea6b-9b07-4905-8a19-736ef0c1bbff_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$337/804347788 +17:38:11.783 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [05a7ea6b-9b07-4905-8a19-736ef0c1bbff_config-0] Registry connection listener to current client:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$1 +17:38:11.783 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [05a7ea6b-9b07-4905-8a19-736ef0c1bbff_config-0] RpcClient init, ServerListFactory = com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$2 +17:38:11.789 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [05a7ea6b-9b07-4905-8a19-736ef0c1bbff_config-0] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +17:38:13.216 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [05a7ea6b-9b07-4905-8a19-736ef0c1bbff_config-0] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1742636293049_127.0.0.1_56908 +17:38:13.217 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [05a7ea6b-9b07-4905-8a19-736ef0c1bbff_config-0] Notify connected event to listeners. +17:38:13.217 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [05a7ea6b-9b07-4905-8a19-736ef0c1bbff_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +17:38:13.217 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [05a7ea6b-9b07-4905-8a19-736ef0c1bbff_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$345/1145023109 +17:38:13.313 [main] INFO c.d.s.DCSSystemApplication - [logStartupProfileInfo,637] - The following 1 profile is active: "dev" +17:38:15.167 [main] INFO o.a.c.h.Http11NioProtocol - [log,173] - Initializing ProtocolHandler ["http-nio-9201"] +17:38:15.168 [main] INFO o.a.c.c.StandardService - [log,173] - Starting service [Tomcat] +17:38:15.168 [main] INFO o.a.c.c.StandardEngine - [log,173] - Starting Servlet engine: [Apache Tomcat/9.0.70] +17:38:15.296 [main] INFO o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring embedded WebApplicationContext +17:38:17.599 [main] INFO c.a.d.p.DruidDataSource - [init,996] - {dataSource-1,master} inited +17:38:17.630 [main] INFO o.a.c.c.StandardService - [log,173] - Stopping service [Tomcat] +17:39:01.065 [background-preinit] INFO o.h.v.i.util.Version - [,21] - HV000001: Hibernate Validator 6.2.5.Final +17:39:01.811 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of 95c25037-5b0c-42fd-9a81-acec49b6762d_config-0 +17:39:01.845 [main] INFO o.r.Reflections - [scan,232] - Reflections took 22 ms to scan 1 urls, producing 3 keys and 6 values +17:39:01.869 [main] INFO o.r.Reflections - [scan,232] - Reflections took 14 ms to scan 1 urls, producing 4 keys and 9 values +17:39:01.881 [main] INFO o.r.Reflections - [scan,232] - Reflections took 9 ms to scan 1 urls, producing 3 keys and 10 values +17:39:01.999 [main] INFO o.r.Reflections - [scan,232] - Reflections took 114 ms to scan 227 urls, producing 0 keys and 0 values +17:39:02.005 [main] INFO o.r.Reflections - [scan,232] - Reflections took 6 ms to scan 1 urls, producing 1 keys and 5 values +17:39:02.016 [main] INFO o.r.Reflections - [scan,232] - Reflections took 9 ms to scan 1 urls, producing 1 keys and 7 values +17:39:02.027 [main] INFO o.r.Reflections - [scan,232] - Reflections took 7 ms to scan 1 urls, producing 2 keys and 8 values +17:39:02.139 [main] INFO o.r.Reflections - [scan,232] - Reflections took 110 ms to scan 227 urls, producing 0 keys and 0 values +17:39:02.141 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [95c25037-5b0c-42fd-9a81-acec49b6762d_config-0] RpcClient init label, labels = {module=config, Vipserver-Tag=null, source=sdk, Amory-Tag=null, Location-Tag=null, taskId=0, AppName=unknown} +17:39:02.142 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [95c25037-5b0c-42fd-9a81-acec49b6762d_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$336/967643830 +17:39:02.142 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [95c25037-5b0c-42fd-9a81-acec49b6762d_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$337/1320443884 +17:39:02.143 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [95c25037-5b0c-42fd-9a81-acec49b6762d_config-0] Registry connection listener to current client:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$1 +17:39:02.144 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [95c25037-5b0c-42fd-9a81-acec49b6762d_config-0] RpcClient init, ServerListFactory = com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$2 +17:39:02.149 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [95c25037-5b0c-42fd-9a81-acec49b6762d_config-0] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +17:39:03.756 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [95c25037-5b0c-42fd-9a81-acec49b6762d_config-0] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1742636343579_127.0.0.1_57001 +17:39:03.758 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [95c25037-5b0c-42fd-9a81-acec49b6762d_config-0] Notify connected event to listeners. +17:39:03.760 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [95c25037-5b0c-42fd-9a81-acec49b6762d_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +17:39:03.761 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [95c25037-5b0c-42fd-9a81-acec49b6762d_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$345/1779378259 +17:39:03.872 [main] INFO c.d.s.DCSSystemApplication - [logStartupProfileInfo,637] - The following 1 profile is active: "dev" +17:39:05.751 [main] INFO o.a.c.h.Http11NioProtocol - [log,173] - Initializing ProtocolHandler ["http-nio-9201"] +17:39:05.751 [main] INFO o.a.c.c.StandardService - [log,173] - Starting service [Tomcat] +17:39:05.752 [main] INFO o.a.c.c.StandardEngine - [log,173] - Starting Servlet engine: [Apache Tomcat/9.0.70] +17:39:05.892 [main] INFO o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring embedded WebApplicationContext +17:39:06.978 [main] INFO c.a.d.p.DruidDataSource - [init,996] - {dataSource-1,master} inited +17:39:06.979 [main] INFO c.b.d.d.DynamicRoutingDataSource - [addDataSource,154] - dynamic-datasource - add a datasource named [master] success +17:39:06.979 [main] INFO c.b.d.d.DynamicRoutingDataSource - [afterPropertiesSet,234] - dynamic-datasource initial loaded [1] datasource,primary datasource named [master] +17:39:16.797 [main] INFO c.a.c.s.SentinelWebMvcConfigurer - [addInterceptors,52] - [Sentinel Starter] register SentinelWebInterceptor with urlPatterns: [/**]. +17:39:24.593 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of fe21c058-434e-4c68-847e-d29c75106549 +17:39:24.594 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [fe21c058-434e-4c68-847e-d29c75106549] RpcClient init label, labels = {module=naming, source=sdk} +17:39:24.600 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [fe21c058-434e-4c68-847e-d29c75106549] RpcClient init, ServerListFactory = com.alibaba.nacos.client.naming.core.ServerListManager +17:39:24.601 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [fe21c058-434e-4c68-847e-d29c75106549] Registry connection listener to current client:com.alibaba.nacos.client.naming.remote.gprc.redo.NamingGrpcRedoService +17:39:24.602 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [fe21c058-434e-4c68-847e-d29c75106549] Register server push request handler:com.alibaba.nacos.client.naming.remote.gprc.NamingPushRequestHandler +17:39:24.604 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [fe21c058-434e-4c68-847e-d29c75106549] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +17:39:24.725 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [fe21c058-434e-4c68-847e-d29c75106549] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1742636364612_127.0.0.1_57051 +17:39:24.725 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [fe21c058-434e-4c68-847e-d29c75106549] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +17:39:24.725 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [fe21c058-434e-4c68-847e-d29c75106549] Notify connected event to listeners. +17:39:24.725 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [fe21c058-434e-4c68-847e-d29c75106549] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$345/1779378259 +17:39:24.824 [main] INFO o.a.c.h.Http11NioProtocol - [log,173] - Starting ProtocolHandler ["http-nio-9201"] +17:39:24.890 [main] INFO c.a.c.n.r.NacosServiceRegistry - [register,75] - nacos registry, DEFAULT_GROUP dcsoft-system 192.168.0.104:9201 register finished +17:39:25.400 [nacos-grpc-client-executor-6] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [fe21c058-434e-4c68-847e-d29c75106549] Receive server push request, request = NotifySubscriberRequest, requestId = 5 +17:39:25.421 [nacos-grpc-client-executor-6] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [fe21c058-434e-4c68-847e-d29c75106549] Ack server push request, request = NotifySubscriberRequest, requestId = 5 +17:39:30.268 [main] INFO c.d.s.DCSSystemApplication - [logStarted,61] - Started DCSSystemApplication in 29.958 seconds (JVM running for 30.915) +17:39:30.292 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-system-dev.yml, group=DEFAULT_GROUP +17:39:30.295 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-system, group=DEFAULT_GROUP +17:39:30.297 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-system.yml, group=DEFAULT_GROUP +17:39:32.970 [RMI TCP Connection(3)-192.168.0.104] INFO o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring DispatcherServlet 'dispatcherServlet' +17:39:41.209 [http-nio-9201-exec-1] INFO o.a.t.u.h.p.Cookie - [log,173] - A cookie header was received [Hm_lvt_be968d539e394cf45975b5117965eb10=1742280385,1742366828,1742451210,1742550106] that contained an invalid cookie. That cookie will be ignored. + Note: further occurrences of this error will be logged at DEBUG level. +17:42:35.825 [SpringApplicationShutdownHook] INFO c.a.c.n.r.NacosServiceRegistry - [deregister,94] - De-registering from Nacos Server now... +17:42:35.837 [SpringApplicationShutdownHook] INFO c.a.c.n.r.NacosServiceRegistry - [deregister,114] - De-registration finished. +17:42:36.178 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [shutdown,454] - Shutdown rpc client, set status to shutdown +17:42:36.178 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [shutdown,456] - Shutdown client event executor java.util.concurrent.ScheduledThreadPoolExecutor@4a4fcbd6[Running, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 0] +17:42:36.178 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [closeConnection,591] - Close current connection 1742636364612_127.0.0.1_57051 +17:42:36.180 [nacos-grpc-client-executor-49] INFO c.a.n.c.r.c.g.GrpcClient - [printIfInfoEnabled,60] - [1742636364612_127.0.0.1_57051]Ignore complete event,isRunning:false,isAbandon=false +17:42:36.188 [SpringApplicationShutdownHook] INFO c.a.n.c.r.c.g.GrpcClient - [shutdown,85] - Shutdown grpc executor java.util.concurrent.ThreadPoolExecutor@44112e67[Running, pool size = 4, active threads = 0, queued tasks = 0, completed tasks = 50] +17:42:36.334 [SpringApplicationShutdownHook] INFO c.b.d.d.DynamicRoutingDataSource - [destroy,211] - dynamic-datasource start closing .... +17:42:36.339 [SpringApplicationShutdownHook] INFO c.a.d.p.DruidDataSource - [close,2138] - {dataSource-1} closing ... +17:42:36.348 [SpringApplicationShutdownHook] INFO c.a.d.p.DruidDataSource - [close,2211] - {dataSource-1} closed +17:42:36.348 [SpringApplicationShutdownHook] INFO c.b.d.d.DynamicRoutingDataSource - [destroy,215] - dynamic-datasource all closed success,bye +17:42:42.942 [background-preinit] INFO o.h.v.i.util.Version - [,21] - HV000001: Hibernate Validator 6.2.5.Final +17:42:43.693 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of 775db382-3576-40c5-b1fa-2e0945f9c161_config-0 +17:42:43.735 [main] INFO o.r.Reflections - [scan,232] - Reflections took 24 ms to scan 1 urls, producing 3 keys and 6 values +17:42:43.767 [main] INFO o.r.Reflections - [scan,232] - Reflections took 15 ms to scan 1 urls, producing 4 keys and 9 values +17:42:43.776 [main] INFO o.r.Reflections - [scan,232] - Reflections took 7 ms to scan 1 urls, producing 3 keys and 10 values +17:42:43.891 [main] INFO o.r.Reflections - [scan,232] - Reflections took 113 ms to scan 227 urls, producing 0 keys and 0 values +17:42:43.897 [main] INFO o.r.Reflections - [scan,232] - Reflections took 6 ms to scan 1 urls, producing 1 keys and 5 values +17:42:43.907 [main] INFO o.r.Reflections - [scan,232] - Reflections took 8 ms to scan 1 urls, producing 1 keys and 7 values +17:42:43.914 [main] INFO o.r.Reflections - [scan,232] - Reflections took 5 ms to scan 1 urls, producing 2 keys and 8 values +17:42:44.021 [main] INFO o.r.Reflections - [scan,232] - Reflections took 105 ms to scan 227 urls, producing 0 keys and 0 values +17:42:44.023 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [775db382-3576-40c5-b1fa-2e0945f9c161_config-0] RpcClient init label, labels = {module=config, Vipserver-Tag=null, source=sdk, Amory-Tag=null, Location-Tag=null, taskId=0, AppName=unknown} +17:42:44.024 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [775db382-3576-40c5-b1fa-2e0945f9c161_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$336/71148574 +17:42:44.024 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [775db382-3576-40c5-b1fa-2e0945f9c161_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$337/344751179 +17:42:44.024 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [775db382-3576-40c5-b1fa-2e0945f9c161_config-0] Registry connection listener to current client:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$1 +17:42:44.025 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [775db382-3576-40c5-b1fa-2e0945f9c161_config-0] RpcClient init, ServerListFactory = com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$2 +17:42:44.032 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [775db382-3576-40c5-b1fa-2e0945f9c161_config-0] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +17:42:45.631 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [775db382-3576-40c5-b1fa-2e0945f9c161_config-0] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1742636565459_127.0.0.1_57310 +17:42:45.635 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [775db382-3576-40c5-b1fa-2e0945f9c161_config-0] Notify connected event to listeners. +17:42:45.636 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [775db382-3576-40c5-b1fa-2e0945f9c161_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +17:42:45.637 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [775db382-3576-40c5-b1fa-2e0945f9c161_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$345/1788662008 +17:42:45.737 [main] INFO c.d.s.DCSSystemApplication - [logStartupProfileInfo,637] - The following 1 profile is active: "dev" +17:42:47.693 [main] INFO o.a.c.h.Http11NioProtocol - [log,173] - Initializing ProtocolHandler ["http-nio-9201"] +17:42:47.694 [main] INFO o.a.c.c.StandardService - [log,173] - Starting service [Tomcat] +17:42:47.694 [main] INFO o.a.c.c.StandardEngine - [log,173] - Starting Servlet engine: [Apache Tomcat/9.0.70] +17:42:47.842 [main] INFO o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring embedded WebApplicationContext +17:42:48.622 [main] INFO c.a.d.p.DruidDataSource - [init,996] - {dataSource-1,master} inited +17:42:48.623 [main] INFO c.b.d.d.DynamicRoutingDataSource - [addDataSource,154] - dynamic-datasource - add a datasource named [master] success +17:42:48.624 [main] INFO c.b.d.d.DynamicRoutingDataSource - [afterPropertiesSet,234] - dynamic-datasource initial loaded [1] datasource,primary datasource named [master] +17:42:51.497 [main] INFO c.a.c.s.SentinelWebMvcConfigurer - [addInterceptors,52] - [Sentinel Starter] register SentinelWebInterceptor with urlPatterns: [/**]. +17:42:53.593 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of 9707a67b-3799-4d25-8681-a450316c741c +17:42:53.593 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [9707a67b-3799-4d25-8681-a450316c741c] RpcClient init label, labels = {module=naming, source=sdk} +17:42:53.595 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [9707a67b-3799-4d25-8681-a450316c741c] RpcClient init, ServerListFactory = com.alibaba.nacos.client.naming.core.ServerListManager +17:42:53.595 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [9707a67b-3799-4d25-8681-a450316c741c] Registry connection listener to current client:com.alibaba.nacos.client.naming.remote.gprc.redo.NamingGrpcRedoService +17:42:53.595 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [9707a67b-3799-4d25-8681-a450316c741c] Register server push request handler:com.alibaba.nacos.client.naming.remote.gprc.NamingPushRequestHandler +17:42:53.595 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [9707a67b-3799-4d25-8681-a450316c741c] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +17:42:53.713 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [9707a67b-3799-4d25-8681-a450316c741c] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1742636573599_127.0.0.1_57342 +17:42:53.713 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [9707a67b-3799-4d25-8681-a450316c741c] Notify connected event to listeners. +17:42:53.713 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [9707a67b-3799-4d25-8681-a450316c741c] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +17:42:53.714 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [9707a67b-3799-4d25-8681-a450316c741c] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$345/1788662008 +17:42:53.779 [main] INFO o.a.c.h.Http11NioProtocol - [log,173] - Starting ProtocolHandler ["http-nio-9201"] +17:42:53.802 [main] INFO c.a.c.n.r.NacosServiceRegistry - [register,75] - nacos registry, DEFAULT_GROUP dcsoft-system 192.168.0.104:9201 register finished +17:42:54.277 [nacos-grpc-client-executor-6] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [9707a67b-3799-4d25-8681-a450316c741c] Receive server push request, request = NotifySubscriberRequest, requestId = 10 +17:42:54.281 [nacos-grpc-client-executor-6] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [9707a67b-3799-4d25-8681-a450316c741c] Ack server push request, request = NotifySubscriberRequest, requestId = 10 +17:42:55.474 [main] INFO c.d.s.DCSSystemApplication - [logStarted,61] - Started DCSSystemApplication in 13.254 seconds (JVM running for 14.163) +17:42:55.482 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-system-dev.yml, group=DEFAULT_GROUP +17:42:55.483 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-system, group=DEFAULT_GROUP +17:42:55.483 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-system.yml, group=DEFAULT_GROUP +17:42:56.636 [RMI TCP Connection(3)-192.168.0.104] INFO o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring DispatcherServlet 'dispatcherServlet' +17:43:09.043 [http-nio-9201-exec-5] INFO o.a.t.u.h.p.Cookie - [log,173] - A cookie header was received [Hm_lvt_be968d539e394cf45975b5117965eb10=1742280385,1742366828,1742451210,1742550106;] that contained an invalid cookie. That cookie will be ignored. + Note: further occurrences of this error will be logged at DEBUG level. +17:50:39.900 [SpringApplicationShutdownHook] INFO c.a.c.n.r.NacosServiceRegistry - [deregister,94] - De-registering from Nacos Server now... +17:50:39.900 [SpringApplicationShutdownHook] INFO c.a.c.n.r.NacosServiceRegistry - [deregister,114] - De-registration finished. +17:50:40.235 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [shutdown,454] - Shutdown rpc client, set status to shutdown +17:50:40.235 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [shutdown,456] - Shutdown client event executor java.util.concurrent.ScheduledThreadPoolExecutor@2b070973[Running, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 0] +17:50:40.235 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [closeConnection,591] - Close current connection 1742636573599_127.0.0.1_57342 +17:50:40.244 [nacos-grpc-client-executor-109] INFO c.a.n.c.r.c.g.GrpcClient - [printIfInfoEnabled,60] - [1742636573599_127.0.0.1_57342]Ignore complete event,isRunning:false,isAbandon=false +17:50:40.246 [SpringApplicationShutdownHook] INFO c.a.n.c.r.c.g.GrpcClient - [shutdown,85] - Shutdown grpc executor java.util.concurrent.ThreadPoolExecutor@46b6231c[Running, pool size = 6, active threads = 0, queued tasks = 0, completed tasks = 110] +17:50:40.406 [SpringApplicationShutdownHook] INFO c.b.d.d.DynamicRoutingDataSource - [destroy,211] - dynamic-datasource start closing .... +17:50:40.408 [SpringApplicationShutdownHook] INFO c.a.d.p.DruidDataSource - [close,2138] - {dataSource-1} closing ... +17:50:40.408 [SpringApplicationShutdownHook] INFO c.a.d.p.DruidDataSource - [close,2211] - {dataSource-1} closed +17:50:40.408 [SpringApplicationShutdownHook] INFO c.b.d.d.DynamicRoutingDataSource - [destroy,215] - dynamic-datasource all closed success,bye diff --git a/logs/dcsoft-system/info.log b/logs/dcsoft-system/info.log new file mode 100644 index 0000000..250b4b2 --- /dev/null +++ b/logs/dcsoft-system/info.log @@ -0,0 +1,61 @@ +15:36:14.412 [background-preinit] INFO o.h.v.i.util.Version - [,21] - HV000001: Hibernate Validator 6.2.5.Final +15:36:15.179 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of 744865f7-d8d1-4783-9111-6ffd1848291a_config-0 +15:36:15.213 [main] INFO o.r.Reflections - [scan,232] - Reflections took 20 ms to scan 1 urls, producing 3 keys and 6 values +15:36:15.237 [main] INFO o.r.Reflections - [scan,232] - Reflections took 14 ms to scan 1 urls, producing 4 keys and 9 values +15:36:15.246 [main] INFO o.r.Reflections - [scan,232] - Reflections took 7 ms to scan 1 urls, producing 3 keys and 10 values +15:36:15.366 [main] INFO o.r.Reflections - [scan,232] - Reflections took 117 ms to scan 227 urls, producing 0 keys and 0 values +15:36:15.378 [main] INFO o.r.Reflections - [scan,232] - Reflections took 8 ms to scan 1 urls, producing 1 keys and 5 values +15:36:15.390 [main] INFO o.r.Reflections - [scan,232] - Reflections took 11 ms to scan 1 urls, producing 1 keys and 7 values +15:36:15.397 [main] INFO o.r.Reflections - [scan,232] - Reflections took 5 ms to scan 1 urls, producing 2 keys and 8 values +15:36:15.519 [main] INFO o.r.Reflections - [scan,232] - Reflections took 121 ms to scan 227 urls, producing 0 keys and 0 values +15:36:15.521 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [744865f7-d8d1-4783-9111-6ffd1848291a_config-0] RpcClient init label, labels = {module=config, Vipserver-Tag=null, source=sdk, Amory-Tag=null, Location-Tag=null, taskId=0, AppName=unknown} +15:36:15.521 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [744865f7-d8d1-4783-9111-6ffd1848291a_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$336/537524656 +15:36:15.522 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [744865f7-d8d1-4783-9111-6ffd1848291a_config-0] Register server push request handler:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$$Lambda$337/1356419559 +15:36:15.522 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [744865f7-d8d1-4783-9111-6ffd1848291a_config-0] Registry connection listener to current client:com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$1 +15:36:15.523 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [744865f7-d8d1-4783-9111-6ffd1848291a_config-0] RpcClient init, ServerListFactory = com.alibaba.nacos.client.config.impl.ClientWorker$ConfigRpcTransportClient$2 +15:36:15.529 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [744865f7-d8d1-4783-9111-6ffd1848291a_config-0] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +15:36:17.215 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [744865f7-d8d1-4783-9111-6ffd1848291a_config-0] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1745825777043_127.0.0.1_59851 +15:36:17.215 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [744865f7-d8d1-4783-9111-6ffd1848291a_config-0] Notify connected event to listeners. +15:36:17.215 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [744865f7-d8d1-4783-9111-6ffd1848291a_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +15:36:17.217 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [744865f7-d8d1-4783-9111-6ffd1848291a_config-0] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$345/50173263 +15:36:17.310 [main] INFO c.d.s.DCSSystemApplication - [logStartupProfileInfo,637] - The following 1 profile is active: "dev" +15:36:19.417 [main] INFO o.a.c.h.Http11NioProtocol - [log,173] - Initializing ProtocolHandler ["http-nio-9201"] +15:36:19.418 [main] INFO o.a.c.c.StandardService - [log,173] - Starting service [Tomcat] +15:36:19.418 [main] INFO o.a.c.c.StandardEngine - [log,173] - Starting Servlet engine: [Apache Tomcat/9.0.70] +15:36:19.557 [main] INFO o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring embedded WebApplicationContext +15:36:20.749 [main] INFO c.a.d.p.DruidDataSource - [init,996] - {dataSource-1,master} inited +15:36:20.750 [main] INFO c.b.d.d.DynamicRoutingDataSource - [addDataSource,154] - dynamic-datasource - add a datasource named [master] success +15:36:20.750 [main] INFO c.b.d.d.DynamicRoutingDataSource - [afterPropertiesSet,234] - dynamic-datasource initial loaded [1] datasource,primary datasource named [master] +15:36:25.326 [main] INFO c.a.c.s.SentinelWebMvcConfigurer - [addInterceptors,52] - [Sentinel Starter] register SentinelWebInterceptor with urlPatterns: [/**]. +15:36:27.505 [main] INFO c.a.n.c.r.client - [lambda$createClient$0,80] - [RpcClientFactory] create a new rpc client of 642c28ba-374e-4b68-b06d-70dc6bdaad2a +15:36:27.505 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [642c28ba-374e-4b68-b06d-70dc6bdaad2a] RpcClient init label, labels = {module=naming, source=sdk} +15:36:27.506 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [642c28ba-374e-4b68-b06d-70dc6bdaad2a] RpcClient init, ServerListFactory = com.alibaba.nacos.client.naming.core.ServerListManager +15:36:27.506 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [642c28ba-374e-4b68-b06d-70dc6bdaad2a] Registry connection listener to current client:com.alibaba.nacos.client.naming.remote.gprc.redo.NamingGrpcRedoService +15:36:27.507 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [642c28ba-374e-4b68-b06d-70dc6bdaad2a] Register server push request handler:com.alibaba.nacos.client.naming.remote.gprc.NamingPushRequestHandler +15:36:27.507 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [642c28ba-374e-4b68-b06d-70dc6bdaad2a] Try to connect to server on start up, server: {serverIp = '127.0.0.1', server main port = 8848} +15:36:27.619 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [642c28ba-374e-4b68-b06d-70dc6bdaad2a] Success to connect to server [127.0.0.1:8848] on start up, connectionId = 1745825787515_127.0.0.1_59915 +15:36:27.619 [com.alibaba.nacos.client.remote.worker] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [642c28ba-374e-4b68-b06d-70dc6bdaad2a] Notify connected event to listeners. +15:36:27.619 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [642c28ba-374e-4b68-b06d-70dc6bdaad2a] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$ConnectResetRequestHandler +15:36:27.620 [main] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [642c28ba-374e-4b68-b06d-70dc6bdaad2a] Register server push request handler:com.alibaba.nacos.common.remote.client.RpcClient$$Lambda$345/50173263 +15:36:27.686 [main] INFO o.a.c.h.Http11NioProtocol - [log,173] - Starting ProtocolHandler ["http-nio-9201"] +15:36:27.715 [main] INFO c.a.c.n.r.NacosServiceRegistry - [register,75] - nacos registry, DEFAULT_GROUP dcsoft-system 192.168.2.21:9201 register finished +15:36:28.182 [nacos-grpc-client-executor-6] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [642c28ba-374e-4b68-b06d-70dc6bdaad2a] Receive server push request, request = NotifySubscriberRequest, requestId = 27 +15:36:28.191 [nacos-grpc-client-executor-6] INFO c.a.n.c.r.client - [printIfInfoEnabled,60] - [642c28ba-374e-4b68-b06d-70dc6bdaad2a] Ack server push request, request = NotifySubscriberRequest, requestId = 27 +15:36:29.144 [main] INFO c.d.s.DCSSystemApplication - [logStarted,61] - Started DCSSystemApplication in 15.465 seconds (JVM running for 16.899) +15:36:29.163 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-system-dev.yml, group=DEFAULT_GROUP +15:36:29.164 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-system, group=DEFAULT_GROUP +15:36:29.166 [main] INFO c.a.c.n.r.NacosContextRefresher - [registerNacosListener,129] - [Nacos Config] Listening config: dataId=dcsoft-system.yml, group=DEFAULT_GROUP +15:36:29.523 [RMI TCP Connection(2)-192.168.2.21] INFO o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring DispatcherServlet 'dispatcherServlet' +15:36:56.800 [http-nio-9201-exec-9] INFO o.a.t.u.h.p.Cookie - [log,173] - A cookie header was received [Hm_lvt_be968d539e394cf45975b5117965eb10=1744178737,1744208190,1744250909,1744265525;] that contained an invalid cookie. That cookie will be ignored. + Note: further occurrences of this error will be logged at DEBUG level. +15:38:42.170 [SpringApplicationShutdownHook] INFO c.a.c.n.r.NacosServiceRegistry - [deregister,94] - De-registering from Nacos Server now... +15:38:42.189 [SpringApplicationShutdownHook] INFO c.a.c.n.r.NacosServiceRegistry - [deregister,114] - De-registration finished. +15:38:42.581 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [shutdown,454] - Shutdown rpc client, set status to shutdown +15:38:42.583 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [shutdown,456] - Shutdown client event executor java.util.concurrent.ScheduledThreadPoolExecutor@4a406acb[Running, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 0] +15:38:42.584 [SpringApplicationShutdownHook] INFO c.a.n.c.r.client - [closeConnection,591] - Close current connection 1745825787515_127.0.0.1_59915 +15:38:42.587 [nacos-grpc-client-executor-43] INFO c.a.n.c.r.c.g.GrpcClient - [printIfInfoEnabled,60] - [1745825787515_127.0.0.1_59915]Ignore complete event,isRunning:false,isAbandon=false +15:38:42.601 [SpringApplicationShutdownHook] INFO c.a.n.c.r.c.g.GrpcClient - [shutdown,85] - Shutdown grpc executor java.util.concurrent.ThreadPoolExecutor@284311a[Running, pool size = 4, active threads = 0, queued tasks = 0, completed tasks = 44] +15:38:42.826 [SpringApplicationShutdownHook] INFO c.b.d.d.DynamicRoutingDataSource - [destroy,211] - dynamic-datasource start closing .... +15:38:42.835 [SpringApplicationShutdownHook] INFO c.a.d.p.DruidDataSource - [close,2138] - {dataSource-1} closing ... +15:38:42.865 [SpringApplicationShutdownHook] INFO c.a.d.p.DruidDataSource - [close,2211] - {dataSource-1} closed +15:38:42.866 [SpringApplicationShutdownHook] INFO c.b.d.d.DynamicRoutingDataSource - [destroy,215] - dynamic-datasource all closed success,bye diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..f835af9 --- /dev/null +++ b/pom.xml @@ -0,0 +1,316 @@ + + + 4.0.0 + + com.dcsoft + dcsoft + 3.6.2 + + dcsoft + http://www.dcsoft.vip + 兴安园区微服务系统 + + + 3.6.2 + UTF-8 + UTF-8 + 1.8 + 2.7.7 + 2021.0.5 + 2021.0.4.0 + 2.7.10 + 3.0.0 + 1.6.2 + 1.27.2 + 2.3.3 + 1.4.6 + 1.2.16 + 3.5.2 + 2.11.0 + 2.3 + 2.0.23 + 0.9.1 + 8.2.2 + 4.1.2 + 5.8.11 + 2.14.2 + + 2.0.23 + 3.1.660 + + + + + + + + + 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.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + + com.github.tobato + fastdfs-client + ${tobato.version} + + + + + io.swagger + swagger-models + ${swagger.core.version} + + + io.swagger + swagger-annotations + ${swagger.core.version} + + + + + pro.fessional + kaptcha + ${kaptcha.version} + + + + + com.github.pagehelper + pagehelper-spring-boot-starter + ${pagehelper.boot.version} + + + + + commons-io + commons-io + ${commons.io.version} + + + + + org.apache.poi + poi-ooxml + ${poi.version} + + + + + org.apache.velocity + velocity-engine-core + ${velocity.version} + + + + + com.alibaba.fastjson2 + fastjson2 + ${fastjson.version} + + + + + io.jsonwebtoken + jjwt + ${jjwt.version} + + + + + com.alibaba + transmittable-thread-local + ${transmittable-thread-local.version} + + + + + com.dcsoft + dcsoft-common-core + ${dcsoft.version} + + + + + com.dcsoft + dcsoft-common-swagger + ${dcsoft.version} + + + + + com.dcsoft + dcsoft-common-security + ${dcsoft.version} + + + + + com.dcsoft + dcsoft-common-datascope + ${dcsoft.version} + + + + + com.dcsoft + dcsoft-common-datasource + ${dcsoft.version} + + + + + com.dcsoft + dcsoft-common-seata + ${dcsoft.version} + + + + + com.dcsoft + dcsoft-common-log + ${dcsoft.version} + + + + + com.dcsoft + dcsoft-common-redis + ${dcsoft.version} + + + + + com.dcsoft + dcsoft-common-sms + ${dcsoft.version} + + + + com.dcsoft + dcsoft-api-system + ${dcsoft.version} + + + + + cn.hutool + hutool-bom + ${hutool.version} + pom + import + + + + com.aliyun + dysmsapi20170525 + ${aliyun.sms.version} + + + + com.tencentcloudapi + tencentcloud-sdk-java-sms + ${tencent.sms.version} + + + + + + + dcsoft-auth + dcsoft-gateway + dcsoft-visual + dcsoft-modules + dcsoft-api + dcsoft-common + + pom + + + + + org.springframework.cloud + spring-cloud-starter-bootstrap + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + ${java.version} + ${java.version} + ${project.build.sourceEncoding} + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + + + + + public + aliyun nexus + https://maven.aliyun.com/repository/public + + true + + + + + + + public + aliyun nexus + https://maven.aliyun.com/repository/public + + true + + + false + + + + +