From 758cfbf0b9c675731b303ad03b5ca0e4996aa7bb Mon Sep 17 00:00:00 2001 From: "review512jwy@163.com" <“review512jwy@163.com”> Date: Fri, 11 Apr 2025 09:22:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 16 + document/cmd | 31 + document/db/init.sql | 140 +++ document/start.sh | 30 + document/update.sh | 17 + model2d3d-viewer-back-common/.gitignore | 15 + model2d3d-viewer-back-common/pom.xml | 35 + .../viewer/back/common/Constants.java | 18 + .../common/exception/BusinessException.java | 36 + .../common/exception/MsgCodeException.java | 26 + .../language/PropertySourceYumFactory.java | 26 + .../language/msg/MsgLanguageChange.java | 54 ++ .../back/common/language/msg/Msg_CN.java | 25 + .../back/common/language/msg/Msg_EN.java | 25 + .../back/common/language/msg/Msg_JP.java | 25 + .../back/common/response/BaseResponse.java | 51 + .../back/common/response/PageResponse.java | 66 ++ .../back/common/response/ResponseCode.java | 28 + .../common/response/SimpleDataResponse.java | 104 ++ .../resources/config/language/msg/msg_cn.yml | 38 + .../resources/config/language/msg/msg_en.yml | 38 + .../resources/config/language/msg/msg_jp.yml | 38 + model2d3d-viewer-back-controller/.gitignore | 15 + model2d3d-viewer-back-controller/dockerfile | 69 ++ model2d3d-viewer-back-controller/pom.xml | 350 +++++++ .../back/Model2d3dViewerApplication.java | 19 + .../viewer/back/configurator/ApiConfig.java | 65 ++ .../back/configurator/CorsConfigurer.java | 38 + .../back/configurator/CrosXssFilter.java | 78 ++ .../back/configurator/RequestWrapper.java | 92 ++ .../handler/GlobalExceptionHandler.java | 118 +++ .../interceptor/AccessApiInterceptor.java | 73 ++ .../interceptor/AccessRequired.java | 10 + .../back/controller/AccountController.java | 96 ++ .../back/controller/CommonController.java | 48 + .../back/controller/CompanyController.java | 126 +++ .../back/controller/HealthController.java | 37 + .../back/controller/RoleController.java | 133 +++ .../back/controller/UserController.java | 138 +++ .../src/main/resources/assembly.xml | 59 ++ .../resources/config/application.properties | 98 ++ .../main/resources/config/logback-boot.xml | 53 ++ .../main/resources/config/version.properties | 3 + model2d3d-viewer-back-dao/.gitignore | 15 + model2d3d-viewer-back-dao/pom.xml | 91 ++ .../viewer/back/dao/MyBatisPlusGenerator.java | 152 +++ .../back/dao/auto/BasicCompanyMapper.java | 17 + .../viewer/back/dao/auto/BasicMenuMapper.java | 17 + .../viewer/back/dao/auto/BasicRoleMapper.java | 17 + .../dao/auto/BasicRoleMenuRelationMapper.java | 17 + .../dao/auto/BasicRoleUserRelationMapper.java | 17 + .../viewer/back/dao/auto/BasicUserMapper.java | 17 + .../back/dao/auto/LoginHistoryMapper.java | 17 + .../back/dao/ex/BasicCompanyMapperExt.java | 32 + .../back/dao/ex/BasicRoleMapperExt.java | 26 + .../ex/BasicRoleMenuRelationMapperExt.java | 16 + .../ex/BasicRoleUserRelationMapperExt.java | 10 + .../back/dao/ex/BasicUserMapperExt.java | 27 + .../back/dao/ex/LoginHistoryMapperExt.java | 10 + .../mappers/auto/BasicCompanyMapper.xml | 20 + .../mappers/auto/BasicMenuMapper.xml | 23 + .../mappers/auto/BasicRoleMapper.xml | 23 + .../auto/BasicRoleMenuRelationMapper.xml | 18 + .../auto/BasicRoleUserRelationMapper.xml | 18 + .../mappers/auto/BasicUserMapper.xml | 32 + .../mappers/auto/LoginHistoryMapper.xml | 18 + .../mappers/ex/BasicCompanyMapperExt.xml | 72 ++ .../mappers/ex/BasicRoleMapperExt.xml | 68 ++ .../ex/BasicRoleMenuRelationMapperExt.xml | 24 + .../mappers/ex/BasicUserMapperExt.xml | 96 ++ .../main/resources/templates/entity.java.ftl | 61 ++ model2d3d-viewer-back-model/.gitignore | 15 + model2d3d-viewer-back-model/pom.xml | 56 ++ .../back/dto/BaseSearchNoCompanysParams.java | 25 + .../viewer/back/dto/BaseSearchParams.java | 23 + .../back/dto/account/CacheUserData.java | 23 + .../viewer/back/dto/account/LoginParam.java | 25 + .../back/dto/company/CompanySearchParams.java | 24 + .../back/dto/company/DeleteCompanyParams.java | 18 + .../back/dto/company/OptCompanyParams.java | 28 + .../viewer/back/dto/role/DeleteRoleParam.java | 20 + .../viewer/back/dto/role/OptRoleParam.java | 38 + .../back/dto/role/RolePageSearchParam.java | 21 + .../viewer/back/dto/user/DeleteUserParam.java | 20 + .../viewer/back/dto/user/ModifyPassword.java | 24 + .../viewer/back/dto/user/OptUserParam.java | 44 + .../viewer/back/dto/user/PageSearchParam.java | 20 + .../viewer/back/dto/user/ResetPassword.java | 23 + .../viewer/back/model/BasicCompany.java | 46 + .../viewer/back/model/BasicMenu.java | 58 ++ .../viewer/back/model/BasicRole.java | 58 ++ .../back/model/BasicRoleMenuRelation.java | 38 + .../back/model/BasicRoleUserRelation.java | 38 + .../viewer/back/model/BasicUser.java | 94 ++ .../viewer/back/model/LoginHistory.java | 38 + .../viewer/back/vo/TreeMenusDTO.java | 27 + .../back/vo/company/CompanyPageDTO.java | 25 + .../viewer/back/vo/role/RoleMenuDTO.java | 27 + .../viewer/back/vo/role/RolePageDTO.java | 25 + .../viewer/back/vo/user/UserInfoVO.java | 15 + .../viewer/back/vo/user/UserPageDTO.java | 43 + model2d3d-viewer-back-service/.gitignore | 15 + model2d3d-viewer-back-service/pom.xml | 55 ++ .../viewer/back/service/AccountService.java | 26 + .../viewer/back/service/CommonService.java | 14 + .../viewer/back/service/CompanyService.java | 33 + .../viewer/back/service/RoleService.java | 32 + .../viewer/back/service/UserService.java | 30 + .../back/service/captcha/CaptchaService.java | 31 + .../back/service/captcha/CaptchaVO.java | 18 + .../back/service/captcha/KaptchaConfig.java | 36 + .../viewer/back/service/common/CommonOpt.java | 89 ++ .../viewer/back/service/common/MenuTree.java | 69 ++ .../back/service/impl/AccountServiceImpl.java | 273 ++++++ .../back/service/impl/CommonServiceImpl.java | 60 ++ .../back/service/impl/CompanyServiceImpl.java | 295 ++++++ .../back/service/impl/RoleServiceImpl.java | 252 +++++ .../back/service/impl/UserServiceImpl.java | 363 +++++++ .../viewer/back/service/impl/JsonsTests.java | 21 + model2d3d-viewer-back-util/.gitignore | 15 + model2d3d-viewer-back-util/pom.xml | 85 ++ .../com/model2d3d/viewer/back/util/Arith.java | 165 ++++ .../viewer/back/util/CommonUtil.java | 763 +++++++++++++++ .../model2d3d/viewer/back/util/DESUtil.java | 192 ++++ .../model2d3d/viewer/back/util/DateUtil.java | 56 ++ .../model2d3d/viewer/back/util/FileUtil.java | 416 ++++++++ .../model2d3d/viewer/back/util/HttpUtil.java | 195 ++++ .../viewer/back/util/NetworkUtil.java | 72 ++ .../viewer/back/util/RandomNumberUtil.java | 43 + .../model2d3d/viewer/back/util/SendMail.java | 260 +++++ .../viewer/back/util/ServiceUtil.java | 125 +++ .../back/util/TimeIntervalSplitter.java | 36 + .../model2d3d/viewer/back/util/URLCoder.java | 54 ++ .../viewer/back/util/ValidatorUtil.java | 887 ++++++++++++++++++ .../viewer/back/util/async/OptAsync.java | 35 + .../viewer/back/util/aurora/TimeInterval.java | 10 + .../back/util/redis/RedisClusterConfig.java | 106 +++ .../back/util/redis/RedisSentinelConfig.java | 111 +++ .../util/redis/RedisStandaloneConfig.java | 106 +++ .../viewer/back/util/redis/RedisUtil.java | 505 ++++++++++ .../model2d3d/viewer/back/util/AppTest.java | 38 + .../viewer/back/util/NearestHourMinute.java | 33 + .../viewer/back/util/QuartileCalculator.java | 41 + .../com/model2d3d/viewer/back/util/Test.java | 89 ++ .../viewer/back/util/ValueSorter.java | 111 +++ pom.xml | 280 ++++++ readme.md | 39 + 147 files changed, 11130 insertions(+) create mode 100644 .gitignore create mode 100644 document/cmd create mode 100644 document/db/init.sql create mode 100644 document/start.sh create mode 100644 document/update.sh create mode 100644 model2d3d-viewer-back-common/.gitignore create mode 100644 model2d3d-viewer-back-common/pom.xml create mode 100644 model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/Constants.java create mode 100644 model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/exception/BusinessException.java create mode 100644 model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/exception/MsgCodeException.java create mode 100644 model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/language/PropertySourceYumFactory.java create mode 100644 model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/language/msg/MsgLanguageChange.java create mode 100644 model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/language/msg/Msg_CN.java create mode 100644 model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/language/msg/Msg_EN.java create mode 100644 model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/language/msg/Msg_JP.java create mode 100644 model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/response/BaseResponse.java create mode 100644 model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/response/PageResponse.java create mode 100644 model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/response/ResponseCode.java create mode 100644 model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/response/SimpleDataResponse.java create mode 100644 model2d3d-viewer-back-common/src/main/resources/config/language/msg/msg_cn.yml create mode 100644 model2d3d-viewer-back-common/src/main/resources/config/language/msg/msg_en.yml create mode 100644 model2d3d-viewer-back-common/src/main/resources/config/language/msg/msg_jp.yml create mode 100644 model2d3d-viewer-back-controller/.gitignore create mode 100644 model2d3d-viewer-back-controller/dockerfile create mode 100644 model2d3d-viewer-back-controller/pom.xml create mode 100644 model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/Model2d3dViewerApplication.java create mode 100644 model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/ApiConfig.java create mode 100644 model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/CorsConfigurer.java create mode 100644 model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/CrosXssFilter.java create mode 100644 model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/RequestWrapper.java create mode 100644 model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/handler/GlobalExceptionHandler.java create mode 100644 model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/interceptor/AccessApiInterceptor.java create mode 100644 model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/interceptor/AccessRequired.java create mode 100644 model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/controller/AccountController.java create mode 100644 model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/controller/CommonController.java create mode 100644 model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/controller/CompanyController.java create mode 100644 model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/controller/HealthController.java create mode 100644 model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/controller/RoleController.java create mode 100644 model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/controller/UserController.java create mode 100644 model2d3d-viewer-back-controller/src/main/resources/assembly.xml create mode 100644 model2d3d-viewer-back-controller/src/main/resources/config/application.properties create mode 100644 model2d3d-viewer-back-controller/src/main/resources/config/logback-boot.xml create mode 100644 model2d3d-viewer-back-controller/src/main/resources/config/version.properties create mode 100644 model2d3d-viewer-back-dao/.gitignore create mode 100644 model2d3d-viewer-back-dao/pom.xml create mode 100644 model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/MyBatisPlusGenerator.java create mode 100644 model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/BasicCompanyMapper.java create mode 100644 model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/BasicMenuMapper.java create mode 100644 model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/BasicRoleMapper.java create mode 100644 model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/BasicRoleMenuRelationMapper.java create mode 100644 model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/BasicRoleUserRelationMapper.java create mode 100644 model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/BasicUserMapper.java create mode 100644 model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/LoginHistoryMapper.java create mode 100644 model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/ex/BasicCompanyMapperExt.java create mode 100644 model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/ex/BasicRoleMapperExt.java create mode 100644 model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/ex/BasicRoleMenuRelationMapperExt.java create mode 100644 model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/ex/BasicRoleUserRelationMapperExt.java create mode 100644 model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/ex/BasicUserMapperExt.java create mode 100644 model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/ex/LoginHistoryMapperExt.java create mode 100644 model2d3d-viewer-back-dao/src/main/resources/mappers/auto/BasicCompanyMapper.xml create mode 100644 model2d3d-viewer-back-dao/src/main/resources/mappers/auto/BasicMenuMapper.xml create mode 100644 model2d3d-viewer-back-dao/src/main/resources/mappers/auto/BasicRoleMapper.xml create mode 100644 model2d3d-viewer-back-dao/src/main/resources/mappers/auto/BasicRoleMenuRelationMapper.xml create mode 100644 model2d3d-viewer-back-dao/src/main/resources/mappers/auto/BasicRoleUserRelationMapper.xml create mode 100644 model2d3d-viewer-back-dao/src/main/resources/mappers/auto/BasicUserMapper.xml create mode 100644 model2d3d-viewer-back-dao/src/main/resources/mappers/auto/LoginHistoryMapper.xml create mode 100644 model2d3d-viewer-back-dao/src/main/resources/mappers/ex/BasicCompanyMapperExt.xml create mode 100644 model2d3d-viewer-back-dao/src/main/resources/mappers/ex/BasicRoleMapperExt.xml create mode 100644 model2d3d-viewer-back-dao/src/main/resources/mappers/ex/BasicRoleMenuRelationMapperExt.xml create mode 100644 model2d3d-viewer-back-dao/src/main/resources/mappers/ex/BasicUserMapperExt.xml create mode 100644 model2d3d-viewer-back-dao/src/main/resources/templates/entity.java.ftl create mode 100644 model2d3d-viewer-back-model/.gitignore create mode 100644 model2d3d-viewer-back-model/pom.xml create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/BaseSearchNoCompanysParams.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/BaseSearchParams.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/account/CacheUserData.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/account/LoginParam.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/company/CompanySearchParams.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/company/DeleteCompanyParams.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/company/OptCompanyParams.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/role/DeleteRoleParam.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/role/OptRoleParam.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/role/RolePageSearchParam.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/user/DeleteUserParam.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/user/ModifyPassword.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/user/OptUserParam.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/user/PageSearchParam.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/user/ResetPassword.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/BasicCompany.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/BasicMenu.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/BasicRole.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/BasicRoleMenuRelation.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/BasicRoleUserRelation.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/BasicUser.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/LoginHistory.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/vo/TreeMenusDTO.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/vo/company/CompanyPageDTO.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/vo/role/RoleMenuDTO.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/vo/role/RolePageDTO.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/vo/user/UserInfoVO.java create mode 100644 model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/vo/user/UserPageDTO.java create mode 100644 model2d3d-viewer-back-service/.gitignore create mode 100644 model2d3d-viewer-back-service/pom.xml create mode 100644 model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/AccountService.java create mode 100644 model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/CommonService.java create mode 100644 model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/CompanyService.java create mode 100644 model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/RoleService.java create mode 100644 model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/UserService.java create mode 100644 model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/captcha/CaptchaService.java create mode 100644 model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/captcha/CaptchaVO.java create mode 100644 model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/captcha/KaptchaConfig.java create mode 100644 model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/common/CommonOpt.java create mode 100644 model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/common/MenuTree.java create mode 100644 model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/impl/AccountServiceImpl.java create mode 100644 model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/impl/CommonServiceImpl.java create mode 100644 model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/impl/CompanyServiceImpl.java create mode 100644 model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/impl/RoleServiceImpl.java create mode 100644 model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/impl/UserServiceImpl.java create mode 100644 model2d3d-viewer-back-service/src/test/java/com/model2d3d/viewer/back/service/impl/JsonsTests.java create mode 100644 model2d3d-viewer-back-util/.gitignore create mode 100644 model2d3d-viewer-back-util/pom.xml create mode 100644 model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/Arith.java create mode 100644 model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/CommonUtil.java create mode 100644 model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/DESUtil.java create mode 100644 model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/DateUtil.java create mode 100644 model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/FileUtil.java create mode 100644 model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/HttpUtil.java create mode 100644 model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/NetworkUtil.java create mode 100644 model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/RandomNumberUtil.java create mode 100644 model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/SendMail.java create mode 100644 model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/ServiceUtil.java create mode 100644 model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/TimeIntervalSplitter.java create mode 100644 model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/URLCoder.java create mode 100644 model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/ValidatorUtil.java create mode 100644 model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/async/OptAsync.java create mode 100644 model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/aurora/TimeInterval.java create mode 100644 model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/redis/RedisClusterConfig.java create mode 100644 model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/redis/RedisSentinelConfig.java create mode 100644 model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/redis/RedisStandaloneConfig.java create mode 100644 model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/redis/RedisUtil.java create mode 100644 model2d3d-viewer-back-util/src/test/java/com/model2d3d/viewer/back/util/AppTest.java create mode 100644 model2d3d-viewer-back-util/src/test/java/com/model2d3d/viewer/back/util/NearestHourMinute.java create mode 100644 model2d3d-viewer-back-util/src/test/java/com/model2d3d/viewer/back/util/QuartileCalculator.java create mode 100644 model2d3d-viewer-back-util/src/test/java/com/model2d3d/viewer/back/util/Test.java create mode 100644 model2d3d-viewer-back-util/src/test/java/com/model2d3d/viewer/back/util/ValueSorter.java create mode 100644 pom.xml create mode 100644 readme.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..520c87b --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +/target/ +/logs/ +/.idea/ +*.iml +*.bak +*.log +/.settings/ +*.project +*.classpath +*.factorypath +*.springBeans +/.apt_generated/ +/.externalToolBuilders/ +/bin/ +/model2d3d-viewer-back-controller/tmp/ +application-*.properties diff --git a/document/cmd b/document/cmd new file mode 100644 index 0000000..74660ad --- /dev/null +++ b/document/cmd @@ -0,0 +1,31 @@ +aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 381659385655.dkr.ecr.ap-northeast-1.amazonaws.com + +docker tag 67f91fc6cfbf 381659385655.dkr.ecr.ap-northeast-1.amazonaws.com/tokyo-build-business:latest + +docker push 381659385655.dkr.ecr.ap-northeast-1.amazonaws.com/tokyo-build-business:latest + +docker pull 381659385655.dkr.ecr.ap-northeast-1.amazonaws.com/tokyo-build-business:latest + +docker run -d -p 8887:20008 -v /home/data-center-business/back/application.properties:/home/data-center-business/config/application.properties 381659385655.dkr.ecr.ap-northeast-1.amazonaws.com/tokyo-build-business + +aws configure + +docker run -e apiEnable=false -e datasourceDNS=tokyo-building-db.caetvgb7diak.ap-northeast-1.rds.amazonaws.com -e datasourceTimeZone=Asia/Tokyo -e datasourceUsername=techsor -e datasourcePassword=Abc#123456xyz -e loggingLevel=ERROR -e loggingPath=/home/data-center-business/log -e loggingAppender=SYSLOG -e redisHost=replication-group-tokyo-build.ncvpel.ng.0001.apne1.cache.amazonaws.com -e redisPassword= -e awsAccesskey=AKIA5OFH5OOZHM3U3KX4 -e awsSecretkey=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 -e awsBucket=tokyo-build-databucket-381659385655 -e ibatisLoggingLog=ERROR -e ibatisLoggingLogFactory=ERROR -d -p 20008:20008 923770123186.dkr.ecr.ap-northeast-1.amazonaws.com/tokyo-build-business:latest + +阿里云 +docker tag e1fe6f58961e registry.cn-shanghai.aliyuncs.com/test-data-business/data-business-server:latest + +docker push registry.cn-shanghai.aliyuncs.com/test-data-business/data-business-server:latest + +docker pull registry.cn-shanghai.aliyuncs.com/test-data-business/data-business-server:latest + +docker exec -it 3c77bb84d338 /bin/bash + +docker run -d -p 20008:20015 -v /home/application.properties:/home/model2d3d-viewer-back/config/application.properties registry.cn-shanghai.aliyuncs.com/test-data-business/data-business-server + +测试环境 +aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 923770123186.dkr.ecr.ap-northeast-1.amazonaws.com + +docker tag ecee6b583d3c 923770123186.dkr.ecr.ap-northeast-1.amazonaws.com/tokyo-build-business:latest + +docker push 923770123186.dkr.ecr.ap-northeast-1.amazonaws.com/tokyo-build-business:latest diff --git a/document/db/init.sql b/document/db/init.sql new file mode 100644 index 0000000..6482df3 --- /dev/null +++ b/document/db/init.sql @@ -0,0 +1,140 @@ +/* +SQLyog 企业版 - MySQL GUI v8.14 +MySQL - 8.0.28 : Database - model2d3d_viewer_back +********************************************************************* +*/ + +/*!40101 SET NAMES utf8 */; + +/*!40101 SET SQL_MODE=''*/; + +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +CREATE DATABASE /*!32312 IF NOT EXISTS*/`model2d3d_viewer_back` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */ /*!80016 DEFAULT ENCRYPTION='N' */; + +USE `model2d3d_viewer_back`; + +/*Table structure for table `basic_company` */ + +DROP TABLE IF EXISTS `basic_company`; + +CREATE TABLE `basic_company` ( + `id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, + `parent_id` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `company_name` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `flag` int DEFAULT '0' COMMENT '0-正常,1-删除', + `create_time` bigint DEFAULT NULL, + `modify_time` bigint DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='企业表'; + +/*Data for the table `basic_company` */ + +insert into `basic_company`(`id`,`parent_id`,`company_name`,`flag`,`create_time`,`modify_time`) values ('1','-1','MiniSolution',0,1658978002231,1658978002231); +/*Table structure for table `basic_menu` */ + +DROP TABLE IF EXISTS `basic_menu`; + +CREATE TABLE `basic_menu` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `parent_menu_id` bigint DEFAULT NULL, + `menu_name` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `menu_name_en` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `menu_name_jp` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `remark` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `menu_level` int DEFAULT '1' COMMENT '菜单级别', + `flag` int DEFAULT '0' COMMENT '0-正常,1-删除', + `create_time` bigint DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +/*Data for the table `basic_menu` */ + +/*Table structure for table `basic_role` */ + +DROP TABLE IF EXISTS `basic_role`; + +CREATE TABLE `basic_role` ( + `id` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL, + `company_id` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `role_name` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `description` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `flag` int DEFAULT '0' COMMENT '0-正常,1-删除', + `creator_id` bigint DEFAULT NULL, + `create_time` bigint DEFAULT NULL, + `modifier_id` bigint DEFAULT NULL, + `modify_time` bigint DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +/*Table structure for table `basic_role_menu_relation` */ + +DROP TABLE IF EXISTS `basic_role_menu_relation`; + +CREATE TABLE `basic_role_menu_relation` ( + `role_id` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `menu_id` bigint DEFAULT NULL, + `creator_id` bigint DEFAULT NULL, + `create_time` bigint DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + + +/*Table structure for table `basic_role_user_relation` */ + +DROP TABLE IF EXISTS `basic_role_user_relation`; + +CREATE TABLE `basic_role_user_relation` ( + `user_id` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `role_id` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `creator_id` bigint DEFAULT NULL, + `create_time` bigint DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + + +/*Table structure for table `basic_user` */ + +DROP TABLE IF EXISTS `basic_user`; + +CREATE TABLE `basic_user` ( + `id` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL, + `company_id` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL, + `shop_uuid` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `username` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `login_name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `password_modify_time` bigint DEFAULT NULL, + `salt` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `email` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `mobile_number` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `last_login_time` bigint DEFAULT NULL, + `remark` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '备注', + `flag` int NOT NULL DEFAULT '0' COMMENT '0-正常,1-删除', + `expire_time` bigint DEFAULT '4114487556000', + `create_time` bigint DEFAULT NULL, + `creator_id` bigint DEFAULT NULL, + `modify_time` bigint DEFAULT NULL, + `modifier_id` bigint DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +/*Data for the table `basic_user` */ + +insert into `basic_user`(`id`,`company_id`,`shop_uuid`,`username`,`login_name`,`password`,`password_modify_time`,`salt`,`email`,`mobile_number`,`last_login_time`,`remark`,`flag`,`expire_time`,`create_time`,`creator_id`,`modify_time`,`modifier_id`) values ('1','1','1','admin_name','admin','nVg+buw0YAs=',1670312031273,'09bc3a7898','1053492832@qq.com',NULL,1743496632944,NULL,0,4114487556000,NULL,NULL,NULL,NULL); +/*Table structure for table `login_history` */ + +DROP TABLE IF EXISTS `login_history`; + +CREATE TABLE `login_history` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `user_id` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `request_ip` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `login_time` bigint DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; diff --git a/document/start.sh b/document/start.sh new file mode 100644 index 0000000..902b2e7 --- /dev/null +++ b/document/start.sh @@ -0,0 +1,30 @@ +#! /bin/sh +#启动方法 +start(){ +now=`date "+%Y%m%d%H%M%S"` +cd /home/model2d3d-viewer-back/back/server/run && nohup /usr/local/java/jdk1.8.0_221/bin/java -server -Xms256m -Xmx256m -jar /home/model2d3d-viewer-back/back/server/run/model2d3d-viewer-back-controller-0.0.1-SNAPSHOT.jar > /dev/null 2>boot.log & +} +#停止方法 +stop(){ + ps -ef|grep java|grep model2d3d-viewer-back-controller-0.0.1-SNAPSHOT.jar|awk '{print $2}'|while read pid + do + kill -9 $pid + done +} + +case "$1" in +start) +start +;; +stop) +stop +;; +restart) +stop +start +;; +*) +printf 'Usage: %s {start|stop|restart}\n' "$prog" +exit 1 +;; +esac \ No newline at end of file diff --git a/document/update.sh b/document/update.sh new file mode 100644 index 0000000..350563e --- /dev/null +++ b/document/update.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +projectName=model2d3d-viewer-back +backFilePath=/home/$projectName/back/server + +basepath=$(cd `dirname $0`; pwd) +cd $basepath + +echo "start for Web" + +rm -rf $backFilePath/run/lib +unzip -o $backFilePath/$projectName.zip -d $backFilePath/run +\cp -r $backFilePath/run/$projectName/* $backFilePath/run/ +rm -rf $backFilePath/run/$projectName + +sh start.sh restart +exit \ No newline at end of file diff --git a/model2d3d-viewer-back-common/.gitignore b/model2d3d-viewer-back-common/.gitignore new file mode 100644 index 0000000..aa23915 --- /dev/null +++ b/model2d3d-viewer-back-common/.gitignore @@ -0,0 +1,15 @@ +/target/ +/logs/ +/.idea/ +*.iml +*.bak +*.log +/.settings/ +*.project +*.classpath +*.factorypath +*.springBeans +/.apt_generated/ +/.externalToolBuilders/ +/bin/ +application-*.properties diff --git a/model2d3d-viewer-back-common/pom.xml b/model2d3d-viewer-back-common/pom.xml new file mode 100644 index 0000000..5720709 --- /dev/null +++ b/model2d3d-viewer-back-common/pom.xml @@ -0,0 +1,35 @@ + + + 4.0.0 + + com.techsor + model2d3d-viewer-back + 0.0.1-SNAPSHOT + + model2d3d-viewer-back-common + model2d3d-viewer-back-common + http://maven.apache.org + + UTF-8 + + + + junit + junit + test + + + + com.techsor + model2d3d-viewer-back-dao + 0.0.1-SNAPSHOT + + + com.techsor + model2d3d-viewer-back-util + 0.0.1-SNAPSHOT + + + + diff --git a/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/Constants.java b/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/Constants.java new file mode 100644 index 0000000..f2913ed --- /dev/null +++ b/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/Constants.java @@ -0,0 +1,18 @@ +package com.model2d3d.viewer.back.common; +/** +* @author Mr.Jiang +* @time 2022年5月20日 下午2:01:41 +*/ +public class Constants { + + //这个很重要,不要随便动 + public static final String DES_SALT = "ci3b512jwy199511"; + + public static final String APP_NAME = "model2d3d_viewer_back:"; + + //用户ID,登录名,企业ID,token + public static final String ACCESS_TOKEN_FORMAT = APP_NAME + "RequestHeader:AccessToken:{0}:{1}:{2}:{3}"; + + public static final String CAPTCHA_VERIFICATION = APP_NAME + "CAPTCHA:VERIFICATION:"; + +} diff --git a/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/exception/BusinessException.java b/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/exception/BusinessException.java new file mode 100644 index 0000000..5981857 --- /dev/null +++ b/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/exception/BusinessException.java @@ -0,0 +1,36 @@ +package com.model2d3d.viewer.back.common.exception; + +/** + * 业务异常处理 + * + */ +public class BusinessException extends RuntimeException{ + + /** + * 实例化一个新的业务异常 + * + * @param msg 异常信息 + */ + public BusinessException(String msg) { + super(msg); + } + + /** + * 实例化一个新的业务异常 + * + * @param cause 异常原因 + */ + public BusinessException(Throwable cause) { + super(cause); + } + + /** + * 实例化一个新的业务异常 + * + * @param msg 异常信息 + * @param cause 异常原因 + */ + public BusinessException(String msg, Throwable cause) { + super(msg, cause); + } +} diff --git a/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/exception/MsgCodeException.java b/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/exception/MsgCodeException.java new file mode 100644 index 0000000..2930cba --- /dev/null +++ b/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/exception/MsgCodeException.java @@ -0,0 +1,26 @@ +package com.model2d3d.viewer.back.common.exception; + +/** + * + * @author jwy-style + * + */ +public class MsgCodeException extends RuntimeException{ + + private String message; + + public MsgCodeException(String message) { + super(message); + this.message = message; + } + + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + +} diff --git a/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/language/PropertySourceYumFactory.java b/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/language/PropertySourceYumFactory.java new file mode 100644 index 0000000..f936b14 --- /dev/null +++ b/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/language/PropertySourceYumFactory.java @@ -0,0 +1,26 @@ +package com.model2d3d.viewer.back.common.language; + +import java.io.IOException; +import java.util.List; + +import org.springframework.boot.env.YamlPropertySourceLoader; +import org.springframework.core.env.PropertySource; +import org.springframework.core.io.support.DefaultPropertySourceFactory; +import org.springframework.core.io.support.EncodedResource; + +/** + * @PropertySource 解析.yum文件需要指定该工厂 + */ +public class PropertySourceYumFactory extends DefaultPropertySourceFactory { + + @Override + public PropertySource createPropertySource(String name, EncodedResource resource) throws IOException { + if (resource == null) { + return super.createPropertySource(name, resource); + } + List> sources = new YamlPropertySourceLoader().load(resource.getResource().getFilename(), resource.getResource()); + return sources.get(0); + } + + +} diff --git a/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/language/msg/MsgLanguageChange.java b/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/language/msg/MsgLanguageChange.java new file mode 100644 index 0000000..53d4f1a --- /dev/null +++ b/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/language/msg/MsgLanguageChange.java @@ -0,0 +1,54 @@ +package com.model2d3d.viewer.back.common.language.msg; + +import org.apache.commons.collections.MapUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class MsgLanguageChange { + @Autowired + private Msg_EN msgEn; + @Autowired + private Msg_CN msgCn; + @Autowired + private Msg_JP msgJp; + + /** + * 参数映射 + * @param languaType + * @param code + * @return + */ + public String getParameterMapByCode(Integer languaType,String code){ + String msg = null; + if(null != languaType){ + if(languaType == 0){//中文 + msg = MapUtils.getString(msgCn.getParameterMap(), code, code); + }else if(languaType == 1){//英文 + msg = MapUtils.getString(msgEn.getParameterMap(), code, code); + }else if(languaType == 2){//日语 + msg = MapUtils.getString(msgJp.getParameterMap(), code, code); + } + }else{ + msg = MapUtils.getString(msgJp.getParameterMap(), code, code); + } + return msg; + } + + public String getBadRequestMessage(Integer languaType,String code){ + String msg = null; + if(null != languaType){ + if(languaType == 0){//中文 + msg = MapUtils.getString(msgCn.getArgumentNotValid(), code, code); + }else if(languaType == 1){//英文 + msg = MapUtils.getString(msgEn.getArgumentNotValid(), code, code); + }else if(languaType == 2){//日语 + msg = MapUtils.getString(msgJp.getArgumentNotValid(), code, code); + } + }else{ + msg = MapUtils.getString(msgJp.getArgumentNotValid(), code, code); + } + return msg; + } + +} diff --git a/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/language/msg/Msg_CN.java b/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/language/msg/Msg_CN.java new file mode 100644 index 0000000..10aac23 --- /dev/null +++ b/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/language/msg/Msg_CN.java @@ -0,0 +1,25 @@ +package com.model2d3d.viewer.back.common.language.msg; + +import java.util.Map; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Component; + +import com.model2d3d.viewer.back.common.language.PropertySourceYumFactory; + +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +@Component +@PropertySource(value = "classpath:/config/language/msg/msg_cn.yml", encoding = "UTF-8", factory = PropertySourceYumFactory.class) +@ConfigurationProperties(prefix = "msgcn") +public class Msg_CN { + + private Map parameterMap; + + private Map argumentNotValid; + +} \ No newline at end of file diff --git a/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/language/msg/Msg_EN.java b/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/language/msg/Msg_EN.java new file mode 100644 index 0000000..91dfc36 --- /dev/null +++ b/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/language/msg/Msg_EN.java @@ -0,0 +1,25 @@ +package com.model2d3d.viewer.back.common.language.msg; + +import java.util.Map; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Component; + +import com.model2d3d.viewer.back.common.language.PropertySourceYumFactory; + +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +@Component +@PropertySource(value = "classpath:/config/language/msg/msg_en.yml", encoding = "UTF-8", factory = PropertySourceYumFactory.class) +@ConfigurationProperties(prefix = "msgen") +public class Msg_EN { + + private Map parameterMap; + + private Map argumentNotValid; + +} \ No newline at end of file diff --git a/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/language/msg/Msg_JP.java b/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/language/msg/Msg_JP.java new file mode 100644 index 0000000..7b3a5a9 --- /dev/null +++ b/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/language/msg/Msg_JP.java @@ -0,0 +1,25 @@ +package com.model2d3d.viewer.back.common.language.msg; + +import java.util.Map; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Component; + +import com.model2d3d.viewer.back.common.language.PropertySourceYumFactory; + +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +@Component +@PropertySource(value = "classpath:/config/language/msg/msg_jp.yml", encoding = "UTF-8", factory = PropertySourceYumFactory.class) +@ConfigurationProperties(prefix = "msgjp") +public class Msg_JP { + + private Map parameterMap; + + private Map argumentNotValid; + +} \ No newline at end of file diff --git a/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/response/BaseResponse.java b/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/response/BaseResponse.java new file mode 100644 index 0000000..48ea11e --- /dev/null +++ b/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/response/BaseResponse.java @@ -0,0 +1,51 @@ +package com.model2d3d.viewer.back.common.response; + +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * + * @author jwy-style + * + */ +public class BaseResponse { + /** + * 返回码 + */ + @Schema(description ="状态码, 0或者200表示成功",example = "0") + private int code; + /** + * 提示信息 + */ + @Schema(description ="简单的提示信息",example = "服务器错误") + private String msg = "success"; + + public BaseResponse() { + + } + + public BaseResponse(int code) { + this.code = code; + } + + public BaseResponse(int code, String msg) { + this.code = code; + this.msg = msg; + } + + 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/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/response/PageResponse.java b/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/response/PageResponse.java new file mode 100644 index 0000000..a6f97d3 --- /dev/null +++ b/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/response/PageResponse.java @@ -0,0 +1,66 @@ +package com.model2d3d.viewer.back.common.response; + +import com.baomidou.mybatisplus.core.metadata.IPage; + +import java.util.Map; + +/** + * + * @author jwy-style + * + * @param + */ +public class PageResponse extends BaseResponse{ + /** + * 对象信息 + */ + private T data; + + private Map errorMap; + + public PageResponse() { + } + + public PageResponse(int code) { + super(code); + } + + public PageResponse(int code, String msg) { + super(code, msg); + } + + public PageResponse(int code,String msg,Map errorMap){ + super(code, msg); + this.errorMap = errorMap; + } + + public static PageResponse success(Object data){ + PageResponse pageResponse = new PageResponse(); + pageResponse.setData((IPage) data); + pageResponse.setCode(ResponseCode.SUCCESS); + pageResponse.setMsg("success"); + return pageResponse; + } + + + public Map getErrorMap() { + return errorMap; + } + + public void setErrorMap(Map errorMap) { + this.errorMap = errorMap; + } + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + + + + + +} diff --git a/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/response/ResponseCode.java b/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/response/ResponseCode.java new file mode 100644 index 0000000..df791b1 --- /dev/null +++ b/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/response/ResponseCode.java @@ -0,0 +1,28 @@ +package com.model2d3d.viewer.back.common.response; + +/** + * + * @author jwy-style + * + */ +public class ResponseCode { + + /** 成功 */ + public static final int OK = 0; + /** + * 请求已成功,请求所希望的响应头或数据体将随此响应返回。 + */ + public static final int SUCCESS = 200; + + //错误请求 + public static final int BAD_REQUEST = 400; + //未授权 + public static final int AUTHORIZE_FAILED = 401; + + //服务器内部错误 + public static final int SERVER_ERROR = 500; + public static final String SERVER_ERROR_MSG = "service error"; + + //查看msg提示信息 + public static final int MSG_ERROR = 20001; +} diff --git a/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/response/SimpleDataResponse.java b/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/response/SimpleDataResponse.java new file mode 100644 index 0000000..94af3ea --- /dev/null +++ b/model2d3d-viewer-back-common/src/main/java/com/model2d3d/viewer/back/common/response/SimpleDataResponse.java @@ -0,0 +1,104 @@ +package com.model2d3d.viewer.back.common.response; + +import com.fasterxml.jackson.annotation.JsonInclude; + +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.Map; + +/** + * + * @author jwy-style + * + * @param + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +public class SimpleDataResponse extends BaseResponse { + /** + * 单个对象 + */ + @Schema(description ="返回的数据",example = "object") + private T data; + + /** + * The parameters Error map. + */ + @Schema(description ="复杂的提示信息",example = "{\"name\":\"长度过长\",\"age\":\"年龄太大\",\"weight\":\"体重超标\"}") + private Map errorMap; + + public SimpleDataResponse() { + super(); + } + + public SimpleDataResponse(int code) { + super(code); + } + + public SimpleDataResponse(int code, String msg) { + super(code, msg); + } + + /** + * 响应结果,携带错误Map + * @param code + * @param msg + * @param errorMap + */ + public SimpleDataResponse(int code, String msg, Map errorMap) { + this(code, msg); + this.errorMap = errorMap; + } + + /** + * 成功响应 + * @return + */ + public static SimpleDataResponse success(){ + return new SimpleDataResponse(ResponseCode.SUCCESS,"Success"); + } + + /** + * 多条数据,成功响应 + * @param rows + * @return + */ + public static SimpleDataResponse success(int rows){ + return new SimpleDataResponse(ResponseCode.SUCCESS,"Success: "+rows); + } + + /** + * 成功响应,携带数据对象返回 + * @param data + * @return + */ + public static SimpleDataResponse success(Object data){ + SimpleDataResponse comm = success(); + comm.setData(data); + return comm; + } + + + public static SimpleDataResponse fail(int code,String message){ + return new SimpleDataResponse(code,message); + } + public static SimpleDataResponse fail(int code,String message,Object data){ + SimpleDataResponse simpleDataResponse= new SimpleDataResponse(code,message); + simpleDataResponse.setData(data); + return simpleDataResponse; + } + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + + public Map getErrorMap() { + return errorMap; + } + + public void setErrorMap(Map errorMap) { + this.errorMap = errorMap; + } +} diff --git a/model2d3d-viewer-back-common/src/main/resources/config/language/msg/msg_cn.yml b/model2d3d-viewer-back-common/src/main/resources/config/language/msg/msg_cn.yml new file mode 100644 index 0000000..0f651aa --- /dev/null +++ b/model2d3d-viewer-back-common/src/main/resources/config/language/msg/msg_cn.yml @@ -0,0 +1,38 @@ +msgcn: + argumentNotValid: + 1000: 未通过参数校验 + 1001: 参数不能为空 + 1002: 长度不能超过{0} + 1003: 长度无效 + 1004: 无效的邮箱 + 1005: 数值范围在{0}到{1}之间 + 1006: 必须大于或等于{0} + 1007: 必须小于或等于{0} + 1008: 无效的参数 + parameterMap: + serviceError: 内部服务错误 + tokenError: 接口鉴权失败 + excelEmpty: 表格为空 + lineNum: 第{0}行: + paramsFormatError: 参数格式错误 + verifCodeExpired: 验证码过期 + verifCodeError: 验证码错误 + accountExpired: 该账号已过期 + pwdError: 密码错误 + userNotExist: 用户不存在 + noOperationAuth: 无操作权限 + excelBuildingLineDuplicate: 表格内存在相同的数据 + userOrEmailNotExist: 用户名或邮箱不存在 + companyNameHasExisted: 平台已存在此企业 + taowaComapny: 不可使用下级企业作为父企业 + hasSubsidiary: 删除的企业拥有下级企业,需先处理下级企业 + roleNameExist: 角色名已存在 + roleHasBinded: 角色已绑定用户,请先解绑再删除 + loginNameOrEmailHasExisted: 用户名或邮箱已被使用 + mailAddUserPwdSubject: 新建账号密码 + mailAddUserPwdContent: 账号 {0} 的密码为:{1}, 请妥善保管

登陆网址:{2} + mailResetUserPwdSubject: 重置账号密码 + pwdFormatError: 密码组成必须包含数字、英文字母、特殊符号(~!@#$%^&*)且大于等于12位 + oldPwdError: 旧密码错误 + newPwdSameOld: 新密码不得与旧密码相同 + companyLimit: 最多可创建15个企业 \ No newline at end of file diff --git a/model2d3d-viewer-back-common/src/main/resources/config/language/msg/msg_en.yml b/model2d3d-viewer-back-common/src/main/resources/config/language/msg/msg_en.yml new file mode 100644 index 0000000..1af63ab --- /dev/null +++ b/model2d3d-viewer-back-common/src/main/resources/config/language/msg/msg_en.yml @@ -0,0 +1,38 @@ +msgen: + argumentNotValid: + 1000: 未通过参数校验 + 1001: 参数不能为空 + 1002: 长度不能超过{0} + 1003: 长度无效 + 1004: 无效的邮箱 + 1005: 数值范围在{0}到{1}之间 + 1006: 必须大于或等于{0} + 1007: 必须小于或等于{0} + 1008: 无效的参数 + parameterMap: + serviceError: Internal service error. + tokenError: API authentication failed. + excelEmpty: The spreadsheet is empty. + lineNum: "Lines {0}:" + paramsFormatError: Parameter format error. + verifCodeExpired: Verification code expired. + verifCodeError: Verification code error. + accountExpired: The account has expired. + pwdError: Password error. + userNotExist: User does not exist. + noOperationAuth: No operation permission. + excelBuildingLineDuplicate: Duplicate data exists in the spreadsheet. + userOrEmailNotExist: 用户名或邮箱不存在 + companyNameHasExisted: 平台已存在此企业 + taowaComapny: 不可使用下级企业作为父企业 + hasSubsidiary: 删除的企业拥有下级企业,需先处理下级企业 + roleNameExist: 角色名已存在 + roleHasBinded: 角色已绑定用户,请先解绑再删除 + loginNameOrEmailHasExisted: 用户名或邮箱已被使用 + mailAddUserPwdSubject: 新建账号密码 + mailAddUserPwdContent: 账号 {0} 的密码为:{1}, 请妥善保管

登陆网址:{2} + mailResetUserPwdSubject: 重置账号密码 + pwdFormatError: 密码组成必须包含数字、英文字母、特殊符号(~!@#$%^&*)且大于等于12位 + oldPwdError: 旧密码错误 + newPwdSameOld: 新密码不得与旧密码相同 + companyLimit: 最多可创建15个企业 \ No newline at end of file diff --git a/model2d3d-viewer-back-common/src/main/resources/config/language/msg/msg_jp.yml b/model2d3d-viewer-back-common/src/main/resources/config/language/msg/msg_jp.yml new file mode 100644 index 0000000..be7730c --- /dev/null +++ b/model2d3d-viewer-back-common/src/main/resources/config/language/msg/msg_jp.yml @@ -0,0 +1,38 @@ +msgjp: + argumentNotValid: + 1000: 未通过参数校验 + 1001: 参数不能为空 + 1002: 长度不能超过{0} + 1003: 长度无效 + 1004: 无效的邮箱 + 1005: 数值范围在{0}到{1}之间 + 1006: 必须大于或等于{0} + 1007: 必须小于或等于{0} + 1008: 无效的参数 + parameterMap: + serviceError: 内部サービスのエラー + tokenError: インターフェイスの認証に失敗 + excelEmpty: フォームが空になっている + lineNum: 行{0}: + paramsFormatError: パラメータのフォーマットエラー + verifCodeExpired: 確認コード期限切れ + verifCodeError: 確認コードエラー + accountExpired: アカウントの有効期限が切れている + pwdError: パスワードエラー + userNotExist: ユーザーが存在しない + noOperationAuth: 操作権限なし + excelBuildingLineDuplicate: テーブルに同じデータがある + userOrEmailNotExist: ユーザーが存在しません + companyNameHasExisted: 会社はすでにプラットフォーム上に存在する + taowaComapny: 下位の会社を親会社として利用することは不可 + hasSubsidiary: 削除対象の会社には下位の会社があるので、先に下位の会社を対応してください + roleNameExist: 役割名が既に登録済み + roleHasBinded: 役割はユーザーにバインドされている ので、削除する前にバインドを解除してください + loginNameOrEmailHasExisted: ユーザー名またはメールボックスはすでに使用されています + mailAddUserPwdSubject: 新規アカウント・パスワードの作成 + mailAddUserPwdContent: アカウント {0} のパスワードは:{1}, お忘れにならないようにお願いします。

ログインWebアドレス:{2} + mailResetUserPwdSubject: アカウント・パスワードのリセット + pwdFormatError: パスワードの構成には、数字、アルファベット、特殊文字(~!@#$%^&*) で、12桁以上 + oldPwdError: 旧パスワードエラー + newPwdSameOld: 注:旧パスワードと同じものを使用しないでください + companyLimit: 最大15のエンタープライズを作成可能 \ No newline at end of file diff --git a/model2d3d-viewer-back-controller/.gitignore b/model2d3d-viewer-back-controller/.gitignore new file mode 100644 index 0000000..aa23915 --- /dev/null +++ b/model2d3d-viewer-back-controller/.gitignore @@ -0,0 +1,15 @@ +/target/ +/logs/ +/.idea/ +*.iml +*.bak +*.log +/.settings/ +*.project +*.classpath +*.factorypath +*.springBeans +/.apt_generated/ +/.externalToolBuilders/ +/bin/ +application-*.properties diff --git a/model2d3d-viewer-back-controller/dockerfile b/model2d3d-viewer-back-controller/dockerfile new file mode 100644 index 0000000..f5341d3 --- /dev/null +++ b/model2d3d-viewer-back-controller/dockerfile @@ -0,0 +1,69 @@ +#FROM openjdk:8-jre-alpine +#FROM amazon-corretto-8 +#FROM amazoncorretto:11 + +# 使用Ubuntu 20.04 LTS作为基础镜像 +FROM ubuntu:20.04 + +# 设置系统的默认编码方式为 UTF-8 +ENV LANG=en_US.UTF-8 +ENV LC_CTYPE=zh_CN.UTF-8 + +# 设置环境变量,避免交互式安装 +ENV DEBIAN_FRONTEND=noninteractive + +# 更新APT软件包索引并安装必要的软件包 +RUN apt-get update && \ + apt-get install -y \ + curl \ + unzip \ + vim \ + fontconfig \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# 安装Terraform +RUN curl -fsSLk https://releases.hashicorp.com/terraform/1.7.5/terraform_1.7.5_linux_amd64.zip -o /tmp/terraform.zip && \ + unzip /tmp/terraform.zip -d /usr/local/bin/ && \ + rm /tmp/terraform.zip + +# 安装Amazon Corretto 11 JDK +RUN curl -fsSLk https://corretto.aws/downloads/resources/11.0.22.7.1/amazon-corretto-11.0.22.7.1-linux-x64.tar.gz -o /tmp/amazon-corretto-11.tar.gz && \ + mkdir /usr/lib/jvm/ && \ + tar -xzvf /tmp/amazon-corretto-11.tar.gz -C /usr/lib/jvm/ && \ + rm /tmp/amazon-corretto-11.tar.gz + +# 设置JAVA_HOME环境变量 +ENV JAVA_HOME=/usr/lib/jvm/amazon-corretto-11.0.22.7.1-linux-x64 +ENV PATH=$JAVA_HOME/bin:$PATH + +ENV JAVA_TOOL_OPTIONS="-Dfile.encoding=UTF8" + +# 打印Terraform版本 +RUN terraform --version + +# 打印Java版本 +RUN java -version + +WORKDIR /home/data-center-admin + +#EXPOSE 20008 + +# 设置时区 +#RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone + +ARG JAR_FILE +ARG LIB_DIR +ARG CONFIG_DIR +ARG AURORA_TERRAFORM +ARG JVM_OPTS + +COPY ${JAR_FILE} app.jar +COPY ${LIB_DIR} lib +COPY ${CONFIG_DIR} config +COPY ${AURORA_TERRAFORM} aurora_terraform + +#ENTRYPOINT ["java", "${JVM_OPTS}", "-jar","app.jar"] +ENTRYPOINT java ${JVM_OPTS} -jar app.jar + + diff --git a/model2d3d-viewer-back-controller/pom.xml b/model2d3d-viewer-back-controller/pom.xml new file mode 100644 index 0000000..83871a5 --- /dev/null +++ b/model2d3d-viewer-back-controller/pom.xml @@ -0,0 +1,350 @@ + + + 4.0.0 + + com.techsor + model2d3d-viewer-back + 0.0.1-SNAPSHOT + + model2d3d-viewer-back-controller + model2d3d-viewer-back-controller + http://maven.apache.org + + UTF-8 + + tokyo-build-admin + latest + ap-northeast-1 + + 923770123186.dkr.ecr.ap-northeast-1.amazonaws.com + AKIA5OFH5OOZHM3U3KX4 + Plkid7RDnHc1gGbp2yAv/Scc+ukI0q8vzBuyEBN2 + + 381659385655.dkr.ecr.ap-northeast-1.amazonaws.com + AKIAVRXFMB43XVQ3GXAL + G0FaGcizm8FlgLxZsL+8xBwfPSzQF71294nrtE2y + + + + + + + com.techsor + model2d3d-viewer-back-service + 0.0.1-SNAPSHOT + + + + com.techsor + model2d3d-viewer-back-common + 0.0.1-SNAPSHOT + + + junit + junit + test + + + + com.spotify + dockerfile-maven-plugin + 1.4.13 + + + + javax.annotation + jsr250-api + + + + + + + + only-package + + true + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + model2d3d-viewer-back + + src/main/resources/assembly.xml + + false + + + + make-assembly + package + + single + + + + + + + + + docker-package + + + + + + com.spotify + dockerfile-maven-plugin + 1.4.13 + + + default + + build + + + + + + registry.cn-shanghai.aliyuncs.com/clouddog/datacenter-admin + ${aws.ecr.tag} + + target/${project.build.finalName}.jar + target/lib + target/config + target/aurora_terraform + ${java.jvm.opts} + + + + + + + + docker-aliyun + + + + + + com.spotify + dockerfile-maven-plugin + 1.4.13 + + + default + + build + + + + + + registry.cn-shanghai.aliyuncs.com/clouddog/datacenter-admin + ${aws.ecr.tag} + + target/${project.build.finalName}.jar + target/lib + target/config + target/aurora_terraform + ${java.jvm.opts} + + + + + + org.apache.maven.plugins + maven-antrun-plugin + 3.0.0 + + + + package + + run + + + + + + + + + + + + + + + + + + + + + + docker-test + + + + + + com.spotify + dockerfile-maven-plugin + 1.4.13 + + + default + + build + + + + + + ${aws.ecr.registry.test}/${aws.ecr.repository} + ${aws.ecr.tag} + + target/${project.build.finalName}.jar + target/lib + target/config + target/aurora_terraform + ${java.jvm.opts} + + + + + + org.apache.maven.plugins + maven-antrun-plugin + 3.0.0 + + + + package + + run + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + docker-production + + + + + + com.spotify + dockerfile-maven-plugin + 1.4.13 + + + default + + build + + + + + + ${aws.ecr.registry.production}/${aws.ecr.repository} + ${aws.ecr.tag} + + target/${project.build.finalName}.jar + target/lib + target/config + target/aurora_terraform + ${java.jvm.opts} + + + + + + org.apache.maven.plugins + maven-antrun-plugin + 3.0.0 + + + + package + + run + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/Model2d3dViewerApplication.java b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/Model2d3dViewerApplication.java new file mode 100644 index 0000000..1a4fbf5 --- /dev/null +++ b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/Model2d3dViewerApplication.java @@ -0,0 +1,19 @@ +package com.model2d3d.viewer.back; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletComponentScan; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.EnableScheduling; + +@SpringBootApplication +@ServletComponentScan +@EnableAsync +//@EnableScheduling +public class Model2d3dViewerApplication { + + public static void main(String[] args) { + SpringApplication.run(Model2d3dViewerApplication.class, args); + } + +} \ No newline at end of file diff --git a/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/ApiConfig.java b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/ApiConfig.java new file mode 100644 index 0000000..f6bdcff --- /dev/null +++ b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/ApiConfig.java @@ -0,0 +1,65 @@ +package com.model2d3d.viewer.back.configurator; + +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import jakarta.servlet.MultipartConfigElement; +import org.springframework.boot.web.servlet.MultipartConfigFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.mobile.device.DeviceHandlerMethodArgumentResolver; +import org.springframework.util.unit.DataSize; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import com.model2d3d.viewer.back.configurator.interceptor.AccessApiInterceptor; + +import java.io.File; +import java.util.List; + +@Configuration +public class ApiConfig implements WebMvcConfigurer { + + @Bean + public AccessApiInterceptor accessApiInterceptor(){ + return new AccessApiInterceptor(); + } + + @Override + public void addInterceptors(InterceptorRegistry registry){ + registry.addInterceptor(accessApiInterceptor()); + } + + @Bean + public DeviceHandlerMethodArgumentResolver deviceHandlerMethodArgumentResolver() { + return new DeviceHandlerMethodArgumentResolver(); + } + + @Override + public void addArgumentResolvers(List argumentResolvers) { + argumentResolvers.add(deviceHandlerMethodArgumentResolver()); + } + + @Bean + public MybatisPlusInterceptor mybatisPlusInterceptor() { + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 如果配置多个插件, 切记分页最后添加 + // 如果有多数据源可以不配具体类型, 否则都建议配上具体的 DbType + return interceptor; + } + + + @Bean + public MultipartConfigElement multipartConfigElement() { + String path = System.getProperty("user.dir")+"/tmp"; + MultipartConfigFactory factory = new MultipartConfigFactory(); + factory.setMaxFileSize(DataSize.ofMegabytes(20L)); + File tmpFile = new File(path); + if (!tmpFile.exists()) { + tmpFile.mkdirs(); + } + factory.setLocation(path); + return factory.createMultipartConfig(); + } +} diff --git a/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/CorsConfigurer.java b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/CorsConfigurer.java new file mode 100644 index 0000000..6c5ad39 --- /dev/null +++ b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/CorsConfigurer.java @@ -0,0 +1,38 @@ +package com.model2d3d.viewer.back.configurator; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; + +/** + * 跨域配置 +* @author jwy +* @time 2022-5-12 17:54:43 + */ +@Configuration +public class CorsConfigurer { + @Value("${crosxss.origin:*}") + private String corsOrigin; + @Bean + public FilterRegistrationBean corsFilter() { + List allowedOriginPatterns = new ArrayList(); + allowedOriginPatterns.add(corsOrigin); + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + CorsConfiguration config = new CorsConfiguration(); + config.setAllowCredentials(true); + config.setAllowedOriginPatterns(allowedOriginPatterns); + config.addAllowedHeader("*"); + config.addAllowedMethod("*"); + source.registerCorsConfiguration("/**", config); + FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source)); + bean.setOrder(0); + return bean; + } +} \ No newline at end of file diff --git a/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/CrosXssFilter.java b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/CrosXssFilter.java new file mode 100644 index 0000000..820e6c9 --- /dev/null +++ b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/CrosXssFilter.java @@ -0,0 +1,78 @@ +package com.model2d3d.viewer.back.configurator; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.annotation.WebFilter; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import java.util.UUID; + +import org.jboss.logging.MDC; + +@WebFilter +public class CrosXssFilter implements Filter { + + private static final Logger logger = LoggerFactory.getLogger(CrosXssFilter.class); + + @Value("${crosxss.filter.disable:false}") + private boolean disable; + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + try { + MDC.put("processNo", UUID.randomUUID().toString().replace("-", "")); + request.setCharacterEncoding("utf-8"); +// response.setContentType("text/html;charset=utf-8"); + if (disable) { + chain.doFilter(request, response); + } else { + //跨域设置 + if (response instanceof HttpServletResponse) { + HttpServletResponse httpServletResponse = (HttpServletResponse) response; + //禁用浏览器缓存 + httpServletResponse.setHeader("Cache-Control", "no-store"); + //禁止被IFrame嵌套 + httpServletResponse.setHeader("X-Frame-Options", "deny"); + //安全性配置 + httpServletResponse.setHeader("X-XSS-Protection", "1; mode=block"); + httpServletResponse.setHeader("X-Content-Type-Options", "nosniff"); + httpServletResponse.setHeader("Referrer-Policy", "origin"); + } + ServletRequest requestWrapper = null; + if(request instanceof HttpServletRequest) { + requestWrapper = new RequestWrapper((HttpServletRequest) request); + } + if(requestWrapper == null) { + chain.doFilter(request, response); + } else { + chain.doFilter(requestWrapper, response); + } + } + } finally { + // 避免线程泄漏 + MDC.clear(); + } + + } + + @Override + public void destroy() { + + } + +} \ No newline at end of file diff --git a/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/RequestWrapper.java b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/RequestWrapper.java new file mode 100644 index 0000000..1478c28 --- /dev/null +++ b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/RequestWrapper.java @@ -0,0 +1,92 @@ +package com.model2d3d.viewer.back.configurator; + +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; + +public class RequestWrapper extends HttpServletRequestWrapper { + + private static final Logger logger = LoggerFactory.getLogger(HttpServletRequestWrapper.class); + + private final String body; + + public RequestWrapper(HttpServletRequest request) { + super(request); + StringBuilder stringBuilder = new StringBuilder(); + BufferedReader bufferedReader = null; + InputStream inputStream = null; + try { + inputStream = request.getInputStream(); + if (inputStream != null) { + bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + char[] charBuffer = new char[128]; + int bytesRead = -1; + while ((bytesRead = bufferedReader.read(charBuffer)) > 0) { + stringBuilder.append(charBuffer, 0, bytesRead); + } + } else { + stringBuilder.append(""); + } + } catch (IOException ex) { + logger.error("RequestWrapper读取流错误", ex); + } finally { + if (inputStream != null) { + try { + inputStream.close(); + } + catch (IOException e) { + e.printStackTrace(); + } + } + if (bufferedReader != null) { + try { + bufferedReader.close(); + } + catch (IOException e) { + e.printStackTrace(); + } + } + } + body = stringBuilder.toString(); + } + + @Override + public ServletInputStream getInputStream() throws IOException { + final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes()); + ServletInputStream servletInputStream = new ServletInputStream() { + @Override + public boolean isFinished() { + return false; + } + @Override + public boolean isReady() { + return false; + } + @Override + public void setReadListener(ReadListener readListener) { + } + @Override + public int read() throws IOException { + return byteArrayInputStream.read(); + } + }; + return servletInputStream; + + } + + @Override + public BufferedReader getReader() throws IOException { + return new BufferedReader(new InputStreamReader(this.getInputStream())); + } + + public String getBody() { + return this.body; + } + +} \ No newline at end of file diff --git a/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/handler/GlobalExceptionHandler.java b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/handler/GlobalExceptionHandler.java new file mode 100644 index 0000000..5d5306b --- /dev/null +++ b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/handler/GlobalExceptionHandler.java @@ -0,0 +1,118 @@ +package com.model2d3d.viewer.back.configurator.handler; + +import com.model2d3d.viewer.back.common.language.msg.MsgLanguageChange; +import com.model2d3d.viewer.back.common.response.ResponseCode; +import com.model2d3d.viewer.back.common.response.SimpleDataResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import org.hibernate.validator.constraints.Length; +import org.hibernate.validator.constraints.Range; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import java.lang.reflect.Field; +import java.text.MessageFormat; +import java.util.HashMap; +import java.util.Map; + +@RestControllerAdvice +public class GlobalExceptionHandler { + + @Autowired + private MsgLanguageChange msgLanguageChange; + + // 处理@NotNull等校验异常 + @ResponseStatus(HttpStatus.BAD_REQUEST)// 这里jakarta.validation.constraints MethodArgumentNotValidException错误码是400(Bad Request) + @ExceptionHandler(MethodArgumentNotValidException.class) + public SimpleDataResponse handleValidationExceptions( + MethodArgumentNotValidException ex, + HttpServletRequest request) { + + // 获取语言类型,默认为中文 + String languageType = request.getHeader("LanguageType"); + if (languageType == null || languageType.isEmpty()) { + languageType = "0"; // 默认中文 + } + + Map errors = new HashMap<>(); + + Integer finalLanguageType = Integer.valueOf(languageType); + ex.getBindingResult().getAllErrors().forEach((error) -> { + String fieldName = ((FieldError) error).getField(); + String errorMessage = error.getDefaultMessage(); + + // 尝试获取字段的注解信息 + try { + Field field = ex.getBindingResult().getTarget().getClass().getDeclaredField(fieldName); + + Length lengthAnnotation = field.getAnnotation(Length.class); + Range rangeAnnotation = field.getAnnotation(Range.class); + Min minAnnotation = field.getAnnotation(Min.class); + Max maxAnnotation = field.getAnnotation(Max.class); + // 处理Length校验 + if (lengthAnnotation != null && ("1002".equals(errorMessage) || errorMessage.contains("length"))) {// 处理长度校验错误 + errorMessage = handleLengthValidationError(lengthAnnotation, finalLanguageType); + } + // 处理Range校验 + else if (rangeAnnotation != null && ("1005".equals(errorMessage) || errorMessage.contains("Range"))) { + errorMessage = handleRangeValidationError(rangeAnnotation, finalLanguageType); + } + // 处理min校验 + else if (minAnnotation != null && ("1006".equals(errorMessage) || errorMessage.contains("Min"))) { + errorMessage = handleMinValidationError(minAnnotation, finalLanguageType); + } + // 处理max校验 + else if (maxAnnotation != null && ("1007".equals(errorMessage) || errorMessage.contains("Max"))) { + errorMessage = handleMaxValidationError(maxAnnotation, finalLanguageType); + } + // 处理其他校验错误 + else { + errorMessage = translateErrorMessage(errorMessage, finalLanguageType); + } + } catch (Exception e) { + // 如果无法获取字段信息,使用默认翻译 + errorMessage = translateErrorMessage(errorMessage, finalLanguageType); + } + + errors.put(fieldName, errorMessage); + }); + + return new SimpleDataResponse( + ResponseCode.BAD_REQUEST, + msgLanguageChange.getBadRequestMessage(finalLanguageType, "1000"), + errors); + } + + private String handleMaxValidationError(Max max, Integer languageType) { + long value = max.value(); + return MessageFormat.format(msgLanguageChange.getBadRequestMessage(languageType, "1007"), value) ; + } + + private String handleMinValidationError(Min min, Integer languageType) { + long value = min.value(); + return MessageFormat.format(msgLanguageChange.getBadRequestMessage(languageType, "1006"), value) ; + } + + private String handleRangeValidationError(Range rangeAnnotation, Integer finalLanguageType) { + long max = rangeAnnotation.max(); + long min = rangeAnnotation.min(); + return MessageFormat.format(msgLanguageChange.getBadRequestMessage(finalLanguageType, "1005"), min, max) ; + } + + private String handleLengthValidationError(Length lengthAnnotation, Integer languageType) { + int max = lengthAnnotation.max(); +// int min = lengthAnnotation.min(); + return MessageFormat.format(msgLanguageChange.getBadRequestMessage(languageType, "1002"), max) ; + } + + private String translateErrorMessage(String errorCode, Integer languageType) { + return msgLanguageChange.getBadRequestMessage(languageType, errorCode); + } + +} diff --git a/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/interceptor/AccessApiInterceptor.java b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/interceptor/AccessApiInterceptor.java new file mode 100644 index 0000000..bfe2261 --- /dev/null +++ b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/interceptor/AccessApiInterceptor.java @@ -0,0 +1,73 @@ +package com.model2d3d.viewer.back.configurator.interceptor; + + +import com.alibaba.fastjson.JSONObject; +import com.model2d3d.viewer.back.common.response.ResponseCode; +import com.model2d3d.viewer.back.service.AccountService; + +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.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.resource.ResourceHttpRequestHandler; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.lang.reflect.Method; + +public class AccessApiInterceptor implements HandlerInterceptor { + + private static final Logger logger = LoggerFactory.getLogger(AccessApiInterceptor.class); + + @Value("${user.login.keytimeout}") + private long keytimeout; + + @Autowired + private AccountService accountService; + + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + if(handler instanceof HandlerMethod) { + HandlerMethod handlerMethod = (HandlerMethod) handler; + Class tClass = handlerMethod.getBeanType(); + AccessRequired annotation = tClass.getAnnotation(AccessRequired.class); + if (annotation == null) { + Method method = handlerMethod.getMethod(); + annotation = method.getAnnotation(AccessRequired.class); + } + try { + if (annotation != null) { + String loginName = request.getHeader("LoginName"); + String accessToken = request.getHeader("AccessToken"); + String userId = request.getHeader("UserId"); + String companyId = request.getHeader("CompanyId"); + + String languageType = request.getHeader("LanguageType"); + response.setContentType("application/json;charset=utf-8"); + String URI = request.getRequestURI(); + logger.info("===============请求的URI :" + URI + " ==============="); + JSONObject jsonObject = new JSONObject(); + + boolean result = accountService.accessAuth(loginName, companyId, userId, accessToken, languageType, jsonObject, keytimeout); + if(!result) { + response.getWriter().print(jsonObject.toString()); + } + return result; + } + } catch (Exception e) { + logger.error("Error from AccessApiInterceptor!", e); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("code", ResponseCode.SERVER_ERROR); + jsonObject.put("msg", ResponseCode.SERVER_ERROR_MSG); + response.getWriter().print(jsonObject.toString()); + return false; + } + // 没有注解通过拦截 + return true; + }else if(handler instanceof ResourceHttpRequestHandler) {//资源文件不拦截 + return true; + } + return false; + } +} diff --git a/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/interceptor/AccessRequired.java b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/interceptor/AccessRequired.java new file mode 100644 index 0000000..eca16cf --- /dev/null +++ b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/configurator/interceptor/AccessRequired.java @@ -0,0 +1,10 @@ +package com.model2d3d.viewer.back.configurator.interceptor; + +import java.lang.annotation.*; + +@Target({ElementType.TYPE,ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface AccessRequired { + +} \ No newline at end of file diff --git a/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/controller/AccountController.java b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/controller/AccountController.java new file mode 100644 index 0000000..a74a3ea --- /dev/null +++ b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/controller/AccountController.java @@ -0,0 +1,96 @@ +package com.model2d3d.viewer.back.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.apache.commons.codec.binary.Base64; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.mobile.device.Device; +import org.springframework.web.bind.annotation.*; + +import com.google.code.kaptcha.impl.DefaultKaptcha; +import com.model2d3d.viewer.back.common.response.SimpleDataResponse; +import com.model2d3d.viewer.back.configurator.interceptor.AccessRequired; +import com.model2d3d.viewer.back.dto.account.CacheUserData; +import com.model2d3d.viewer.back.dto.account.LoginParam; +import com.model2d3d.viewer.back.service.AccountService; +import com.model2d3d.viewer.back.service.captcha.CaptchaService; +import com.model2d3d.viewer.back.service.captcha.CaptchaVO; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import javax.imageio.ImageIO; + +/** + * 账户管理 + * @author jwy-style + * + */ +@RestController +@RequestMapping("/account") +@Tag(name = "AccountController",description = "账号登录/登出、获取验证码接口") +public class AccountController { + + @Autowired + private AccountService accountService; + @Autowired + private DefaultKaptcha producer; + @Autowired + private CaptchaService captchaService; + + + @Operation(summary = "用户登录") + @RequestMapping(value = "/login", method = RequestMethod.POST) + public SimpleDataResponse login(@RequestBody LoginParam loginParam, + @Parameter(name="LanguageType",description="语言类型 0:中文 1:英文 2:日文",required=true, schema = @Schema(defaultValue = "2")) @RequestHeader(required=true) Integer LanguageType, + HttpServletRequest request, + HttpServletResponse response, + Device device) { + return accountService.login(loginParam,device,LanguageType,request,response); + } + + + + /** + * 用户退出登录 + */ + @AccessRequired + @Operation(summary = "用户退出") + @RequestMapping(value = "/logout", method = RequestMethod.GET) + public SimpleDataResponse logout( @Parameter(name="LoginName",description="登录名",required=true) @RequestHeader(required=true) String LoginName, + @Parameter(name="AccessToken",description="鉴权token",required=true) @RequestHeader(required=true) String AccessToken, + @Parameter(name="UserId",description="用户ID",required=true) @RequestHeader(required=true) Long UserId, + @Parameter(name="CompanyId",description="所属企业ID",required=false) @RequestHeader(required=false) String CompanyId, + @Parameter(name="LanguageType",description="语言类型 0:中文 1:英文 2:日文",required=true, schema = @Schema(defaultValue = "2")) @RequestHeader(required=true) Integer LanguageType) { + return accountService.logout(AccessToken,CompanyId,LoginName,UserId); + } + + /** + * 获取验证码 + * @return + */ + @Operation(summary = "获取登录验证码") + @RequestMapping(value = "/getCaptcha", method = RequestMethod.GET ) + public SimpleDataResponse getCaptcha() throws IOException { + // 生成文字验证码 + String content = producer.createText(); + // 生成图片验证码 + ByteArrayOutputStream outputStream = null; + BufferedImage image = producer.createImage(content); + outputStream = new ByteArrayOutputStream(); + ImageIO.write(image, "jpg", outputStream); + // 对字节数组Base64编码 +// BASE64Encoder encoder = new BASE64Encoder(); + String str = "data:image/jpeg;base64,"; + String base64Img = str + Base64.encodeBase64String(outputStream.toByteArray()).replace("\n", "").replace("\r", ""); + CaptchaVO captchaVO = captchaService.cacheCaptcha(content); + captchaVO.setBase64Img(base64Img); + return SimpleDataResponse.success(captchaVO); + } + +} \ No newline at end of file diff --git a/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/controller/CommonController.java b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/controller/CommonController.java new file mode 100644 index 0000000..f1c752e --- /dev/null +++ b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/controller/CommonController.java @@ -0,0 +1,48 @@ +package com.model2d3d.viewer.back.controller; + +import java.util.List; + +import io.swagger.v3.oas.annotations.Hidden; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +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.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.alibaba.fastjson.JSONObject; +import com.model2d3d.viewer.back.common.response.SimpleDataResponse; +import com.model2d3d.viewer.back.service.CommonService; + +/** + * + * @author jwy-style + * + */ +//@Hidden +@RestController//代表返回的是json格式的数据,这个注解是Spring4之后新加的注解 +@RequestMapping("/common") //http请求路径映射 +@Tag(name = "CommonController",description = "公共接口") +@SuppressWarnings("unchecked") +public class CommonController{ + + private static Logger logger = LoggerFactory.getLogger(CommonController.class); + + @Autowired + private CommonService commonService; + + + @Hidden + @Operation(summary = "检测apikey是否有效") + @RequestMapping(value = "/checkApikey",method = RequestMethod.GET) + public SimpleDataResponse checkApikey( + @Parameter(name="apikey",description="apikey值",required=true) @RequestParam String apikey){ + return commonService.checkApikey(apikey); + } +} diff --git a/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/controller/CompanyController.java b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/controller/CompanyController.java new file mode 100644 index 0000000..1b00d89 --- /dev/null +++ b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/controller/CompanyController.java @@ -0,0 +1,126 @@ +package com.model2d3d.viewer.back.controller; + +import java.util.List; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.model2d3d.viewer.back.common.response.PageResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import com.model2d3d.viewer.back.common.exception.BusinessException; +import com.model2d3d.viewer.back.common.response.ResponseCode; +import com.model2d3d.viewer.back.common.response.SimpleDataResponse; +import com.model2d3d.viewer.back.configurator.interceptor.AccessRequired; +import com.model2d3d.viewer.back.dto.company.CompanySearchParams; +import com.model2d3d.viewer.back.dto.company.DeleteCompanyParams; +import com.model2d3d.viewer.back.dto.company.OptCompanyParams; +import com.model2d3d.viewer.back.vo.company.CompanyPageDTO; +import com.model2d3d.viewer.back.vo.TreeMenusDTO; +import com.model2d3d.viewer.back.service.CompanyService; + +/** + * + * @author jwy-style + * + */ +@RestController//代表返回的是json格式的数据,这个注解是Spring4之后新加的注解 +//@AccessRequired //注解标识是否需要验证token +@RequestMapping("/company") //http请求路径映射 +@Tag(name = "CompanyController",description = "企业管理的相关接口") +@SuppressWarnings("unchecked") +public class CompanyController { + + private static Logger logger = LoggerFactory.getLogger(CompanyController.class); + + @Autowired + private CompanyService companyService; + + + @AccessRequired + @Operation(summary = "添加企业") + @RequestMapping(value = "/add",method = RequestMethod.POST) + public SimpleDataResponse add( + @RequestBody @Validated OptCompanyParams optCompanyParams, + @Parameter(name="LoginName",description="登录名",required=true,schema = @Schema(defaultValue = "admin")) @RequestHeader(required=true) String LoginName, + @Parameter(name="AccessToken",description="鉴权token",required=true) @RequestHeader(required=true) String AccessToken, + @Parameter(name="UserId",description="用户ID",required=true,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) Long UserId, + @Parameter(name="CompanyId",description="所属企业ID",required=false,schema = @Schema(defaultValue = "1")) @RequestHeader(required=false) String CompanyId, + @Parameter(name="LanguageType",description="语言类型 0:中文 1:英文 2:日文",required=true,schema = @Schema(defaultValue = "0")) @RequestHeader(required=true) Integer LanguageType){ + return companyService.add(optCompanyParams, CompanyId, UserId, LanguageType); + } + + @AccessRequired + @Operation(summary = "编辑企业") + @RequestMapping(value = "/edit",method = RequestMethod.POST) + public SimpleDataResponse edit( + @RequestBody @Validated OptCompanyParams optCompanyParams, + @Parameter(name="LoginName",description="登录名",required=true,schema = @Schema(defaultValue = "admin")) @RequestHeader(required=true) String LoginName, + @Parameter(name="AccessToken",description="鉴权token",required=true) @RequestHeader(required=true) String AccessToken, + @Parameter(name="UserId",description="用户ID",required=true,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) Long UserId, + @Parameter(name="CompanyId",description="所属企业ID",required=false,schema = @Schema(defaultValue = "1")) @RequestHeader(required=false) String CompanyId, + @Parameter(name="LanguageType",description="语言类型 0:中文 1:英文 2:日文",required=true,schema = @Schema(defaultValue = "0")) @RequestHeader(required=true) Integer LanguageType) { + return companyService.edit(optCompanyParams, CompanyId, UserId, LanguageType); + } + + @AccessRequired + @Operation(summary = "删除企业") + @RequestMapping(value = "/batchDelete",method = RequestMethod.POST) + public SimpleDataResponse batchDelete( + @RequestBody @Validated DeleteCompanyParams deleteCompanyParams, + @Parameter(name="LoginName",description="登录名",required=true,schema = @Schema(defaultValue = "admin")) @RequestHeader(required=true) String LoginName, + @Parameter(name="AccessToken",description="鉴权token",required=true) @RequestHeader(required=true) String AccessToken, + @Parameter(name="UserId",description="用户ID",required=true,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) Long UserId, + @Parameter(name="CompanyId",description="所属企业ID",required=false,schema = @Schema(defaultValue = "1")) @RequestHeader(required=false) String CompanyId, + @Parameter(name="LanguageType",description="语言类型 0:中文 1:英文 2:日文",required=true,schema = @Schema(defaultValue = "0")) @RequestHeader(required=true) Integer LanguageType){ + return companyService.batchDelete(deleteCompanyParams, CompanyId, UserId, LanguageType); + } + + @AccessRequired + @Operation(summary = "获取当前登录用户下的企业菜单树") + @RequestMapping(value = "/getCompanyTree",method = RequestMethod.GET) + public SimpleDataResponse> getCompanyTree( + @Parameter(name="LoginName",description="登录名",required=true,schema = @Schema(defaultValue = "admin")) @RequestHeader(required=true) String LoginName, + @Parameter(name="AccessToken",description="鉴权token",required=true) @RequestHeader(required=true) String AccessToken, + @Parameter(name="UserId",description="用户ID",required=true,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) Long UserId, + @Parameter(name="CompanyId",description="所属企业ID",required=false,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) String CompanyId, + @Parameter(name="LanguageType",description="语言类型 0:中文 1:英文 2:日文",required=true,schema = @Schema(defaultValue = "0")) @RequestHeader(required=true) Integer LanguageType){ + return companyService.getCompanyTree(CompanyId, UserId, LanguageType); + } + + @AccessRequired + @Operation(summary = "获取企业列表") + @RequestMapping(value = "/getListPage",method = RequestMethod.GET) + public PageResponse> getListPage( + @Parameter(name="LoginName",description="登录名",required=true,schema = @Schema(defaultValue = "admin")) @RequestHeader(required=true) String LoginName, + @Parameter(name="AccessToken",description="鉴权token",required=true) @RequestHeader(required=true) String AccessToken, + @Parameter(name="UserId",description="用户ID",required=true,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) Long UserId, + @Parameter(name="CompanyId",description="所属企业ID",required=false,schema = @Schema(defaultValue = "1")) @RequestHeader(required=false) String CompanyId, +// @Parameter(name="LoginCompanyId",description="登录用户的企业ID",required=false,schema = @Schema(defaultValue = "1") @RequestHeader(required=false) Long LoginCompanyId, + @Parameter(name="LanguageType",description="语言类型 0:中文 1:英文 2:日文",required=true,schema = @Schema(defaultValue = "0")) @RequestHeader(required=true) Integer LanguageType, + @Parameter(name="UTCOffset",description="格林威治时间与本地时间的差值,单位是分钟,比如东八区是 -480",required=true,schema = @Schema(defaultValue = "-480")) @RequestHeader(required=true) Integer UTCOffset, + CompanySearchParams pageSearchParam + ) throws BusinessException { + + pageSearchParam.setUserId(UserId); + + PageResponse> pageResponse = new PageResponse>(); + try{ + pageResponse.setData(companyService.getListPage(pageSearchParam, CompanyId, UserId, LanguageType, UTCOffset)); + pageResponse.setCode(ResponseCode.SUCCESS); + pageResponse.setMsg("success"); + }catch (Exception e){ + logger.error("查询列表报错",e); + pageResponse.setCode(ResponseCode.SERVER_ERROR); + pageResponse.setMsg(ResponseCode.SERVER_ERROR_MSG); + } + return pageResponse; + } + +} diff --git a/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/controller/HealthController.java b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/controller/HealthController.java new file mode 100644 index 0000000..ee47b15 --- /dev/null +++ b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/controller/HealthController.java @@ -0,0 +1,37 @@ +package com.model2d3d.viewer.back.controller; + +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.alibaba.fastjson.JSONObject; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.Properties; + +@RestController +@Tag(name = "HealthController",description = "健康检测接口") +public class HealthController { + + @GetMapping("/healthcheck") + public String health(){ + return "ok"; + } + + @GetMapping("/version") + public String getVersion() throws IOException { + Properties properties = new Properties(); + Reader in = new InputStreamReader(this.getClass().getResourceAsStream("/config/version.properties"),"utf-8"); + BufferedReader bufferedReader = new BufferedReader(in); + properties.load(bufferedReader); + String version=properties.getProperty("project.latest.version"); + String content = properties.getProperty(version); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("version", version); + jsonObject.put("content", content); + return jsonObject.toString(); + } +} diff --git a/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/controller/RoleController.java b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/controller/RoleController.java new file mode 100644 index 0000000..9674b9e --- /dev/null +++ b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/controller/RoleController.java @@ -0,0 +1,133 @@ +package com.model2d3d.viewer.back.controller; + + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.model2d3d.viewer.back.common.exception.BusinessException; +import com.model2d3d.viewer.back.common.response.PageResponse; +import com.model2d3d.viewer.back.common.response.ResponseCode; +import com.model2d3d.viewer.back.common.response.SimpleDataResponse; +import com.model2d3d.viewer.back.configurator.interceptor.AccessRequired; +import com.model2d3d.viewer.back.dto.role.DeleteRoleParam; +import com.model2d3d.viewer.back.dto.role.OptRoleParam; +import com.model2d3d.viewer.back.dto.role.RolePageSearchParam; +import com.model2d3d.viewer.back.vo.TreeMenusDTO; +import com.model2d3d.viewer.back.vo.role.RolePageDTO; +import com.model2d3d.viewer.back.service.RoleService; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +/** + * + * @author jwy-style + * + */ +@RestController//代表返回的是json格式的数据,这个注解是Spring4之后新加的注解 +@AccessRequired //注解标识是否需要验证token +@RequestMapping("/role") //http请求路径映射 +@Tag(name = "RoleController",description = "角色权限的相关接口") +@SuppressWarnings("unchecked") +public class RoleController { + + private static Logger logger = LoggerFactory.getLogger(RoleController.class); + + @Autowired + private RoleService roleService; + + + @Operation(summary = "添加角色") + @RequestMapping(value = "/add",method = RequestMethod.POST) + public SimpleDataResponse add( + @RequestBody @Validated OptRoleParam optRoleParam, + @Parameter(name="LoginName",description="登录名",required=true,schema = @Schema(defaultValue = "admin")) @RequestHeader(required=true) String LoginName, + @Parameter(name="AccessToken",description="鉴权token",required=true) @RequestHeader(required=true) String AccessToken, + @Parameter(name="UserId",description="用户ID",required=true,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) Long UserId, + @Parameter(name="CompanyId",description="所属企业ID",required=false,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) String CompanyId, + @Parameter(name="LanguageType",description="语言类型 0:中文 1:英文 2:日文",required=true,schema = @Schema(defaultValue = "0")) @RequestHeader(required=true) Integer LanguageType){ + return roleService.add(optRoleParam, CompanyId, UserId, LanguageType); + } + + @Operation(summary = "编辑角色") + @RequestMapping(value = "/edit",method = RequestMethod.POST) + public SimpleDataResponse edit( + @RequestBody @Validated OptRoleParam optRoleParam, + @Parameter(name="LoginName",description="登录名",required=true,schema = @Schema(defaultValue = "admin")) @RequestHeader(required=true) String LoginName, + @Parameter(name="AccessToken",description="鉴权token",required=true) @RequestHeader(required=true) String AccessToken, + @Parameter(name="UserId",description="用户ID",required=true,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) Long UserId, + @Parameter(name="CompanyId",description="所属企业ID",required=false,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) String CompanyId, + @Parameter(name="LanguageType",description="语言类型 0:中文 1:英文 2:日文",required=true,schema = @Schema(defaultValue = "0")) @RequestHeader(required=true) Integer LanguageType){ + return roleService.edit(optRoleParam, CompanyId, UserId, LanguageType); + } + + @Operation(summary = "删除角色") + @RequestMapping(value = "/batchDelete",method = RequestMethod.POST) + public SimpleDataResponse batchDelete( + @RequestBody @Validated DeleteRoleParam deleteRoleParam, + @Parameter(name="LoginName",description="登录名",required=true,schema = @Schema(defaultValue = "admin")) @RequestHeader(required=true) String LoginName, + @Parameter(name="AccessToken",description="鉴权token",required=true) @RequestHeader(required=true) String AccessToken, + @Parameter(name="UserId",description="用户ID",required=true,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) Long UserId, + @Parameter(name="CompanyId",description="所属企业ID",required=false,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) String CompanyId, + @Parameter(name="LanguageType",description="语言类型 0:中文 1:英文 2:日文",required=true,schema = @Schema(defaultValue = "0")) @RequestHeader(required=true) Integer LanguageType){ + return roleService.batchDelete(deleteRoleParam, CompanyId, UserId, LanguageType); + } + + @Operation(summary = "获取角色列表") + @RequestMapping(value = "/getListPage",method = RequestMethod.GET) + public PageResponse> getListPage( + @Parameter(name="LoginName",description="登录名",required=true,schema = @Schema(defaultValue = "admin")) @RequestHeader(required=true) String LoginName, + @Parameter(name="AccessToken",description="鉴权token",required=true) @RequestHeader(required=true) String AccessToken, + @Parameter(name="UserId",description="用户ID",required=true,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) Long UserId, + @Parameter(name="CompanyId",description="所属企业ID",required=false,schema = @Schema(defaultValue = "1")) @RequestHeader(required=false) String CompanyId, + @Parameter(name="LanguageType",description="语言类型 0:中文 1:英文 2:日文",required=true,schema = @Schema(defaultValue = "0")) @RequestHeader(required=true) Integer LanguageType, + RolePageSearchParam pageSearchParam + ) throws BusinessException { + + pageSearchParam.setUserId(UserId); +// pageSearchParam.setCompanyId(CompanyId); + PageResponse> pageResponse = new PageResponse>(); + try{ + pageResponse.setData(roleService.getListPage(pageSearchParam, CompanyId, UserId, LanguageType)); + pageResponse.setCode(ResponseCode.SUCCESS); + pageResponse.setMsg("success"); + }catch (Exception e){ + logger.error("查询列表报错",e); + pageResponse.setCode(ResponseCode.SERVER_ERROR); + pageResponse.setMsg(ResponseCode.SERVER_ERROR_MSG); + } + return pageResponse; + } + + @Operation(summary = "获取当前登录用户拥有的权限菜单树") + @RequestMapping(value = "/getOwnMenuIds",method = RequestMethod.GET) + public SimpleDataResponse> getOwnMenuIds( + @Parameter(name="LoginName",description="登录名",required=true,schema = @Schema(defaultValue = "admin")) @RequestHeader(required=true) String LoginName, + @Parameter(name="AccessToken",description="鉴权token",required=true) @RequestHeader(required=true) String AccessToken, + @Parameter(name="UserId",description="用户ID",required=true,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) Long UserId, + @Parameter(name="CompanyId",description="所属企业ID",required=false,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) String CompanyId, + @Parameter(name="LanguageType",description="语言类型 0:中文 1:英文 2:日文",required=true,schema = @Schema(defaultValue = "0")) @RequestHeader(required=true) Integer LanguageType){ + return roleService.getOwnMenuIds(CompanyId, UserId, LanguageType); + } + + @Operation(summary = "获取对应角色拥有的权限菜单ID") + @RequestMapping(value = "/getMenuIdsByRoleId",method = RequestMethod.GET) + public SimpleDataResponse getMenuIdsByRoleId( + @Parameter(name="roleId",description="角色ID",required=true, schema = @Schema(defaultValue = "28")) @RequestParam Long roleId, + @Parameter(name="LoginName",description="登录名",required=true,schema = @Schema(defaultValue = "admin")) @RequestHeader(required=true) String LoginName, + @Parameter(name="AccessToken",description="鉴权token",required=true) @RequestHeader(required=true) String AccessToken, + @Parameter(name="UserId",description="用户ID",required=true,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) Long UserId, + @Parameter(name="CompanyId",description="所属企业ID",required=false,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) String CompanyId, + @Parameter(name="LanguageType",description="语言类型 0:中文 1:英文 2:日文",required=true,schema = @Schema(defaultValue = "0")) @RequestHeader(required=true) Integer LanguageType){ + return roleService.getMenuIdsByRoleId(roleId, CompanyId, UserId, LanguageType); + } + +} diff --git a/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/controller/UserController.java b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/controller/UserController.java new file mode 100644 index 0000000..4afedcc --- /dev/null +++ b/model2d3d-viewer-back-controller/src/main/java/com/model2d3d/viewer/back/controller/UserController.java @@ -0,0 +1,138 @@ +package com.model2d3d.viewer.back.controller; + + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.model2d3d.viewer.back.common.exception.BusinessException; +import com.model2d3d.viewer.back.common.response.PageResponse; +import com.model2d3d.viewer.back.common.response.ResponseCode; +import com.model2d3d.viewer.back.common.response.SimpleDataResponse; +import com.model2d3d.viewer.back.configurator.interceptor.AccessRequired; +import com.model2d3d.viewer.back.dto.user.DeleteUserParam; +import com.model2d3d.viewer.back.dto.user.ModifyPassword; +import com.model2d3d.viewer.back.dto.user.OptUserParam; +import com.model2d3d.viewer.back.dto.user.PageSearchParam; +import com.model2d3d.viewer.back.dto.user.ResetPassword; +import com.model2d3d.viewer.back.service.UserService; +import com.model2d3d.viewer.back.vo.user.UserPageDTO; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +/** + * + * @author jwy-style + * + */ +@RestController//代表返回的是json格式的数据,这个注解是Spring4之后新加的注解 +//@AccessRequired //注解标识是否需要验证token +@RequestMapping("/user") //http请求路径映射 +@Tag(name = "UserController",description = "用户管理的相关接口") +@SuppressWarnings("unchecked") +public class UserController { + + private static Logger logger = LoggerFactory.getLogger(UserController.class); + + @Autowired + private UserService userService; + + @AccessRequired + @Operation(summary = "添加用户") + @RequestMapping(value = "/add",method = RequestMethod.POST) + public SimpleDataResponse add( + @RequestBody @Validated OptUserParam optUserParam, + @Parameter(name="LoginName",description="登录名",required=true,schema = @Schema(defaultValue = "admin")) @RequestHeader(required=true) String LoginName, + @Parameter(name="AccessToken",description="鉴权token",required=true) @RequestHeader(required=true) String AccessToken, + @Parameter(name="UserId",description="用户ID",required=true,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) Long UserId, + @Parameter(name="CompanyId",description="所属企业ID",required=false,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) String CompanyId, + @Parameter(name="LanguageType",description="语言类型 0:中文 1:英文 2:日文",required=true,schema = @Schema(defaultValue = "0")) @RequestHeader(required=true) Integer LanguageType){ + return userService.add(optUserParam, CompanyId, UserId, LanguageType); + } + + @AccessRequired + @Operation(summary = "编辑用户") + @RequestMapping(value = "/edit",method = RequestMethod.POST) + public SimpleDataResponse edit( + @RequestBody @Validated OptUserParam optUserParam, + @Parameter(name="LoginName",description="登录名",required=true,schema = @Schema(defaultValue = "admin")) @RequestHeader(required=true) String LoginName, + @Parameter(name="AccessToken",description="鉴权token",required=true) @RequestHeader(required=true) String AccessToken, + @Parameter(name="UserId",description="用户ID",required=true,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) Long UserId, + @Parameter(name="CompanyId",description="所属企业ID",required=false,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) String CompanyId, + @Parameter(name="LanguageType",description="语言类型 0:中文 1:英文 2:日文",required=true,schema = @Schema(defaultValue = "0")) @RequestHeader(required=true) Integer LanguageType){ + return userService.edit(optUserParam, CompanyId, UserId, LanguageType); + } + + @AccessRequired + @Operation(summary = "删除用户") + @RequestMapping(value = "/batchDelete",method = RequestMethod.POST) + public SimpleDataResponse batchDelete( + @RequestBody @Validated DeleteUserParam deleteUserParam, + @Parameter(name="LoginName",description="登录名",required=true,schema = @Schema(defaultValue = "admin")) @RequestHeader(required=true) String LoginName, + @Parameter(name="AccessToken",description="鉴权token",required=true) @RequestHeader(required=true) String AccessToken, + @Parameter(name="UserId",description="用户ID",required=true,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) Long UserId, + @Parameter(name="CompanyId",description="所属企业ID",required=false,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) String CompanyId, + @Parameter(name="LanguageType",description="语言类型 0:中文 1:英文 2:日文",required=true,schema = @Schema(defaultValue = "0")) @RequestHeader(required=true) Integer LanguageType){ + return userService.batchDelete(deleteUserParam, CompanyId, UserId, LanguageType); + } + + @AccessRequired + @Operation(summary = "重置密码") + @RequestMapping(value = "/batchResetPassword",method = RequestMethod.POST) + public SimpleDataResponse batchResetPassword( + @RequestBody @Validated ResetPassword resetPassword, + @Parameter(name="LoginName",description="登录名",required=true,schema = @Schema(defaultValue = "admin")) @RequestHeader(required=true) String LoginName, + @Parameter(name="AccessToken",description="鉴权token",required=true) @RequestHeader(required=true) String AccessToken, + @Parameter(name="UserId",description="用户ID",required=true,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) Long UserId, + @Parameter(name="CompanyId",description="所属企业ID",required=false,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) String CompanyId, + @Parameter(name="LanguageType",description="语言类型 0:中文 1:英文 2:日文",required=true,schema = @Schema(defaultValue = "0")) @RequestHeader(required=true) Integer LanguageType){ + return userService.batchResetPassword(resetPassword, CompanyId, UserId, LanguageType); + } + + @AccessRequired + @Operation(summary = "修改密码") + @RequestMapping(value = "/modifyPassword",method = RequestMethod.POST) + public SimpleDataResponse modifyPassword( + @RequestBody @Validated ModifyPassword modifyPassword, + @Parameter(name="LoginName",description="登录名",required=true,schema = @Schema(defaultValue = "admin")) @RequestHeader(required=true) String LoginName, + @Parameter(name="AccessToken",description="鉴权token",required=true) @RequestHeader(required=true) String AccessToken, + @Parameter(name="UserId",description="用户ID",required=true,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) Long UserId, + @Parameter(name="CompanyId",description="所属企业ID",required=false,schema = @Schema(defaultValue = "1")) @RequestHeader(required=false) String CompanyId, + @Parameter(name="LanguageType",description="语言类型 0:中文 1:英文 2:日文",required=true,schema = @Schema(defaultValue = "0")) @RequestHeader(required=true) Integer LanguageType + ) { + return userService.modifyPassword(modifyPassword, CompanyId, UserId, LanguageType); + } + + @AccessRequired + @Operation(summary = "获取用户列表") + @RequestMapping(value = "/getListPage",method = RequestMethod.GET) + public PageResponse> getListPage( + @Parameter(name="LoginName",description="登录名",required=true,schema = @Schema(defaultValue = "admin")) @RequestHeader(required=true) String LoginName, + @Parameter(name="AccessToken",description="鉴权token",required=true) @RequestHeader(required=true) String AccessToken, + @Parameter(name="UserId",description="用户ID",required=true,schema = @Schema(defaultValue = "1")) @RequestHeader(required=true) Long UserId, + @Parameter(name="CompanyId",description="所属企业ID",required=false,schema = @Schema(defaultValue = "1")) @RequestHeader(required=false) String CompanyId, + @Parameter(name="LanguageType",description="语言类型 0:中文 1:英文 2:日文",required=true,schema = @Schema(defaultValue = "0")) @RequestHeader(required=true) Integer LanguageType, + PageSearchParam pageSearchParam + ) throws BusinessException { + + pageSearchParam.setUserId(UserId); +// pageSearchParam.setCompanyId(CompanyId); + PageResponse> pageResponse = new PageResponse>(); + try{ + pageResponse.setData(userService.getListPage(pageSearchParam, CompanyId, UserId, LanguageType)); + pageResponse.setCode(ResponseCode.SUCCESS); + pageResponse.setMsg("success"); + }catch (Exception e){ + logger.error("查询列表报错",e); + pageResponse.setCode(ResponseCode.SERVER_ERROR); + pageResponse.setMsg(ResponseCode.SERVER_ERROR_MSG); + } + return pageResponse; + } + +} diff --git a/model2d3d-viewer-back-controller/src/main/resources/assembly.xml b/model2d3d-viewer-back-controller/src/main/resources/assembly.xml new file mode 100644 index 0000000..b17b06d --- /dev/null +++ b/model2d3d-viewer-back-controller/src/main/resources/assembly.xml @@ -0,0 +1,59 @@ + + + + model2d3d-viewer-back + + + zip + + + + + + + + ${project.build.directory} + / + + *.jar + + + + + + ${project.build.directory}/jar + / + + lib/*.jar + + + *.jar + + + + + + ${project.build.directory}/lib + /lib + + *.jar + + + + + + ${project.build.directory}/config + /config + + application.properties + + + + + + ${project.build.directory}/sql + /sql + + + + diff --git a/model2d3d-viewer-back-controller/src/main/resources/config/application.properties b/model2d3d-viewer-back-controller/src/main/resources/config/application.properties new file mode 100644 index 0000000..600777a --- /dev/null +++ b/model2d3d-viewer-back-controller/src/main/resources/config/application.properties @@ -0,0 +1,98 @@ +server.port=${serverPort} + +api.enable=${apiEnable} + +spring.mvc.pathmatch.matching-strategy= ANT_PATH_MATCHER + +#mybatis.mapperLocations=classpath:mappers/**/*.xml +# MyBatis-Plus 配置 +mybatis-plus.mapper-locations=classpath:mappers/**/*.xml +# MyBatis 原生配置 +mybatis-plus.configuration.map-underscore-to-camel-case=true +mybatis-plus.configuration.cache-enabled=false +mybatis-plus.configuration.lazy-loading-enabled=false +mybatis-plus.configuration.multiple-result-sets-enabled=false +# MyBatis-Plus 全局配置 +mybatis-plus.global-config.banner=false +mybatis-plus.global-config.enable-sql-runner=false +# 数据库相关配置 +mybatis-plus.global-config.db-config.table-underline=true + +spring.datasource.name=model2d3d_viewer_back +spring.datasource.url=jdbc:mysql://${datasourceDNS}/model2d3d_viewer_back?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=${datasourceTimeZone} +spring.datasource.username=${datasourceUsername} +spring.datasource.password=${datasourcePassword} +#使用druid数据源 +spring.datasource.type=com.alibaba.druid.pool.DruidDataSource +spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver + +#配置log日志 +logging.config=classpath:config/logback-boot.xml +logging_level=${loggingLevel} +logging_path=${loggingPath} +#部署时使用SYSLOG +logging_appender=${loggingAppender} +logging_maxHistory=${loggingMaxHistory:7} +logging_maxFileSize=100MB +mybatis_log_level=${mybatisLogLevel} + +user.login.keytimeout=360000 + +#集群模式cluster +spring.redis.cluster.nodes=192.168.0.30:7000,192.168.0.30:7001 +#跨集群执行命令时要遵循的最大重定向数量 +spring.redis.cluster.max-redirects=3 +#哨兵模式sentinel +spring.redis.sentinel.master=mymaster +spring.redis.sentinel.nodes=192.168.0.30:16379,192.168.0.30:16379 + +#单机模式standalone +spring.redis.host=${redisHost} +spring.redis.port=6379 + +spring.redis.password=${redisPassword} +spring.redis.timeout=5000 +#Redis数据库索引(默认为0) +spring.redis.database=15 +#配置启动模式cluster、sentinel、standalone +spring.redis.mode=standalone +# Lettuce +# 连接池最大连接数(使用负值表示没有限制) +spring.redis.lettuce.pool.max-active=8 +# 连接池最大阻塞等待时间(使用负值表示没有限制) +spring.redis.lettuce.pool.max-wait=100 +# 连接池中的最大空闲连接 +spring.redis.lettuce.pool.max-idle=8 +# 连接池中的最小空闲连接 +spring.redis.lettuce.pool.min-idle=0 +# 关闭超时时间 +spring.redis.lettuce.shutdown-timeout=100 + + +#邮件发送信息 +mail.smtp.host=email-smtp.ap-northeast-1.amazonaws.com +mail.smtp.port=465 +mail.smtp.auth=true +mail.smtp.ssl=true +mail.sender.username=AKIAVRXFMB43Z4Q6WGZN +mail.sender.password_encrypted=true +mail.sender.password=a/52R0rao7ksRMvl1j17fVEmPCw7gC9OreHDqWOE+S7sgmoQT0YgoLRJqOlJqX7e +mail.sender.sendername=datacenter-info +mail.sender.from=alert@ttkdatatechbuild.com +#邮件通知服务开关 +mail.send.switch=true + +Spring.mvc.hiddenmethod.filter.enabled=true +#单个文件上传发大小 +spring.servlet.multipart.max-file-size=20MB +#多个文件上传的共大小不得超过100M +spring.servlet.multipart.max-request-size=100MB + +server.servlet.context-path=/api + +web.login.url=${webLoginUrl} + + +springdoc.swagger-ui.doc-expansion=none +springdoc.swagger-ui.operations-sorter=alpha +springdoc.swagger-ui.tags-sorter=alpha \ No newline at end of file diff --git a/model2d3d-viewer-back-controller/src/main/resources/config/logback-boot.xml b/model2d3d-viewer-back-controller/src/main/resources/config/logback-boot.xml new file mode 100644 index 0000000..1557180 --- /dev/null +++ b/model2d3d-viewer-back-controller/src/main/resources/config/logback-boot.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} %p [%t] %m%n + + UTF-8 + + + + + ${logging_path}/spring.log + + + + + + ${logging_path}/spring.%d.%i.gz + + ${logging_maxHistory} + + + ${logging_maxFileSize} + + + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} %-5p [%t] %c %m%n + + + UTF-8 + + + + + + + + + + + diff --git a/model2d3d-viewer-back-controller/src/main/resources/config/version.properties b/model2d3d-viewer-back-controller/src/main/resources/config/version.properties new file mode 100644 index 0000000..10d9a5d --- /dev/null +++ b/model2d3d-viewer-back-controller/src/main/resources/config/version.properties @@ -0,0 +1,3 @@ +project.latest.version=v0.0.1.20240228 + +v0.0.1.20240228=1.初始版本 \ No newline at end of file diff --git a/model2d3d-viewer-back-dao/.gitignore b/model2d3d-viewer-back-dao/.gitignore new file mode 100644 index 0000000..aa23915 --- /dev/null +++ b/model2d3d-viewer-back-dao/.gitignore @@ -0,0 +1,15 @@ +/target/ +/logs/ +/.idea/ +*.iml +*.bak +*.log +/.settings/ +*.project +*.classpath +*.factorypath +*.springBeans +/.apt_generated/ +/.externalToolBuilders/ +/bin/ +application-*.properties diff --git a/model2d3d-viewer-back-dao/pom.xml b/model2d3d-viewer-back-dao/pom.xml new file mode 100644 index 0000000..31b43df --- /dev/null +++ b/model2d3d-viewer-back-dao/pom.xml @@ -0,0 +1,91 @@ + + + 4.0.0 + + com.techsor + model2d3d-viewer-back + 0.0.1-SNAPSHOT + + model2d3d-viewer-back-dao + model2d3d-viewer-back-dao + http://maven.apache.org + + UTF-8 + + + + + + org.freemarker + freemarker + 2.3.34 + + + + + com.baomidou + mybatis-plus-boot-starter + 3.5.11 + + + + org.mybatis + mybatis-spring + + + + + + + com.baomidou + mybatis-plus-jsqlparser + 3.5.11 + + + + + + com.baomidou + mybatis-plus-generator + 3.5.11 + + + + + org.mybatis + mybatis-spring + 3.0.4 + + + + com.techsor + model2d3d-viewer-back-model + 0.0.1-SNAPSHOT + + + + + + + + + + com.mysql + mysql-connector-j + 9.2.0 + + + + com.alibaba + druid + 1.1.3 + + + + junit + junit + test + + + diff --git a/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/MyBatisPlusGenerator.java b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/MyBatisPlusGenerator.java new file mode 100644 index 0000000..6061ce9 --- /dev/null +++ b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/MyBatisPlusGenerator.java @@ -0,0 +1,152 @@ +package com.model2d3d.viewer.back.dao; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.generator.AutoGenerator; +import com.baomidou.mybatisplus.generator.config.*; +import com.baomidou.mybatisplus.generator.config.builder.GeneratorBuilder; +import com.baomidou.mybatisplus.generator.config.rules.DateType; +import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; +import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine; +import com.baomidou.mybatisplus.generator.config.querys.MySqlQuery; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class MyBatisPlusGenerator { + + public static void main(String[] args) { + // 1. 数据源配置 + DataSourceConfig dataSourceConfig = new DataSourceConfig.Builder( + "jdbc:mysql://rm-bp11k2zm2fr7864428o.mysql.rds.aliyuncs.com:3306/model2d3d_viewer_back?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai", + "zhc", + "Youqu48bnb1") + .dbQuery(new MySqlQuery()) + .schema("model2d3d_viewer_back") + .build(); + + // 2. 全局配置(这里设置公共配置,实际路径在pathInfo中单独指定) + GlobalConfig globalConfig = GeneratorBuilder.globalConfigBuilder() + .author("jwy") + .disableOpenDir() + .enableSwagger() + .dateType(DateType.TIME_PACK) + .commentDate("") + .build(); + + // 3. 包配置(包名设置) + PackageConfig packageConfig = GeneratorBuilder.packageConfigBuilder() + .parent("com.model2d3d.viewer.back") + .entity("model") // 实体类包名 + .mapper("dao.auto") // Mapper接口包名 + .service("service") // Service接口包名 + .serviceImpl("service.impl") // Service实现类包名 + .controller("controller") // Controller包名 + .xml("mappers.auto") // XML文件包名 + .pathInfo(getPathInfo()) // 各层级的实际输出路径 + .build(); + + // 4 + // 自增主键的表 + List autoIncrementTables = Arrays.asList( + "login_history", + "basic_menu" + ); + // uuid算法主键的表 + List assignIdTables = Arrays.asList( + "basic_role", + "basic_company", + "basic_user" + ); + // 没有主键的表 + List noIdTables = Arrays.asList( + "basic_role_menu_relation", + "basic_role_user_relation" + ); + + // 5. 为不同类型表创建不同的策略配置 + generateForTables(dataSourceConfig, globalConfig, packageConfig, + autoIncrementTables, IdType.AUTO); + + generateForTables(dataSourceConfig, globalConfig, packageConfig, + assignIdTables, IdType.ASSIGN_UUID); + + generateForTables(dataSourceConfig, globalConfig, packageConfig, + noIdTables, IdType.NONE); + } + + private static void generateForTables(DataSourceConfig dataSourceConfig, + GlobalConfig globalConfig, + PackageConfig packageConfig, + List tables, + IdType idType) { + StrategyConfig strategyConfig = GeneratorBuilder.strategyConfigBuilder() + .addInclude(tables) + + .entityBuilder() + .enableFileOverride() // 实体类覆盖 + .enableLombok() + .enableTableFieldAnnotation() + .naming(NamingStrategy.underline_to_camel) + .columnNaming(NamingStrategy.underline_to_camel) + .enableChainModel() + .enableRemoveIsPrefix() + .logicDeleteColumnName("deleted") + .idType(idType) + + .mapperBuilder() + .enableFileOverride() // Mapper接口覆盖 + .enableBaseResultMap() + .enableBaseColumnList() + .formatMapperFileName("%sMapper") + .formatXmlFileName("%sMapper") + + .controllerBuilder() + .enableRestStyle() + .disable() + + .serviceBuilder() + .formatServiceFileName("I%sService") + .formatServiceImplFileName("%sServiceImpl") + .disable() + + .build(); + + // 5. 模板配置 + TemplateConfig templateConfig = GeneratorBuilder.templateConfigBuilder() + .entity("/templates/entity.java") //使用自定义模板 + .build(); + + // 6. 创建生成器并执行 + new AutoGenerator(dataSourceConfig) + .global(globalConfig) + .packageInfo(packageConfig) + .strategy(strategyConfig) + .template(templateConfig) + .execute(new FreemarkerTemplateEngine()); + } + + // 自定义各层级的实际输出路径 + private static Map getPathInfo() { + String projectRoot = System.getProperty("user.dir"); + Map pathInfo = new HashMap<>(); + + // 实体类输出到 model 模块 + pathInfo.put(OutputFile.entity, projectRoot + "/model2d3d-viewer-back-model/src/main/java/com/pet/map/back/model"); + // Mapper接口输出到 dao 模块 + pathInfo.put(OutputFile.mapper, projectRoot + "/model2d3d-viewer-back-dao/src/main/java/com/pet/map/back/dao/auto"); + // XML文件输出到 resources 目录 + pathInfo.put(OutputFile.xml, projectRoot + "/model2d3d-viewer-back-dao/src/main/resources/mappers/auto"); + + // Service和ServiceImpl输出到 service 模块 + pathInfo.put(OutputFile.service, projectRoot + "/model2d3d-viewer-back-service/src/main/java/com/pet/map/back/service"); + pathInfo.put(OutputFile.serviceImpl, projectRoot + "/model2d3d-viewer-back-service/src/main/java/com/pet/map/back/service/impl"); + // Controller输出到 controller 模块 + pathInfo.put(OutputFile.controller, projectRoot + "/model2d3d-viewer-back-controller/src/main/java/com/pet/map/back/controller"); + + + + return pathInfo; + } +} \ No newline at end of file diff --git a/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/BasicCompanyMapper.java b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/BasicCompanyMapper.java new file mode 100644 index 0000000..9b08d3d --- /dev/null +++ b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/BasicCompanyMapper.java @@ -0,0 +1,17 @@ +package com.model2d3d.viewer.back.dao.auto; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.model2d3d.viewer.back.model.BasicCompany; + +/** + *

+ * 企业表 Mapper 接口 + *

+ * + * @author jwy + * @since + */ +public interface BasicCompanyMapper extends BaseMapper { + +} + diff --git a/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/BasicMenuMapper.java b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/BasicMenuMapper.java new file mode 100644 index 0000000..259ecac --- /dev/null +++ b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/BasicMenuMapper.java @@ -0,0 +1,17 @@ +package com.model2d3d.viewer.back.dao.auto; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.model2d3d.viewer.back.model.BasicMenu; + +/** + *

+ * Mapper 接口 + *

+ * + * @author jwy + * @since + */ +public interface BasicMenuMapper extends BaseMapper { + +} + diff --git a/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/BasicRoleMapper.java b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/BasicRoleMapper.java new file mode 100644 index 0000000..319ea61 --- /dev/null +++ b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/BasicRoleMapper.java @@ -0,0 +1,17 @@ +package com.model2d3d.viewer.back.dao.auto; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.model2d3d.viewer.back.model.BasicRole; + +/** + *

+ * Mapper 接口 + *

+ * + * @author jwy + * @since + */ +public interface BasicRoleMapper extends BaseMapper { + +} + diff --git a/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/BasicRoleMenuRelationMapper.java b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/BasicRoleMenuRelationMapper.java new file mode 100644 index 0000000..60c12ff --- /dev/null +++ b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/BasicRoleMenuRelationMapper.java @@ -0,0 +1,17 @@ +package com.model2d3d.viewer.back.dao.auto; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.model2d3d.viewer.back.model.BasicRoleMenuRelation; + +/** + *

+ * Mapper 接口 + *

+ * + * @author jwy + * @since + */ +public interface BasicRoleMenuRelationMapper extends BaseMapper { + +} + diff --git a/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/BasicRoleUserRelationMapper.java b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/BasicRoleUserRelationMapper.java new file mode 100644 index 0000000..1277921 --- /dev/null +++ b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/BasicRoleUserRelationMapper.java @@ -0,0 +1,17 @@ +package com.model2d3d.viewer.back.dao.auto; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.model2d3d.viewer.back.model.BasicRoleUserRelation; + +/** + *

+ * Mapper 接口 + *

+ * + * @author jwy + * @since + */ +public interface BasicRoleUserRelationMapper extends BaseMapper { + +} + diff --git a/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/BasicUserMapper.java b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/BasicUserMapper.java new file mode 100644 index 0000000..b6e306c --- /dev/null +++ b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/BasicUserMapper.java @@ -0,0 +1,17 @@ +package com.model2d3d.viewer.back.dao.auto; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.model2d3d.viewer.back.model.BasicUser; + +/** + *

+ * Mapper 接口 + *

+ * + * @author jwy + * @since + */ +public interface BasicUserMapper extends BaseMapper { + +} + diff --git a/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/LoginHistoryMapper.java b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/LoginHistoryMapper.java new file mode 100644 index 0000000..0dd4311 --- /dev/null +++ b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/auto/LoginHistoryMapper.java @@ -0,0 +1,17 @@ +package com.model2d3d.viewer.back.dao.auto; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.model2d3d.viewer.back.model.LoginHistory; + +/** + *

+ * Mapper 接口 + *

+ * + * @author jwy + * @since + */ +public interface LoginHistoryMapper extends BaseMapper { + +} + diff --git a/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/ex/BasicCompanyMapperExt.java b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/ex/BasicCompanyMapperExt.java new file mode 100644 index 0000000..a78079f --- /dev/null +++ b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/ex/BasicCompanyMapperExt.java @@ -0,0 +1,32 @@ +package com.model2d3d.viewer.back.dao.ex; + +import java.util.List; +import java.util.Map; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.model2d3d.viewer.back.model.BasicCompany; +import org.apache.ibatis.annotations.Mapper; + +import com.model2d3d.viewer.back.dao.auto.BasicCompanyMapper; +import com.model2d3d.viewer.back.dto.company.CompanySearchParams; +import com.model2d3d.viewer.back.dto.company.OptCompanyParams; +import com.model2d3d.viewer.back.vo.TreeMenusDTO; +import com.model2d3d.viewer.back.vo.company.CompanyPageDTO; +import org.apache.ibatis.annotations.Param; + +@Mapper +public interface BasicCompanyMapperExt extends BasicCompanyMapper{ + + List getSubCompanyByParentId(Map searchChildMap); + + List getSelectList(Map paramMap); + + int checkExist(OptCompanyParams optCompanyParams); + + IPage getListPage(Page page, @Param("params") CompanySearchParams pageSearchParam); + + List getListForTree(); + + +} diff --git a/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/ex/BasicRoleMapperExt.java b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/ex/BasicRoleMapperExt.java new file mode 100644 index 0000000..db24709 --- /dev/null +++ b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/ex/BasicRoleMapperExt.java @@ -0,0 +1,26 @@ +package com.model2d3d.viewer.back.dao.ex; + +import java.util.List; +import java.util.Map; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.model2d3d.viewer.back.dto.role.RolePageSearchParam; +import org.apache.ibatis.annotations.Mapper; + +import com.model2d3d.viewer.back.dao.auto.BasicRoleMapper; +import com.model2d3d.viewer.back.dto.role.OptRoleParam; +import com.model2d3d.viewer.back.vo.TreeMenusDTO; +import com.model2d3d.viewer.back.vo.role.RolePageDTO; +import org.apache.ibatis.annotations.Param; + +@Mapper +public interface BasicRoleMapperExt extends BasicRoleMapper { + + Long checkExist(OptRoleParam param); + + List getOwnMenuIds(Map paramMap); + + IPage getListPage(Page page, @Param("params") RolePageSearchParam pageSearchParam); + +} diff --git a/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/ex/BasicRoleMenuRelationMapperExt.java b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/ex/BasicRoleMenuRelationMapperExt.java new file mode 100644 index 0000000..76030a5 --- /dev/null +++ b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/ex/BasicRoleMenuRelationMapperExt.java @@ -0,0 +1,16 @@ +package com.model2d3d.viewer.back.dao.ex; + +import java.util.Map; + +import org.apache.ibatis.annotations.Mapper; + +import com.model2d3d.viewer.back.dao.auto.BasicRoleMenuRelationMapper; + +@Mapper +public interface BasicRoleMenuRelationMapperExt extends BasicRoleMenuRelationMapper { + + void batchInsert(Map paramMap); + + String getMenuIdsByRoleId(Long roleId); + +} diff --git a/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/ex/BasicRoleUserRelationMapperExt.java b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/ex/BasicRoleUserRelationMapperExt.java new file mode 100644 index 0000000..3848843 --- /dev/null +++ b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/ex/BasicRoleUserRelationMapperExt.java @@ -0,0 +1,10 @@ +package com.model2d3d.viewer.back.dao.ex; + +import org.apache.ibatis.annotations.Mapper; + +import com.model2d3d.viewer.back.dao.auto.BasicRoleUserRelationMapper; + +@Mapper +public interface BasicRoleUserRelationMapperExt extends BasicRoleUserRelationMapper { + +} diff --git a/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/ex/BasicUserMapperExt.java b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/ex/BasicUserMapperExt.java new file mode 100644 index 0000000..c110bee --- /dev/null +++ b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/ex/BasicUserMapperExt.java @@ -0,0 +1,27 @@ +package com.model2d3d.viewer.back.dao.ex; + +import java.util.List; +import java.util.Map; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import com.model2d3d.viewer.back.dao.auto.BasicUserMapper; +import com.model2d3d.viewer.back.dto.user.OptUserParam; +import com.model2d3d.viewer.back.dto.user.PageSearchParam; +import com.model2d3d.viewer.back.vo.user.UserInfoVO; +import com.model2d3d.viewer.back.vo.user.UserPageDTO; + +@Mapper +public interface BasicUserMapperExt extends BasicUserMapper{ + + Long checkExist(OptUserParam param); + + IPage getListPage(Page page, @Param("params") PageSearchParam pageSearchParam); + + String getMenuIdsByUserId(@Param("userId") String userId); + + UserInfoVO getAccountInfo(Map paramMap); + +} diff --git a/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/ex/LoginHistoryMapperExt.java b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/ex/LoginHistoryMapperExt.java new file mode 100644 index 0000000..cf8de41 --- /dev/null +++ b/model2d3d-viewer-back-dao/src/main/java/com/model2d3d/viewer/back/dao/ex/LoginHistoryMapperExt.java @@ -0,0 +1,10 @@ +package com.model2d3d.viewer.back.dao.ex; + +import org.apache.ibatis.annotations.Mapper; + +import com.model2d3d.viewer.back.dao.auto.LoginHistoryMapper; + +@Mapper +public interface LoginHistoryMapperExt extends LoginHistoryMapper{ + +} diff --git a/model2d3d-viewer-back-dao/src/main/resources/mappers/auto/BasicCompanyMapper.xml b/model2d3d-viewer-back-dao/src/main/resources/mappers/auto/BasicCompanyMapper.xml new file mode 100644 index 0000000..a94a5a5 --- /dev/null +++ b/model2d3d-viewer-back-dao/src/main/resources/mappers/auto/BasicCompanyMapper.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + id, parent_id, company_name, flag, create_time, modify_time + + + diff --git a/model2d3d-viewer-back-dao/src/main/resources/mappers/auto/BasicMenuMapper.xml b/model2d3d-viewer-back-dao/src/main/resources/mappers/auto/BasicMenuMapper.xml new file mode 100644 index 0000000..e7fc93d --- /dev/null +++ b/model2d3d-viewer-back-dao/src/main/resources/mappers/auto/BasicMenuMapper.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + id, parent_menu_id, menu_name, menu_name_en, menu_name_jp, remark, menu_level, flag, create_time + + + diff --git a/model2d3d-viewer-back-dao/src/main/resources/mappers/auto/BasicRoleMapper.xml b/model2d3d-viewer-back-dao/src/main/resources/mappers/auto/BasicRoleMapper.xml new file mode 100644 index 0000000..35b9ce6 --- /dev/null +++ b/model2d3d-viewer-back-dao/src/main/resources/mappers/auto/BasicRoleMapper.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + id, company_id, role_name, description, flag, creator_id, create_time, modifier_id, modify_time + + + diff --git a/model2d3d-viewer-back-dao/src/main/resources/mappers/auto/BasicRoleMenuRelationMapper.xml b/model2d3d-viewer-back-dao/src/main/resources/mappers/auto/BasicRoleMenuRelationMapper.xml new file mode 100644 index 0000000..2410100 --- /dev/null +++ b/model2d3d-viewer-back-dao/src/main/resources/mappers/auto/BasicRoleMenuRelationMapper.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + role_id, menu_id, creator_id, create_time + + + diff --git a/model2d3d-viewer-back-dao/src/main/resources/mappers/auto/BasicRoleUserRelationMapper.xml b/model2d3d-viewer-back-dao/src/main/resources/mappers/auto/BasicRoleUserRelationMapper.xml new file mode 100644 index 0000000..c284e22 --- /dev/null +++ b/model2d3d-viewer-back-dao/src/main/resources/mappers/auto/BasicRoleUserRelationMapper.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + user_id, role_id, creator_id, create_time + + + diff --git a/model2d3d-viewer-back-dao/src/main/resources/mappers/auto/BasicUserMapper.xml b/model2d3d-viewer-back-dao/src/main/resources/mappers/auto/BasicUserMapper.xml new file mode 100644 index 0000000..d28e8b0 --- /dev/null +++ b/model2d3d-viewer-back-dao/src/main/resources/mappers/auto/BasicUserMapper.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, company_id, shop_uuid, username, login_name, password, password_modify_time, salt, email, mobile_number, last_login_time, remark, flag, expire_time, create_time, creator_id, modify_time, modifier_id + + + diff --git a/model2d3d-viewer-back-dao/src/main/resources/mappers/auto/LoginHistoryMapper.xml b/model2d3d-viewer-back-dao/src/main/resources/mappers/auto/LoginHistoryMapper.xml new file mode 100644 index 0000000..f08c7ac --- /dev/null +++ b/model2d3d-viewer-back-dao/src/main/resources/mappers/auto/LoginHistoryMapper.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + id, user_id, request_ip, login_time + + + diff --git a/model2d3d-viewer-back-dao/src/main/resources/mappers/ex/BasicCompanyMapperExt.xml b/model2d3d-viewer-back-dao/src/main/resources/mappers/ex/BasicCompanyMapperExt.xml new file mode 100644 index 0000000..4677202 --- /dev/null +++ b/model2d3d-viewer-back-dao/src/main/resources/mappers/ex/BasicCompanyMapperExt.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/model2d3d-viewer-back-dao/src/main/resources/mappers/ex/BasicRoleMapperExt.xml b/model2d3d-viewer-back-dao/src/main/resources/mappers/ex/BasicRoleMapperExt.xml new file mode 100644 index 0000000..dbe890f --- /dev/null +++ b/model2d3d-viewer-back-dao/src/main/resources/mappers/ex/BasicRoleMapperExt.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/model2d3d-viewer-back-dao/src/main/resources/mappers/ex/BasicRoleMenuRelationMapperExt.xml b/model2d3d-viewer-back-dao/src/main/resources/mappers/ex/BasicRoleMenuRelationMapperExt.xml new file mode 100644 index 0000000..f72161b --- /dev/null +++ b/model2d3d-viewer-back-dao/src/main/resources/mappers/ex/BasicRoleMenuRelationMapperExt.xml @@ -0,0 +1,24 @@ + + + + + + INSERT INTO + basic_role_menu_relation (role_id, menu_id, creator_id, create_time) + VALUES + + (#{roleId}, #{item}, #{creatorId}, #{createTime}) + + + + + + \ No newline at end of file diff --git a/model2d3d-viewer-back-dao/src/main/resources/mappers/ex/BasicUserMapperExt.xml b/model2d3d-viewer-back-dao/src/main/resources/mappers/ex/BasicUserMapperExt.xml new file mode 100644 index 0000000..f2f148a --- /dev/null +++ b/model2d3d-viewer-back-dao/src/main/resources/mappers/ex/BasicUserMapperExt.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/model2d3d-viewer-back-dao/src/main/resources/templates/entity.java.ftl b/model2d3d-viewer-back-dao/src/main/resources/templates/entity.java.ftl new file mode 100644 index 0000000..1ced4f5 --- /dev/null +++ b/model2d3d-viewer-back-dao/src/main/resources/templates/entity.java.ftl @@ -0,0 +1,61 @@ +package ${package.Entity}; + +import com.baomidou.mybatisplus.annotation.*; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.experimental.Accessors; + +import java.io.Serializable; +<#-- 自动导入日期类型 --> +<#list table.fields as field> + <#if field.propertyType == "LocalDate"> +import java.time.LocalDate; + <#break> + + +<#list table.fields as field> + <#if field.propertyType == "LocalDateTime"> +import java.time.LocalDateTime; + <#break> + + + +<#-- 类定义 --> +@Getter +@Setter +@ToString +@Accessors(chain = true) +@TableName("${table.name}") +@Schema(description = "${table.comment!}") +public class ${entity} implements Serializable { + +<#-- 主键字段处理 --> +<#assign hasPk = false> +<#list table.fields as field> + <#if field.keyFlag> + <#assign hasPk = true> + @TableId(value = "${field.name}", type = IdType.${idType!"ASSIGN_ID"}) + @Schema(description = "${field.comment!}") + private ${field.propertyType} ${field.propertyName}; + + + + +<#-- 普通字段处理 --> +<#list table.fields as field> + <#if !field.keyFlag> + @TableField("${field.name}") + @Schema(description = "${field.comment!}") + private ${field.propertyType} ${field.propertyName}; + + + + +<#-- 无主键表的额外处理 --> +<#if !hasPk> +<#-- 在这里可以添加无主键表特有的方法或注释 --> +<#-- 例如,可能需要提供手动主键生成策略或者修改操作方法 --> + +} diff --git a/model2d3d-viewer-back-model/.gitignore b/model2d3d-viewer-back-model/.gitignore new file mode 100644 index 0000000..aa23915 --- /dev/null +++ b/model2d3d-viewer-back-model/.gitignore @@ -0,0 +1,15 @@ +/target/ +/logs/ +/.idea/ +*.iml +*.bak +*.log +/.settings/ +*.project +*.classpath +*.factorypath +*.springBeans +/.apt_generated/ +/.externalToolBuilders/ +/bin/ +application-*.properties diff --git a/model2d3d-viewer-back-model/pom.xml b/model2d3d-viewer-back-model/pom.xml new file mode 100644 index 0000000..9fee014 --- /dev/null +++ b/model2d3d-viewer-back-model/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + + com.techsor + model2d3d-viewer-back + 0.0.1-SNAPSHOT + + model2d3d-viewer-back-model + model2d3d-viewer-back-model + http://maven.apache.org + + UTF-8 + + + + + + org.hibernate.validator + hibernate-validator + 9.0.0.CR1 + + + org.glassfish + javax.el + 3.0.1-b11 + + + + org.hibernate.validator + hibernate-validator-cdi + 9.0.0.CR1 + + + + + com.baomidou + mybatis-plus-boot-starter + 3.5.11 + + + + org.mybatis + mybatis-spring + + + + + + junit + junit + test + + + diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/BaseSearchNoCompanysParams.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/BaseSearchNoCompanysParams.java new file mode 100644 index 0000000..c897e26 --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/BaseSearchNoCompanysParams.java @@ -0,0 +1,25 @@ +package com.model2d3d.viewer.back.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +/** +* @author Mr.Jiang +* @time 2022年4月23日 下午1:55:22 +*/ +@Setter +@Getter +public class BaseSearchNoCompanysParams { + + /** 页码 */ + @Schema(description = "当前页码(默认第一页)",example = "1") + private Integer pageNum; + /** 每页显示的条数 */ + @Schema(description = "每页显示的条数(默认20条)", example = "20") + private Integer pageSize; + + @Schema(description = "用户ID", hidden = true) + private Long userId; + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/BaseSearchParams.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/BaseSearchParams.java new file mode 100644 index 0000000..23e7755 --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/BaseSearchParams.java @@ -0,0 +1,23 @@ +package com.model2d3d.viewer.back.dto; + +import java.util.List; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +/** +* @author Mr.Jiang +* @time 2022年4月23日 下午1:55:22 +*/ +@Setter +@Getter +public class BaseSearchParams extends BaseSearchNoCompanysParams{ + + @Schema(description = "查询对象所属企业ID,多个使用逗号连接") + private String companyIds; + + @Schema(description = "查询对象所属企业ID", hidden = true) + private List companyIdList; + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/account/CacheUserData.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/account/CacheUserData.java new file mode 100644 index 0000000..e168de4 --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/account/CacheUserData.java @@ -0,0 +1,23 @@ +package com.model2d3d.viewer.back.dto.account; + +import lombok.Data; + +/** +* @author Mr.Jiang +* @time 2022年5月20日 下午2:08:50 +*/ +@Data +public class CacheUserData { + + private String accessToken; + private String userId; + private String companyId; + private String username; + private String loginName; + private String password; + private Long createTime; + private Long expireTime; + private String menuIds; +// private String userGroupIds; + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/account/LoginParam.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/account/LoginParam.java new file mode 100644 index 0000000..496cf6e --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/account/LoginParam.java @@ -0,0 +1,25 @@ +package com.model2d3d.viewer.back.dto.account; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** +* @author Mr.Jiang +* @time 2022年5月20日 下午7:13:50 +*/ +@Data +public class LoginParam { + + @Schema(description ="登录名",example = "admin") + private String loginname; + + @Schema(description = "密码",example = "123456") + private String password; + + @Schema(description = "验证码的请求标识ID",example = "111weyu2-123rt2u1-121ueiu2") + private String captchaRequestId; + + @Schema(description = "验证码值",example = "Z3xA") + private String captcha; + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/company/CompanySearchParams.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/company/CompanySearchParams.java new file mode 100644 index 0000000..c495bf1 --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/company/CompanySearchParams.java @@ -0,0 +1,24 @@ +package com.model2d3d.viewer.back.dto.company; + +import com.model2d3d.viewer.back.dto.BaseSearchParams; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** +* @author Mr.Jiang +* @time 2022年7月21日 下午8:50:31 +*/ +@Data +public class CompanySearchParams extends BaseSearchParams{ + + @Schema(description ="企业名",example = "张三李四") + private String companyName; + + @Schema(description ="登录账号的企业ID",example = "1", hidden = true) + private String selfCompanyId; + +// @Schema(description ="1-未进入系统homepage页面获取,2-点击企业后进入系统后获取",example = "2") +// private Integer searchType; + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/company/DeleteCompanyParams.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/company/DeleteCompanyParams.java new file mode 100644 index 0000000..48dc68f --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/company/DeleteCompanyParams.java @@ -0,0 +1,18 @@ +package com.model2d3d.viewer.back.dto.company; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +/** +* @author Mr.Jiang +* @time 2022年7月21日 下午8:50:31 +*/ +@Data +public class DeleteCompanyParams{ + + @NotBlank(message = "1001") + @Schema(description ="企业ID,多个使用半角字符逗号连接",example = "2738967,587") + private String companyIds; + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/company/OptCompanyParams.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/company/OptCompanyParams.java new file mode 100644 index 0000000..b56f7e6 --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/company/OptCompanyParams.java @@ -0,0 +1,28 @@ +package com.model2d3d.viewer.back.dto.company; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +/** +* @author Mr.Jiang +* @time 2022年7月21日 下午8:50:31 +*/ +@Data +public class OptCompanyParams{ + + @Schema(description ="企业唯一标识ID,新增时无此参数",example = "2738967") + private String companyId; + + @Schema(description ="父企业ID",example = "2738967", hidden = true) + private String parentId; + + @NotBlank(message = "1001") + @Length(max = 500,message = "1002") + @Schema(description ="企业名称",example = "testAccount1", required = true) + private String companyName; + + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/role/DeleteRoleParam.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/role/DeleteRoleParam.java new file mode 100644 index 0000000..1f9df03 --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/role/DeleteRoleParam.java @@ -0,0 +1,20 @@ +package com.model2d3d.viewer.back.dto.role; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; + +/** +* @author Mr.Jiang +* @time 2022年4月23日 下午1:59:33 +*/ +@Setter +@Getter +public class DeleteRoleParam { + + @NotBlank(message = "1001") + @Schema(description ="Id,多个使用逗号连接",example = "3,5", required = true) + private String roleIds; + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/role/OptRoleParam.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/role/OptRoleParam.java new file mode 100644 index 0000000..b22d6e1 --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/role/OptRoleParam.java @@ -0,0 +1,38 @@ +package com.model2d3d.viewer.back.dto.role; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; +import org.hibernate.validator.constraints.Length; +import org.hibernate.validator.constraints.Range; + +/** +* @author zhc +* @time 2022年6月14日10:56:38 +*/ +@Setter +@Getter +public class OptRoleParam { + + @Schema(description ="角色ID, 新增时无此参数",example = "111", required = false) + private String roleId; + + @NotBlank(message = "1001") + @Length(max = 100,message = "1002") + @Schema(description ="角色名称",example = "管理员", required = true) + private String roleName; + + @Length(max = 500,message = "1002") + @Schema(description ="描述",example = "这是管理员描述") + private String description; + + @Schema(description ="菜单权限ID,使用逗号连接",example = "1,4,5,6") + private String menuIds; + + @Schema(description ="所属企业ID",example = "2", hidden = true) + private String companyId; + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/role/RolePageSearchParam.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/role/RolePageSearchParam.java new file mode 100644 index 0000000..dc2b3c0 --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/role/RolePageSearchParam.java @@ -0,0 +1,21 @@ +package com.model2d3d.viewer.back.dto.role; + +import com.model2d3d.viewer.back.dto.BaseSearchParams; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +/** +* @author Mr.zhc +* @time 2022年7月27日12:06:35 +*/ +@Setter +@Getter +public class RolePageSearchParam extends BaseSearchParams{ + + @Schema(description ="角色名",example = "test", required = false) + private String roleName; + + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/user/DeleteUserParam.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/user/DeleteUserParam.java new file mode 100644 index 0000000..2a84ce9 --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/user/DeleteUserParam.java @@ -0,0 +1,20 @@ +package com.model2d3d.viewer.back.dto.user; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; + +/** +* @author Mr.Jiang +* @time 2022年4月23日 下午1:59:33 +*/ +@Setter +@Getter +public class DeleteUserParam { + + @NotBlank(message = "1001") + @Schema(description ="Id,多个使用逗号连接",example = "3,5", required = true) + private String userIds; + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/user/ModifyPassword.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/user/ModifyPassword.java new file mode 100644 index 0000000..521ad06 --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/user/ModifyPassword.java @@ -0,0 +1,24 @@ +package com.model2d3d.viewer.back.dto.user; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; + +/** +* @author Mr.Jiang +* @time 2022年4月23日 下午1:59:33 +*/ +@Setter +@Getter +public class ModifyPassword{ + + @NotBlank(message = "1001") + @Schema(description ="旧密码",example = "haoihg09278", required = true) + private String oldPassword; + + @NotBlank(message = "1001") + @Schema(description ="新密码",example = "og.ayhgih", required = true) + private String newPassword; + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/user/OptUserParam.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/user/OptUserParam.java new file mode 100644 index 0000000..36f34da --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/user/OptUserParam.java @@ -0,0 +1,44 @@ +package com.model2d3d.viewer.back.dto.user; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; +import org.hibernate.validator.constraints.Length; + +/** +* @author zhc +* @time 2022年6月14日10:56:38 +*/ +@Setter +@Getter +public class OptUserParam { + + + @Schema(description ="用户ID, 新增时无此参数",example = "111", required = false) + private String userId; + + @Schema(description ="角色ID",example = "24", required = false) + private String roleId; + + @NotBlank(message = "1001") + @Length(max = 255,message = "1002") + @Schema(description ="用户名",example = "管理员", required = true) + private String username; + + @Schema(description ="登录名",example = "adminmin", hidden = true) + private String loginName; + + @Email(message = "1004") + @Schema(description ="用户邮箱",example = "1057897@qq.com", required = true) + private String email; + + @Schema(description ="手机号码,这里要加上国际区号,比如日本是+81,传给后台的就是+81-08041165856,中国是+86,传给后台的就是+86-18841165856",example = "+81-08041165856", required = false) + private String mobileNumber; + + @Schema(description ="所属企业ID",example = "2", hidden = true) + private String companyId; + + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/user/PageSearchParam.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/user/PageSearchParam.java new file mode 100644 index 0000000..bd61469 --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/user/PageSearchParam.java @@ -0,0 +1,20 @@ +package com.model2d3d.viewer.back.dto.user; + +import com.model2d3d.viewer.back.dto.BaseSearchParams; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +/** +* @author Mr.zhc +* @time 2022年7月27日12:06:35 +*/ +@Setter +@Getter +public class PageSearchParam extends BaseSearchParams{ + + @Schema(description ="用户名/用户邮箱",example = "test", required = false) + private String keyword; + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/user/ResetPassword.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/user/ResetPassword.java new file mode 100644 index 0000000..bd45855 --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/dto/user/ResetPassword.java @@ -0,0 +1,23 @@ +package com.model2d3d.viewer.back.dto.user; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; + +/** +* @author Mr.Jiang +* @time 2022年4月23日 下午1:59:33 +*/ +@Setter +@Getter +public class ResetPassword{ + + @NotBlank(message = "1001") + @Schema(description ="Id,多个使用逗号连接",example = "3,5", required = true) + private String userIds; + +// @Schema(description ="重置密码方式 1-管理员直接重置密码,账号邮箱接收该密码,2-发送重置密码链接到绑定的账户邮箱中,用户自己重置密码",example = "2", required = true) +// private Integer resetType = 1; + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/BasicCompany.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/BasicCompany.java new file mode 100644 index 0000000..4eb8701 --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/BasicCompany.java @@ -0,0 +1,46 @@ +package com.model2d3d.viewer.back.model; + +import com.baomidou.mybatisplus.annotation.*; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +@Getter +@Setter +@ToString +@Accessors(chain = true) +@TableName("basic_company") +@Schema(description = "企业表") +public class BasicCompany implements Serializable { + + @TableId(value = "id", type = IdType.ASSIGN_UUID) + @Schema(description = "") + private String id; + + + @TableField("parent_id") + @Schema(description = "") + private String parentId; + + @TableField("company_name") + @Schema(description = "") + private String companyName; + + @TableField("flag") + @Schema(description = "0-正常,1-删除") + private Integer flag; + + @TableField("create_time") + @Schema(description = "") + private Long createTime; + + @TableField("modify_time") + @Schema(description = "") + private Long modifyTime; + + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/BasicMenu.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/BasicMenu.java new file mode 100644 index 0000000..d8c8eca --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/BasicMenu.java @@ -0,0 +1,58 @@ +package com.model2d3d.viewer.back.model; + +import com.baomidou.mybatisplus.annotation.*; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +@Getter +@Setter +@ToString +@Accessors(chain = true) +@TableName("basic_menu") +@Schema(description = "") +public class BasicMenu implements Serializable { + + @TableId(value = "id", type = IdType.AUTO) + @Schema(description = "") + private Long id; + + + @TableField("parent_menu_id") + @Schema(description = "") + private Long parentMenuId; + + @TableField("menu_name") + @Schema(description = "") + private String menuName; + + @TableField("menu_name_en") + @Schema(description = "") + private String menuNameEn; + + @TableField("menu_name_jp") + @Schema(description = "") + private String menuNameJp; + + @TableField("remark") + @Schema(description = "") + private String remark; + + @TableField("menu_level") + @Schema(description = "菜单级别") + private Integer menuLevel; + + @TableField("flag") + @Schema(description = "0-正常,1-删除") + private Integer flag; + + @TableField("create_time") + @Schema(description = "") + private Long createTime; + + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/BasicRole.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/BasicRole.java new file mode 100644 index 0000000..4927b88 --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/BasicRole.java @@ -0,0 +1,58 @@ +package com.model2d3d.viewer.back.model; + +import com.baomidou.mybatisplus.annotation.*; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +@Getter +@Setter +@ToString +@Accessors(chain = true) +@TableName("basic_role") +@Schema(description = "") +public class BasicRole implements Serializable { + + @TableId(value = "id", type = IdType.ASSIGN_UUID) + @Schema(description = "") + private String id; + + + @TableField("company_id") + @Schema(description = "") + private String companyId; + + @TableField("role_name") + @Schema(description = "") + private String roleName; + + @TableField("description") + @Schema(description = "") + private String description; + + @TableField("flag") + @Schema(description = "0-正常,1-删除") + private Integer flag; + + @TableField("creator_id") + @Schema(description = "") + private Long creatorId; + + @TableField("create_time") + @Schema(description = "") + private Long createTime; + + @TableField("modifier_id") + @Schema(description = "") + private Long modifierId; + + @TableField("modify_time") + @Schema(description = "") + private Long modifyTime; + + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/BasicRoleMenuRelation.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/BasicRoleMenuRelation.java new file mode 100644 index 0000000..df73ef2 --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/BasicRoleMenuRelation.java @@ -0,0 +1,38 @@ +package com.model2d3d.viewer.back.model; + +import com.baomidou.mybatisplus.annotation.*; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +@Getter +@Setter +@ToString +@Accessors(chain = true) +@TableName("basic_role_menu_relation") +@Schema(description = "") +public class BasicRoleMenuRelation implements Serializable { + + + @TableField("role_id") + @Schema(description = "") + private String roleId; + + @TableField("menu_id") + @Schema(description = "") + private Long menuId; + + @TableField("creator_id") + @Schema(description = "") + private Long creatorId; + + @TableField("create_time") + @Schema(description = "") + private Long createTime; + + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/BasicRoleUserRelation.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/BasicRoleUserRelation.java new file mode 100644 index 0000000..a260bad --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/BasicRoleUserRelation.java @@ -0,0 +1,38 @@ +package com.model2d3d.viewer.back.model; + +import com.baomidou.mybatisplus.annotation.*; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +@Getter +@Setter +@ToString +@Accessors(chain = true) +@TableName("basic_role_user_relation") +@Schema(description = "") +public class BasicRoleUserRelation implements Serializable { + + + @TableField("user_id") + @Schema(description = "") + private String userId; + + @TableField("role_id") + @Schema(description = "") + private String roleId; + + @TableField("creator_id") + @Schema(description = "") + private Long creatorId; + + @TableField("create_time") + @Schema(description = "") + private Long createTime; + + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/BasicUser.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/BasicUser.java new file mode 100644 index 0000000..3e8beba --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/BasicUser.java @@ -0,0 +1,94 @@ +package com.model2d3d.viewer.back.model; + +import com.baomidou.mybatisplus.annotation.*; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +@Getter +@Setter +@ToString +@Accessors(chain = true) +@TableName("basic_user") +@Schema(description = "") +public class BasicUser implements Serializable { + + @TableId(value = "id", type = IdType.ASSIGN_UUID) + @Schema(description = "") + private String id; + + + @TableField("company_id") + @Schema(description = "") + private String companyId; + + @TableField("shop_uuid") + @Schema(description = "") + private String shopUuid; + + @TableField("username") + @Schema(description = "") + private String username; + + @TableField("login_name") + @Schema(description = "") + private String loginName; + + @TableField("password") + @Schema(description = "") + private String password; + + @TableField("password_modify_time") + @Schema(description = "") + private Long passwordModifyTime; + + @TableField("salt") + @Schema(description = "") + private String salt; + + @TableField("email") + @Schema(description = "") + private String email; + + @TableField("mobile_number") + @Schema(description = "") + private String mobileNumber; + + @TableField("last_login_time") + @Schema(description = "") + private Long lastLoginTime; + + @TableField("remark") + @Schema(description = "备注") + private String remark; + + @TableField("flag") + @Schema(description = "0-正常,1-删除") + private Integer flag; + + @TableField("expire_time") + @Schema(description = "") + private Long expireTime; + + @TableField("create_time") + @Schema(description = "") + private Long createTime; + + @TableField("creator_id") + @Schema(description = "") + private Long creatorId; + + @TableField("modify_time") + @Schema(description = "") + private Long modifyTime; + + @TableField("modifier_id") + @Schema(description = "") + private Long modifierId; + + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/LoginHistory.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/LoginHistory.java new file mode 100644 index 0000000..ca45812 --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/model/LoginHistory.java @@ -0,0 +1,38 @@ +package com.model2d3d.viewer.back.model; + +import com.baomidou.mybatisplus.annotation.*; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +@Getter +@Setter +@ToString +@Accessors(chain = true) +@TableName("login_history") +@Schema(description = "") +public class LoginHistory implements Serializable { + + @TableId(value = "id", type = IdType.AUTO) + @Schema(description = "") + private Long id; + + + @TableField("user_id") + @Schema(description = "") + private String userId; + + @TableField("request_ip") + @Schema(description = "") + private String requestIp; + + @TableField("login_time") + @Schema(description = "") + private Long loginTime; + + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/vo/TreeMenusDTO.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/vo/TreeMenusDTO.java new file mode 100644 index 0000000..56ebad4 --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/vo/TreeMenusDTO.java @@ -0,0 +1,27 @@ +package com.model2d3d.viewer.back.vo; + +import java.util.List; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** +* @author Mr.Jiang +* @time 2022年7月29日 下午4:37:50 +*/ +@Data +public class TreeMenusDTO { + + @Schema(description ="节点ID",example = "11", required = true) + private String key; + + @Schema(description ="父节点ID",example = "2", hidden = true) + private String parentKey; + + @Schema(description ="节点名称",example = "添加", required = true) + private String label; + + @Schema(description ="子节点",example = "[]", required = false) + private List children; + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/vo/company/CompanyPageDTO.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/vo/company/CompanyPageDTO.java new file mode 100644 index 0000000..9d3c3fd --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/vo/company/CompanyPageDTO.java @@ -0,0 +1,25 @@ +package com.model2d3d.viewer.back.vo.company; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** +* @author Mr.Jiang +* @time 2022年7月21日 下午8:50:31 +*/ +@Data +public class CompanyPageDTO{ + + @Schema(description ="企业唯一标识ID,新增时无此参数",example = "2738967") + private String companyId; + + @Schema(description ="企业名称",example = "testAccount1", required = true) + private String companyName; + + @Schema(description ="所属企业ID",example = "2738967") + private String parentId; + + @Schema(description ="所属企业名称",example = "testAccount1", required = true) + private String parentCompanyName; + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/vo/role/RoleMenuDTO.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/vo/role/RoleMenuDTO.java new file mode 100644 index 0000000..808f68a --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/vo/role/RoleMenuDTO.java @@ -0,0 +1,27 @@ +package com.model2d3d.viewer.back.vo.role; + +import java.util.List; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** +* @author Mr.Jiang +* @time 2022年7月29日 下午4:37:50 +*/ +@Data +public class RoleMenuDTO { + + @Schema(description ="菜单ID",example = "11", required = true) + private String key; + + @Schema(description ="父菜单ID",example = "2", hidden = true) + private String parentKey; + + @Schema(description ="菜单名称",example = "添加", required = true) + private String label; + + @Schema(description ="子菜单",example = "[]", required = false) + private List children; + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/vo/role/RolePageDTO.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/vo/role/RolePageDTO.java new file mode 100644 index 0000000..555282b --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/vo/role/RolePageDTO.java @@ -0,0 +1,25 @@ +package com.model2d3d.viewer.back.vo.role; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** +* @author Mr.Jiang +* @time 2022年5月22日 下午10:37:02 +*/ +@Data +public class RolePageDTO { + + @Schema(description ="角色ID",example = "111", required = true) + private String roleId; + + @Schema(description ="角色名称",example = "管理员", required = true) + private String roleName; + + @Schema(description ="描述",example = "这是管理员描述", required = true) + private String description; + + @Schema(description ="最后更新时间",example = "1689878789647", required = true) + private Long modifyTime; + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/vo/user/UserInfoVO.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/vo/user/UserInfoVO.java new file mode 100644 index 0000000..244352c --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/vo/user/UserInfoVO.java @@ -0,0 +1,15 @@ +package com.model2d3d.viewer.back.vo.user; + +import com.model2d3d.viewer.back.model.BasicUser; +import lombok.Data; + +/** +* @author Mr.Jiang +* @time 2022年5月22日 下午10:37:02 +*/ +@Data +public class UserInfoVO extends BasicUser { + + private String parentCompanyId; + +} diff --git a/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/vo/user/UserPageDTO.java b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/vo/user/UserPageDTO.java new file mode 100644 index 0000000..8e8ad45 --- /dev/null +++ b/model2d3d-viewer-back-model/src/main/java/com/model2d3d/viewer/back/vo/user/UserPageDTO.java @@ -0,0 +1,43 @@ +package com.model2d3d.viewer.back.vo.user; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** +* @author Mr.Jiang +* @time 2022年5月22日 下午10:37:02 +*/ +@Data +public class UserPageDTO { + + @Schema(description ="企业唯一标识ID,新增时无此参数",example = "2738967") + private String companyId; + + @Schema(description ="企业名称",example = "testAccount1", required = true) + private String companyName; + + @Schema(description ="用户ID, 新增时无此参数",example = "111", required = false) + private String userId; + + @Schema(description ="角色ID",example = "24", required = false) + private String roleId; + + @Schema(description ="角色名",example = "24", required = false) + private String roleName; + + @Schema(description ="用户名",example = "管理员", required = true) + private String username; + +// @Schema(description ="登录名",example = "adminmin", required = true) +// private String loginName; + + @Schema(description ="用户邮箱",example = "1057897@qq.com", required = true) + private String email; + + @Schema(description ="手机号码,这里要加上国际区号,比如日本是+81,传给后台的就是+81-08041165856,中国是+86,传给后台的就是+86-18841165856",example = "+81-08041165856", required = false) + private String mobileNumber; + + @Schema(description ="创建时间",example = "1678990326897", required = false) + private Long createTime; + +} diff --git a/model2d3d-viewer-back-service/.gitignore b/model2d3d-viewer-back-service/.gitignore new file mode 100644 index 0000000..aa23915 --- /dev/null +++ b/model2d3d-viewer-back-service/.gitignore @@ -0,0 +1,15 @@ +/target/ +/logs/ +/.idea/ +*.iml +*.bak +*.log +/.settings/ +*.project +*.classpath +*.factorypath +*.springBeans +/.apt_generated/ +/.externalToolBuilders/ +/bin/ +application-*.properties diff --git a/model2d3d-viewer-back-service/pom.xml b/model2d3d-viewer-back-service/pom.xml new file mode 100644 index 0000000..94d7c3b --- /dev/null +++ b/model2d3d-viewer-back-service/pom.xml @@ -0,0 +1,55 @@ + + + 4.0.0 + + com.techsor + model2d3d-viewer-back + 0.0.1-SNAPSHOT + + model2d3d-viewer-back-service + model2d3d-viewer-back-service + http://maven.apache.org + + UTF-8 + + + + + com.techsor + model2d3d-viewer-back-dao + 0.0.1-SNAPSHOT + + + + com.techsor + model2d3d-viewer-back-model + 0.0.1-SNAPSHOT + + + + com.techsor + model2d3d-viewer-back-util + 0.0.1-SNAPSHOT + + + + com.techsor + model2d3d-viewer-back-common + 0.0.1-SNAPSHOT + + + + junit + junit + test + + + + com.github.penggle + kaptcha + 2.3.2 + + + + diff --git a/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/AccountService.java b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/AccountService.java new file mode 100644 index 0000000..51edea6 --- /dev/null +++ b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/AccountService.java @@ -0,0 +1,26 @@ +package com.model2d3d.viewer.back.service; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.mobile.device.Device; + +import com.alibaba.fastjson.JSONObject; +import com.model2d3d.viewer.back.common.response.SimpleDataResponse; +import com.model2d3d.viewer.back.dto.account.LoginParam; + +/** + * 账户信息Service + */ +public interface AccountService { + + boolean accessAuth(String userName, String companyId, String userId, String accessToken, String languageType, JSONObject jsonObject, Long keytimeout); + + SimpleDataResponse login(LoginParam loginParam, Device device, Integer languageType, HttpServletRequest request, + HttpServletResponse response); + + SimpleDataResponse logout(String accessToken, String companyId, String loginName, Long userId); + + SimpleDataResponse getCaptcha(String requestId, Device device, Integer languageType, HttpServletRequest request, + HttpServletResponse response); + +} diff --git a/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/CommonService.java b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/CommonService.java new file mode 100644 index 0000000..3ff248f --- /dev/null +++ b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/CommonService.java @@ -0,0 +1,14 @@ +package com.model2d3d.viewer.back.service; + +import com.model2d3d.viewer.back.common.response.SimpleDataResponse; + +/** + * + * @author jwy-style + * + */ +public interface CommonService { + + SimpleDataResponse checkApikey(String apikey); + +} diff --git a/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/CompanyService.java b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/CompanyService.java new file mode 100644 index 0000000..079d4a7 --- /dev/null +++ b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/CompanyService.java @@ -0,0 +1,33 @@ +package com.model2d3d.viewer.back.service; + +import java.util.List; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.model2d3d.viewer.back.common.response.SimpleDataResponse; +import com.model2d3d.viewer.back.dto.company.CompanySearchParams; +import com.model2d3d.viewer.back.dto.company.DeleteCompanyParams; +import com.model2d3d.viewer.back.dto.company.OptCompanyParams; +import com.model2d3d.viewer.back.vo.TreeMenusDTO; +import com.model2d3d.viewer.back.vo.company.CompanyPageDTO; + +/** + * + * @author jwy-style + * + */ +public interface CompanyService { + + boolean idsAuth(String valueOf, String needAuthIds); + + SimpleDataResponse add(OptCompanyParams optCompanyParams, String companyId, Long userId, Integer languageType); + + SimpleDataResponse edit(OptCompanyParams optCompanyParams, String companyId, Long userId, Integer languageType); + + SimpleDataResponse batchDelete(DeleteCompanyParams deleteCompanyParams, String companyId, Long userId, Integer languageType); + + IPage getListPage(CompanySearchParams pageSearchParam, String companyId, Long userId, + Integer languageType, Integer uTCOffset); + + SimpleDataResponse> getCompanyTree(String companyId, Long userId, Integer languageType); + +} diff --git a/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/RoleService.java b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/RoleService.java new file mode 100644 index 0000000..95fdd18 --- /dev/null +++ b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/RoleService.java @@ -0,0 +1,32 @@ +package com.model2d3d.viewer.back.service; + +import java.util.List; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.model2d3d.viewer.back.common.response.SimpleDataResponse; +import com.model2d3d.viewer.back.dto.role.DeleteRoleParam; +import com.model2d3d.viewer.back.dto.role.OptRoleParam; +import com.model2d3d.viewer.back.dto.role.RolePageSearchParam; +import com.model2d3d.viewer.back.vo.TreeMenusDTO; +import com.model2d3d.viewer.back.vo.role.RolePageDTO; + +/** + * Service. + */ +public interface RoleService { + + SimpleDataResponse add(OptRoleParam param, String companyId, Long userId, Integer languageType); + + SimpleDataResponse edit(OptRoleParam param, String companyId, Long userId, Integer languageType); + + SimpleDataResponse batchDelete(DeleteRoleParam deleteRoleParam, String companyId, Long userId, Integer languageType); + + SimpleDataResponse> getOwnMenuIds(String companyId, Long userId, Integer languageType); + + SimpleDataResponse getMenuIdsByRoleId(Long roleId, String companyId, Long userId, Integer languageType); + + IPage getListPage(RolePageSearchParam pageSearchParam, + String companyId, Long userId, Integer languageType); + + +} diff --git a/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/UserService.java b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/UserService.java new file mode 100644 index 0000000..e3ab4dd --- /dev/null +++ b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/UserService.java @@ -0,0 +1,30 @@ +package com.model2d3d.viewer.back.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.model2d3d.viewer.back.common.response.SimpleDataResponse; +import com.model2d3d.viewer.back.dto.user.DeleteUserParam; +import com.model2d3d.viewer.back.dto.user.ModifyPassword; +import com.model2d3d.viewer.back.dto.user.OptUserParam; +import com.model2d3d.viewer.back.dto.user.ResetPassword; +import com.model2d3d.viewer.back.vo.user.UserPageDTO; + +/** + * Agent Service. + */ +public interface UserService { + + SimpleDataResponse add(OptUserParam optUserParam, String companyId, Long userId, Integer languageType); + + SimpleDataResponse edit(OptUserParam optUserParam, String companyId, Long userId, Integer languageType); + + SimpleDataResponse batchDelete(DeleteUserParam deleteUserParam, String companyId, Long userId, Integer languageType); + + IPage getListPage(com.model2d3d.viewer.back.dto.user.PageSearchParam pageSearchParam, + String companyId, Long userId, Integer languageType); + + SimpleDataResponse batchResetPassword(ResetPassword resetPassword, String companyId, Long userId, + Integer languageType); + + SimpleDataResponse modifyPassword(ModifyPassword modifyPassword, String companyId, Long userId, Integer languageType); + +} diff --git a/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/captcha/CaptchaService.java b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/captcha/CaptchaService.java new file mode 100644 index 0000000..198e3ce --- /dev/null +++ b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/captcha/CaptchaService.java @@ -0,0 +1,31 @@ +package com.model2d3d.viewer.back.service.captcha; + +import java.util.UUID; + +import com.model2d3d.viewer.back.util.redis.RedisUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.model2d3d.viewer.back.common.Constants; + + +@Service +public class CaptchaService { + + private static final long CAPTCHA_TIMEOUT = 120L; + + @Autowired + private RedisUtil redisUtils; + + public CaptchaVO cacheCaptcha(String captcha){ + //生成一个随机标识符 + String captchaKey = UUID.randomUUID().toString(); + //缓存验证码并设置过期时间 + redisUtils.set(Constants.CAPTCHA_VERIFICATION.concat(captchaKey),captcha,CAPTCHA_TIMEOUT); + CaptchaVO captchaVO = new CaptchaVO(); + captchaVO.setCaptchaRequestId(captchaKey); + return captchaVO; + } + +} + diff --git a/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/captcha/CaptchaVO.java b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/captcha/CaptchaVO.java new file mode 100644 index 0000000..312d4e2 --- /dev/null +++ b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/captcha/CaptchaVO.java @@ -0,0 +1,18 @@ +package com.model2d3d.viewer.back.service.captcha; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class CaptchaVO { + /** + * + */ + @Schema(description ="验证码的请求标识ID",example = "12313-12313-123213-12313") + private String captchaRequestId; + /** + * base64字符串 + */ + @Schema(description ="验证码图片的base64编码结果",example = "data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAAoAG4DASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD0JRUiimKKkUUAPUVIBTFFSCgB6ipFFMXHrXnWp+MNVg8UmysB56tuCR7gANu7e5PHyqUkX1JXvkAgHpiipAK5Twv4yg1+8uLB4ZILy24lR0f5TkgBjtCqxxnbn6ZFaWreIYNJuoYZQ37w8uq7wnBPzAHIHHXB4DHoCQAbqipFFcJqHjSW612w0PQzbzTzgPJcrJviCfNuVSMjfhHOCR9w9c1H41+I9v4Ms44I1+23wYxMpOMFURiT+EiH8/SgD0NRUgFeAwfG7xSsnmyeG1kt+h2o4xzjr9QRXovw68fz+OTe79NNkLTZv3EnJcEjH5H9PWgDvVFSAU1RUgFAHGKKkUUxRUiigCC/vodNsZbuc4SNS31wCcfpXkNrrPiv4kX9ydMvv7M0uIkF168KeD9Qa9K8a2c194O1KC3UtO0XyY6g5H9M14L4X0nQ5rmay13Wri0hjLGSGNtoZg2PQg8DNAHcfDrV9QtfHl1oM+qG+ijLgzM25SQB0P1x/wB81asVa7+Lk5lLHTyQU+bETYPmRAH13hm9zW34APhj7Rc2/hixIii/193MCWJAOCuc55z6VhSJc6P41kvxYO1rGTtUKTkAZ2jGOQOV+hHrQAeJ7dNE+K2m6nb3BR2IMvK5ZOjEkHJ4IOADwcmt3x7FeWVnc65bgIfL85WOzcNuBjdtbjkEcA57iuTiXU/F/wASLO8t9PuIdNjmVnyvy8DIJweODkd8H06db4tjGqauNGY3GDkRw4G0gA/NlwcgE5LDGMDkYoAZ8FLGBtCuNSmuI7m7knwzE5KbQVXBPP3Sw+ntXB6vAus/GrT7LUzuVpwlyCflLAnOPwCj8K6jQtG1fwL4ns4IrSW7sJQB5mzoSAp45xuwMZPABzyaufFHwNfSS23ifQIw8to5nliUct82/cPXnt6UAevQ2VtHEI0t4gmScBBjJOSfzJP41NbWlva7vIgji3kFtigbjjHOPavK/CXxr0a8sEt9fkay1GMbZCyfK59R6V6B4c8V6P4qW6fSLnz1tnCSMBgZIyMUAbqipAKaoqQCgDjFFSKKKKAHgAjBHBrl9R+G/hrVb37VcWWGJJYIdoY7cc/kD9R70UUAdRY6faadbrb2dvHBEvRY1wOuf61ZeCKZCkkaOp6hhmiigBtrpllZyeZbWkELbduY41XAznHA9earN4ftptaGpS7WZV2qoXHXruIPzA8cHjgUUUAbQVSQSASKlVRjGOPSiigDk9b+F/hPxBeG7vNMC3DEFpIWKbvqBx+la3hbwfo/hG1e30mBo1kILszZZiABz+WfxNFFAHRKKkAoooA//9k=") + private String base64Img; +} diff --git a/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/captcha/KaptchaConfig.java b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/captcha/KaptchaConfig.java new file mode 100644 index 0000000..f43f5eb --- /dev/null +++ b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/captcha/KaptchaConfig.java @@ -0,0 +1,36 @@ +package com.model2d3d.viewer.back.service.captcha; + +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; + +@Configuration +public class KaptchaConfig { + @Bean + public DefaultKaptcha producer(){ + + DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); + Properties properties = new Properties(); + properties.setProperty("kaptcha.border", "no"); + properties.setProperty("kaptcha.border.color", "105,179,90"); + properties.setProperty("kaptcha.textproducer.font.color", "black"); + properties.setProperty("kaptcha.image.width", "110"); + properties.setProperty("kaptcha.image.height", "40"); + properties.setProperty("kaptcha.textproducer.char.string","23456789abcdefghkmnpqrstuvwxyzABCDEFGHKMNPRSTUVWXYZ"); + properties.setProperty("kaptcha.textproducer.font.size", "30"); + properties.setProperty("kaptcha.textproducer.char.space","3"); + properties.setProperty("kaptcha.session.key", "code"); + properties.setProperty("kaptcha.textproducer.char.length", "4"); + properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑"); +// properties.setProperty("kaptcha.obscurificator.impl","com.xxx");可以重写实现类 + properties.setProperty("kaptcha.noise.impl","com.google.code.kaptcha.impl.NoNoise"); + Config config = new Config(properties); + defaultKaptcha.setConfig(config); + + return defaultKaptcha; + } +} \ No newline at end of file diff --git a/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/common/CommonOpt.java b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/common/CommonOpt.java new file mode 100644 index 0000000..2f72972 --- /dev/null +++ b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/common/CommonOpt.java @@ -0,0 +1,89 @@ +package com.model2d3d.viewer.back.service.common; + +import java.util.*; +import java.util.stream.Collectors; + +import com.model2d3d.viewer.back.model.BasicCompany; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.model2d3d.viewer.back.dao.ex.BasicCompanyMapperExt; +import com.model2d3d.viewer.back.util.CommonUtil; + +/** +* @author Mr.Jiang +* @time 2022年5月28日 上午7:41:40 +*/ +@Component +public class CommonOpt { + + private static Logger logger = LoggerFactory.getLogger(CommonOpt.class); + + @Autowired + private BasicCompanyMapperExt basicCompanyMapperExt; + + + /** + * 根据自身企业ID获取子企业ID的list,list包含自身ID + * + * @param companyId 自身ID + * + * @return + */ + public List getSelfAndSubCompanyId(String companyId) { + List idsList = new ArrayList(); + idsList.add(companyId); + collectChildIds(idsList, Collections.singletonList(companyId)); + return idsList; + } + + + private void collectChildIds(List idsList, List parentCompanyIds) { + Map searchChildMap = new HashMap(); + searchChildMap.put("companyIds", parentCompanyIds); + List childCompanyList = basicCompanyMapperExt.getSubCompanyByParentId(searchChildMap); + if (CollectionUtils.isNotEmpty(childCompanyList)) { + List childIdsList = childCompanyList.stream().map(BasicCompany::getId).collect(Collectors.toList()); + idsList.addAll(childIdsList); + collectChildIds(idsList, childIdsList); + } + } + + + /** + * 过滤掉不属于targetCompany和它子企业的ID + * + * @param targetCompanyId 指定企业ID + * + * @param needProcessedCompanyIds 需要被处理的企业ID + * + */ + public List filterCompanyIds(String targetCompanyId, String needProcessedCompanyIds) { + List selfAndSubCompanyList = getSelfAndSubCompanyId(targetCompanyId); + if (StringUtils.isNotBlank(needProcessedCompanyIds)) { + List needProcessedCompanyIdList = CommonUtil.commaStr2LongList(needProcessedCompanyIds); + return needProcessedCompanyIdList.stream().filter(selfAndSubCompanyList::contains).collect(Collectors.toList()); + } + return null; + } + + /** + * 判断subId在不在parentId子企业下 + * @param parentId + * @param subId + * @return + */ + public boolean isSubCompany(String parentId, Long subId) { + List selfAndSubCompanyList = getSelfAndSubCompanyId(parentId); + if (selfAndSubCompanyList.contains(subId)) { + return true; + } else { + return false; + } + } + +} diff --git a/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/common/MenuTree.java b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/common/MenuTree.java new file mode 100644 index 0000000..f256e60 --- /dev/null +++ b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/common/MenuTree.java @@ -0,0 +1,69 @@ +package com.model2d3d.viewer.back.service.common; + +import java.util.ArrayList; +import java.util.List; + +import com.model2d3d.viewer.back.vo.TreeMenusDTO; + +/** +* @author Mr.Jiang +* @time 2022年7月29日 下午4:50:26 +*/ +public class MenuTree { + + /** + * 所有的菜单数据 + */ + private List menuList = new ArrayList(); + + public MenuTree(List menuList) { + this.menuList = menuList; + } + + /** + * 建立树形结构 + * + * @return + */ + public List buildTree(String rootNodeKey) { + List treeMenus = new ArrayList(); + for (TreeMenusDTO menuNode : getRootNode(rootNodeKey)) { + menuNode = buildChildTree(menuNode); + treeMenus.add(menuNode); + } + return treeMenus; + } + + /** + * 递归,建立子树形结构 + * + * @param pNode + * @return + */ + private TreeMenusDTO buildChildTree(TreeMenusDTO pNode) { + List childMenus = new ArrayList(); + for (TreeMenusDTO menuNode : menuList) { + if (menuNode.getParentKey().equals(pNode.getKey())) { + childMenus.add(buildChildTree(menuNode)); + } + } + pNode.setChildren(childMenus); + return pNode; + } + + /** + * 获取根节点 + * @param rootNodeKey + * + * @return + */ + private List getRootNode(String rootNodeKey) { + List rootMenuLists = new ArrayList(); + for (TreeMenusDTO menuNode : menuList) { + if (menuNode.getParentKey().equalsIgnoreCase(rootNodeKey)) { + rootMenuLists.add(menuNode); + } + } + return rootMenuLists; + } +} diff --git a/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/impl/AccountServiceImpl.java b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/impl/AccountServiceImpl.java new file mode 100644 index 0000000..c1916dc --- /dev/null +++ b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/impl/AccountServiceImpl.java @@ -0,0 +1,273 @@ +package com.model2d3d.viewer.back.service.impl; + +import java.text.MessageFormat; +import java.util.HashMap; +import java.util.Map; + +import com.model2d3d.viewer.back.model.BasicUser; +import com.model2d3d.viewer.back.model.LoginHistory; +import com.model2d3d.viewer.back.util.redis.RedisUtil; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.StringUtils; +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.mobile.device.Device; +import org.springframework.stereotype.Service; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.TypeReference; +import com.model2d3d.viewer.back.common.Constants; +import com.model2d3d.viewer.back.common.exception.MsgCodeException; +import com.model2d3d.viewer.back.common.language.msg.MsgLanguageChange; +import com.model2d3d.viewer.back.common.response.ResponseCode; +import com.model2d3d.viewer.back.common.response.SimpleDataResponse; +import com.model2d3d.viewer.back.dao.ex.BasicUserMapperExt; +import com.model2d3d.viewer.back.dao.ex.LoginHistoryMapperExt; +import com.model2d3d.viewer.back.dto.account.CacheUserData; +import com.model2d3d.viewer.back.dto.account.LoginParam; +import com.model2d3d.viewer.back.service.AccountService; +import com.model2d3d.viewer.back.util.DESUtil; +import com.model2d3d.viewer.back.util.NetworkUtil; +import com.model2d3d.viewer.back.util.RandomNumberUtil; +import com.model2d3d.viewer.back.util.ServiceUtil; +import com.model2d3d.viewer.back.util.ValidatorUtil; +import com.model2d3d.viewer.back.vo.user.UserInfoVO; + +/** + * 账户信息ServiceImpl + */ +@Service +public class AccountServiceImpl implements AccountService { + + private Logger logger = LoggerFactory.getLogger(AccountServiceImpl.class); + + @Value("${user.login.keytimeout:3600}") + private long loginTimeOut; + + + private static final long CAPTCHA_TIMEOUT = 120L; + + + @Autowired + private BasicUserMapperExt basicUserMapperExt; + @Autowired + private LoginHistoryMapperExt loginHistoryMapperExt; + @Autowired + private MsgLanguageChange msgLanguageChange; + @Autowired + private RedisUtil redisUtil; + + @Override + public boolean accessAuth(String loginName, String companyId, String userId, String accessToken, String languageType, JSONObject jsonObject, Long keytimeout) { + if (StringUtils.isBlank(languageType)) { + languageType = "2"; + } + //如果user_name,token不为空,则判定token合法性后取值权限,为空则返回token为空请求参数错误401 + if (StringUtils.isBlank(accessToken) || StringUtils.isBlank(loginName) + || StringUtils.isBlank(companyId) || StringUtils.isBlank(userId)) { + jsonObject.put("code", ResponseCode.AUTHORIZE_FAILED); + jsonObject.put("msg", msgLanguageChange.getParameterMapByCode(Integer.valueOf(languageType), "tokenError")); + return false; + } else { + String key = MessageFormat.format(Constants.ACCESS_TOKEN_FORMAT, userId, loginName, companyId, accessToken); + Object userDataStr = redisUtil.get(key); + if (null != userDataStr) { + CacheUserData cacheUserData = (CacheUserData) JSON.parseObject(userDataStr.toString(), new TypeReference() {}); + if (cacheUserData != null) { + String accessTokenOld = cacheUserData.getAccessToken(); + if (!StringUtils.equals(accessToken, accessTokenOld)) { + jsonObject.put("code", ResponseCode.AUTHORIZE_FAILED); + jsonObject.put("msg", msgLanguageChange.getParameterMapByCode(Integer.valueOf(languageType), "tokenError")); + return false; + } else { + redisUtil.set(key, JSONObject.toJSONString(cacheUserData), loginTimeOut); + return true; + } + } else { + jsonObject.put("code", ResponseCode.AUTHORIZE_FAILED); + jsonObject.put("msg", msgLanguageChange.getParameterMapByCode(Integer.valueOf(languageType), "tokenError")); + return false; + } + } else{ + jsonObject.put("code", ResponseCode.AUTHORIZE_FAILED); + jsonObject.put("msg", msgLanguageChange.getParameterMapByCode(Integer.valueOf(languageType), "tokenError")); + return false; + } + } + } + + @Override + public SimpleDataResponse login(LoginParam loginParam, Device device, Integer languageType, + HttpServletRequest request, HttpServletResponse response) { + SimpleDataResponse SimpleDataResponse = new SimpleDataResponse(ResponseCode.MSG_ERROR, msgLanguageChange.getParameterMapByCode(languageType, "serviceError")); + LoginHistory loginHistory = new LoginHistory(); + try { + String msgCode = "serviceError"; + //基础参数校验 + if (!validParam(loginParam).isEmpty()) { + throw new MsgCodeException("paramsFormatError"); + } + + if (StringUtils.isNotBlank(loginParam.getCaptchaRequestId())) { + String captchaKey = Constants.CAPTCHA_VERIFICATION.concat(loginParam.getCaptchaRequestId()); + Object captch = redisUtil.get(captchaKey); + if(captch == null){ + throw new MsgCodeException("verifCodeExpired"); + } + if(!loginParam.getCaptcha().equalsIgnoreCase(captch.toString())){ + throw new MsgCodeException("verifCodeError"); + } + redisUtil.remove(captchaKey); + } + + UserInfoVO userInfoVO = getAccountInfo(loginParam.getLoginname()); + if (userInfoVO != null) { + long currentUnixTime = System.currentTimeMillis(); + if(userInfoVO.getExpireTime() != null){ + if(userInfoVO.getExpireTime() < currentUnixTime){ + throw new MsgCodeException("accountExpired"); + } + } + + String inputPwd = DESUtil.encrypt(loginParam.getPassword(), userInfoVO.getSalt()); + if (userInfoVO.getPassword().equals(inputPwd)) { + userInfoVO.setLastLoginTime(currentUnixTime); + updateUserInfo(userInfoVO); + //使用Redis 保存用户token + String accessToken = ServiceUtil.CreateAccessToken(userInfoVO.getLoginName(), String.valueOf(currentUnixTime)); + + CacheUserData cacheUserData = new CacheUserData(); + cacheUserData.setAccessToken(accessToken); + cacheUserData.setCreateTime(userInfoVO.getCreateTime()); + cacheUserData.setLoginName(userInfoVO.getLoginName()); + cacheUserData.setUserId(userInfoVO.getId()); + cacheUserData.setUsername(userInfoVO.getUsername()); + cacheUserData.setExpireTime(userInfoVO.getExpireTime()); + cacheUserData.setCompanyId(userInfoVO.getCompanyId()); + cacheUserData.setMenuIds(basicUserMapperExt.getMenuIdsByUserId(userInfoVO.getId())); + + response.setHeader("AccessToken", accessToken); + + //设置请求ip地址和访问终端类型 + loginHistory.setLoginTime(currentUnixTime); + loginHistory.setUserId(userInfoVO.getId()); + try{ + loginHistory.setRequestIp(NetworkUtil.getIpAddress(request)); + }catch (Exception e){ + logger.error("getIpAddress error",e); + } + //将 redisUserData对象 保存到redis中 + String key = MessageFormat.format(Constants.ACCESS_TOKEN_FORMAT, userInfoVO.getId(), userInfoVO.getLoginName(), userInfoVO.getCompanyId(), accessToken); + boolean isWrite = redisUtil.set(key, JSONObject.toJSONString(cacheUserData), loginTimeOut); + if (isWrite) { + loginHistoryMapperExt.insert(loginHistory); + + SimpleDataResponse.setMsg("account login success"); + SimpleDataResponse.setCode(ResponseCode.OK); + SimpleDataResponse.setData(cacheUserData); + } else { + return new SimpleDataResponse(ResponseCode.SERVER_ERROR, "account login failed, userData is write failed"); + } + } else { + throw new MsgCodeException("pwdError"); + } + } else { + throw new MsgCodeException("userOrEmailNotExist"); + } + }catch (MsgCodeException e) { + return new SimpleDataResponse(ResponseCode.MSG_ERROR, + msgLanguageChange.getParameterMapByCode(languageType, e.getMessage())); + } catch (Exception e) { + logger.error("account login failed", e); + return SimpleDataResponse; + } + return SimpleDataResponse; + } + + private void updateUserInfo(BasicUser basicUser) { + basicUserMapperExt.updateById(basicUser); + } + + private UserInfoVO getAccountInfo(String loginname) { +// //邮箱或者登录名登录 +// BasicUserExample basicUserExample = new BasicUserExample(); +// BasicUserExample.Criteria criteria = basicUserExample.createCriteria(); +// criteria.andLoginNameEqualTo(loginname).andFlagNotEqualTo(1).andUserTypeEqualTo(1); +// +//// BasicUserExample.Criteria criteria2 = basicUserExample.createCriteria(); +//// criteria2.andEmailEqualTo(loginname).andFlagNotEqualTo(1).andUserTypeEqualTo(1); +//// +//// basicUserExample.or(criteria2); +// +// List users = basicUserMapperExt.selectByExample(basicUserExample); +// if (CollectionUtils.isNotEmpty(users)) { +// return users.get(0); +// } else { +// return null; +// } + Map paramMap = new HashMap<>(); + paramMap.put("loginname", loginname); + return basicUserMapperExt.getAccountInfo(paramMap); + } + + private Map validParam(LoginParam loginParam) { + Map errorMap = new HashMap(); +// if (ValidatorUtil.validParameterAlert(loginParam.getCaptchaRequestId(), "captchaKey", true, 1, 64, 4, errorMap) > 0) { +// logger.info("Parameter [captchaKey] check failed."); +// } +// if (ValidatorUtil.validParameterAlert(loginParam.getCaptcha(), "captcha", true, 1, 6, 4, errorMap) > 0) { +// logger.info("Parameter [captcha] check failed."); +// } + + if (ValidatorUtil.validParameterAlert(loginParam.getLoginname(), "loginname", true, 1, 20, 4, errorMap) > 0) { + logger.info("Parameter [account] check failed."); + } + if (ValidatorUtil.validParameterAlert(loginParam.getPassword(), "password", true, 1, 20, 4, errorMap) > 0) { + logger.info("Parameter [password] check failed."); + } + return errorMap; + } + + @Override + public SimpleDataResponse logout(String accessToken, String companyId, String loginName, Long userId) { + SimpleDataResponse simpleDataResponse = new SimpleDataResponse(); + try { + //移除accessToken + String key = MessageFormat.format(Constants.ACCESS_TOKEN_FORMAT, userId, loginName, companyId, accessToken); + redisUtil.delKey(key); + simpleDataResponse.setCode(ResponseCode.OK); + simpleDataResponse.setMsg("account [" + loginName + "] logout success"); + logger.info(simpleDataResponse.getMsg()); + } catch (Exception e) { + logger.error("account [" + loginName + "] logout failed", e); + simpleDataResponse.setCode(ResponseCode.SERVER_ERROR); + simpleDataResponse.setMsg(ResponseCode.SERVER_ERROR_MSG); + } + return simpleDataResponse; + } + + @Override + public SimpleDataResponse getCaptcha(String requestId, Device device, Integer languageType, + HttpServletRequest request, HttpServletResponse response) { + SimpleDataResponse simpleDataResponse = new SimpleDataResponse(); + try { + String code = RandomNumberUtil.createRandomNumber(4); + String captchaKey = Constants.CAPTCHA_VERIFICATION.concat(requestId); + boolean captchaIsWrited = redisUtil.set(captchaKey, code, CAPTCHA_TIMEOUT); + + simpleDataResponse.setCode(ResponseCode.OK); + simpleDataResponse.setData(code); + + } catch (Exception e) { + logger.error("getCaptcha failed", e); + simpleDataResponse.setCode(ResponseCode.OK); + simpleDataResponse.setMsg(ResponseCode.SERVER_ERROR_MSG); + } + return simpleDataResponse; + } + +} diff --git a/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/impl/CommonServiceImpl.java b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/impl/CommonServiceImpl.java new file mode 100644 index 0000000..bce34d9 --- /dev/null +++ b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/impl/CommonServiceImpl.java @@ -0,0 +1,60 @@ +package com.model2d3d.viewer.back.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.model2d3d.viewer.back.model.BasicCompany; +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.stereotype.Service; + +import com.model2d3d.viewer.back.common.response.SimpleDataResponse; +import com.model2d3d.viewer.back.dao.ex.BasicCompanyMapperExt; +import com.model2d3d.viewer.back.service.CommonService; +import com.model2d3d.viewer.back.service.common.CommonOpt; + +/** + * + * @author jwy-style + * + */ +@Service +public class CommonServiceImpl implements CommonService { + + private static Logger logger = LoggerFactory.getLogger(CommonServiceImpl.class); + + @Value("${spring.datasource.url}") + private String dbUrl; + @Value("${spring.datasource.username}") + private String dbUsername; + @Value("${spring.datasource.password}") + private String dbPassword; + + @Autowired + private CommonOpt commonOpt; + + @Autowired + private BasicCompanyMapperExt basicCompanyMapperExt; + + + @Override + public SimpleDataResponse checkApikey(String apikey) { + SimpleDataResponse resp = new SimpleDataResponse(); + try { + long count = basicCompanyMapperExt.selectCount(new LambdaQueryWrapper() + .ne(BasicCompany::getFlag, 1)); + + resp.setCode(200); + if (count > 0) { + resp.setData(true); + } else { + resp.setData(false); + } + + } catch (Exception e) { + resp.setCode(500); + resp.setData(e.getMessage()); + } + return resp; + } +} diff --git a/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/impl/CompanyServiceImpl.java b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/impl/CompanyServiceImpl.java new file mode 100644 index 0000000..b4ced8d --- /dev/null +++ b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/impl/CompanyServiceImpl.java @@ -0,0 +1,295 @@ +package com.model2d3d.viewer.back.service.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.model2d3d.viewer.back.dao.ex.BasicUserMapperExt; +import com.model2d3d.viewer.back.model.BasicCompany; +import com.model2d3d.viewer.back.model.BasicUser; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.interceptor.TransactionAspectSupport; + +import com.model2d3d.viewer.back.common.exception.MsgCodeException; +import com.model2d3d.viewer.back.common.language.msg.MsgLanguageChange; +import com.model2d3d.viewer.back.common.response.ResponseCode; +import com.model2d3d.viewer.back.common.response.SimpleDataResponse; +import com.model2d3d.viewer.back.dao.ex.BasicCompanyMapperExt; +import com.model2d3d.viewer.back.dto.company.CompanySearchParams; +import com.model2d3d.viewer.back.dto.company.DeleteCompanyParams; +import com.model2d3d.viewer.back.dto.company.OptCompanyParams; +import com.model2d3d.viewer.back.service.CompanyService; +import com.model2d3d.viewer.back.service.common.CommonOpt; +import com.model2d3d.viewer.back.service.common.MenuTree; +import com.model2d3d.viewer.back.util.CommonUtil; +import com.model2d3d.viewer.back.util.async.OptAsync; +import com.model2d3d.viewer.back.vo.TreeMenusDTO; +import com.model2d3d.viewer.back.vo.company.CompanyPageDTO; + +/** + * + * @author jwy-style + * + */ +@Service +public class CompanyServiceImpl implements CompanyService { + + private static Logger logger = LoggerFactory.getLogger(CompanyServiceImpl.class); + + //{0}:时间戳变量 {1}:企业ID + private static final String APIKEY_FORMAT = "cp_{0}_{1}"; + + @Autowired + private OptAsync optAsync; + @Autowired + private MsgLanguageChange msgLanguageChange; + @Autowired + private BasicCompanyMapperExt basicCompanyMapperExt; + @Autowired + private CommonOpt commonOpt; + @Autowired + private BasicUserMapperExt basicUserMapperExt; + + + @Override + public boolean idsAuth(String companyId, String needAuthIds) { +// if (StringUtils.isBlank(needAuthIds)) { +// return false; +// } +// +// List ids = Arrays.asList(StringUtils.split(needAuthIds, ",")).stream() +// .map(id -> CommonUtil.String2Long(id.trim())).collect(Collectors.toList()); +// +// BasicCompanyExample basicCompanyExample = new BasicCompanyExample(); +// BasicCompanyExample.Criteria criteria = basicCompanyExample.createCriteria(); +// criteria.andFlagNotEqualTo(1).andCompanyIdEqualTo(companyId).andIdIn(ids); +// Long count = basicCompanyMapperExt.countByExample(basicCompanyExample); + +// Set idSet = new HashSet<>(ids); +// if (Objects.equals(count, (long)idSet.size())) { +// return true; +// } + return false; + } + + + @Override + @Transactional + public SimpleDataResponse add(OptCompanyParams optCompanyParams, String companyId, Long userId, + Integer languageType) { + try { + optCompanyParams.setCompanyId(null); + optCompanyParams.setParentId(companyId); + //校验参数 + SimpleDataResponse checkResult = checkParam(optCompanyParams, languageType); + if (200 != checkResult.getCode()) { + return checkResult; + } + //重复校验 + SimpleDataResponse checkExistResult = checkExist(optCompanyParams, languageType); + if (200 != checkExistResult.getCode()) { + return checkExistResult; + } +// //数量校验 +// SimpleDataResponse checkLimitResult = checkLimit(languageType); +// if (200 != checkLimitResult.getCode()) { +// return checkLimitResult; +// } + long currentUnix = System.currentTimeMillis(); + BasicCompany basicCompany = new BasicCompany(); + BeanUtils.copyProperties(optCompanyParams,basicCompany); + basicCompany.setId(null); + basicCompany.setParentId(optCompanyParams.getParentId()); + basicCompany.setCreateTime(currentUnix); + basicCompanyMapperExt.insert(basicCompany); + + return SimpleDataResponse.success(); + } catch (Exception e) { + logger.error("新增企业出错", e); + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + return new SimpleDataResponse(ResponseCode.SERVER_ERROR, ResponseCode.SERVER_ERROR_MSG); + } + } + + + private SimpleDataResponse checkExist(OptCompanyParams optCompanyParams, Integer languageType) { + if (basicCompanyMapperExt.checkExist(optCompanyParams) > 0) { + return new SimpleDataResponse(ResponseCode.MSG_ERROR, msgLanguageChange.getParameterMapByCode(languageType, "companyNameHasExisted")); + } + return SimpleDataResponse.success(); + } + + + private SimpleDataResponse checkParam(OptCompanyParams optCompanyParams, Integer languageType) { + if(StringUtils.isBlank(optCompanyParams.getCompanyName()) || optCompanyParams.getCompanyName().length() > 500){ + return new SimpleDataResponse(ResponseCode.MSG_ERROR, "Parameter [companyName] error"); + } +// if(null != optCompanyParams.getCompanyId() && optCompanyParams.getCompanyId().longValue() == optCompanyParams.getParentId().longValue()){ +// return new SimpleDataResponse(ResponseCode.MSG_ERROR, "parentId can not be the same as companyId"); +// } + return SimpleDataResponse.success(); + } + + + @Override + @Transactional + public SimpleDataResponse edit(OptCompanyParams optCompanyParams, String companyId, Long userId, + Integer languageType) { + try { +// optCompanyParams.setParentId(companyId); + //校验参数 + SimpleDataResponse checkResult = checkParam(optCompanyParams, languageType); + if (200 != checkResult.getCode()) { + return checkResult; + } + + BasicCompany oldBC = basicCompanyMapperExt.selectById(optCompanyParams.getCompanyId()); + //不存在, 这基本不可能,给个英文提示就行,省得翻译 + if (ObjectUtils.isEmpty(oldBC) || 1 == oldBC.getFlag()){ + return new SimpleDataResponse(ResponseCode.MSG_ERROR, "Not found"); + } + /**一些权限校验操作**/ + try { + List selfAndSubCompanyList = commonOpt.getSelfAndSubCompanyId(companyId); + //编辑的企业不属于自己所管的企业 + if (!selfAndSubCompanyList.contains(oldBC.getId())){ + throw new MsgCodeException(msgLanguageChange.getParameterMapByCode(languageType, "noOperationAuth")); + } + //父企业ID不属于自己所管的企业 +// if (!selfAndSubCompanyList.contains(optCompanyParams.getParentId())){ +// throw new MsgCodeException(msgLanguageChange.getParameterMapByCode(languageType, "noOperationAuth")); +// } + } catch (MsgCodeException e) { + return new SimpleDataResponse(ResponseCode.MSG_ERROR, e.getMessage()); + } + + //防止套娃 +// List idsList = commonOpt.getSelfAndSubCompanyId(optCompanyParams.getCompanyId()); +// if (CollectionUtils.isNotEmpty(idsList) && idsList.contains(optCompanyParams.getParentId())) { +// return new SimpleDataResponse(ResponseCode.MSG_ERROR, msgLanguageChange.getParameterMapByCode(languageType, "taowaComapny")); +// } + + //重复校验 + SimpleDataResponse checkExistResult = checkExist(optCompanyParams, languageType); + if (200 != checkExistResult.getCode()) { + return checkExistResult; + } + BasicCompany basicCompany = new BasicCompany(); + BeanUtils.copyProperties(optCompanyParams,basicCompany); + basicCompany.setId(optCompanyParams.getCompanyId()); + basicCompany.setParentId(null); + basicCompany.setModifyTime(System.currentTimeMillis()); + basicCompanyMapperExt.updateById(basicCompany); + + return SimpleDataResponse.success(); + } catch (Exception e) { + logger.error("编辑企业出错", e); + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + return new SimpleDataResponse(ResponseCode.SERVER_ERROR, ResponseCode.SERVER_ERROR_MSG); + } + } + + + @Override + @Transactional + public SimpleDataResponse batchDelete(DeleteCompanyParams deleteCompanyParams, String companyId, Long userId, + Integer languageType) { + if (StringUtils.isBlank(deleteCompanyParams.getCompanyIds())) { + return SimpleDataResponse.success(); + } + try { + List ids = Arrays.stream(deleteCompanyParams.getCompanyIds().split(",")).collect(Collectors.toList()); + + if (ids.contains(companyId)) { + return new SimpleDataResponse(ResponseCode.MSG_ERROR, "can not delete your own company"); + } + + //删除的企业拥有下级企业,需先处理下级企业 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.in(BasicCompany::getParentId, ids).eq(BasicCompany::getFlag, 0); + List childList = basicCompanyMapperExt.selectList(queryWrapper); + // 判断是否有子企业 + if (CollectionUtils.isNotEmpty(childList)) { + return new SimpleDataResponse(ResponseCode.MSG_ERROR, msgLanguageChange.getParameterMapByCode(languageType, "hasSubsidiary")); + } + + + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.in(BasicCompany::getId, commonOpt.filterCompanyIds(companyId, deleteCompanyParams.getCompanyIds())); + basicCompanyMapperExt.update(new BasicCompany().setFlag(1), updateWrapper); + + //删除企业下的用户 + LambdaUpdateWrapper updateUserWrapper = new LambdaUpdateWrapper<>(); + updateUserWrapper.in(BasicUser::getCompanyId, ids); + basicUserMapperExt.update(new BasicUser().setFlag(1), updateUserWrapper); + + + return SimpleDataResponse.success(); + } catch (Exception e) { + logger.error("删除企业出错", e); + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + return new SimpleDataResponse(ResponseCode.SERVER_ERROR, ResponseCode.SERVER_ERROR_MSG); + } + } + + + @Override + public IPage getListPage(CompanySearchParams pageSearchParam, String companyId, + Long userId, Integer languageType, Integer uTCOffset) { +// pageSearchParam.setSelfCompanyId(companyId); + //list防${}注入 + if (StringUtils.isBlank(pageSearchParam.getCompanyIds())) { + pageSearchParam.setCompanyIdList(commonOpt.getSelfAndSubCompanyId(companyId)); + } else { + pageSearchParam.setCompanyIdList(commonOpt.filterCompanyIds(companyId, pageSearchParam.getCompanyIds())); + } + + // 使用 MyBatis-Plus 提供的分页对象 Page + Page page = new Page<>( + pageSearchParam.getPageNum() == null ? 1 : pageSearchParam.getPageNum(), + pageSearchParam.getPageSize() == null ? 20 : pageSearchParam.getPageSize()); + IPage resultList = basicCompanyMapperExt.getListPage(page, pageSearchParam); + + return resultList; + } + + + @Override + public SimpleDataResponse> getCompanyTree(String companyId, Long userId, Integer languageType) { + List companyList = basicCompanyMapperExt.getListForTree(); + if (CollectionUtils.isNotEmpty(companyList)) { + TreeMenusDTO rootTree = new TreeMenusDTO(); + //先把自身节点作为根节点 + String rootId = companyId+""; + for (TreeMenusDTO treeMenusDTO : companyList) { + if (rootId.equals(treeMenusDTO.getKey())) { + rootTree = treeMenusDTO; + break; + } + } + + MenuTree menuTree =new MenuTree(companyList); + companyList = menuTree.buildTree(rootId); + + rootTree.setChildren(companyList); + + return SimpleDataResponse.success(rootTree); + } else { + return SimpleDataResponse.success(new ArrayList()); + } + } + +} diff --git a/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/impl/RoleServiceImpl.java b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/impl/RoleServiceImpl.java new file mode 100644 index 0000000..9f4b73d --- /dev/null +++ b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/impl/RoleServiceImpl.java @@ -0,0 +1,252 @@ +package com.model2d3d.viewer.back.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.model2d3d.viewer.back.common.language.msg.MsgLanguageChange; +import com.model2d3d.viewer.back.common.response.ResponseCode; +import com.model2d3d.viewer.back.common.response.SimpleDataResponse; +import com.model2d3d.viewer.back.dao.ex.BasicRoleMapperExt; +import com.model2d3d.viewer.back.dao.ex.BasicRoleMenuRelationMapperExt; +import com.model2d3d.viewer.back.dao.ex.BasicRoleUserRelationMapperExt; +import com.model2d3d.viewer.back.dto.role.DeleteRoleParam; +import com.model2d3d.viewer.back.dto.role.OptRoleParam; +import com.model2d3d.viewer.back.dto.role.RolePageSearchParam; +import com.model2d3d.viewer.back.model.*; +import com.model2d3d.viewer.back.service.RoleService; +import com.model2d3d.viewer.back.service.common.CommonOpt; +import com.model2d3d.viewer.back.service.common.MenuTree; +import com.model2d3d.viewer.back.vo.TreeMenusDTO; +import com.model2d3d.viewer.back.vo.company.CompanyPageDTO; +import com.model2d3d.viewer.back.vo.role.RolePageDTO; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.interceptor.TransactionAspectSupport; + +@Service +public class RoleServiceImpl implements RoleService { + + private static Logger logger = LoggerFactory.getLogger(RoleServiceImpl.class); + + @Autowired + private BasicRoleMapperExt basicRoleMapperExt; + @Autowired + private BasicRoleMenuRelationMapperExt basicRoleMenuRelationMapperExt; + @Autowired + private BasicRoleUserRelationMapperExt basicRoleUserRelationMapperExt; + @Autowired + private MsgLanguageChange msgLanguageChange; + @Autowired + private CommonOpt commonOpt; + + + + @Override + @Transactional + public SimpleDataResponse add(OptRoleParam param, String companyId, Long userId, Integer languageType) { + try { + param.setCompanyId(companyId); + param.setRoleId(null); + //校验参数 + SimpleDataResponse checkResult = checkParam(param, languageType); + if (200 != checkResult.getCode()) { + return checkResult; + } + //重复校验 + if (checkExist(param) > 0) { + return new SimpleDataResponse(ResponseCode.MSG_ERROR, msgLanguageChange.getParameterMapByCode(languageType, "roleNameExist")); + } + + long currentUnix = System.currentTimeMillis(); + BasicRole basicRole = new BasicRole(); + BeanUtils.copyProperties(param, basicRole); + basicRole.setCreatorId(userId); + basicRole.setCreateTime(currentUnix); + basicRole.setModifierId(userId); + basicRole.setModifyTime(currentUnix); + basicRole.setCompanyId(companyId); + basicRoleMapperExt.insert(basicRole); + + insertRoleMenuRelation(userId, currentUnix, basicRole.getId(), param.getMenuIds()); + + return SimpleDataResponse.success(); + } catch (Exception e) { + logger.error("添加角色报错", e); + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + return new SimpleDataResponse(ResponseCode.SERVER_ERROR, ResponseCode.SERVER_ERROR_MSG); + } + } + + + + private void insertRoleMenuRelation(Long userId, long currentUnix, String roleId, String menuIds) { + if (StringUtils.isNoneBlank(menuIds)) { + //先删除原有的角色ID + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(BasicRoleMenuRelation::getRoleId, roleId); + basicRoleMenuRelationMapperExt.delete(queryWrapper); + + //重新插入关联关系 + List idList = Arrays.asList(menuIds.split(",")).stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList()); + Map paramMap = new HashMap(); + paramMap.put("roleId", roleId); + paramMap.put("menuIds", idList); + paramMap.put("creatorId", userId); + paramMap.put("createTime", currentUnix); + basicRoleMenuRelationMapperExt.batchInsert(paramMap); + } + } + + + private long checkExist(OptRoleParam param) { + return basicRoleMapperExt.checkExist(param); + } + + + private SimpleDataResponse checkParam(OptRoleParam param, Integer languageType) { +// if(StringUtils.isBlank(param.getRoleName()) || param.getRoleName().length() > 100){ +// return new SimpleDataResponse(ResponseCode.MSG_ERROR, "Parameter [roleName] error"); +// } + return SimpleDataResponse.success(); + } + + + @Override + @Transactional + public SimpleDataResponse edit(OptRoleParam param, String companyId, Long userId, Integer languageType) { + try { + param.setCompanyId(companyId); + //校验参数 + SimpleDataResponse checkResult = checkParam(param, languageType); + if (200 != checkResult.getCode()) { + return checkResult; + } + //重复校验 + if (checkExist(param) > 0) { + return new SimpleDataResponse(ResponseCode.MSG_ERROR, msgLanguageChange.getParameterMapByCode(languageType, "roleNameExist")); + } + + long currentUnix = System.currentTimeMillis(); + BasicRole basicRole = new BasicRole(); + BeanUtils.copyProperties(param, basicRole); + basicRole.setId(param.getRoleId()); + basicRole.setModifierId(userId); + basicRole.setModifyTime(currentUnix); + basicRoleMapperExt.updateById(basicRole); + + insertRoleMenuRelation(userId, currentUnix, basicRole.getId(), param.getMenuIds()); + + return SimpleDataResponse.success(); + } catch (Exception e) { + logger.error("编辑角色报错", e); + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + return new SimpleDataResponse(ResponseCode.SERVER_ERROR, ResponseCode.SERVER_ERROR_MSG); + } + } + + + + @Override + @Transactional + public SimpleDataResponse batchDelete(DeleteRoleParam deleteRoleParam, String companyId, Long userId, + Integer languageType) { + try { + List idList = Arrays.stream(deleteRoleParam.getRoleIds().split(",")).collect(Collectors.toList()); + //先判断该角色有没有用户绑定 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.in(BasicRoleUserRelation::getRoleId, idList).last("LIMIT 1"); + if (basicRoleUserRelationMapperExt.selectCount(queryWrapper) > 0) { + return new SimpleDataResponse(ResponseCode.MSG_ERROR, msgLanguageChange.getParameterMapByCode(languageType, "roleHasBinded")); + } + + //基础表删除 + basicRoleMapperExt.update(null, new LambdaUpdateWrapper() + .in(BasicRole::getId, idList) + .set(BasicRole::getFlag, 1)); + + + // 删除用户-角色关联表 + basicRoleUserRelationMapperExt.delete(new LambdaQueryWrapper() + .in(BasicRoleUserRelation::getRoleId, idList)); + // 删除菜单-角色关联表 + basicRoleMenuRelationMapperExt.delete(new LambdaQueryWrapper() + .in(BasicRoleMenuRelation::getRoleId, idList)); + + return SimpleDataResponse.success(); + } catch (Exception e) { + logger.error("删除角色报错", e); + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + return new SimpleDataResponse(ResponseCode.SERVER_ERROR, ResponseCode.SERVER_ERROR_MSG); + } + } + + + + @Override + public SimpleDataResponse> getOwnMenuIds(String companyId, Long userId, Integer languageType) { + Map paramMap = new HashMap(); + paramMap.put("userId", userId); + paramMap.put("companyId", companyId); + paramMap.put("languageType", languageType); + if (1 == userId.intValue()) { + paramMap.put("superRole", 1); + } + List menuList = basicRoleMapperExt.getOwnMenuIds(paramMap); + if (CollectionUtils.isNotEmpty(menuList)) { + MenuTree menuTree =new MenuTree(menuList); + menuList=menuTree.buildTree("-1"); + return SimpleDataResponse.success(menuList); + } else { + return SimpleDataResponse.success(new ArrayList()); + } + } + + + + @Override + public SimpleDataResponse getMenuIdsByRoleId(Long roleId, String companyId, Long userId, + Integer languageType) { + try { + return SimpleDataResponse.success(basicRoleMenuRelationMapperExt.getMenuIdsByRoleId(roleId)); + } catch (Exception e) { + logger.error("获取角色菜单出错", e); + return new SimpleDataResponse(ResponseCode.SERVER_ERROR, ResponseCode.SERVER_ERROR_MSG); + } + } + + + + @Override + public IPage getListPage(RolePageSearchParam pageSearchParam, String companyId, Long userId, + Integer languageType) { + //list防${}注入 + if (StringUtils.isBlank(pageSearchParam.getCompanyIds())) { + pageSearchParam.setCompanyIdList(commonOpt.getSelfAndSubCompanyId(companyId)); + } else { + pageSearchParam.setCompanyIdList(commonOpt.filterCompanyIds(companyId, pageSearchParam.getCompanyIds())); + } + + // 使用 MyBatis-Plus 提供的分页对象 Page + Page page = new Page<>( + pageSearchParam.getPageNum() == null ? 1 : pageSearchParam.getPageNum(), + pageSearchParam.getPageSize() == null ? 20 : pageSearchParam.getPageSize()); + IPage resultList = basicRoleMapperExt.getListPage(page, pageSearchParam); + return resultList; + } + +} diff --git a/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/impl/UserServiceImpl.java b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..5bbdb21 --- /dev/null +++ b/model2d3d-viewer-back-service/src/main/java/com/model2d3d/viewer/back/service/impl/UserServiceImpl.java @@ -0,0 +1,363 @@ +package com.model2d3d.viewer.back.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.model2d3d.viewer.back.common.exception.MsgCodeException; +import com.model2d3d.viewer.back.common.language.msg.MsgLanguageChange; +import com.model2d3d.viewer.back.common.response.ResponseCode; +import com.model2d3d.viewer.back.common.response.SimpleDataResponse; +import com.model2d3d.viewer.back.dao.ex.BasicCompanyMapperExt; +import com.model2d3d.viewer.back.dao.ex.BasicRoleUserRelationMapperExt; +import com.model2d3d.viewer.back.dao.ex.BasicUserMapperExt; +import com.model2d3d.viewer.back.dto.user.DeleteUserParam; +import com.model2d3d.viewer.back.dto.user.ModifyPassword; +import com.model2d3d.viewer.back.dto.user.OptUserParam; +import com.model2d3d.viewer.back.dto.user.PageSearchParam; +import com.model2d3d.viewer.back.dto.user.ResetPassword; +import com.model2d3d.viewer.back.model.*; +import com.model2d3d.viewer.back.service.UserService; +import com.model2d3d.viewer.back.service.common.CommonOpt; +import com.model2d3d.viewer.back.util.CommonUtil; +import com.model2d3d.viewer.back.util.DESUtil; +import com.model2d3d.viewer.back.util.RandomNumberUtil; +import com.model2d3d.viewer.back.util.async.OptAsync; +import com.model2d3d.viewer.back.util.redis.RedisUtil; +import com.model2d3d.viewer.back.vo.company.CompanyPageDTO; +import com.model2d3d.viewer.back.vo.user.UserPageDTO; + +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.interceptor.TransactionAspectSupport; + +@Service +public class UserServiceImpl implements UserService { + + private static Logger logger = LoggerFactory.getLogger(UserServiceImpl.class); + + //同时含大写字母、小写字母、数字和特殊字符且长度大于8 + private static final String pwdPattern = "^(?=.*\\d)(?=.*[a-zA-Z])(?=.*[~!@#$%^&*])[\\da-zA-Z~!@#$%^&*]{12,}$"; + + + @Value("${web.login.url}") + private String webLoginUrl; + + @Autowired + private RedisUtil redisUtil; + @Autowired + private OptAsync optAsync; + @Autowired + private CommonOpt commonOpt; + @Autowired + private BasicUserMapperExt basicUserMapperExt; + @Autowired + private BasicRoleUserRelationMapperExt basicRoleUserRelationMapperExt; + @Autowired + private MsgLanguageChange msgLanguageChange; + @Autowired + private BasicCompanyMapperExt basicCompanyMapperExt; + + + @Override + @Transactional + public SimpleDataResponse add(OptUserParam param, String companyId, Long userId, Integer languageType) { + try { +// if (StringUtils.isBlank(param.getLoginName())) { + param.setLoginName(param.getUsername()); +// } + if (!"1".equals(companyId)) {//非顶级账号 + param.setCompanyId(companyId); + } else if (null == param.getCompanyId()) {//admin账号必须能选择企业归属 + return new SimpleDataResponse(ResponseCode.MSG_ERROR, "companyId is required"); + } + + param.setUserId(null); + //校验参数 + SimpleDataResponse checkResult = checkParam(param, languageType); + if (200 != checkResult.getCode()) { + return checkResult; + } + //重复校验 + if (checkExist(param) > 0) { + return new SimpleDataResponse(ResponseCode.MSG_ERROR, msgLanguageChange.getParameterMapByCode(languageType, "loginNameOrEmailHasExisted")); + } + + long currentUnix = System.currentTimeMillis(); + BasicUser basicUser = new BasicUser(); + BeanUtils.copyProperties(param, basicUser); + basicUser.setCreatorId(userId); + basicUser.setCreateTime(currentUnix); + basicUser.setModifierId(userId); + basicUser.setModifyTime(currentUnix); +// basicUser.setCompanyId(companyId); + basicUser.setSalt(RandomNumberUtil.createRandomLowerLetterAndNumber(10)); + String rawPwd = generateRandomPwd(); + basicUser.setPassword(DESUtil.encrypt(rawPwd, basicUser.getSalt())); + + basicUserMapperExt.insert(basicUser); + + insertUserRoleRelation(userId, currentUnix, basicUser.getId(), param.getRoleId()); + + BasicCompany basicCompany = basicCompanyMapperExt.selectById(basicUser.getCompanyId()); + + //邮箱通知密码 + String loginUrl = webLoginUrl; + optAsync.doSendWork( + msgLanguageChange.getParameterMapByCode(languageType, "mailAddUserPwdSubject") + "【" + basicCompany.getCompanyName() +"】", + MessageFormat.format(msgLanguageChange.getParameterMapByCode(languageType, "mailAddUserPwdContent"), basicUser.getLoginName(), rawPwd, loginUrl), + basicUser.getEmail(), + null); + + return SimpleDataResponse.success(); + } catch (Exception e) { + logger.error("添加用户报错", e); + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + return new SimpleDataResponse(ResponseCode.SERVER_ERROR, ResponseCode.SERVER_ERROR_MSG); + } + } + + + private void insertUserRoleRelation(Long creatorId, long currentUnix, String userId, String roleId) { + // 先删除原有的关联关系 + if (userId != null) { + basicRoleUserRelationMapperExt.delete(new LambdaQueryWrapper() + .eq(BasicRoleUserRelation::getUserId, userId)); + } + // 重新插入关联关系 + if (Objects.nonNull(userId) && Objects.nonNull(roleId)) { + BasicRoleUserRelation basicRoleUserRelation = new BasicRoleUserRelation(); + basicRoleUserRelation.setCreateTime(currentUnix); + basicRoleUserRelation.setCreatorId(creatorId); + basicRoleUserRelation.setRoleId(roleId); + basicRoleUserRelation.setUserId(userId); + basicRoleUserRelationMapperExt.insert(basicRoleUserRelation); + } + + } + + + private Long checkExist(OptUserParam param) { + return basicUserMapperExt.checkExist(param); + } + + + private SimpleDataResponse checkParam(OptUserParam param, Integer languageType) { + if(StringUtils.isBlank(param.getEmail()) || param.getEmail().length() > 100){ + return new SimpleDataResponse(ResponseCode.MSG_ERROR, "Parameter [email] error"); + } + if(StringUtils.isBlank(param.getLoginName()) || param.getLoginName().length() > 100){ + return new SimpleDataResponse(ResponseCode.MSG_ERROR, "Parameter [loginName] error"); + } + if(StringUtils.isBlank(param.getUsername()) || param.getUsername().length() > 100){ + return new SimpleDataResponse(ResponseCode.MSG_ERROR, "Parameter [username] error"); + } + if(StringUtils.isNotBlank(param.getMobileNumber()) && (!param.getMobileNumber().startsWith("+") || param.getMobileNumber().split("-").length != 2)){ + return new SimpleDataResponse(ResponseCode.MSG_ERROR, "Parameter [mobileNumber] error"); + } + return SimpleDataResponse.success(); + } + + + @Override + public SimpleDataResponse edit(OptUserParam param, String companyId, Long userId, Integer languageType) { + try { +// if (StringUtils.isBlank(param.getLoginName())) { + param.setLoginName(param.getUsername()); +// } + if (!"1".equals(companyId)) {//非顶级账号 + param.setCompanyId(companyId); + } else if (null == param.getCompanyId()) {//admin账号必须能选择企业归属 + return new SimpleDataResponse(ResponseCode.MSG_ERROR, "companyId is required"); + } + //校验参数 + SimpleDataResponse checkResult = checkParam(param, languageType); + if (200 != checkResult.getCode()) { + return checkResult; + } + + BasicUser oldBU = basicUserMapperExt.selectById(param.getUserId()); + //不存在, 这基本不可能,给个英文提示就行,省得翻译 + if (ObjectUtils.isEmpty(oldBU) || 1 == oldBU.getFlag()){ + return new SimpleDataResponse(ResponseCode.MSG_ERROR, "Not found"); + } + /**一些权限校验操作**/ + try { + List selfAndSubCompanyList = commonOpt.getSelfAndSubCompanyId(companyId); + //编辑的用户不属于自己所管的企业 + if (!selfAndSubCompanyList.contains(oldBU.getCompanyId())){ + throw new MsgCodeException(msgLanguageChange.getParameterMapByCode(languageType, "noOperationAuth")); + } + } catch (MsgCodeException e) { + return new SimpleDataResponse(ResponseCode.MSG_ERROR, e.getMessage()); + } + + //重复校验 + if (checkExist(param) > 0) { + return new SimpleDataResponse(ResponseCode.MSG_ERROR, msgLanguageChange.getParameterMapByCode(languageType, "loginNameOrEmailHasExisted")); + } + + long currentUnix = System.currentTimeMillis(); + BasicUser basicUser = new BasicUser(); + BeanUtils.copyProperties(param, basicUser); + basicUser.setId(param.getUserId()); + basicUser.setModifierId(userId); + basicUser.setModifyTime(currentUnix); +// basicUser.setCompanyId(companyId); + if (StringUtils.isBlank(param.getMobileNumber())) { + basicUser.setMobileNumber(""); + } + basicUserMapperExt.updateById(basicUser); + + insertUserRoleRelation(userId, currentUnix, basicUser.getId(), param.getRoleId()); + + return SimpleDataResponse.success(); + } catch (Exception e) { + logger.error("编辑用户报错", e); + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + return new SimpleDataResponse(ResponseCode.SERVER_ERROR, ResponseCode.SERVER_ERROR_MSG); + } + } + + + @Override + public SimpleDataResponse batchDelete(DeleteUserParam deleteUserParam, String companyId, Long userId, + Integer languageType) { + try { + //基础表删除 + List idList = Arrays.stream(deleteUserParam.getUserIds().split(",")).collect(Collectors.toList()); + + basicUserMapperExt.update(new BasicUser(), + new LambdaUpdateWrapper() + .in(BasicUser::getId, idList) // 根据 idList 更新 + .in(BasicUser::getCompanyId, commonOpt.getSelfAndSubCompanyId(companyId)) // 根据 companyId 过滤 + .set(BasicUser::getFlag, 1)); // 设置 flag 字段为 1 + + + //删除用户-角色关联表 +// BasicRoleUserRelationExample deleteRoleUserRelationExample = new BasicRoleUserRelationExample(); +// BasicRoleUserRelationExample.Criteria deleteCriteria = deleteRoleUserRelationExample.createCriteria(); +// deleteCriteria.andUserIdIn(idList); +// basicRoleUserRelationMapperExt.deleteByExample(deleteRoleUserRelationExample); + + return SimpleDataResponse.success(); + } catch (Exception e) { + logger.error("删除用户报错", e); + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + return new SimpleDataResponse(ResponseCode.SERVER_ERROR, ResponseCode.SERVER_ERROR_MSG); + } + } + + + @Override + public IPage getListPage(PageSearchParam pageSearchParam, String companyId, Long userId, + Integer languageType) { + //list防${}注入 + if (StringUtils.isBlank(pageSearchParam.getCompanyIds())) { + pageSearchParam.setCompanyIdList(commonOpt.getSelfAndSubCompanyId(companyId)); + } else { + pageSearchParam.setCompanyIdList(commonOpt.filterCompanyIds(companyId, pageSearchParam.getCompanyIds())); + } + + // 使用 MyBatis-Plus 提供的分页对象 Page + Page page = new Page<>( + pageSearchParam.getPageNum() == null ? 1 : pageSearchParam.getPageNum(), + pageSearchParam.getPageSize() == null ? 20 : pageSearchParam.getPageSize()); + IPage resultList = basicUserMapperExt.getListPage(page, pageSearchParam); + return resultList; + } + + + @Override + public SimpleDataResponse batchResetPassword(ResetPassword resetPassword, String companyId, Long userId, + Integer languageType) { + if (StringUtils.isBlank(resetPassword.getUserIds())) { + return SimpleDataResponse.success(); + } + try { + List ids = Arrays.asList(StringUtils.split(resetPassword.getUserIds(), ",")).stream() + .map(id -> CommonUtil.String2Long(id.trim())).collect(Collectors.toList()); + + List userList = basicUserMapperExt.selectList( + new LambdaQueryWrapper() + .in(BasicUser::getCompanyId, commonOpt.getSelfAndSubCompanyId(companyId)) // 根据公司ID过滤 + .in(BasicUser::getId, ids)); + + if (CollectionUtils.isNotEmpty(userList)) { + long currentUnix = System.currentTimeMillis(); + for (BasicUser basicUser : userList) { + String rawPwd = generateRandomPwd(); + basicUser.setPassword(DESUtil.encrypt(rawPwd, basicUser.getSalt())); +// basicUser.setPasswordModifyTime(currentUnix); + basicUserMapperExt.updateById(basicUser); + + BasicCompany basicCompany = basicCompanyMapperExt.selectById(basicUser.getCompanyId()); + + //邮箱通知密码 + String loginUrl = webLoginUrl; + optAsync.doSendWork( + msgLanguageChange.getParameterMapByCode(languageType, "mailResetUserPwdSubject") + "【" + basicCompany.getCompanyName() +"】", + MessageFormat.format(msgLanguageChange.getParameterMapByCode(languageType, "mailAddUserPwdContent"), basicUser.getLoginName(), rawPwd, loginUrl), + basicUser.getEmail(), + null); + } + } + + return SimpleDataResponse.success(); + } catch (Exception e) { + logger.error("重置密码出错", e); + return new SimpleDataResponse(ResponseCode.SERVER_ERROR, ResponseCode.SERVER_ERROR_MSG); + } + } + + + private String generateRandomPwd() { + return RandomNumberUtil.createRandomLowerLetterAndNumber(6) + +"!gM@" + + RandomNumberUtil.createRandomLowerLetterAndNumber(6); + } + + + @Override + public SimpleDataResponse modifyPassword(ModifyPassword modifyPassword, String companyId, Long userId, + Integer languageType) { + try { + if (!Pattern.matches(pwdPattern, modifyPassword.getNewPassword())) { + return new SimpleDataResponse(ResponseCode.MSG_ERROR, msgLanguageChange.getParameterMapByCode(languageType, "pwdFormatError")); + } + BasicUser basicUser = basicUserMapperExt.selectById(userId); + if (!DESUtil.encrypt(modifyPassword.getOldPassword(), basicUser.getSalt()).equals(basicUser.getPassword())) { + return new SimpleDataResponse(ResponseCode.MSG_ERROR, msgLanguageChange.getParameterMapByCode(languageType, "oldPwdError")); + } + String newPwd = DESUtil.encrypt(modifyPassword.getNewPassword(), basicUser.getSalt()); + if (newPwd.equals(basicUser.getPassword())) { + return new SimpleDataResponse(ResponseCode.MSG_ERROR, msgLanguageChange.getParameterMapByCode(languageType, "newPwdSameOld")); + } + basicUser.setPassword(newPwd); + basicUser.setModifyTime(System.currentTimeMillis()); +// basicUser.setPasswordModifyTime(basicUser.getModifyTime()); + basicUserMapperExt.updateById(basicUser); + + return SimpleDataResponse.success(); + } catch (Exception e) { + logger.error("modifyPassword出错",e); + return new SimpleDataResponse(ResponseCode.SERVER_ERROR, ResponseCode.SERVER_ERROR_MSG); + } + } + +} diff --git a/model2d3d-viewer-back-service/src/test/java/com/model2d3d/viewer/back/service/impl/JsonsTests.java b/model2d3d-viewer-back-service/src/test/java/com/model2d3d/viewer/back/service/impl/JsonsTests.java new file mode 100644 index 0000000..dae0eab --- /dev/null +++ b/model2d3d-viewer-back-service/src/test/java/com/model2d3d/viewer/back/service/impl/JsonsTests.java @@ -0,0 +1,21 @@ +package com.model2d3d.viewer.back.service.impl; + +import java.util.HashMap; +import java.util.Map; + +import com.alibaba.fastjson.JSON; +import org.junit.Test; + +public class JsonsTests { + + @Test + public void testJson(){ + Map jsonMap=new HashMap<>(); + + jsonMap.put("a", "1"); + jsonMap.put("b", "2"); + String jsonValue="{\"a\":\"1\",\"b\":\"2\"}"; + System.out.println(JSON.toJSONString(jsonMap)); + + } +} diff --git a/model2d3d-viewer-back-util/.gitignore b/model2d3d-viewer-back-util/.gitignore new file mode 100644 index 0000000..aa23915 --- /dev/null +++ b/model2d3d-viewer-back-util/.gitignore @@ -0,0 +1,15 @@ +/target/ +/logs/ +/.idea/ +*.iml +*.bak +*.log +/.settings/ +*.project +*.classpath +*.factorypath +*.springBeans +/.apt_generated/ +/.externalToolBuilders/ +/bin/ +application-*.properties diff --git a/model2d3d-viewer-back-util/pom.xml b/model2d3d-viewer-back-util/pom.xml new file mode 100644 index 0000000..ebab5c2 --- /dev/null +++ b/model2d3d-viewer-back-util/pom.xml @@ -0,0 +1,85 @@ + + + 4.0.0 + + com.techsor + model2d3d-viewer-back + 0.0.1-SNAPSHOT + + model2d3d-viewer-back-util + model2d3d-viewer-back-util + http://maven.apache.org + + UTF-8 + + + + junit + junit + test + + + + + org.springframework.boot + spring-boot-starter-mobile + 1.5.22.RELEASE + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + io.lettuce + lettuce-core + 5.1.6.RELEASE + + + + org.apache.commons + commons-lang3 + + + org.apache.commons + commons-pool2 + + + commons-collections + commons-collections + 3.2.2 + + + com.alibaba + fastjson + 2.0.7.graal + + + + org.dom4j + dom4j + 2.1.3 + + + + commons-io + commons-io + 2.11.0 + + + + com.google.code.gson + gson + 2.9.0 + + + + javax.mail + mail + 1.5.0-b01 + + + + diff --git a/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/Arith.java b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/Arith.java new file mode 100644 index 0000000..3176e78 --- /dev/null +++ b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/Arith.java @@ -0,0 +1,165 @@ +package com.model2d3d.viewer.back.util; +import java.math.BigDecimal; + +/** + * 进行BigDecimal对象的加减乘除,四舍五入等运算的工具类 + * + * 由于Java的简单类型不能够精确的对浮点数进行运算,这个工具类提供精 + * 确的浮点数运算,包括加减乘除和四舍五入。 + */ +public class Arith { + //默认除法运算精度 + private static final int DEF_DIV_SCALE = 10; + + //这个类不能实例化 + private Arith(){ + } + + /** + * 提供精确的加法运算。 + * @param v1 被加数 + * @param v2 加数 + * @return 两个参数的和 + */ + public static double add(double v1,double v2){ + BigDecimal b1 = new BigDecimal(Double.toString(v1)); + BigDecimal b2 = new BigDecimal(Double.toString(v2)); + return b1.add(b2).doubleValue(); + } + + /** + * 提供精确的减法运算。 + * @param v1 被减数 + * @param v2 减数 + * @return 两个参数的差 + */ + public static double sub(double v1,double v2){ + BigDecimal b1 = new BigDecimal(Double.toString(v1)); + BigDecimal b2 = new BigDecimal(Double.toString(v2)); + return b1.subtract(b2).doubleValue(); + } + + /** + * 提供精确的乘法运算。 + * @param v1 被乘数 + * @param v2 乘数 + * @return 两个参数的积 + */ + public static double mul(double v1,double v2){ + BigDecimal b1 = new BigDecimal(Double.toString(v1)); + BigDecimal b2 = new BigDecimal(Double.toString(v2)); + return b1.multiply(b2).doubleValue(); + } + + /** + * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 + * 小数点以后10位,以后的数字四舍五入。 + * @param v1 被除数 + * @param v2 除数 + * @return 两个参数的商 + */ + public static double div(double v1,double v2){ + return div(v1,v2,DEF_DIV_SCALE); + } + + /** + * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 + * 定精度,以后的数字四舍五入。 + * @param v1 被除数 + * @param v2 除数 + * @param scale 表示表示需要精确到小数点以后几位。 + * @return 两个参数的商 + */ + public static double div(double v1,double v2,int scale){ + if(scale<0){ + throw new IllegalArgumentException( + "The scale must be a positive integer or zero"); + } + BigDecimal b1 = new BigDecimal(Double.toString(v1)); + BigDecimal b2 = new BigDecimal(Double.toString(v2)); + return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue(); + } + + /** + * 提供精确的小数位四舍五入处理。 + * @param v 需要四舍五入的数字 + * @param scale 小数点后保留几位 + * @return 四舍五入后的结果 + */ + public static double round(double v,int scale){ + if(scale<0){ + throw new IllegalArgumentException( + "The scale must be a positive integer or zero"); + } + BigDecimal b = new BigDecimal(Double.toString(v)); + BigDecimal one = new BigDecimal("1"); + return b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue(); + } + + /** + * 提供精确的类型转换(Float) + * @param v 需要被转换的数字 + * @return 返回转换结果 + */ + public static float convertsToFloat(double v){ + BigDecimal b = BigDecimal.valueOf(v); + return b.floatValue(); + } + + /** + * 提供精确的类型转换(Int)不进行四舍五入 + * @param v 需要被转换的数字 + * @return 返回转换结果 + */ + public static int convertsToInt(double v){ + BigDecimal b = BigDecimal.valueOf(v); + return b.intValue(); + } + + /** + * 提供精确的类型转换(Long) + * @param v 需要被转换的数字 + * @return 返回转换结果 + */ + public static long convertsToLong(double v){ + BigDecimal b = BigDecimal.valueOf(v); + return b.longValue(); + } + + /** + * 返回两个数中大的一个值 + * @param v1 需要被对比的第一个数 + * @param v2 需要被对比的第二个数 + * @return 返回两个数中大的一个值 + */ + public static double returnMax(double v1,double v2){ + BigDecimal b1 = BigDecimal.valueOf(v1); + BigDecimal b2 = BigDecimal.valueOf(v2); + return b1.max(b2).doubleValue(); + } + + /** + * 返回两个数中小的一个值 + * @param v1 需要被对比的第一个数 + * @param v2 需要被对比的第二个数 + * @return 返回两个数中小的一个值 + */ + public static double returnMin(double v1,double v2){ + BigDecimal b1 = BigDecimal.valueOf(v1); + BigDecimal b2 = BigDecimal.valueOf(v2); + return b1.min(b2).doubleValue(); + } + + /** + * 精确对比两个数字 + * @param v1 需要被对比的第一个数 + * @param v2 需要被对比的第二个数 + * @return 如果两个数一样则返回0,如果第一个数比第二个数大则返回1,反之返回-1 + */ + public static int compareTo(double v1,double v2){ + BigDecimal b1 = BigDecimal.valueOf(v1); + BigDecimal b2 = BigDecimal.valueOf(v2); + return b1.compareTo(b2); + } + +} \ No newline at end of file diff --git a/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/CommonUtil.java b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/CommonUtil.java new file mode 100644 index 0000000..26eecfb --- /dev/null +++ b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/CommonUtil.java @@ -0,0 +1,763 @@ +package com.model2d3d.viewer.back.util; + +import java.lang.reflect.Field; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import com.alibaba.fastjson.JSONObject; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + + +public class CommonUtil { + + private static final String decimalsRegex = "[.](.*)"; + + private static final String hexStringRegex = "^[A-Fa-f0-9]+$"; + + private static final String betweenQuotesRegex = "\"([^\"]*)\""; + + /** + * String转Int + * + * @param s + * @return + */ + public static int String2Int(String s) { + try { + return Integer.parseInt(s); + } catch (Exception e) { + return 0; + } + } + + /** + * String转Long + * + * @param s + * @return + */ + public static Long String2Long(String s) { + try { + return Long.parseLong(s); + } catch (Exception e) { + return Long.parseLong("0"); + } + } + /** + * String转Double + * + * @param s + * @return + */ + public static Double String2Double(String s) { + try { + return Double.parseDouble(s); + } catch (Exception e) { + return Double.parseDouble("0.00"); + } + } + /** + * String转Float + * + * @param s + * @return + */ + public static Float String2Float(String s) { + try { + return Float.parseFloat(s); + } catch (Exception e) { + return Float.parseFloat("0.00"); + } + } + /** + * 十六进制Object转Long + * + * @param s + * @return + */ + public static Long HexObject2Long(Object s) { + try { + return Long.parseLong(s.toString(),16); + } catch (Exception e) { + return Long.parseLong("0"); + } + } + + /** + * 十六进制Object转Int + * + * @param s + * @return + */ + public static Integer HexObject2Int(Object s) { + try { + return Integer.parseInt(s.toString(),16); + } catch (Exception e) { + return Integer.parseInt("0"); + } + } + + /** + * 十六进制字符串转二进制字符串,高位在左,低位在右 + * @param hexString + * @return + */ + public static String hexString2binary(String hexString) + { + if (hexString == null || hexString.length() % 2 != 0) + return null; + String bString = "", tmp; + for (int i = 0; i < hexString.length(); i++) + { + tmp = "0000"+ Integer.toBinaryString(Integer.parseInt(hexString.substring(i, i + 1), 16)); + bString += tmp.substring(tmp.length() - 4); + } + return bString; + } + + /** + * 十进制转补位的byte字符串 + * @param s 需转换的十进制值 + * @param length 需满足的长度 + * @return + */ + public static String Int2ByteString(int s,int length) { + try { + return String.format("%0"+length+"d", Long.parseLong(Integer.toBinaryString(s))); + } catch (Exception e) { + return String.format("%0"+length+"d", Long.parseLong(Integer.toBinaryString(s))); + } + } + + /** + * 十六进制字符串转ascii码字符串 + * @param hex + * @return + */ + public static String convertHexToString(String hex){ + StringBuilder sb = new StringBuilder(); + StringBuilder temp = new StringBuilder(); + for( int i=0; i 0; i--) { + char c = binary.charAt(i - 1); + int algorism = c - '0'; + result += Math.pow(2, max - i) * algorism; + } + return result; + } + + + /** + * 十进制转十六进制 + * @param decimal + * @return + */ + public static String decimalToHex(int decimal) { + String result = ""; + result = Integer.toHexString(decimal); + if (result.length() % 2 == 1) { + result = "0" + result; + } + result = result.toUpperCase(); + return result; + } + + /** + * 将对象转换为json格式字符串 + * + * @param Object + * @return json string + */ + public static String toJSON(Object obj) { + ObjectMapper om = new ObjectMapper(); + try { + String json = om.writeValueAsString(obj); + return json; + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + return null; + } + + + /** + * 给字符串补0 + * @param str 需要补齐长度的字符串 + * @param strLength 需要补足的长度 + * @param type 1左补0, 2右补0 + * @return + */ + public static String addZeroForString(String str, int strLength, int type) { + int strLen = str.length(); + StringBuffer sb = null; + if(type == 1){ + while (strLen < strLength) { + sb = new StringBuffer(); + sb.append("0").append(str);// 左补0 + //sb.append(str).append("0");//右补0 + str = sb.toString(); + strLen = str.length(); + } + }else{ + while (strLen < strLength) { + sb = new StringBuffer(); +// sb.append("0").append(str);// 左补0 + sb.append(str).append("0");//右补0 + str = sb.toString(); + strLen = str.length(); + } + } + return str; + } + + + /** + * 判断是否为整数 + * @param str + * @return + */ + public static boolean isInteger(String str) { + Pattern pattern = Pattern.compile("^-?[0-9]\\d*$"); + return pattern.matcher(str).matches(); + } + + /** + * 判定是否为非负数(整数、小数) + * @param str + * @return + */ + public static boolean isDecimal(String str) { + int index = str.indexOf("."); + if(index<0){ + return StringUtils.isNumeric(str); + }else{ + String num1 = str.substring(0,index); + String num2 = str.substring(index+1); + return StringUtils.isNumeric(num1) && StringUtils.isNumeric(num2); + } + } + + /** + * 判断是否为非负数 + * @param str + * @return + */ + public static boolean isPositiveOrZero(String str) { + return str.matches("(0|([1-9]\\d*))(\\.\\d+)?"); + } + + + /** + * unix时间变更为datetime类型 + * + * @param s + * @return + */ + public static Date ObjectUnix2DateStr(Object s) { + try { + return new java.util.Date(1000*Long.parseLong(s.toString())); + } catch (Exception e) { + return new Date(); + } + } + + /** + * 获取UUID方法 + * @return + */ + public static String getUUID() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + return sdf.format(new Date()) + UUID.randomUUID().toString().replace("-",""); + } + + /** + * 获取字符串型的当前年.月.日 yyyy_MM_dd 格式 + * @return + */ + public static String TableDateFM2D(){ + SimpleDateFormat sdf = new SimpleDateFormat("yyyy_MM_dd"); + return sdf.format(new Date()); + } + + /** + * 获取字符串型的当前年.月 yyyy_MM 格式 + * @return + */ + public static String TableDateFM2M(){ + SimpleDateFormat sdf = new SimpleDateFormat("yyyy_MM"); + return sdf.format(new Date()); + } + + + /** + * 根据传入的date,返回数据表需要的日期格式 + * @param date + * @param mode 0:yyyy_MM格式, 1:yyyy_MM_dd + * @return + */ + public static String TableDateByDateStr(Object date, int mode){ + String resultDate = ""; + SimpleDateFormat sdfFull = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy_MM"); + if(mode > 0){ + sdf = new SimpleDateFormat("yyyy_MM_dd"); + } + try { + Date datetime = sdfFull.parse(date.toString()); + resultDate = sdf.format(datetime); + } catch (ParseException e) { + e.printStackTrace(); + } + return resultDate; + } + + + /** + * 根据传入的秒级时间戳,返回数据表需要的日期格式 + * @param date + * @param mode 0:yyyy_MM格式, 1:yyyy_MM_dd + * @return + */ + public static String TableDateByUnix(Object date, int mode){ + SimpleDateFormat sdf = new SimpleDateFormat("yyyy_MM"); + if(mode > 0){ + sdf = new SimpleDateFormat("yyyy_MM_dd"); + } + String tabTime = sdf.format(Long.parseLong(date.toString()+"000")); + return tabTime; + } + + /** + * json排版修改 + * + * @param s + * @return + */ + public static String String2Rep(String s) { + try { + return s.replace(",", ",\n").replace("[", "\n[\n") + .replace("{", "\n{\n").replace("}", "\n}\n") + .replace("]", "\n]\n"); + } catch (Exception e) { + return s; + } + } + + + /**8 + * Convert byte[] to hex string.这里我们可以将byte转换成int,然后利用Integer.toHexString(int)来转换成16进制字符串。 + * @param src byte[] data + * @return hex string + */ + public static String bytesToHexString(byte[] src){ + StringBuilder stringBuilder = new StringBuilder(""); + if (src == null || src.length <= 0) { + return null; + } + for (int i = 0; i < src.length; i++) { + int v = src[i] & 0xFF; + String hv = Integer.toHexString(v); + if (hv.length() < 2) { + stringBuilder.append(0); + } + stringBuilder.append(hv); + } + return stringBuilder.toString(); + } + + public static String StringtoHexString(String s) { + String str = ""; + for (int i = 0; i < s.length(); i++) { + int ch = (int) s.charAt(i); + String s4 = Integer.toHexString(ch & 0xFF); + if (s4.length() == 1) { + s4 = '0' + s4; + } + str = str + s4; + } + return str;// 0x表示十六进制 + } + /** + * Convert hex string to byte[] + * @param hexString the hex string + * @return byte[] + */ + public static byte[] HexString2Bytes(String src) { + int size = src.length(); + byte[] ret = new byte[size / 2]; + byte[] tmp = src.getBytes(); + for (int i = 0; i < size / 2; i++) { + ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]); + } + return ret; + } + private static byte uniteBytes(byte src0, byte src1) { + char _b0 = (char) Byte.decode("0x" + new String(new byte[] { src0 })).byteValue(); + _b0 = (char) (_b0 << 4); + char _b1 = (char) Byte.decode("0x" + new String(new byte[] { src1 })).byteValue(); + byte ret = (byte) (_b0 ^ _b1); + return ret; + } + /** + * 获取更改时区后的日期 + * @param date 日期 + * @param oldZone 旧时区对象 + * @param newZone 新时区对象 + * @return 日期 + */ + public static String changeTimeZone(String datetime, TimeZone oldZone, TimeZone newZone) { + String result = ""; + if(datetime != null && datetime.length()>0){ + SimpleDateFormat DateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date date = null; + try { + date = DateFormat.parse(datetime); + } catch (Exception e) { + e.printStackTrace(); + } + Date dateTmp = null; + if (date != null) { + int timeOffset = oldZone.getRawOffset() - newZone.getRawOffset(); + dateTmp = new Date(date.getTime() - timeOffset); + result = DateFormat.format(dateTmp); + } + } + return result; + } + /** + * 获取浏览器版本信息 + * @date:2016-9-19 + * @author:jiangwy + * @param agent + * @return + */ + public static String getBrowserName(String agent) { + if(agent.indexOf("msie 7")>0){ + return "ie7"; + }else if(agent.indexOf("msie 8")>0){ + return "ie8"; + }else if(agent.indexOf("msie 9")>0){ + return "ie9"; + }else if(agent.indexOf("msie 10")>0){ + return "ie10"; + }else if(agent.indexOf("msie")>0){ + return "ie"; + }else if(agent.indexOf("opera")>0){ + return "opera"; + }else if(agent.indexOf("firefox")>0){ + return "firefox"; + }else if(agent.indexOf("webkit")>0){ + return "webkit"; + }else if(agent.indexOf("gecko")>0 && agent.indexOf("rv:11")>0){ + return "ie11"; + }else{ + return "Others"; + } + } + + /** + * 百度坐标系计算两经纬度点之间的距离(单位:米) + * @param lng1 经度 + * @param lat1 纬度 + * @param lng2 + * @param lat2 + * @return + */ + public static double getBMapDistance(double lat_a, double lng_a, double lat_b, double lng_b){ + double pk = 180 / Math.PI; + double a1 = lat_a / pk; + double a2 = lng_a / pk; + double b1 = lat_b / pk; + double b2 = lng_b / pk; + double t1 = Math.cos(a1) * Math.cos(a2) * Math.cos(b1) * Math.cos(b2); + double t2 = Math.cos(a1) * Math.sin(a2) * Math.cos(b1) * Math.sin(b2); + double t3 = Math.sin(a1) * Math.sin(b1); + double tt = Math.acos(t1 + t2 + t3); + return 6370996.81 * tt; + } + + /** + * 将用角度表示的角转换为近似相等的用弧度表示的角 Math.toRadians + * @param d + * @return + */ + private static double rad(double d) + { + return d * Math.PI / 180.0; + } + + /** + * gps计算两经纬度点之间的距离(单位:米) + * @param lat1 + * @param lng1 + * @param lat2 + * @param lng2 + * @return + */ + public static double getGPSDistance(double lat1, double lng1, double lat2, double lng2) + { + double radLat1 = rad(lat1); + double radLat2 = rad(lat2); + double a = radLat1 - radLat2; + double b = rad(lng1) - rad(lng2); + double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a/2),2) + + Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(b/2),2))); + s = s * 6370996.81; + s = Math.round(s * 10000.0) / 10.0; + return s; + } + + /** + * 拼接List里Map的某个特定键对应的所有值 + * @param list + * @param param + * @return + */ + public static String JointListParam(List> list , String Key, String jointParam){ + for(int i = 0; i< list.size();i++){ + if(list.get(i).get(Key) != null && list.get(i).get(Key) != "" ){ + if(jointParam == null || jointParam.length() <= 0){ + jointParam = list.get(i).get(Key).toString(); + }else{ + jointParam = jointParam + "," + list.get(i).get(Key).toString(); + } + } + } + return jointParam; + } + + /** + * 根据前端的年、月、日等参数拼接返回yyyy-mm-dd hh:mm:ss格式数据 + * @param params + * @return + */ + public static Map getStartAndEndTime(Map params,String year, String month, String day, String dayCount) { + Map resultTime = new HashMap(); + String upStime = ""; + String upEtime = ""; + try { + if(params.get(year).toString().length() > 0 && params.get(month).toString().length() > 0 && params.get(day).toString().length() > 0){ + String bMonth = "0"+ params.get(month).toString(); + String bDay = ""; + if(params.get(day).toString().equals("0")){ + bDay = params.get(dayCount).toString(); + upStime = params.get(year).toString() + "-" + bMonth.substring(bMonth.length()-2, bMonth.length()) + "-" + "01" + " 00:00:00"; + upEtime = params.get(year).toString() + "-" + bMonth.substring(bMonth.length()-2, bMonth.length()) + "-" + bDay + " 23:59:59"; + }else{ + bDay = "0"+ params.get(day).toString(); + upStime = params.get(year).toString() + "-" + bMonth.substring(bMonth.length()-2, bMonth.length()) + "-" + + bDay.substring(bDay.length()-2, bDay.length()) + " 00:00:00"; + upEtime = params.get(year).toString() + "-" + bMonth.substring(bMonth.length()-2, bMonth.length()) + "-" + + bDay.substring(bDay.length()-2, bDay.length()) + " 23:59:59"; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + resultTime.put("upStime", upStime); + resultTime.put("upEtime", upEtime); + return resultTime; + } + + /** + * 对象集合赋值 + */ + public static List copyList(List list , Class clas){ + String aStr = JSONObject.toJSONString(list); + return JSONObject.parseArray(aStr, clas); + } + + /** + * 以list1为主体,根据键名groupKey,合并list1和list2 + * @param list1 + * @param list2 + * @param groupKey + * @return + */ + public static void mergeList2ToList1(List> list1, List> list2, String groupKey){ + try { + //将list2集合转换为map + Map map2 = list2.stream().collect( + Collectors.toMap(s->s.get(groupKey).toString(), s -> s)); + //合并数据,这里将list2集合的数据合并到list1集合上 + list1.forEach(n -> { + String keyStr = MapUtils.getString(n, groupKey); + if(StringUtils.isNotBlank(keyStr) && map2.containsKey(keyStr)){ + Map person = (Map) map2.get(keyStr); + if (null != person) { + for (String key : person.keySet()) { + n.put(key, person.get(key)); + } + } + } + }); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 去除小数 + * @param str + * @return + */ + public static String removeDecimals(String str) { + return str.replaceAll(decimalsRegex,""); + } + + /** + * 合并两个list + * @param list1 + * @param list2 + * @param groupKey + * @return + */ + public static List> mergeList(List> list1, List> list2, String groupKey){ + list1.addAll(list2); + Set set = new HashSet<>(); + return list1.stream() + .collect(Collectors.groupingBy(o->{ + //暂存所有key + set.addAll(o.keySet()); + //按groupKey分组 + return o.get(groupKey); + })).entrySet().stream().map(o->{ + //合并 + Map map = o.getValue().stream().flatMap(m->{ + return m.entrySet().stream(); + }).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a,b)->b)); + //为没有的key赋值null + set.stream().forEach(k->{ + if(!map.containsKey(k)) map.put(k, ""); + }); + return map; + }).collect(Collectors.toList()); + } + + public static String getBeforeMinutes(int armOnlineMinutes) { + Calendar beforeTime = Calendar.getInstance(); + beforeTime.add(Calendar.MINUTE, -armOnlineMinutes);// 5分钟之前的时间 + Date beforeD = beforeTime.getTime(); + String beforeTimeString = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(beforeD); + return beforeTimeString; + } + + private static boolean isEmojiCharacter(char codePoint) { + return (codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA) + || (codePoint == 0xD) + || ((codePoint >= 0x20) && (codePoint <= 0xD7FF)) + || ((codePoint >= 0xE000) && (codePoint <= 0xFFFD)) + || ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF)); + } + + /** + * 过滤emoji 或者 其他非文字类型的字符 + * + * @param source + * @return + */ + public static String filterEmoji(String source) { + if (StringUtils.isBlank(source)) { + return source; + } + StringBuilder buf = null; + int len = source.length(); + for (int i = 0; i < len; i++) { + char codePoint = source.charAt(i); + if (isEmojiCharacter(codePoint)) { + if (buf == null) { + buf = new StringBuilder(source.length()); + } + buf.append(codePoint); + } + } + if (buf == null) { + return source; + } else { + if (buf.length() == len) { + buf = null; + return source; + } else { + return buf.toString(); + } + } + } + + public static boolean isHexString(String string) { + Pattern pattern = Pattern.compile(hexStringRegex); + return pattern.matcher(string).matches(); + } + + public static Long dateStr2Stamp(SimpleDateFormat sdf, String dataeStr) { + if (StringUtils.isBlank(dataeStr)) { + return null; + } + try { + return sdf.parse(dataeStr).getTime(); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + public static List commaStr2LongList(String commaStr) { + if (StringUtils.isBlank(commaStr)) { + return Collections.emptyList(); // 如果字符串为空或为null,返回空列表 + } + return Arrays.asList(commaStr.split(",")); + } + + //截取双引号间的内容 + public static String extractContentBetweenQuotes(String text) { + Pattern pattern = Pattern.compile(betweenQuotesRegex); + Matcher matcher = pattern.matcher(text); + + if (matcher.find()) { + return matcher.group(1); + } + + return null; // 如果找不到匹配项,返回null + } + + public static MultiValueMap convertToMultiValueMap(Object obj) throws IllegalAccessException { + MultiValueMap multiValueMap = new LinkedMultiValueMap<>(); + Field[] fields = obj.getClass().getDeclaredFields(); + for (Field field : fields) { + field.setAccessible(true); + Object value = field.get(obj); + if (value != null) { + multiValueMap.set(field.getName(), value.toString()); + } + } + return multiValueMap; + } + +} diff --git a/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/DESUtil.java b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/DESUtil.java new file mode 100644 index 0000000..6a73420 --- /dev/null +++ b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/DESUtil.java @@ -0,0 +1,192 @@ +package com.model2d3d.viewer.back.util; + +import javax.crypto.Cipher; +import javax.crypto.CipherInputStream; +import javax.crypto.CipherOutputStream; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.DESKeySpec; +import javax.crypto.spec.IvParameterSpec; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.security.Key; +import java.util.Base64; + +/** + * + * @author jwy-style + * + */ +public class DESUtil { + + /** + * 偏移变量,固定占8位字节 + */ + private final static String IV_PARAMETER = "12345678"; + /** + * 密钥算法 + */ + private static final String ALGORITHM = "DES"; + /** + * 加密/解密算法-工作模式-填充模式 + */ + private static final String CIPHER_ALGORITHM = "DES/CBC/PKCS5Padding"; + /** + * 默认编码 + */ + private static final String CHARSET = "utf-8"; + + /** + * 生成key + * + * @param password + * @return + * @throws Exception + */ + private static Key generateKey(String password) throws Exception { + DESKeySpec dks = new DESKeySpec(password.getBytes(CHARSET)); + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM); + return keyFactory.generateSecret(dks); + } + + + /** + * DES加密字符串 + * + * @param password 加密密码,长度不能够小于8位 + * @param data 待加密字符串 + * @return 加密后内容 + */ + public static String encrypt(String data, String password) { + if (password== null || password.length() < 8) { + throw new RuntimeException("加密失败,key不能小于8位"); + } + if (data == null) + return null; + try { + Key secretKey = generateKey(password); + Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); + IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET)); + cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv); + byte[] bytes = cipher.doFinal(data.getBytes(CHARSET)); + + //JDK1.8及以上可直接使用Base64,JDK1.7及以下可以使用BASE64Encoder + //Android平台可以使用android.util.Base64 + return new String(Base64.getEncoder().encode(bytes)); + + } catch (Exception e) { + e.printStackTrace(); + return data; + } + } + + /** + * DES解密字符串 + * + * @param password 解密密码,长度不能够小于8位 + * @param data 待解密字符串 + * @return 解密后内容 + */ + public static String decrypt(String data, String password) { + if (password== null || password.length() < 8) { + throw new RuntimeException("加密失败,key不能小于8位"); + } + if (data == null) + return null; + try { + Key secretKey = generateKey(password); + Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); + IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET)); + cipher.init(Cipher.DECRYPT_MODE, secretKey, iv); + return new String(cipher.doFinal(Base64.getDecoder().decode(data.getBytes(CHARSET))), CHARSET); + } catch (Exception e) { + e.printStackTrace(); + return data; + } + } + + /** + * DES加密文件 + * + * @param srcFile 待加密的文件 + * @param destFile 加密后存放的文件路径 + * @return 加密后的文件路径 + */ + public static String encryptFile(String password, String srcFile, String destFile) { + + if (password== null || password.length() < 8) { + throw new RuntimeException("加密失败,key不能小于8位"); + } + try { + IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET)); + Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); + cipher.init(Cipher.ENCRYPT_MODE, generateKey(password), iv); + InputStream is = new FileInputStream(srcFile); + OutputStream out = new FileOutputStream(destFile); + CipherInputStream cis = new CipherInputStream(is, cipher); + byte[] buffer = new byte[1024]; + int r; + while ((r = cis.read(buffer)) > 0) { + out.write(buffer, 0, r); + } + cis.close(); + is.close(); + out.close(); + return destFile; + } catch (Exception ex) { + ex.printStackTrace(); + } + return null; + } + + /** + * DES解密文件 + * + * @param srcFile 已加密的文件 + * @param destFile 解密后存放的文件路径 + * @return 解密后的文件路径 + */ + public static String decryptFile(String password, String srcFile, String destFile) { + if (password== null || password.length() < 8) { + throw new RuntimeException("加密失败,key不能小于8位"); + } + try { + File file = new File(destFile); + if (!file.exists()) { + file.getParentFile().mkdirs(); + file.createNewFile(); + } + IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET)); + Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); + cipher.init(Cipher.DECRYPT_MODE, generateKey(password), iv); + InputStream is = new FileInputStream(srcFile); + OutputStream out = new FileOutputStream(destFile); + CipherOutputStream cos = new CipherOutputStream(out, cipher); + byte[] buffer = new byte[1024]; + int r; + while ((r = is.read(buffer)) >= 0) { + cos.write(buffer, 0, r); + } + cos.close(); + is.close(); + out.close(); + return destFile; + } catch (Exception ex) { + ex.printStackTrace(); + } + return null; + } + + public static void main(String[] args){ + String salt = "ci3b512jwy199511"; + String encodeString = encrypt("cp_" + System.currentTimeMillis()+ "_1",salt); + System.out.println(encodeString); + System.out.println(decrypt(encodeString, salt)); + + String base64sString = Base64.getEncoder().encodeToString(encodeString.getBytes()); + System.out.println(base64sString); + byte[] decodedBytes = Base64.getDecoder().decode(base64sString); + String rawApikey = DESUtil.decrypt(new String(decodedBytes, StandardCharsets.UTF_8), salt); + System.out.println(rawApikey); + } +} \ No newline at end of file diff --git a/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/DateUtil.java b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/DateUtil.java new file mode 100644 index 0000000..63b138c --- /dev/null +++ b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/DateUtil.java @@ -0,0 +1,56 @@ +package com.model2d3d.viewer.back.util; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.*; + +/** + * 时间转换工具类 + */ +public class DateUtil { + + public static void main(String[] args) { + // 指定的日期时间字符串 + String dateString = "2023-12-31 23:59:59"; + // 指定的时区 + String timeZoneId = "Asia/Tokyo"; // 日本时区 + + System.out.println(dateStr2Timestamp(dateString, "yyyy-MM-dd HH:mm:ss", timeZoneId)); + + System.out.println(timestamp2DateStr(1609513500000L, "yyyy-MM-dd HH:mm:ss", timeZoneId)); + } + + public static long dateStr2Timestamp(String dateStr, String dateFormat, String timeZoneId) { + try { + // 创建 SimpleDateFormat 对象来解析日期时间字符串 + SimpleDateFormat sdf = new SimpleDateFormat(dateFormat); + // 设置 SimpleDateFormat 对象的时区 + sdf.setTimeZone(TimeZone.getTimeZone(timeZoneId)); + // 解析日期时间字符串并得到 Date 对象 + Date date = sdf.parse(dateStr); + // 获取时间戳(单位:秒) + return date.getTime(); + } catch (ParseException e) { + System.out.println("日期时间字符串转时间戳失败:" + e.getMessage()); + return 0; + } + } + + public static String timestamp2DateStr(long milliseconds, String dateFormat, String timeZoneId) { + try { + Instant instant = Instant.ofEpochMilli(milliseconds); + ZoneId zoneId = ZoneId.of(timeZoneId); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat); + + String formattedDateTime = formatter.format(instant.atZone(zoneId)); + return formattedDateTime; + } catch (Exception e) { + System.out.println("时间戳转日期时间字符串失败:" + e.getMessage()); + return ""; + } + } + +} diff --git a/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/FileUtil.java b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/FileUtil.java new file mode 100644 index 0000000..cdd6110 --- /dev/null +++ b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/FileUtil.java @@ -0,0 +1,416 @@ +package com.model2d3d.viewer.back.util; + +import jakarta.servlet.http.HttpServletResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; +import java.net.URLEncoder; +import java.text.DecimalFormat; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +public class FileUtil { + private static Logger logger = LoggerFactory.getLogger(FileUtil.class); + + /** + * 保存文件 + * @param multipartFile 文件 + * @param filePath 存储路径 + * @param fileName 存储文件名 + * @return 文件url + */ + public static boolean SaveFile(MultipartFile multipartFile,String filePath,String fileName) { + boolean result = false; + if(multipartFile.isEmpty()) + return true; + File file = new File(filePath); + if (!file.exists()) { + file.mkdirs(); + } + try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath + File.separator + fileName))){ + FileInputStream fileInputStream = (FileInputStream) multipartFile.getInputStream(); + byte[] bs = new byte[1024]; + int len; + while ((len = fileInputStream.read(bs)) != -1) { + bos.write(bs, 0, len); + } + bos.flush(); + result = true; + } catch (IOException e) { + logger.error("SaveFile ERROR",e); + } + return result; + } + + /** + * 下载文件 + * @param response + * @param file + * @param fileName + * @return + */ + public static String downloadFile(HttpServletResponse response, File file, String fileName){ + if (fileName != null) { + //当前是从该工程的WEB-INF//File//下获取文件(该目录可以在下面一行代码配置)然后下载到C:\\users\\downloads即本机的默认下载的目录 + if (file.exists()) { + response.setContentType("application/force-download");// 设置强制下载不打开 + response.addHeader("Access-Control-Expose-Headers","Content-Disposition"); + response.addHeader("Content-Disposition", + "attachment;fileName=" + fileName);// 设置文件名 + byte[] buffer = new byte[1024]; + try (FileInputStream fis = new FileInputStream(file)){ + BufferedInputStream bis = new BufferedInputStream(fis); + OutputStream os = response.getOutputStream(); + int i = bis.read(buffer); + while (i != -1) { + os.write(buffer, 0, i); + i = bis.read(buffer); + } + } catch (Exception e) { + logger.error("-----downloadFile---error:"+e.getMessage(),e); + } + } + } + return null; + } + + public static void downloadExcelFile(HttpServletResponse response,File file,String fileName){ + try { + if (fileName != null) { + logger.debug(file.getAbsolutePath()); + //当前是从该工程的WEB-INF//File//下获取文件(该目录可以在下面一行代码配置)然后下载到C:\\users\\downloads即本机的默认下载的目录 + if (file.exists()) { + response.setContentType("application/octet-stream"); + // 告诉浏览器用什么软件可以打开此文件 + response.addHeader("Access-Control-Expose-Headers","Content-Disposition"); + response.addHeader("Content-Disposition","attachment;fileName=" +URLEncoder.encode(fileName, "UTF-8"));// 设置文件名 + byte[] buffer = new byte[1024]; + try (FileInputStream fis = new FileInputStream(file)){ + BufferedInputStream bis = new BufferedInputStream(fis); + OutputStream os = response.getOutputStream(); + int i = bis.read(buffer); + while (i != -1) { + os.write(buffer, 0, i); + i = bis.read(buffer); + } + } catch (Exception e) { + logger.error("-----downloadFile---error:"+e.getMessage(),e); + } + }else{ + logger.error("-----downloadFile---文件不存在------"+file.getName()); + } + } + } catch (Exception e) { + logger.error("-----downloadFile---error:"+e.getMessage(),e); + } + } + + public static void downloadExcelFile(HttpServletResponse response,InputStream fis,String fileName){ + try { + if (fileName != null) { + response.setHeader("Access-Control-Expose-Headers", "Content-Disposition"); + //通知客服文件的MIME类型 + response.setContentType("application/vnd.ms-excel;charset=UTF-8"); + //获取文件的路径 + response.setCharacterEncoding("UTF-8"); + // 告诉浏览器用什么软件可以打开此文件 + response.addHeader("Access-Control-Expose-Headers","Content-Disposition"); + response.addHeader("Content-Disposition","attachment;fileName=" +URLEncoder.encode(fileName, "UTF-8"));// 设置文件名 + byte[] buffer = new byte[1024]; + try (BufferedInputStream bis = new BufferedInputStream(fis)){ + OutputStream os = response.getOutputStream(); + int i = bis.read(buffer); + while (i != -1) { + os.write(buffer, 0, i); + i = bis.read(buffer); + } + response.setHeader("Content-Length", String.valueOf(fis.available())); + } catch (Exception e) { + logger.error("-----downloadFile---error:"+e.getMessage(),e); + } + } + } catch (Exception e) { + logger.error("-----downloadFile---error:"+e.getMessage(),e); + } + } + + /** + * 将二进制转换成文件保存 + * @param instreams 二进制流 + * @param imgPath 图片的保存路径 + * @param imgName 图片的名称 + * @return + * 1:保存正常 + * 0:保存失败 + */ + public static int saveToImgByInputStream(InputStream instreams,String imgPath,String imgName){ + int stateInt = 1; + if(instreams != null){ + File file=new File(imgPath,imgName);//可以是任何图片格式.jpg,.png等 + try (FileOutputStream fos=new FileOutputStream(file);){ + byte[] b = new byte[1024]; + int nRead = 0; + while ((nRead = instreams.read(b)) != -1) { + fos.write(b, 0, nRead); + } + fos.flush(); + } catch (Exception e) { + stateInt = 0; + logger.error("saveToImgByInputStream ERROR",e); + } + } + return stateInt; + } + + public static String formetFileSize(long fileS) {//转换文件大小 + DecimalFormat df = new DecimalFormat("#.00"); + String fileSizeString = ""; + if (fileS < 1024) { + fileSizeString = df.format((double) fileS) + "B"; + } else if (fileS < 1048576) { + fileSizeString = df.format((double) fileS / 1024) + "K"; + } else if (fileS < 1073741824) { + fileSizeString = df.format((double) fileS / 1048576) + "M"; + } else { + fileSizeString = df.format((double) fileS / 1073741824) + "G"; + } + return fileSizeString; + } + + /** + * 获取文件大小转M + * @param fileS + * @return + */ + public static String changeFileSize(long fileS) {//转换文件大小 + DecimalFormat df = new DecimalFormat("#0.00"); + return df.format((double) fileS / 1048576); + } + + /** + * zip文件压缩 + * @param inputFile 待压缩文件夹/文件名 + * @param outputFile 生成的压缩包名字 + */ + public static void zipCompress(String inputFile, String outputFile) throws Exception { + ZipOutputStream out = null; + BufferedOutputStream bos = null; + try { + File fileParent = new File(outputFile).getParentFile(); + if (!fileParent.exists()) + fileParent.mkdirs();// 能创建多级目录 + //创建zip输出流 + out = new ZipOutputStream(new FileOutputStream(outputFile)); + //创建缓冲输出流 + bos = new BufferedOutputStream(out); + File input = new File(inputFile); + compress(out, bos, input,null); + bos.close(); + out.close(); + } finally { + if(bos != null) bos.close(); + if(out != null) out.close(); + } + + } + + public static void zipMultiFile(String filePath, String zipPath) { + File fileParent = new File(zipPath).getParentFile(); + if (!fileParent.exists()) + fileParent.mkdirs();// 能创建多级目录 + File file = new File(filePath); //获取其file对象 + File[] srcFiles = file.listFiles(); //遍历path下的文件和目录,放在File数组中 + if (null != srcFiles && srcFiles.length > 0) { + zipFiles(srcFiles, new File(zipPath)); + } + } + + public static void zipFiles(File[] srcFiles, File zipFile) { + // 判断压缩后的文件存在不,不存在则创建 + if (!zipFile.exists()) { + try { + zipFile.createNewFile(); + } catch (IOException e) { + logger.info("导出zip, createNewFile出错", e); + } + } +// // 创建 FileOutputStream 对象 +// FileOutputStream fileOutputStream = null; +// // 创建 ZipOutputStream +// ZipOutputStream zipOutputStream = null; + // 创建 FileInputStream 对象 + FileInputStream fileInputStream = null; + try (FileOutputStream fileOutputStream = new FileOutputStream(zipFile); + ZipOutputStream zipOutputStream = new ZipOutputStream(fileOutputStream); + ){ +// // 实例化 FileOutputStream 对象 +// fileOutputStream = new FileOutputStream(zipFile); +// // 实例化 ZipOutputStream 对象 +// zipOutputStream = new ZipOutputStream(fileOutputStream); + // 创建 ZipEntry 对象 + ZipEntry zipEntry = null; + // 遍历源文件数组 + for (int i = 0; i < srcFiles.length; i++) { + // 将源文件数组中的当前文件读入 FileInputStream 流中 + fileInputStream = new FileInputStream(srcFiles[i]); + // 实例化 ZipEntry 对象,源文件数组中的当前文件 + zipEntry = new ZipEntry(srcFiles[i].getName()); + zipOutputStream.putNextEntry(zipEntry); + // 该变量记录每次真正读的字节个数 + int len; + // 定义每次读取的字节数组 + byte[] buffer = new byte[1024]; + while ((len = fileInputStream.read(buffer)) > 0) { + zipOutputStream.write(buffer, 0, len); + } + //数组中每个file使用完后,要关闭对应的FileInputStream流 + fileInputStream.close(); + } + } catch (IOException e) { + logger.info("导出zipFiles出错", e); + } finally { + try { + if(fileInputStream != null) fileInputStream.close(); + } catch (IOException e) { + logger.info("导出zipFiles, finally出错", e); + } + } + } + + /** + * @param name 压缩文件名,可以写为null保持默认 + */ + //递归压缩 + public static void compress(ZipOutputStream out, BufferedOutputStream bos, File input, String name) throws IOException { + FileInputStream fos = null; + BufferedInputStream bis = null; + try { + if (name == null) { + name = input.getName(); + } + //如果路径为目录(文件夹) + if (input.isDirectory()) { + //取出文件夹中的文件(或子文件夹) + File[] flist = input.listFiles(); + if (flist.length == 0)//如果文件夹为空,则只需在目的地zip文件中写入一个目录进入 + { + out.putNextEntry(new ZipEntry(name + File.separator)); + } else//如果文件夹不为空,则递归调用compress,文件夹中的每一个文件(或文件夹)进行压缩 + { + for (int i = 0; i < flist.length; i++) { + compress(out, bos, flist[i], name + File.separator + flist[i].getName()); + } + } + } else//如果不是目录(文件夹),即为文件,则先写入目录进入点,之后将文件写入zip文件中 + { + out.putNextEntry(new ZipEntry(name)); + fos = new FileInputStream(input); + bis = new BufferedInputStream(fos); + int len; + //将源文件写入到zip文件中 + byte[] buf = new byte[1024]; + while ((len = bis.read(buf)) != -1) { + bos.write(buf,0,len); + } + bis.close(); + fos.close(); + } + } finally { + if(bis != null) bis.close(); + if(fos != null) fos.close(); + } + } + + + /** + * 删除文件,可以是文件或文件夹 + * + * @param fileName + * 要删除的文件名 + * @return 删除成功返回true,否则返回false + */ + public static boolean delete(String fileName) { + File file = new File(fileName); + if (!file.exists()) { + System.out.println("删除文件失败:" + fileName + "不存在!"); + return false; + } else { + if (file.isFile()) + return deleteFile(fileName); + else + return deleteDirectory(fileName); + } + } + + /** + * 删除单个文件 + * @param fileName + * 要删除的文件的文件名 + * @return 单个文件删除成功返回true,否则返回false + */ + public static boolean deleteFile(String fileName) { + File file = new File(fileName); + // 如果文件路径所对应的文件存在,并且是一个文件,则直接删除 + if (file.exists() && file.isFile()) { + if (file.delete()) { + logger.info("删除单个文件" + fileName + "成功!"); + return true; + } else { + logger.info("删除单个文件" + fileName + "失败!"); + return false; + } + } else { + logger.info("删除单个文件失败:" + fileName + "不存在!"); + return false; + } + } + + /** + * 删除目录及目录下的文件 + * + * @param dir + * 要删除的目录的文件路径 + * @return 目录删除成功返回true,否则返回false + */ + public static boolean deleteDirectory(String dir) { + // 如果dir不以文件分隔符结尾,自动添加文件分隔符 + if (!dir.endsWith(File.separator)) + dir = dir + File.separator; + File dirFile = new File(dir); + // 如果dir对应的文件不存在,或者不是一个目录,则退出 + if ((!dirFile.exists()) || (!dirFile.isDirectory())) { + logger.info("删除目录失败:" + dir + "不存在!"); + return false; + } + boolean flag = true; + // 删除文件夹中的所有文件包括子目录 + File[] files = dirFile.listFiles(); + for (int i = 0; i < files.length; i++) { + // 删除子文件 + if (files[i].isFile()) { + flag = deleteFile(files[i].getAbsolutePath()); + if (!flag) + break; + } + // 删除子目录 + else if (files[i].isDirectory()) { + flag = deleteDirectory(files[i].getAbsolutePath()); + if (!flag) + break; + } + } + if (!flag) { + logger.info("删除目录失败!"); + return false; + } + // 删除当前目录 + if (dirFile.delete()) { + logger.info("删除目录" + dir + "成功!"); + return true; + } else { + return false; + } + } +} diff --git a/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/HttpUtil.java b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/HttpUtil.java new file mode 100644 index 0000000..ca3419b --- /dev/null +++ b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/HttpUtil.java @@ -0,0 +1,195 @@ +package com.model2d3d.viewer.back.util; + +import java.io.*; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.*; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.alibaba.fastjson.JSONObject; + +public class HttpUtil { + + private static Logger logger = LoggerFactory.getLogger(HttpUtil.class); + + /** + * 向指定URL发送GET方法的请求 + * + * @param httpurl + * 请求参数用?拼接在url后边,请求参数应该是 name1=value1&name2=value2 的形式。 + * @return result 所代表远程资源的响应结果 + */ + public static String doGet(String httpurl, HashMap headerMap) { + System.out.printf("Get request, url:%s, header:%s\n", httpurl, JSONObject.toJSONString(headerMap)); + HttpURLConnection connection = null; + InputStream is = null; + BufferedReader br = null; + String result = null;// 返回结果字符串 + try { + // 创建远程url连接对象 + URL url = new URL(httpurl); + // 通过远程url连接对象打开一个连接,强转成httpURLConnection类 + connection = (HttpURLConnection) url.openConnection(); + //设置header + if (null != headerMap && !headerMap.isEmpty()) { + for (Map.Entry item : headerMap.entrySet()) { + connection.setRequestProperty(item.getKey().toString(),item.getValue().toString());//设置header + } + } + // 设置连接方式:get + connection.setRequestMethod("GET"); + // 设置连接主机服务器的超时时间:15000毫秒 + connection.setConnectTimeout(15000); + // 设置读取远程返回的数据时间:60000毫秒 + connection.setReadTimeout(60000); + // 发送请求 + connection.connect(); + // 通过connection连接,获取输入流 + if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { + is = connection.getInputStream(); + } else { + is = connection.getErrorStream(); + } + // 封装输入流is,并指定字符集 + br = new BufferedReader(new InputStreamReader(is, "UTF-8")); + // 存放数据 + StringBuffer sbf = new StringBuffer(); + String temp = null; + while ((temp = br.readLine()) != null) { + sbf.append(temp); + sbf.append("\r\n"); + } + result = sbf.toString(); + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + // 关闭资源 + if (null != br) { + try { + br.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + if (null != is) { + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + connection.disconnect();// 关闭远程连接 + } + + return result; + } + + + /** + * 向指定 URL 发送POST方法的请求 + * + * @param httpUrl + * 发送请求的 URL + * @param param + * 请求参数应该是{"key":"==g43sEvsUcbcunFv3mHkIzlHO4iiUIT R7WwXuSVKTK0yugJnZSlr6qNbxsL8OqCUAFyCDCoRKQ882m6cTTi0q9uCJsq JJvxS+8mZVRP/7lWfEVt8/N9mKplUA68SWJEPSXyz4MDeFam766KEyvqZ99d"}的形式。 + * @return 所代表远程资源的响应结果 + */ + public static String doPost(String httpUrl, String param, HashMap headerMap) { +// logger.info("doPost请求, url:{}, param:{}, headerMap:{}", httpUrl, param, JSONObject.toJSONString(headerMap)); + System.out.printf("Post request, url:%s, param:%s, header:%s\n", httpUrl, param, JSONObject.toJSONString(headerMap)); + HttpURLConnection connection = null; + InputStream is = null; + OutputStream os = null; + BufferedReader br = null; + String result = null; + try { + URL url = new URL(httpUrl); + // 通过远程url连接对象打开连接 + connection = (HttpURLConnection) url.openConnection(); + //设置header + if (null != headerMap && !headerMap.isEmpty()) { + for (Map.Entry item : headerMap.entrySet()) { + connection.setRequestProperty(item.getKey().toString(),item.getValue().toString());//设置header + } + } + // 设置连接请求方式 + connection.setRequestMethod("POST"); + // 设置连接主机服务器超时时间:15000毫秒 + connection.setConnectTimeout(15000); + // 设置读取主机服务器返回数据超时时间:60000毫秒 + connection.setReadTimeout(60000); + + // 默认值为:false,当向远程服务器传送数据/写数据时,需要设置为true + connection.setDoOutput(true); + // 默认值为:true,当前向远程服务读取数据时,设置为true,该参数可有可无 + connection.setDoInput(true); + // 设置传入参数的格式:请求参数应该是 name1=value1&name2=value2 的形式。 + if (null == headerMap || (!headerMap.containsKey("Content-Type") && !headerMap.containsKey("content-type"))) { + connection.setRequestProperty("Content-Type", "application/json"); + } + // 设置鉴权信息:Authorization: Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0 + //connection.setRequestProperty("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0"); + // 通过连接对象获取一个输出流 + os = connection.getOutputStream(); + // 通过输出流对象将参数写出去/传输出去,它是通过字节数组写出的 + os.write(param.getBytes()); + // 通过连接对象获取一个输入流,向远程读取 + if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { + is = connection.getInputStream(); + } else { + is = connection.getErrorStream(); + } + // 对输入流对象进行包装:charset根据工作项目组的要求来设置 + br = new BufferedReader(new InputStreamReader(is, "UTF-8")); + + StringBuffer sbf = new StringBuffer(); + String temp = null; + // 循环遍历一行一行读取数据 + while ((temp = br.readLine()) != null) { + sbf.append(temp); + sbf.append("\r\n"); + } + result = sbf.toString(); + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + // 关闭资源 + if (null != br) { + try { + br.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (null != os) { + try { + os.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (null != is) { + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + // 断开与远程地址url的连接 + connection.disconnect(); + } + return result; + } + +} + diff --git a/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/NetworkUtil.java b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/NetworkUtil.java new file mode 100644 index 0000000..31bc81b --- /dev/null +++ b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/NetworkUtil.java @@ -0,0 +1,72 @@ +package com.model2d3d.viewer.back.util; + +import jakarta.servlet.http.HttpServletRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; + +/** + * 常用获取客户端信息的工具 + */ +public class NetworkUtil { + private static Logger logger = LoggerFactory.getLogger(NetworkUtil.class); + /** + * 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址; + * + * @param request + * @return + * @throws IOException + */ + public final static String getIpAddress(HttpServletRequest request) throws IOException { + // 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址 + + String ip = request.getHeader("X-Forwarded-For"); + if (logger.isInfoEnabled()) { + logger.info("getIpAddress(HttpServletRequest) - X-Forwarded-For - String ip=" + ip); + } + + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + if (logger.isInfoEnabled()) { + logger.info("getIpAddress(HttpServletRequest) - Proxy-Client-IP - String ip=" + ip); + } + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + if (logger.isInfoEnabled()) { + logger.info("getIpAddress(HttpServletRequest) - WL-Proxy-Client-IP - String ip=" + ip); + } + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_CLIENT_IP"); + if (logger.isInfoEnabled()) { + logger.info("getIpAddress(HttpServletRequest) - HTTP_CLIENT_IP - String ip=" + ip); + } + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_X_FORWARDED_FOR"); + if (logger.isInfoEnabled()) { + logger.info("getIpAddress(HttpServletRequest) - HTTP_X_FORWARDED_FOR - String ip=" + ip); + } + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + if (logger.isInfoEnabled()) { + logger.info("getIpAddress(HttpServletRequest) - getRemoteAddr - String ip=" + ip); + } + } + } else if (ip.length() > 15) { + String[] ips = ip.split(","); + for (int index = 0; index < ips.length; index++) { + String strIp = (String) ips[index]; + if (!("unknown".equalsIgnoreCase(strIp))) { + ip = strIp; + break; + } + } + } + return ip; + } +} diff --git a/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/RandomNumberUtil.java b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/RandomNumberUtil.java new file mode 100644 index 0000000..c333c11 --- /dev/null +++ b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/RandomNumberUtil.java @@ -0,0 +1,43 @@ +package com.model2d3d.viewer.back.util; + +import java.util.Random; + +/** +* @author Mr.Jiang +* @time 2022年5月5日 下午8:57:20 +*/ +public class RandomNumberUtil { + private RandomNumberUtil() { + } + public static String createRandomNumber(int length) { + StringBuilder strBuffer = new StringBuilder(); + Random rd = new Random(); + for (int i = 0; i < length; i++) { + strBuffer.append(rd.nextInt(10)); + } + return strBuffer.toString(); + } + + + //生成随机数字和字母, + public static String createRandomLowerLetterAndNumber(int length) { + String val = ""; + Random random = new Random(); + //参数length,表示生成几位随机数 + for(int i = 0; i < length; i++) { + String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num"; + //输出字母还是数字 + if( "char".equalsIgnoreCase(charOrNum) ) { + //输出是大写字母还是小写字母 +// int temp = random.nextInt(2) % 2 == 0 ? 65 : 97; + //输出小写字母 + int temp = 97; + val += (char)(random.nextInt(26) + temp); + } else if( "num".equalsIgnoreCase(charOrNum) ) { + val += String.valueOf(random.nextInt(10)); + } + } + return val; + } +} + diff --git a/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/SendMail.java b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/SendMail.java new file mode 100644 index 0000000..f118da0 --- /dev/null +++ b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/SendMail.java @@ -0,0 +1,260 @@ +package com.model2d3d.viewer.back.util; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.mail.*; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeUtility; +import java.io.*; +import java.security.Security; +import java.util.Date; +import java.util.Properties; + + +public class SendMail { + private static Logger logger = LoggerFactory.getLogger(SendMail.class); + /** + * Message对象将存储我们实际发送的电子邮件信息, + * Message对象被作为一个MimeMessage对象来创建并且需要知道应当选择哪一个JavaMail session。 + */ + private MimeMessage message; + + /** + * Session类代表JavaMail中的一个邮件会话。 + * 每一个基于JavaMail的应用程序至少有一个Session(可以有任意多的Session)。 + * + * JavaMail需要Properties来创建一个session对象。 寻找"mail.smtp.host" 属性值就是发送邮件的主机 + * 寻找"mail.smtp.auth" 身份验证,目前免费邮件服务器都需要这一项 + */ + private Session session; + + /*** + * 邮件是既可以被发送也可以被受到。JavaMail使用了两个不同的类来完成这两个功能:Transport 和 Store。 Transport + * 是用来发送信息的,而Store用来收信。对于我们只需要用到Transport对象。 + */ + private Transport transport; + + private String mailHost = ""; + private int mailPort = 25; + private String sender_username = ""; + private String sender_password = ""; + private String email_sendername = ""; + private boolean mailSsl = false; + private boolean password_encrypted = false; + private String mail_from=""; + private Properties properties = new Properties(); + + /* + * 初始化方法 + */ + public SendMail(boolean debug) { + InputStream in = SendMail.class.getResourceAsStream("/config/application.properties"); + if (null == in) { + //升级springboot版本后修改了pom文件,部署到linux时,如果jar包不包含application.properties文件,用上面的方法读取不到,用下面这个防止为空 + String filePath = System.getProperty("user.dir") + "/config/application.properties"; + try { + in = new BufferedInputStream(new FileInputStream(filePath)); + } catch (FileNotFoundException e1) { + logger.error("发送邮件加载application.properties出错:{}", e1.getMessage()); + } + } + String rawPassword = ""; + try { + properties.load(in); + this.mailHost = properties.getProperty("mail.smtp.host"); + this.mailPort = CommonUtil.String2Int(properties.getProperty("mail.smtp.port")); + this.mailSsl = Boolean.valueOf(properties.getProperty("mail.smtp.ssl")) ; + this.sender_username = properties.getProperty("mail.sender.username"); + rawPassword = properties.getProperty("mail.sender.password"); + this.email_sendername = URLCoder.urlDecoder(properties.getProperty("mail.sender.sendername")); + this.password_encrypted = Boolean.valueOf(properties.getProperty("mail.sender.password_encrypted")); + String fromString = properties.getProperty("mail.sender.from"); + this.mail_from = (fromString == null?sender_username:fromString); + } catch (IOException e) { + logger.error("mail参数初始化失败", e); + } + if (this.password_encrypted) { + try { + this.sender_password = DESUtil.decrypt(rawPassword, "ci3b512jwy199511"); + } catch (Exception e) { + e.printStackTrace(); + } + }else { + this.sender_password = rawPassword; + } + session = Session.getInstance(properties); + session.setDebug(debug);// 开启后有调试信息 + message = new MimeMessage(session); + } + /** + * + * @param subject + * @param sendHtml + * @param receiveUser + */ + public void sendMail(String subject, String sendHtml, String receiveUser, String cc){ + if(this.mailSsl) { + sendMailSsl(subject, sendHtml, receiveUser, cc); + }else { + doSendHtmlEmail25(subject, sendHtml, receiveUser, cc); + } + } + + /** + * 发送邮件 + * + * @param subject + * 邮件主题 + * @param sendHtml + * 邮件内容 + * @param receiveUser + * 收件人地址 + * @param cc + */ + public void doSendHtmlEmail25(String subject, String sendHtml, String receiveUser, String cc) { + try { + // 发件人 + // InternetAddress from = new InternetAddress(sender_username); + // 下面这个是设置发送人的Nick name + InternetAddress from = new InternetAddress( + MimeUtility.encodeWord(email_sendername) + " <" + mail_from + ">"); + message.setFrom(from); + + // 收件人 + InternetAddress to = new InternetAddress(receiveUser); + message.setRecipient(Message.RecipientType.TO, to);// 还可以有CC、BCC +// InternetAddress cto = new InternetAddress(mail_from); +// message.setRecipient(Message.RecipientType.CC, cto); + if (StringUtils.isNotBlank(cc)) { + message.setRecipients(Message.RecipientType.CC, InternetAddress.parse(cc)); + } + + // 邮件主题 + message.setSubject(subject); + + String content = sendHtml.toString(); + // 邮件内容,也可以使纯文本"text/plain" + message.setContent(content, "text/html;charset=UTF-8"); + + // 保存邮件 + message.saveChanges(); + + transport = session.getTransport("smtp"); + // smtp验证,就是你用来发邮件的邮箱用户名密码 + transport.connect(mailHost, mailPort,sender_username, sender_password); + // 发送 + transport.sendMessage(message, message.getAllRecipients()); + // System.out.println("send success!"); + } catch (Exception e) { + logger.error("doSendHtmlEmail25出错", e); + } finally { + if (transport != null) { + try { + transport.close(); + } catch (MessagingException e) { + logger.error("doSendHtmlEmail25 transport出错", e); + } + } + } + } + + + public void sendMailSsl(String subject, String sendHtml, String receiveUser, String cc){ + try { +// Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider()); + final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory"; + final Properties p = System.getProperties() ; + p.setProperty("mail.smtp.host", mailHost); + p.setProperty("mail.smtp.auth", "true"); + p.setProperty("mail.smtp.ssl.protocols", "TLSv1.2"); + p.setProperty("mail.smtp.user", sender_username); + p.setProperty("mail.smtp.pass", sender_password); + + p.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY); + p.setProperty("mail.smtp.socketFactory.fallback", "false"); + //邮箱发送服务器端口,这里设置为465端口 + p.setProperty("mail.smtp.port", mailPort+""); + p.setProperty("mail.smtp.socketFactory.port",mailPort+""); + + // 根据邮件会话属性和密码验证器构造一个发送邮件的session + Session session = Session.getInstance(p, new Authenticator(){ + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(p.getProperty("mail.smtp.user"),p.getProperty("mail.smtp.pass")); + } + }); + session.setDebug(true); + Message message = new MimeMessage(session); + //消息发送的主题 + message.setSubject(subject); + //接受消息的人 + message.setReplyTo(InternetAddress.parse(mail_from)); + + //消息的发送者 + + InternetAddress from = new InternetAddress( + MimeUtility.encodeWord(email_sendername) + " <" + mail_from + ">"); + message.setFrom(from); + +// message.setFrom(new InternetAddress(p.getProperty("mail.smtp.user"),sender_username)); + // 创建邮件的接收者地址,并设置到邮件消息中 +// String[] split = receiveUser.split(","); +// InternetAddress []tos = new InternetAddress[split.length]; +// for (int i = 0; i < split.length; i++) { +// tos[i]=new InternetAddress(split[i]); +// } + // 设置抄送人 +// if (cc != null && cc.length() > 0) { +// message.setRecipients(Message.RecipientType.CC, InternetAddress.parse(cc)); +// } + //message.setRecipients(Message.RecipientType.TO, tos); + + InternetAddress to = new InternetAddress(receiveUser); + message.setRecipient(Message.RecipientType.TO, to);// 还可以有CC、BCC +// InternetAddress cto = new InternetAddress(mail_from); +// message.setRecipient(Message.RecipientType.CC, cto); + if (StringUtils.isNotBlank(cc)) { + message.setRecipients(Message.RecipientType.CC, InternetAddress.parse(cc)); + } + + + // 消息发送的时间 + message.setSentDate(new Date()); + + String content = sendHtml.toString(); + // 邮件内容,也可以使纯文本"text/plain" + message.setContent(content, "text/html;charset=UTF-8"); + +// Multipart mainPart = new MimeMultipart(); +// // 创建一个包含HTML内容的MimeBodyPart +// BodyPart html = new MimeBodyPart(); +// // 设置HTML内容 +// html.setContent(sendHtml+ email_urlinfo, "text/html; charset=utf-8"); +// mainPart.addBodyPart(html); +// // 将MiniMultipart对象设置为邮件内容 +// message.setContent(mainPart); +// // 设置附件 +//// if (fileList != null && fileList.length > 0) { +//// for (int i = 0; i < fileList.length; i++) { +//// html = new MimeBodyPart(); +//// FileDataSource fds = new FileDataSource(fileList[i]); +//// html.setDataHandler(new DataHandler(fds)); +//// html.setFileName(MimeUtility.encodeText(fds.getName(), "UTF-8", "B")); +//// mainPart.addBodyPart(html); +//// } +//// } +// message.setContent(mainPart); + message.saveChanges(); + Transport.send(message); + } catch (MessagingException e) { + logger.error("sendMail--error:"+e.getMessage(),e); + e.printStackTrace(); + } catch (UnsupportedEncodingException e) { + logger.error("sendMail--error:"+e.getMessage(),e); + e.printStackTrace(); + } + } + +} \ No newline at end of file diff --git a/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/ServiceUtil.java b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/ServiceUtil.java new file mode 100644 index 0000000..cf4dbc0 --- /dev/null +++ b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/ServiceUtil.java @@ -0,0 +1,125 @@ +package com.model2d3d.viewer.back.util; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.*; + +import org.apache.commons.lang3.RandomStringUtils; + +/** + * 在处理业务是对参数进行处理的类 + */ +public class ServiceUtil { + + /** + * 把以‘,’号分隔的区域转换为区域数组 + * 如把"重庆#北京#上海"转换为一个列表,包含三个元素,重庆、北京、上海 + * + * @param areas 形如"重庆#北京#上海"的字符串 + * @return 链表 + */ + public static List getAreas(String areas) { + if (isEmpty(areas)) { + return null; + } + List areasList = null; + String[] areaArray = areas.split(","); + if (areaArray.length > 0) { + areasList = new ArrayList(); + for (String s : areaArray) { + areasList.add(s); + } + } + return areasList; + } + + /** + * 把以‘,’号分隔的区域转换为数据库Province In (?) 中问号中应有的形式 + * + * @param areas + * @return + */ + public static String getAreasAsString(String areas) { + if (isEmpty(areas)) { + return null; + } + + StringBuilder builder = new StringBuilder(256); + String[] areaArray = areas.split(","); + boolean bFirst = true; + for (String s : areaArray) { + if (!bFirst) { + builder.append(","); + } + builder.append("\'"); + builder.append(s); + builder.append("\'"); + bFirst = false; + } + return builder.toString(); + } + + public static boolean isEmpty(String str){ + if (str ==null ||"".equals(str)) + return true; + return false; + } + + /** + * 生成随机字符串 + * @param length 表示生成字符串的长度 + * @return + */ + public static String getRandomString(int length) { + String base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@$%^*()"; +// Random random = new Random(); +// StringBuffer sb = new StringBuffer(); +// for (int i = 0; i < length; i++) { +// int number = random.nextInt(base.length()); +// sb.append(base.charAt(number)); +// } + return RandomStringUtils.random(length, base); + } + + public static Date getCurrentDay(){ + Calendar day=Calendar.getInstance(); + day.set(Calendar.HOUR_OF_DAY,0); + day.set(Calendar.MINUTE,0); + day.set(Calendar.SECOND,0); + day.set(Calendar.MILLISECOND,0); + return day.getTime(); + } + + + public static String CreateAccessToken(String userId,String timestamp){ + String[] paramArr = new String[]{userId,timestamp}; + Arrays.sort(paramArr); + String content = paramArr[0].concat(paramArr[1]); + String access_token = null; + try { + MessageDigest md = MessageDigest.getInstance("SHA-1"); + byte[] digest = md.digest(content.toString().getBytes()); + access_token = byteToStr(digest); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return access_token; + } + + private static String byteToStr(byte[] byteArray){ + String strDigest=""; + for(int i=0;i>> 4) & 0X0F]; + tempArr[1] = Digit[mByte & 0X0F]; + String s = new String(tempArr); + return s; + } +} diff --git a/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/TimeIntervalSplitter.java b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/TimeIntervalSplitter.java new file mode 100644 index 0000000..e599340 --- /dev/null +++ b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/TimeIntervalSplitter.java @@ -0,0 +1,36 @@ +package com.model2d3d.viewer.back.util; + +import java.util.ArrayList; +import java.util.List; + +import com.model2d3d.viewer.back.util.aurora.TimeInterval; + +public class TimeIntervalSplitter { + + public static void main(String[] args) { + long startTime = 1609430400000L; // 起始时间戳,2021-01-01 00:00:00 + long endTime = 1609513500000L; // 结束时间戳,2021-01-02 00:00:00 + long intervalInMilliseconds = 3600000; // 固定时间间隔为1小时(3600秒) + + List timeIntervals = splitTimeRange(startTime, endTime, intervalInMilliseconds); + + for (TimeInterval interval : timeIntervals) { + System.out.println("[" + interval.getStartTime() + ", " + interval.getEndTime() + "]"); + } + } + + public static List splitTimeRange(long startTime, long endTime, long intervalInMilliseconds) { + List timeIntervals = new ArrayList<>(); + + long current = startTime; + while (current < endTime) { + long intervalEnd = Math.min(current + intervalInMilliseconds, endTime); + TimeInterval interval = new TimeInterval(current, intervalEnd); + timeIntervals.add(interval); + current += intervalInMilliseconds; + } + + return timeIntervals; + } + +} diff --git a/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/URLCoder.java b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/URLCoder.java new file mode 100644 index 0000000..5271a4e --- /dev/null +++ b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/URLCoder.java @@ -0,0 +1,54 @@ +package com.model2d3d.viewer.back.util; +import java.io.UnsupportedEncodingException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** +* @author Mr.Jiang +* @time 2022年8月3日 下午9:29:28 +*/ +public class URLCoder { + + private static Logger logger = LoggerFactory.getLogger(URLCoder.class); + + public static String urlEncoder(String str) { + logger.info("url待编码:{}", str); + String result = ""; + if (null == str) { + return ""; + } + try { + result = java.net.URLEncoder.encode(str, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + logger.info("url编码结果:{}", result); + return result; + } + + public static String urlDecoder(String str) { + logger.info("url待解码:{}", str); + String result = ""; + if (null == str) { + return ""; + } + try { + result = java.net.URLDecoder.decode(str, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + logger.info("url解码结果:{}", result); + return result; + } + + public static void main(String[] args) { + // TODO Auto-generated method stub + String s = urlEncoder("DriveMate安全運転管理クラウド"); + System.out.println("编码:"+s); + String s1 = urlDecoder(s); + System.out.println("解码:"+s1); + + } + +} diff --git a/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/ValidatorUtil.java b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/ValidatorUtil.java new file mode 100644 index 0000000..76e9548 --- /dev/null +++ b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/ValidatorUtil.java @@ -0,0 +1,887 @@ +package com.model2d3d.viewer.back.util; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.DateFormatUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.UnsupportedEncodingException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 验证工具类 + */ +public class ValidatorUtil { + private static Logger logger = LoggerFactory.getLogger(ValidatorUtil.class); + + private static final String pwdMatch = "(?!^\\d+$)(?!^[A-Za-z]+$)(?!^[^A-Za-z0-9]+$)(?!^.*[\\u4E00-\\u9FA5].*$)^\\S{8,20}$"; + + private static final String ipAddrMatch = "^((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])$"; + + + /** + * 验证必填 + * @param value 验证的值 + * @param parameterName 参数名称 + * @param required 是否必填;true:必填;false:不必填 + * @param errorMap 存放错误消息 + * @return true: 验证通过;false:未通过 + */ + public static boolean validParameterRequired(Object value,String parameterName,boolean required,Map errorMap){ + if(errorMap == null){ + errorMap = new HashMap<>(); + } + if(required){ + if(value == null){ + errorMap.put(parameterName,"不能为空"); + return false; + }else if(value instanceof Date){ + + }else{ + String v = String.valueOf(value); + if (value == null || v.length() == 0 || "".equals(v.trim())) { + errorMap.put(parameterName,"不能为空"); + return false; + } + } + } + return true; + } + + /** + * 验证是一个日期 + * @param date 验证的值 + * @param parameterName 参数名称 + * @param required 是否必填;true:必填;false:不必填 + * @param errorMap 存放错误消息 + * @return true: 验证通过;false:未通过 + */ + public static boolean validParameterDateAlert(Object date,String parameterName,boolean required,Map errorMap){ + if(errorMap == null){ + errorMap = new HashMap<>(); + } + if(!validParameterRequired(date, parameterName, required, errorMap)){ + return false; + } + if(!(date instanceof Date) && null != date){ + String v = String.valueOf(date); + //说明已填写:验证是否为日期格式 + if(null != v && v.length()>0){ + if(!isDate(v)){ + errorMap.put(parameterName,"不是一个日期格式;格式:(例如:2017-02-27)"); + return false; + } + } + } + + return true; + } + + /** + * 验证是否在指定日期之前 + * @param targetDate 目标日期 + * @param beforeDate 之前的日期 + * @param parameterName 参数名称 + * @param required 是否必填;true:必填;false:不必填 + * @param errorMap 存放错误消息 + * @return true: 验证通过;false:未通过 + */ + public static boolean validParameterDateBeforeAlert(Object targetDate,Object beforeDate,String parameterName,boolean required,Map errorMap){ + if(errorMap == null){ + errorMap = new HashMap<>(); + } + if(!validParameterDateAlert(beforeDate,parameterName,required,errorMap)){ + return false; + } + + if(!(targetDate instanceof Date)){ + String before = String.valueOf(beforeDate); + //说明已填写:验证是否在指定日期之前 + if(null == before || before.length()<=0 || !isDate(beforeDate)){ + return true; + } + } + + if(!isDateBefore(targetDate, beforeDate)){ + errorMap.put(parameterName,"[ "+dateFormat(beforeDate)+" ] 不是 [ "+dateFormat(targetDate)+" ]之前的一个日期。"); + return false; + } + + return true; + } + + /** + * 验证是否在指定日期之后 + * @param targetDate 目标日期 + * @param afterDate 之后的日期 + * @param parameterName 参数名称 + * @param required 是否必填;true:必填;false:不必填 + * @param errorMap 存放错误消息 + * @return true: 验证通过;false:未通过 + */ + public static boolean validParameterDateAfterAlert(Object targetDate,Object afterDate,String parameterName,boolean required,Map errorMap){ + if(errorMap == null){ + errorMap = new HashMap<>(); + } + if(!validParameterDateAlert(afterDate,parameterName,required,errorMap)){ + return false; + } + if(!(afterDate instanceof Date)){ + String after = String.valueOf(afterDate); + //说明已填写:验证是否在指定日期之后 + if(null == after || after.length()<=0 || !isDate(afterDate)){ + return true; + } + } + if(!isDateAfter(targetDate, afterDate)){ + errorMap.put(parameterName,"[ "+dateFormat(afterDate)+" ]不是[ "+dateFormat(targetDate)+" ]之后的一个日期。"); + return false; + } + return true; + } + + /** + * 验证日期是否在指定的开始日期-结束日期之间(不包含开始日期、结束日期) + * @param beginDate 开始日期 + * @param endDate 结束日期 + * @param date 比较的日期 + * @param parameterName 参数名称 + * @param required 是否必填;true:必填;false:不必填 + * @param errorMap 存放错误消息 + * @return + */ + public static boolean validParameterBetweenDateAlert(Object beginDate,Object endDate,Object date,String parameterName,boolean required,Map errorMap){ + if(errorMap == null){ + errorMap = new HashMap<>(); + } + if(!validParameterDateAlert(date,parameterName,required,errorMap)){ + return false; + } + + if(!(date instanceof Date)){ + String d = String.valueOf(date); + if(null == d || d.length()<=0 || !isDate(date)){ + return true; + } + } + + if(!isDateBetween(beginDate, endDate,date)){ + errorMap.put(parameterName,"[ "+dateFormat(date)+" ]必须在[ "+dateFormat(beginDate)+" ]-[ "+dateFormat(endDate)+" ]之间。"); + return false; + } + return true; + } + + /** + * 日期格式化 yyyy-MM-dd + * @param date 日期 + * @return + */ + private static String dateFormat(Object date){ + if(date instanceof Date){ + return DateFormatUtils.format((Date) date,"yyyy-MM-dd"); + } + return String.valueOf(date); + } + + + /** + * 校验参数方法. + * + * @param target 需要校验的目标字符串 + * @param fieldName 错误信息绑定的属性名 + * @param isrequired 是否必填 + * @param minLength 最小长度 + * @param maxLength 最大长度 + * @param dateType data type + * 1.字符串为数字, + * 2. 字符串为“0”---”9”, ”a”---”z”,”A”---”Z” ; + * 3.字符串为values中的值 + * 4.任意字符串 + * 5.IP + * 6.Email地址 + * 7.电话号码(移动电话:18000000000、固定电话:023-6500000、400电话) + * 8:电话号码不符合要求:移动号码 + * 9:电话号码不符合要求:座机(固定电话) + * 10:电话号码不符合要求:4000000000 + * 11:日期格式:2017-02-27 + * 12: 数字或者小数:1 或者 -1 或者 0.1 或者 -0.1 + * @param errorMap 错误信息Map + * @return true:success;false: failed + * @version + */ + public static boolean validParameterAlert2(Object target, String fieldName, boolean isrequired, + int minLength, int maxLength, int dateType, Map errorMap) { + return (validParameterAlert(target, fieldName, isrequired, minLength, maxLength, dateType, null, errorMap)==0); + } + + + /** + * 校验参数方法. + * + * @param target 需要校验的目标字符串 + * @param fieldName 错误信息绑定的属性名 + * @param isrequired 是否必填 + * @param minLength 最小长度 + * @param maxLength 最大长度 + * @param dataType data type + * 1.字符串为数字, + * 2. 字符串为“0”---”9”, ”a”---”z”,”A”---”Z” ; + * 3.字符串为values中的值 + * 4.任意字符串 + * 5.IP + * 6.Email地址 + * 7.电话号码(移动电话:18000000000、固定电话:023-6500000、400电话) + * 8:电话号码不符合要求:移动号码 + * 9:电话号码不符合要求:座机(固定电话) + * 10:电话号码不符合要求:4000000000 + * 11:日期格式:2017-02-27 + * 12: 数字或者小数:1 或者 -1 或者 0.1 或者 -0.1 + * @param errorMap 错误信息Map + * @return int 0:success, other failure + * @version + */ + public static int validParameterAlert(Object target, String fieldName, boolean isrequired, + int minLength, int maxLength, int dataType, Map errorMap) { + return validParameterAlert(target, fieldName, isrequired, minLength, maxLength, dataType, null, errorMap); + } + + /** + * 校验参数方法. + * + * @param target 需要校验的目标字符串 + * @param fieldName 错误信息绑定的属性名 + * @param required 是否必填 + * @param minLength 最小长度 + * @param maxLength 最大长度 + * @param dataType data type + * 1.字符串为数字, + * 2. 字符串为“0”---”9”, ”a”---”z”,”A”---”Z” ; + * 3.字符串为values中的值 + * 4.任意字符串 + * 5.IP + * 6.Email地址 + * 7.电话号码(移动电话:18000000000、固定电话:023-6500000、400电话) + * 8:电话号码不符合要求:移动号码 + * 9:电话号码不符合要求:座机(固定电话) + * 10:电话号码不符合要求:4000000000 + * 11:日期格式:2017-02-27 + * 12: 数字或者小数:1 或者 -1 或者 0.1 或者 -0.1 + * @param errorMap 错误信息Map + * @return int 0:success, other failure + * @version + */ + public static int validParameterAlert(Object target, String fieldName, boolean required, + int minLength, int maxLength, int dataType, String[] values, Map errorMap) { + int resultCode = 0; + try { + resultCode = ValidatorUtil.validParameter(target, required, minLength, maxLength, dataType, values); + } catch (Exception e) { + throw new RuntimeException(e); + } + /** + * 1:必填但没填写 + * 2:不符合要求的长度范围,限制最小长度 + * 3:包含单双引号 + * 4:非数字 + * 5 不符合handletype为2所要求的值 + * 6不符合handletype为3所要求的值 + * 7:不符合要求的ip地址 + * 8 大于要求的最大长度,不限制最小长度 + * 9 不符合要求的email地址 + */ + switch (resultCode) { + case 0: + return resultCode; + case 1: + errorMap.put(fieldName, "不能为空"); + break; + case 2: + if (minLength != maxLength) { + errorMap.put(fieldName, "不能少于" + minLength + + "且不能超过" + maxLength + "个字符"); + } else { + errorMap.put(fieldName, "应该为" + minLength + "个字符"); + } + break; + case 3: + errorMap.put(fieldName, "不允许带有单引号或双引号"); + break; + case 4: + errorMap.put(fieldName, "必须是数字"); + break; + case 5: + errorMap.put(fieldName, "不能超过" + maxLength + "个字符,并且只能是数字和字母"); + break; + case 6:// no this + if (null != values && values.length > 0) { + String str = ""; + for (String v : values) { + str += str.equals("") ? v : ", " + v; + } + errorMap.put(fieldName, "只能是 [" + str + "] 范围的值"); + } + break; + case 7: + errorMap.put(fieldName, "请填写" + "正确的IP地址"); + break; + case 8: + errorMap.put(fieldName, "不能少于" + maxLength + "个字符"); + break; + case 9: + errorMap.put(fieldName, "请填写正确的电子邮箱地址"); + break; + case 10: + errorMap.put(fieldName, "请填写正确的电话号码;格式:移动号码(例如:18000000000) 或者 座机(固定电话)(例如:023-6666666) 或者 400 电话号码(例如:4000000000)"); + break; + case 11: + errorMap.put(fieldName, "请填写正确的电话号码;格式:移动号码(例如:18000000000)"); + break; + case 12: + errorMap.put(fieldName, "请填写正确的电话号码;格式:座机(固定电话)(例如:023-6666666)"); + break; + case 13: + errorMap.put(fieldName, "请填写正确的电话号码;格式:400 电话号码(例如:4000000000)"); + break; + case 14: + errorMap.put(fieldName, "请填写正确的日期;格式:(例如:2017-02-01)"); + break; + case 15: + errorMap.put(fieldName, "请填写正确的数值;整数或者小数 格式:(1 或者 -1 或者 0.1 或者 -0.1)"); + break; + default:// hand type is not correct + resultCode = 99; + break; + } + return resultCode; + } + + /** + * 预处理参数,默认值、长度等 + * + * @param target 参数 + * @param required 必填 + * @param minLength 是已经填写了值的情况下的参数最小参数,即最少填写1 + * @param maxLength 参数最大长度 + * @param dataType 数据类型 + * 1.字符串为数字, + * 2. 字符串为“0”---”9”, ”a”---”z”,”A”---”Z” ; + * 3.字符串为values中的值 + * 4.任意字符串 + * 5.IP + * 6.Email地址 + * 7.电话号码(移动电话:18000000000、固定电话:023-6500000、400电话) + * 8:电话号码不符合要求:移动号码 + * 9:电话号码不符合要求:座机(固定电话) + * 10:电话号码不符合要求:4000000000 + * 11:日期格式:2017-02-27 + * 12: 数字或者小数:1 或者 -1 或者 0.1 或者 -0.1 + * @param values 参数列表值 + * @return int 0:ok + * 1:必填但没填写 + * 2:不符合要求的长度范围,限制最小长度 + * 3:包含单双引号 + * 4:非数字 + * 5:不符合handletype为2所要求的值 + * 6:不符合handletype为3所要求的值 + * 7:不符合要求的ip地址 + * 8:大于要求的最大长度,不限制最小长度 + * 9:不符合要求的email地址 + * 10: 电话号码不符合要求:移动号码 或者 座机 或者 400 电话号码 + * 11:电话号码不符合要求:移动号码 + * 12:电话号码不符合要求:座机(固定电话) + * 13:电话号码不符合要求:4000000000 + * 14: 验证是日期格式:2017-02-27 + * 15: 数字或者小数:1 或者 -1 或者 0.1 或者 -0.1 + * @throws Exception the exception + */ + public static int validParameter(Object target, boolean required, int minLength, int maxLength, int dataType, String[] values) throws Exception { + int resultCode = 0; + String targetStr = ""; + if(null != target){ + targetStr = String.valueOf(target); + } + // 判断是否必填 + if (required && (null == target || targetStr.length() == 0 || "".equals(targetStr.trim()))) { + return 1; + }else if (null == target || targetStr.length() == 0 || "".equals(targetStr.trim())) { + return 0; + } + + //不是Date(日期)类型 + if(!(target instanceof Date)){ + int len = targetStr.length(); //默认 0 + if (minLength > 0 && (len < minLength || len > maxLength)) { + return 2; + }else if (len > maxLength) { + return 8; + } + // check whether contains ' and " character + if (targetStr.indexOf('\'') >= 0 || targetStr.indexOf('\"') >= 0) { + return 3; + } + } + switch (dataType) { // 1.字符串为数字 ; 2. 字符串为“0”---”9”, ”a”---”z”, + // ”A”---”Z” ;3 .字符串为values中的值 4.任意字符串 + case 1: + if (!isNumeric(targetStr)) { + resultCode = 4; + } + break; + case 2: + if (!isNumOrChar(targetStr)) { + resultCode = 5; + } + break; + case 3: + resultCode = 6; + if (values == null) { + break; + } + for (int i = 0; i < values.length; i++) { + String tmp = values[i]; + if (targetStr.toLowerCase().equals(tmp.toLowerCase())) { // 都转化为小写进行比较 + resultCode = 0; + break; + } + } + break; + case 4: + break; + case 5: + if (!isIp(targetStr)) { + resultCode = 7; + } + break; + case 6: + if (!isEmail(targetStr)) { + resultCode = 9; + } + break; + case 7: + if(!isPhoneNumber(targetStr)){ + resultCode = 10; + } + break; + case 8: //验证移动电话号码 + if(!isMobilePhone(targetStr)){ + resultCode = 11; + } + break; + case 9: //验证固定电话号码 + if(!isTelephone(targetStr)){ + resultCode = 12; + } + break; + case 10: //验证400电话 + if(!is400Phone(targetStr)){ + resultCode = 13; + } + break; + case 11: //验证是日期格式:2017-02-27 + if(!isDate(target)){ + resultCode = 14; + } + break; + case 12: //验证是数字或者小数(包含负数) + if(!isNumberOrDecimal(targetStr)){ + resultCode = 15; + } + break; + default: + resultCode = 99; + break; + } + return resultCode; + } + + + + /** + * 正则表达式验证 + * + * @param deststr 被检查字符串 + * @param regex 正则表达式 + * @return boolean ,true_符合正则表达式 + */ + public static boolean isRegex(String deststr, String regex) { + if (deststr == null || deststr.trim().length() == 0) { + return false; + } + return deststr.matches(regex); + } + + /** + * 数字验证 + * + * @param deststr 被检查字符串 + * @return boolean ,true_数字 + */ + public static boolean isNumeric(String deststr) { + return deststr.matches("\\d+"); + } + + /** + * 判断是数字或者小数(包含负数) + * @param str 检查的字符串 + * @return + */ + public static boolean isNumberOrDecimal(String str){ + return str.matches("(-?\\d+)|(-?\\d+\\.\\d+)"); + } + /** + * 邮箱验证 + * + * @param deststr 被检查字符串 + * @return boolean ,true_邮箱 + */ + public static boolean isEmail(String deststr) { + return deststr.matches("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$"); + } + + /** + * 字符串是否由0--9,a--z,A--Z组成 + * + * @param deststr 被检查字符串 + * @return boolean ,true_字符串由0--9,a--z,A--Z组成 + */ + public static boolean isNumOrChar(String deststr) { + return deststr.matches("\\w+"); + } + + + /** + * 得到字符的长度,统一用UTF-8,汉字算三 + * + * @param tmp string + * @return int string length -1_表示返回错误,其他为字段长度 + */ + public static int getCharLength(String tmp) { + int len = 1; + try { + len = tmp.getBytes("UTF-8").length; + } catch (UnsupportedEncodingException e) { + len = -1; + } + return len; + } + + + /** + * IP检验 + * + * @param ip ip address + * @return boolean true:yes false:no + */ + public static boolean isIp(String ip) { + return ip.matches("([1-9]|[1-9]\\d|1\\d{2}|2[0-1]\\d|23[0-2])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}"); + } + + /** + * 判断字符串是否为合法手机号 11位 13 14 15 18开头 + * + * @param str the str + * @return boolean boolean + */ + public static boolean isMobile(String str){ + if(isEmpty(str)) + return false; + return str.matches("^(13|14|15|18|17)\\d{9}$"); + } + + /** + * 判断是否为数字 + * + * @param str the str + * @return boolean boolean + */ + public static boolean isNumber(String str) { + try{ + Integer.parseInt(str); + return true; + }catch(Exception ex){ + return false; + } + } + + /** + * 判断字符串是否为非空(包含null与"") + * + * @param str the str + * @return boolean boolean + */ + public static boolean isNotEmpty(String str){ + if(str == null || "".equals(str)) + return false; + return true; + } + + /** + * 判断字符串是否为非空(包含null与""," ") + * + * @param str the str + * @return boolean boolean + */ + public static boolean isNotEmptyIgnoreBlank(String str){ + if(str == null || "".equals(str) || "".equals(str.trim())) + return false; + return true; + } + + /** + * 判断字符串是否为空(包含null与"") + * + * @param str the str + * @return boolean boolean + */ + public static boolean isEmpty(String str){ + if(str == null || "".equals(str)) + return true; + return false; + } + + /** + * 判断字符串是否为空(包含null与""," ") + * + * @param str the str + * @return boolean boolean + */ + public static boolean isEmptyIgnoreBlank(String str){ + if(str == null || "".equals(str) || "".equals(str.trim())) + return true; + return false; + } + + /** + * 判断是否为浮点数或者整数 + * + * @param str the str + * @return true Or false + */ + public static boolean isNumerOrFloat(String str){ + Pattern pattern = Pattern.compile("^(-?\\d+)(\\.\\d+)?$"); + Matcher isNum = pattern.matcher(str); + if( !isNum.matches() ){ + return false; + } + return true; + } + + /** + * 验证字符串是否是时间格式. + * + * @param dateStr 时间字符串 + * @param format 时间格式 默认为:yyyy-MM-dd HH:mm:ss + * @return 返回值 true:是时间格式 false:不是时间格式 + */ + public static boolean isValidDate(String dateStr, String format) { + if(dateStr == null || dateStr.trim().length() == 0) { + return false; + } + if(format == null || format.trim().length() == 0) { + format = "yyyy-MM-dd HH:mm:ss"; + } + SimpleDateFormat df = new SimpleDateFormat(format); + try { + df.parse(dateStr); + return true; + } catch (Exception e) { + return false; + } + } + + /** + * 验证电话号码 + * 匹配格式:17,13,15(除154),18 开头的移动号码 + * 匹配格式:座机电话如:023-600000000 + * 匹配格式:400电话;如:4000000000 + * @param phoneNumber + * @return + */ + public static boolean isPhoneNumber(String phoneNumber){ + if(null == phoneNumber){ + return false; + } + String regExp ="^((17[0-9])|(13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$|(0[0-9]{2,3}-[0-9]{7,8})$|(4\\d{9})$"; + Pattern p = Pattern.compile(regExp); + return p.matcher(phoneNumber).find(); + } + + + /** + * 验证移动电话 + * 匹配格式:17,13,15(除154),18 开头的移动号码 + * @param mobilePhone 电话号码 + * @return + */ + public static boolean isMobilePhone(String mobilePhone){ + if(null == mobilePhone){ + return false; + } + return mobilePhone.matches("^((17[0-9])|(13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$"); + } + + /** + * 验证固定电话号码 + * 匹配格式:座机电话如:023-600000000 + * @param telephone 电话号码 + * @return + */ + public static boolean isTelephone(String telephone){ + if(null == telephone){ + return false; + } + return telephone.matches("^0[0-9]{2,3}-[0-9]{7,8}$"); + } + + + /** + * 400电话号码 + * 匹配格式:400电话;如:4000000000 + * @param phoneNumber + * @return + */ + public static boolean is400Phone(String phoneNumber){ + if(null == phoneNumber){ + return false; + } + String regExp ="^4\\d{9}$"; + Pattern p = Pattern.compile(regExp); + return p.matcher(phoneNumber).find(); + } + + + /** + * 验证是否为日期格式 + * 格式:如:2017-02-27 + * 年:1000-9999 + * 月:01-12 + * 日:01-31 + * @param date 日期的字符串 + * @return true:是;false:否 + */ + public static boolean isDate(Object date){ + if(date == null){ + return false; + } + if(!(date instanceof Date)){ + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + format.setLenient(false); //这个的功能是不把2017-02-29 转换为2017-03-01(严格模式-平年的2月没有29日) + try { + Date parse = format.parse(String.valueOf(date)); + return true; + } catch (ParseException e) { +// e.printStackTrace(); + return false; + } + } + return true; +// return date.matches("^([^0,\\D])\\d{3}-((0[1-9]{1})|(1[0-2]{1}))-((0[1-9]{1})|([1-2]{1}[0-9]{1})|3[0-1]{1})$"); + } + + + /** + * 判断在某个日期之后 + * @param targetDate 目标日期 2017-02-27 + * @param afterDate 之后的日期 2017-02-28 + * @return true:是;false:否 + */ + public static boolean isDateAfter(Object targetDate,Object afterDate){ + if(isDate(targetDate) && isDate(afterDate)){ + Date target = null; + Date after = null; + SimpleDateFormat simpleDateFormat= new SimpleDateFormat("yyyy-MM-dd"); + try { + if(targetDate instanceof Date){ + target = simpleDateFormat.parse(simpleDateFormat.format((Date) targetDate)); + }else{ + target = simpleDateFormat.parse(String.valueOf(targetDate)); + } + if(afterDate instanceof Date){ + after = simpleDateFormat.parse(simpleDateFormat.format((Date) afterDate)); + }else{ + after = simpleDateFormat.parse(String.valueOf(afterDate)); + } + //after 在某个日期之后 + return after.after(target); + } catch (ParseException e) { + e.printStackTrace(); + } + } + return false; + } + + /** + * 验证在某日期之后 + * @param targetDate 目标日期 2017-02-21 + * @param beforeDate 之前的日期 2017-02-11 + * @return true:是;false:否 + */ + public static boolean isDateBefore(Object targetDate,Object beforeDate){ + if(isDate(targetDate) && isDate(beforeDate)){ + Date target = null; + Date before = null; + SimpleDateFormat simpleDateFormat= new SimpleDateFormat("yyyy-MM-dd"); + try { + if(targetDate instanceof Date){ + target = (Date) targetDate; + }else{ + target = simpleDateFormat.parse(String.valueOf(targetDate)); + } + if(beforeDate instanceof Date){ + before = (Date) beforeDate; + }else{ + before = simpleDateFormat.parse(String.valueOf(beforeDate)); + } + //before 在 目标日期 之前 + return before.before(target); + } catch (ParseException e) { + e.printStackTrace(); + } + } + return false; + } + + /** + * 判断在指定日期之间(不包含开始、结束日期) + * @param beginDate 开始日期 2017-01-01 + * @param endDate 结束日期 2017-03-10 + * @param date 比较日期 2017-02-10 + * @return + */ + public static boolean isDateBetween(Object beginDate,Object endDate,Object date){ + return (isDateAfter(beginDate,date) && isDateBefore(endDate,date)); + } + + + //禁止实例化 + private ValidatorUtil(){} + + /** + * 验证参数 + * @param errorMap + */ +// public static void validateParameter(Map errorMap){ +// if(!errorMap.isEmpty()){ +// throw new ParametersException(errorMap); +// } +// } + + public static boolean validPassWord(String newpwd) { + return newpwd.matches(pwdMatch); + } + + public static boolean validIpAddr(String ip) { + if (StringUtils.isBlank(ip)) { + return false; + } + return ip.matches(ipAddrMatch); + } + +} diff --git a/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/async/OptAsync.java b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/async/OptAsync.java new file mode 100644 index 0000000..a5c4c30 --- /dev/null +++ b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/async/OptAsync.java @@ -0,0 +1,35 @@ +package com.model2d3d.viewer.back.util.async; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +import com.model2d3d.viewer.back.util.SendMail; + +/** + * 异步操作 + * @author jwy-style + */ +@Component +public class OptAsync{ + + private Logger logger = LoggerFactory.getLogger(OptAsync.class); + + + + @Async + public void doSendWork(String subject, String sendHtml, String receiveUser, String cc) { + SendMail cn = new SendMail(false); + logger.info("---SendMailAsync---start----"); + logger.info("---SendMailContent-----主题:{}, 收件人:{}, 抄送人:{}, 内容:{}", subject, receiveUser, cc, sendHtml); + try { + cn.sendMail(subject, sendHtml, receiveUser, cc); + } catch (Exception e) { + logger.error("----SendMailAsync--error:"+e.getMessage(),e); + } + + logger.info("---SendMailAsync---end----"); + } + +} diff --git a/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/aurora/TimeInterval.java b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/aurora/TimeInterval.java new file mode 100644 index 0000000..3ea3fc2 --- /dev/null +++ b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/aurora/TimeInterval.java @@ -0,0 +1,10 @@ +package com.model2d3d.viewer.back.util.aurora; + +import lombok.Data; + +@Data +public class TimeInterval { + + private final long startTime; + private final long endTime; +} diff --git a/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/redis/RedisClusterConfig.java b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/redis/RedisClusterConfig.java new file mode 100644 index 0000000..b7f2f6e --- /dev/null +++ b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/redis/RedisClusterConfig.java @@ -0,0 +1,106 @@ +package com.model2d3d.viewer.back.util.redis; + +import java.io.Serializable; +import java.time.Duration; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import org.apache.commons.pool2.impl.GenericObjectPoolConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisClusterConfiguration; +import org.springframework.data.redis.connection.RedisConfiguration; +import org.springframework.data.redis.connection.RedisPassword; +import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; +import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +/** + * Redis 集群模式配置 + * @author jwy-style + * + */ +@Configuration +@ConditionalOnProperty(prefix = "spring.redis",value = "mode", havingValue = "cluster", matchIfMissing = false) +public class RedisClusterConfig { + + private static Logger logger = LoggerFactory.getLogger(RedisClusterConfig.class); + + public RedisClusterConfig() { + logger.info("RedisConfig--Cluster--init"); + } + @Value("${spring.redis.cluster.nodes}") + private String nodes; + @Value("${spring.redis.cluster.max-redirects}") + private Integer maxRedirects; + + @Value("${spring.redis.password}") + private String password; + + @Value("${spring.redis.timeout}") + private long timeout; + + @Value("${spring.redis.lettuce.shutdown-timeout}") + private long shutDownTimeout; + + @Value("${spring.redis.lettuce.pool.max-idle}") + private int maxIdle; + + @Value("${spring.redis.lettuce.pool.min-idle}") + private int minIdle; + + @Value("${spring.redis.lettuce.pool.max-active}") + private int maxActive; + + @Value("${spring.redis.lettuce.pool.max-wait}") + private long maxWait; + + @Bean + public RedisClusterConfiguration redisClusterConfiguration() { + Set hosts = new HashSet<>(); + hosts.addAll(Arrays.asList(nodes.split(","))); + RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration(hosts); + redisClusterConfiguration.setMaxRedirects(maxRedirects); + redisClusterConfiguration.setPassword(RedisPassword.of(password)); + + return redisClusterConfiguration; + } + + @Bean + public LettuceConnectionFactory lettuceConnectionFactory(RedisConfiguration redisConfiguration) { + GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig(); + genericObjectPoolConfig.setMaxIdle(maxIdle); + genericObjectPoolConfig.setMinIdle(minIdle); + genericObjectPoolConfig.setMaxTotal(maxActive); + genericObjectPoolConfig.setMaxWaitMillis(maxWait); + genericObjectPoolConfig.setTimeBetweenEvictionRunsMillis(100); + + LettuceClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder() + .commandTimeout(Duration.ofMillis(timeout)) + .shutdownTimeout(Duration.ofMillis(shutDownTimeout)) + .poolConfig(genericObjectPoolConfig) + .build(); + LettuceConnectionFactory factory = new LettuceConnectionFactory(redisConfiguration, clientConfig); + return factory; + } + + @Bean + public RedisTemplate redisTemplate(LettuceConnectionFactory redisConnectionFactory){ + redisConnectionFactory.setShareNativeConnection(false);//交由定义池控制 + RedisTemplate template = new RedisTemplate(); + template.setKeySerializer(new StringRedisSerializer()); + template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); + template.setHashKeySerializer(new StringRedisSerializer());// Hash key序列化 + template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());// Hash value序列化 + template.setConnectionFactory(redisConnectionFactory); + return template; + } +} diff --git a/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/redis/RedisSentinelConfig.java b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/redis/RedisSentinelConfig.java new file mode 100644 index 0000000..aaae082 --- /dev/null +++ b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/redis/RedisSentinelConfig.java @@ -0,0 +1,111 @@ +package com.model2d3d.viewer.back.util.redis; + +import java.io.Serializable; +import java.time.Duration; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import org.apache.commons.pool2.impl.GenericObjectPoolConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConfiguration; +import org.springframework.data.redis.connection.RedisPassword; +import org.springframework.data.redis.connection.RedisSentinelConfiguration; +import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; +import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +/** + * Redis缓存配置类 + * Redis cache configuration class. + * + * Author: jwy-style + */ +@Configuration +@ConditionalOnProperty(prefix ="spring.redis" ,name = "mode", havingValue = "sentinel" , matchIfMissing = false) +public class RedisSentinelConfig { + + private static Logger logger = LoggerFactory.getLogger(RedisSentinelConfig.class); + + public RedisSentinelConfig() { + logger.info("RedisConfig---Sentinel--init"); + } + @Value("${spring.redis.sentinel.master}") + private String master; + @Value("${spring.redis.sentinel.nodes}") + private String nodes; + + @Value("${spring.redis.database}") + private int database; + + @Value("${spring.redis.password}") + private String password; + + @Value("${spring.redis.timeout}") + private long timeout; + + @Value("${spring.redis.lettuce.shutdown-timeout}") + private long shutDownTimeout; + + @Value("${spring.redis.lettuce.pool.max-idle}") + private int maxIdle; + + @Value("${spring.redis.lettuce.pool.min-idle}") + private int minIdle; + + @Value("${spring.redis.lettuce.pool.max-active}") + private int maxActive; + + @Value("${spring.redis.lettuce.pool.max-wait}") + private long maxWait; + + + @Bean + public RedisSentinelConfiguration redisSentinelConfiguration() { + Set hosts = new HashSet<>(); + hosts.addAll(Arrays.asList(nodes.split(","))); + RedisSentinelConfiguration redisSentinelConfiguration = new RedisSentinelConfiguration(master,hosts); + redisSentinelConfiguration.setPassword(RedisPassword.of(password)); + redisSentinelConfiguration.setDatabase(database); + return redisSentinelConfiguration; + } + + @Bean + public LettuceConnectionFactory lettuceConnectionFactory(RedisConfiguration redisConfiguration) { + GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig(); + genericObjectPoolConfig.setMaxIdle(maxIdle); + genericObjectPoolConfig.setMinIdle(minIdle); + genericObjectPoolConfig.setMaxTotal(maxActive); + genericObjectPoolConfig.setMaxWaitMillis(maxWait); + genericObjectPoolConfig.setTimeBetweenEvictionRunsMillis(100); + + LettuceClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder() + .commandTimeout(Duration.ofMillis(timeout)) + .shutdownTimeout(Duration.ofMillis(shutDownTimeout)) + .poolConfig(genericObjectPoolConfig) + .build(); + LettuceConnectionFactory factory = new LettuceConnectionFactory(redisConfiguration, clientConfig); + return factory; + } + + + @Bean + public RedisTemplate redisTemplate(LettuceConnectionFactory redisConnectionFactory){ + redisConnectionFactory.setShareNativeConnection(false);//交由自定义池控制 + RedisTemplate template = new RedisTemplate(); + template.setKeySerializer(new StringRedisSerializer()); + template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); + template.setHashKeySerializer(new StringRedisSerializer());// Hash key序列化 + template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());// Hash value序列化 + template.setConnectionFactory(redisConnectionFactory); + return template; + } +} \ No newline at end of file diff --git a/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/redis/RedisStandaloneConfig.java b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/redis/RedisStandaloneConfig.java new file mode 100644 index 0000000..3b12fd4 --- /dev/null +++ b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/redis/RedisStandaloneConfig.java @@ -0,0 +1,106 @@ +package com.model2d3d.viewer.back.util.redis; + +import java.io.Serializable; +import java.time.Duration; + +import org.apache.commons.pool2.impl.GenericObjectPoolConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConfiguration; +import org.springframework.data.redis.connection.RedisPassword; +import org.springframework.data.redis.connection.RedisStandaloneConfiguration; +import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; +import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +/** + * Redis single mode + * @author jwy-style + * + */ +@Configuration +@ConditionalOnProperty(prefix = "spring.redis",value = "mode", havingValue = "standalone", matchIfMissing = false) +public class RedisStandaloneConfig { + + private static Logger logger = LoggerFactory.getLogger(RedisStandaloneConfig.class); + + public RedisStandaloneConfig() { + logger.info("RedisConfig---standalone--init"); + } + @Value("${spring.redis.host}") + private String host; + + @Value("${spring.redis.port}") + private int port; + + @Value("${spring.redis.database}") + private int database; + + @Value("${spring.redis.password}") + private String password; + + @Value("${spring.redis.timeout}") + private long timeout; + + @Value("${spring.redis.lettuce.shutdown-timeout}") + private long shutDownTimeout; + + @Value("${spring.redis.lettuce.pool.max-idle}") + private int maxIdle; + + @Value("${spring.redis.lettuce.pool.min-idle}") + private int minIdle; + + @Value("${spring.redis.lettuce.pool.max-active}") + private int maxActive; + + @Value("${spring.redis.lettuce.pool.max-wait}") + private long maxWait; + + @Bean + public RedisStandaloneConfiguration redisStandaloneConfiguration() { + RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(); + redisStandaloneConfiguration.setDatabase(database); + redisStandaloneConfiguration.setHostName(host); + redisStandaloneConfiguration.setPort(port); + redisStandaloneConfiguration.setPassword(RedisPassword.of(password)); + return redisStandaloneConfiguration; + } + + @Bean + public LettuceConnectionFactory lettuceConnectionFactory(RedisConfiguration redisConfiguration) { + GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig(); + genericObjectPoolConfig.setMaxIdle(maxIdle); + genericObjectPoolConfig.setMinIdle(minIdle); + genericObjectPoolConfig.setMaxTotal(maxActive); + genericObjectPoolConfig.setMaxWaitMillis(maxWait); + genericObjectPoolConfig.setTimeBetweenEvictionRunsMillis(100); + + LettuceClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder() + .commandTimeout(Duration.ofMillis(timeout)) + .shutdownTimeout(Duration.ofMillis(shutDownTimeout)) + .poolConfig(genericObjectPoolConfig) + .build(); + LettuceConnectionFactory factory = new LettuceConnectionFactory(redisConfiguration, clientConfig); + return factory; + } + + @Bean + public RedisTemplate redisTemplate(LettuceConnectionFactory redisConnectionFactory){ + redisConnectionFactory.setShareNativeConnection(false);//交由定义池控制 + RedisTemplate template = new RedisTemplate(); + template.setKeySerializer(new StringRedisSerializer()); + template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); + template.setHashKeySerializer(new StringRedisSerializer());// Hash key序列化 + template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());// Hash value序列化 + template.setConnectionFactory(redisConnectionFactory); + return template; + } +} \ No newline at end of file diff --git a/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/redis/RedisUtil.java b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/redis/RedisUtil.java new file mode 100644 index 0000000..1e73808 --- /dev/null +++ b/model2d3d-viewer-back-util/src/main/java/com/model2d3d/viewer/back/util/redis/RedisUtil.java @@ -0,0 +1,505 @@ +package com.model2d3d.viewer.back.util.redis; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.InvalidDataAccessApiUsageException; +import org.springframework.data.redis.core.*; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import jakarta.annotation.Resource; +import java.io.Serializable; +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +/** + * Redis工具类 + */ +@Component +public class RedisUtil { + + private RedisTemplate redisTemplate; + @Autowired + public void setRedisTemplate(RedisTemplate redisTemplate){ +// StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); +// Jackson2JsonRedisSerializer jackson2 = new Jackson2JsonRedisSerializer(Object.class); +// //设置value值以 json 格式保存 +// redisTemplate.setKeySerializer(stringRedisSerializer); +// redisTemplate.setValueSerializer(jackson2); +// redisTemplate.setHashKeySerializer(stringRedisSerializer); +// redisTemplate.setHashValueSerializer(jackson2); + + Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); + ObjectMapper om = new ObjectMapper(); + om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); + jackson2JsonRedisSerializer.setObjectMapper(om); + redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); + redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); + this.redisTemplate = redisTemplate; + } + + /** + * Operate Redis + * Redis operation template class + * + * @return RedisTemplate instance + */ + public RedisTemplate getRedisTemplate(){ + return redisTemplate; + } + + @Resource(name = "redisTemplate") + private ValueOperations valueOperations; + + /** + * String (String operation class) + * String type operation template + * + * @return ValueOperations instance + */ + public ValueOperations getValueOperations(){ + return valueOperations; + } + + @Resource(name = "redisTemplate") + private HashOperations hashOperations; + + /** + * Hash (Hash table operation) + * Hash type operation template + * + * @return HashOperations instance + */ + public HashOperations getHashOperations(){ + return hashOperations; + } + + + @Resource(name = "redisTemplate") + private ListOperations listOperations; + + /** + * List (List operation) + * List type operation template + * + * @return ListOperations instance + */ + public ListOperations getListOperations(){ + return listOperations; + } + + @Resource(name = "redisTemplate") + private SetOperations setOperations; + /** + * Set (Set operation) + * Set type operation template + * + * @return SetOperations instance + */ + public SetOperations getSetOperations(){ + return setOperations; + } + + @Resource(name = "redisTemplate") + public ZSetOperations zSetOperations; + /** + * ZSet (Sorted Set operation) + * Sorted Set type operation template + * + * @return ZSetOperations instance + */ + public ZSetOperations getZSetOperations(){ + return zSetOperations; + } + + /** + * Set the expiration time for a key (unit: seconds) { Command: EXPIRE [key] [seconds] } + * + * @param key Key + * @param expireTime Expiration time (unit: seconds) + * @return True if the expiration was set successfully, false otherwise + */ + public boolean expire(String key, Long expireTime){ + return redisTemplate.expire(key, expireTime, TimeUnit.SECONDS); + } + + + /** + * Set the expiration time for a key (unit: seconds) { Command: EXPIRE [key] [seconds] } + * + * @param key Key + * @param expireTime Expiration time (unit: seconds) + * @return True if the expiration was set successfully, false otherwise + */ + public boolean updateExprieTime(final String key, Long expireTime){ + return expire(key, expireTime); + } + + /** + * Get auto-increment (increment by 1 each time) + * Increment the integer value stored at key by one + * If the key does not exist, it is initialized to 0 before performing the operation + * + * @param key Key + * @return Long value after increment + */ + public Long getAutoIncrement(String key){ + return valueOperations.increment(key, 1); + } + + /** + * Retrieve cached data + * + * @param key Key + * @return Cached object + */ + public Object get(final String key) { + return valueOperations.get(key); + } + + /** + * Retrieve cached data + * + * @param key Key + * @return Cached object + */ + public Object getWithDefault(final String key,Object defaultValue) { + if (valueOperations.get(key)==null){ + return defaultValue; + }else{ + return valueOperations.get(key); + } + } + + /** + * String data type + * Set value of key with string data type + * + * @param key Key + * @param value Value + * @return True if set operation succeeds, false otherwise + */ + public boolean set(String key, Object value) { + try { + valueOperations.set(key, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } + + + + /** + * String data type + * Write to cache with expiration time + * + * @param key Key + * @param value Value + * @param expireTime Expiration time (in seconds) + * @return True if the operation succeeds, false otherwise + */ + public boolean set(String key, Object value, Long expireTime) { + try { + valueOperations.set(key, value, expireTime, TimeUnit.SECONDS); + return true; + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } + + /** + * Operations on Redis Hash data type + * (With expiration time) + * + * 1. Set the hash field field in hash table key to value. + * 2. If key does not exist, a new hash table is created and HSET operation is performed. + * 3. If field already exists in the hash table, its value is overwritten. + * + * @param key Key + * @param hashKey Hash key + * @param hashValue Hash value + * @param expireTime Expiration time (in seconds) + * @return True if the operation succeeds, false otherwise + */ + public boolean hashPut(String key, String hashKey, Object hashValue, Long expireTime) { + try { + hashOperations.put(key, hashKey, hashValue); + return expire(key, expireTime); + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } + + /** + * Operations on Redis Hash data type + * (With expiration time) + * + * 1. Set multiple field-value (field-value pairs) in hash table key simultaneously. + * 2. This command will overwrite existing fields in the hash table. + * 3. If key does not exist, an empty hash table is created and HMSET operation is performed. + * + * @param key Key + * @param hashKeyValue Key-value pairs for hash + * @param expireTime Expiration time (in seconds) + * @return True if the operation succeeds, false otherwise + */ + public boolean hashPutAll(String key, Map hashKeyValue, Long expireTime) { + try { + hashOperations.putAll(key, hashKeyValue); + return expire(key, expireTime); + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } + + + public boolean hashPutAll(String key,Map hashKeyValue){ + try{ + hashOperations.putAll(key,hashKeyValue); +// return expire(key,expireTime); + return true; + }catch (Exception e){ + e.printStackTrace(); + } + return false; + } + + + /** + * Get all members in the sorted set 'key' in ascending order of score. + * Members are sorted in ascending order by their score values. + * + * @param key Key + * @return Set of members in ascending order by score + */ + public Set zsetAllAsc(String key){ + return zSetOperations.range(key, 0, -1); + } + + /** + * Get all members in the sorted set 'key' in descending order of score. + * Members are sorted in descending order by their score values. + * + * @param key Key + * @return Set of members in descending order by score + */ + public Set zsetAllDesc(String key){ + return zSetOperations.reverseRange(key, 0, -1); + } + +//============================================================================================= + /** + * Delete a single key. + * + * @param key Key to delete + * @return True if the key is deleted successfully, false otherwise + */ + public boolean delKey(String key){ + redisTemplate.delete(key); + return true; + } + + /** + * Delete multiple keys. + * + * @param keys Collection of keys to delete + * @return True if all keys are deleted successfully, false otherwise + */ + public boolean delKeys(Collection keys){ + redisTemplate.delete(keys); + return true; + } + + /** + * Remove keys matching the specified pattern. + * + * @param pattern Pattern for keys to delete + */ + public void removePattern(final String pattern) { + Set keys = redisTemplate.keys(pattern); + if (keys.size() > 0){ + redisTemplate.delete(keys); + } + } + + + + /** + * Batch delete corresponding values. + * + * @param keys Array of keys to delete + */ + public void remove(final String... keys) { + for (String key : keys) { + remove(key); + } + } + + /** + * Delete the corresponding value. + * + * @param key Key to delete + */ + public void remove(final String key) { + if (exists(key)) { + redisTemplate.delete(key); + } + } + + /** + * Check if the key exists. { Command: EXISTS [key] } + * + * @param key Key to check + * @return true if the key exists, false otherwise + */ + public boolean existsKey(String key) { + return redisTemplate.hasKey(key); + } + + /** + * Check if there is a corresponding value in the cache. + * + * @param key Key to check + * @return true if the value exists, false otherwise + */ + public boolean exists(final String key) { + return redisTemplate.hasKey(key); + } + + /** + * Rename a key to newKey using the RENAMENX command. + * If newKey already exists in the database, the rename operation fails (returns false). + * (Key must exist; returns false if the key does not exist (ERR no such key)) + * + * @param oldKey Old key name + * @param newKey New key name + * @return true if the key was renamed successfully, false otherwise + */ + public boolean renamenx(String oldKey, String newKey) { + try { + return redisTemplate.renameIfAbsent(oldKey, newKey); + } catch (InvalidDataAccessApiUsageException e) { + e.printStackTrace(); + } + return false; + } + + /** + * Rename a key to newKey using the RENAME command. + * (Key must exist; returns false if the key does not exist (ERR no such key)) + * If newKey already exists in the database, it will be overwritten by oldKey. + * (Equivalent to deleting the key corresponding to newKey in the database, then renaming oldKey to newKey) + * + * @param oldKey Old key name + * @param newKey New key name + * @return true if the key was renamed successfully, false otherwise + */ + public boolean rename(String oldKey, String newKey) { + try { + redisTemplate.rename(oldKey, newKey); + return true; + } catch (InvalidDataAccessApiUsageException e) { + e.printStackTrace(); + } + return false; + } + + /** + * Generate a Redis key. + * For example: + * generatorKey("abc:{0}:efg:{1}", 123, 345) -> abc:123:efg:345 + * + * @param regex Group definition for Redis key + * @param values Placeholder values for key naming rules + * @return Redis key + */ + public static String generatorKey(String regex, Object ... values) { + String key = regex; + if (StringUtils.isEmpty(key)) { + return ""; + } + return MessageFormat.format(key, Arrays.stream(values).map(value ->String.valueOf(value)).toArray()); + } + + /** + * Increment the numeric value stored in the key by one. + * + * @param key Key to increment + * @return Incremented value or -999 if an error occurs + */ + public Long incr(String key) { + try { + return valueOperations.increment(key); + } catch (Exception e) { + e.printStackTrace(); + } + return -999L; + } + + + public List hgetall(String key) { + try { + return redisTemplate.opsForHash().values(key); + }catch (Exception e){ + e.printStackTrace(); + return null; + } + } + + public void HSet (String key, String hashKey, Object value) { + try { + redisTemplate.opsForHash().put(key, hashKey, value); + }catch (Exception e){ + e.printStackTrace(); + } + } + + public Object HGet(String key, String hashKey) { + try { + return redisTemplate.opsForHash().get(key, hashKey); + }catch (Exception e){ + e.printStackTrace(); + return null; + } + } + + public Boolean zadd(String key, Object value, double score) { + try { + return redisTemplate.opsForZSet().add(key, value, score); + }catch (Exception e){ + e.printStackTrace(); + return false; + } + } + + public Set zRangeByScore(String key, double min, double max) { + return redisTemplate.opsForZSet().rangeByScore(key, min, max); + } + + public Long zRemRangeByScore(String key, double min, long max) { + return zSetOperations.removeRangeByScore(key, min, max); + } + + public Boolean setIfAbsent(String key, Object value, long timeout, TimeUnit unit) { + try { + return redisTemplate.opsForValue().setIfAbsent(key, value, timeout, unit); + }catch (Exception e){ + e.printStackTrace(); + return false; + } + } +} diff --git a/model2d3d-viewer-back-util/src/test/java/com/model2d3d/viewer/back/util/AppTest.java b/model2d3d-viewer-back-util/src/test/java/com/model2d3d/viewer/back/util/AppTest.java new file mode 100644 index 0000000..5a195ce --- /dev/null +++ b/model2d3d-viewer-back-util/src/test/java/com/model2d3d/viewer/back/util/AppTest.java @@ -0,0 +1,38 @@ +package com.model2d3d.viewer.back.util; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +} diff --git a/model2d3d-viewer-back-util/src/test/java/com/model2d3d/viewer/back/util/NearestHourMinute.java b/model2d3d-viewer-back-util/src/test/java/com/model2d3d/viewer/back/util/NearestHourMinute.java new file mode 100644 index 0000000..98a0b70 --- /dev/null +++ b/model2d3d-viewer-back-util/src/test/java/com/model2d3d/viewer/back/util/NearestHourMinute.java @@ -0,0 +1,33 @@ +package com.model2d3d.viewer.back.util; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; + +public class NearestHourMinute { + public static void main(String[] args) { + // 假设给定的时间戳是当前时间的时间戳,你也可以替换为其他时间戳 + long timestamp = 1712370811936L; + + // 将时间戳转换为LocalDateTime对象 + LocalDateTime dateTime = LocalDateTime.ofInstant( + java.time.Instant.ofEpochMilli(timestamp), + java.time.ZoneId.systemDefault() + ); + + // 获取分钟数 + int second = dateTime.getSecond(); + + // 找出离给定时间戳最近的整点分钟 + LocalDateTime nearestMinute; + if (second < 30) { + nearestMinute = dateTime.withSecond(0).withNano(0); + } else { + nearestMinute = dateTime.withSecond(0).withNano(0).plusMinutes(1); + } + + long secs = nearestMinute.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); + + System.out.println("给定时间戳最近的整点分钟是:" + secs); + } +} diff --git a/model2d3d-viewer-back-util/src/test/java/com/model2d3d/viewer/back/util/QuartileCalculator.java b/model2d3d-viewer-back-util/src/test/java/com/model2d3d/viewer/back/util/QuartileCalculator.java new file mode 100644 index 0000000..ea6e417 --- /dev/null +++ b/model2d3d-viewer-back-util/src/test/java/com/model2d3d/viewer/back/util/QuartileCalculator.java @@ -0,0 +1,41 @@ +package com.model2d3d.viewer.back.util; + +import java.util.*; + +public class QuartileCalculator { + + public static void main(String[] args) { +// List list = Arrays.asList(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 9.0, 8.0, 10.0, 11.0); + List list = Arrays.asList(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 9.0, 8.0, 10.0); + + // 首先对列表进行排序 + Collections.sort(list); + + System.out.println(list); + + // 计算四分位数 + double q1 = calculateQuartile(list, 0.25); + double q2 = calculateMedian(list); + double q3 = calculateQuartile(list, 0.75); + + System.out.println("Q1: " + q1); + System.out.println("Q2: " + q2); + System.out.println("Q3: " + q3); + } + + private static double calculateMedian(List sortedList) { + int size = sortedList.size(); + if (size % 2 == 0) { + // 偶数个元素,取中间两个数的平均值 + return (sortedList.get(size / 2 - 1) + sortedList.get(size / 2)) / 2.0; + } else { + // 奇数个元素,取中间那个数 + return sortedList.get(size / 2); + } + } + + private static double calculateQuartile(List sortedList, double quartilePosition) { + int index = (int) (quartilePosition * sortedList.size()); + return sortedList.get(index); + } +} \ No newline at end of file diff --git a/model2d3d-viewer-back-util/src/test/java/com/model2d3d/viewer/back/util/Test.java b/model2d3d-viewer-back-util/src/test/java/com/model2d3d/viewer/back/util/Test.java new file mode 100644 index 0000000..7d92df1 --- /dev/null +++ b/model2d3d-viewer-back-util/src/test/java/com/model2d3d/viewer/back/util/Test.java @@ -0,0 +1,89 @@ +package com.model2d3d.viewer.back.util; + +import static org.mockito.ArgumentMatchers.intThat; + +import java.text.ParseException; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneId; +import java.util.Calendar; +import java.util.Date; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * + * @author jwy + * + */ +public class Test { + + private final static long ondDayMillis = 3600 * 24 * 1000; + + private static final String betweenQuotesRegex = "\"([^\"]*)\""; + + public static void main(String[] args) throws ParseException{ + long ZeroTime = getTodayZeroTime(); + System.out.println(ZeroTime); + long startTime = ZeroTime - ondDayMillis; + System.out.println(startTime); + long endTime = ZeroTime - 1; + System.out.println(endTime); + + int days = 2; + System.out.println("前"+ days +"天的0点的毫秒级时间戳: " + getMinusZeroTimestamp(days)); + + int mins = 9; + minusInterval(mins); + + System.out.println(CommonUtil.extractContentBetweenQuotes("aurora_cluster_endpoint = \"company-13-aurora-cluster.cluster-cde6q2assvmn.ap-northeast-1.rds.amazonaws.com\"")); + + } + + public static String extractContentBetweenQuotes(String text) { + Pattern pattern = Pattern.compile(betweenQuotesRegex); + Matcher matcher = pattern.matcher(text); + + if (matcher.find()) { + return matcher.group(1); + } + + return null; // 如果找不到匹配项,返回null + } + + private static void minusInterval(int mins) { + LocalDateTime now = LocalDateTime.now(); + int currentSecond = now.getSecond(); + System.out.println("当前秒:" + currentSecond); + System.out.println("当前分钟:" + now.withSecond(0).withNano(0). + atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); + + // 减去指定的分钟数并将秒数和纳秒数设为0 + LocalDateTime previousMinute = now.minusMinutes(mins).withSecond(0).withNano(0); + + // 获取前n分钟整分钟的毫秒级时间戳 + System.out.println("前"+ mins +"分钟:" + previousMinute.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); + } + + private static long getTodayZeroTime() { + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + return calendar.getTime().getTime(); + } + + public static Long getMinusZeroTimestamp(int days) { +// String timeZone = "Asia/Tokyo"; + // 获取今天的日期 + LocalDate today = LocalDate.now(); + // 减去n天 + LocalDate nDaysAgo = today.minusDays(days); + // 将日期转换为午夜12点的时间 + LocalDateTime midnight = nDaysAgo.atStartOfDay(); + // 将LocalDateTime转换为Instant + return midnight.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); + } +} diff --git a/model2d3d-viewer-back-util/src/test/java/com/model2d3d/viewer/back/util/ValueSorter.java b/model2d3d-viewer-back-util/src/test/java/com/model2d3d/viewer/back/util/ValueSorter.java new file mode 100644 index 0000000..3570067 --- /dev/null +++ b/model2d3d-viewer-back-util/src/test/java/com/model2d3d/viewer/back/util/ValueSorter.java @@ -0,0 +1,111 @@ +package com.model2d3d.viewer.back.util; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import com.alibaba.fastjson.JSON; + +public class ValueSorter { + + public final static String respDateTimeFormat = "yyyy-MM-dd HH:mm:00"; + public final static String timeZoneId = "Asia/Tokyo"; + + static class ElementData { + + public double getValue() { + return value; + } + + public void setValue(double value) { + this.value = value; + } + + public long getMilliTimestamp() { + return milliTimestamp; + } + + public void setMilliTimestamp(long milliTimestamp) { + this.milliTimestamp = milliTimestamp; + } + + double value; + long milliTimestamp; + + public ElementData() { + } + + public ElementData(double value, long milliTimestamp) { + this.value = value; + this.milliTimestamp = milliTimestamp; + + } + } + + public static void main(String[] args) { + // 假设有一个List对象存储了数据集 + List dataList = new ArrayList<>(); + dataList.add(new ElementData(15.8, 1710570103940L)); + dataList.add(new ElementData(17.2, 1710571113941L)); + dataList.add(new ElementData(24.5, 1710572123942L)); + dataList.add(new ElementData(26.7, 1710573133943L)); + dataList.add(new ElementData(18.9, 1710574143944L)); + dataList.add(new ElementData(12.5, 1710575153945L)); + dataList.add(new ElementData(14.3, 1710576163946L)); + dataList.add(new ElementData(20.1, 1710577173947L)); + dataList.add(new ElementData(21.6, 1710578183948L)); + dataList.add(new ElementData(23.0, 1710579193949L)); + dataList.add(new ElementData(25.0, 1710579999949L)); + + // 打印排序后的结果 + for (ElementData dataPoint : dataList) { + System.out.println("Value: " + dataPoint.value + ", milliTimestamp: " + dataPoint.milliTimestamp); + } + + System.out.println("——————————————————————"); + + // 按照value字段排序 + Collections.sort(dataList, Comparator.comparingDouble(dataPoint -> dataPoint.value)); + + // 打印排序后的结果 + for (ElementData dataPoint : dataList) { + System.out.println("Value: " + dataPoint.value + ", milliTimestamp: " + dataPoint.milliTimestamp); + } + + ElementData aaData = calculateQuartile(dataList, 0.25); + System.out.println(JSON.toJSONString(aaData)); + System.out.println(JSON.toJSONString(DateUtil.timestamp2DateStr(aaData.getMilliTimestamp(), respDateTimeFormat, timeZoneId))); + + ElementData aaData2 = calculateMedian(dataList); + System.out.println(JSON.toJSONString(aaData2)); + System.out.println(JSON.toJSONString(DateUtil.timestamp2DateStr(aaData2.getMilliTimestamp(), respDateTimeFormat, timeZoneId))); + + ElementData aaData3 = calculateQuartile(dataList, 0.75); + System.out.println(JSON.toJSONString(aaData3)); + System.out.println(JSON.toJSONString(DateUtil.timestamp2DateStr(aaData3.getMilliTimestamp(), respDateTimeFormat, timeZoneId))); + } + + private static ElementData calculateMedian(List sortedList) { + int size = sortedList.size(); + if (size % 2 == 0) { + // 偶数个元素,取中间两个数的平均值 + ElementData data1 = sortedList.get(size / 2 - 1); + ElementData data2 = sortedList.get(size / 2); + ElementData resData = new ElementData(); + resData.setValue((data1.getValue()+data2.getValue())/2.0); + resData.setMilliTimestamp((data1.getMilliTimestamp()+data2.getMilliTimestamp())/2); + + return resData; + } else { + // 奇数个元素,取中间那个数 + return sortedList.get(size/2); + } + } + + private static ElementData calculateQuartile(List sortedList, double quartilePosition) { + int index = (int) (quartilePosition * sortedList.size()); + return sortedList.get(index); + } +} + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..1d597b6 --- /dev/null +++ b/pom.xml @@ -0,0 +1,280 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 3.2.12 + + + + com.techsor + model2d3d-viewer-back + 0.0.1-SNAPSHOT + model2d3d-viewer-back + pom + + + model2d3d-viewer-back-util + model2d3d-viewer-back-common + model2d3d-viewer-back-model + model2d3d-viewer-back-dao + model2d3d-viewer-back-service + model2d3d-viewer-back-controller + + + data center business + + + com.model2d3d.viewer.back.Model2d3dViewerApplication + 17 + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-logging + + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.projectlombok + lombok + + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.5.0 + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + **/application.properties + + + + lib/ + true + ${main.basedir} + + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + package + + copy-dependencies + + + + ${project.build.directory}/lib + false + false + runtime + + + + + + + org.apache.maven.plugins + maven-resources-plugin + + UTF-8 + true + + xlsx + xls + zip + + + + + + copy-resources + package + + copy-resources + + + + + src/main/resources + + + ${project.build.directory}/ + + + + + + + + + src/main/resources + + **/*.* + + true + + + + + + + + development + + true + + + 30001 + + true + + + rm-bp11k2zm2fr7864428o.mysql.rds.aliyuncs.com:3306 + Asia/Shanghai + zhc + Youqu48bnb1 + + DEBUG + E:/logDemo + CONSOLELOG + 30 + + r-uf63x4g5p6ir5xao87pd.redis.rds.aliyuncs.com + B2BGn4gK4htgkEwP + + http://49.234.37.33:92/#/user/login + + DEBUG + + + + + org.apache.maven.plugins + maven-surefire-plugin + + false + + + + + + + + + test + + false + + + 30001 + + true + + + rm-bp11k2zm2fr7864428o.mysql.rds.aliyuncs.com:3306 + Asia/Shanghai + zhc + Youqu48bnb1 + + DEBUG + E:/logDemo + CONSOLELOG + 30 + + r-uf63x4g5p6ir5xao87pd.redis.rds.aliyuncs.com + B2BGn4gK4htgkEwP + + http://49.234.37.33:92/#/user/login + + DEBUG + + + + + org.apache.maven.plugins + maven-surefire-plugin + + false + + + + + + + + + + production + + false + + + 30001 + + true + + + rm-bp11k2zm2fr7864428o.mysql.rds.aliyuncs.com:3306 + Asia/Shanghai + zhc + Youqu48bnb1 + + DEBUG + E:/logDemo + CONSOLELOG + 30 + + r-uf63x4g5p6ir5xao87pd.redis.rds.aliyuncs.com + B2BGn4gK4htgkEwP + + http://49.234.37.33:92/#/user/login + + DEBUG + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + + + \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..6f2ddf5 --- /dev/null +++ b/readme.md @@ -0,0 +1,39 @@ +当前版本:v0.2.1 + + +# 目录结构如下 + +│ +├─model2d3d-viewer-back-common +│ +├─model2d3d-viewer-back-controller +│ +│─model2d3d-viewer-back-dao +│ ├─java +│ │ ├─auto----Mybatis-Generator自动生成的持久层接口 +│ │ └─ex------自定义接口, 继承上面对应的auto +│ ├─resources +│ │ ├─mappers +│ │ │ ├─auto----Mybatis-Generator自动生成的映射sql文件, 对应上面的auto接口 +│ │ │ └─ex------自定义sql, 对应上面的ex接口 +│ │ └─mybatis-generator +│ │ └─generatorConfig.xml-----配置数据库表,配置完后双击data-center-business-dao下的runGenerator.bat, Mybatis-Generator自动构建实体类、持久层接口等 +│ └─runGenerator.bat +│ +├─model2d3d-viewer-back-model +│ ├─dto +│ ├─entity +│ ├─model--------Mybatis-Generator自动生成的实体类 +│ └─vo +│ +├─model2d3d-viewer-back-service +│ +├─model2d3d-viewer-back-util 工具类 +│ +└─document---------一些说明文档、脚本、部署sql等等 + + +# swagger接口地址 ++ http://127.0.0.1:20008/swagger-ui.html + +### 开发时,可注释掉controller类上的@AccessRequired注解,不用进行鉴权,省得每次都要登录获取token \ No newline at end of file