From 7011024e46cb828cd79166423797ce761b1cfbce Mon Sep 17 00:00:00 2001 From: Administrator Date: Fri, 13 Dec 2024 09:50:15 +0800 Subject: [PATCH] First --- .gitignore | 10 + admin-server/.gitignore | 33 + admin-server/pom.xml | 68 ++ .../hd/admin/AdminServerApplication.java | 18 + .../hd/admin/config/NotifierConfig.java | 54 ++ .../evotech/hd/admin/config/PrintConfig.java | 43 ++ .../src/main/resources/application.yml | 58 ++ .../src/main/resources/logback-spring.xml | 90 +++ authorization-server/.gitignore | 33 + authorization-server/pom.xml | 104 +++ .../AuthorizationServerApplication.java | 19 + .../oauth2/AuthorizationServerConfig.java | 262 +++++++ .../config/oauth2/MyAccessToken.java | 18 + .../MyAuthenticationFailureHandler.java | 42 ++ .../MyAuthenticationSuccessHandler.java | 63 ++ .../oauth2/MyOAuth2TokenJwtCustomizer.java | 32 + .../config/oauth2/RSAKeyPair.java | 25 + .../OAuth2AuthenticationProviderUtils.java | 79 +++ .../passwordmode/OAuth2EndpointUtils.java | 101 +++ ...OAuth2PasswordAuthenticationConverter.java | 82 +++ .../OAuth2PasswordAuthenticationProvider.java | 186 +++++ .../OAuth2PasswordAuthenticationToken.java | 55 ++ .../security/MyAccessDeniedHandler.java | 36 + .../security/MyAuthenticationEntryPoint.java | 40 ++ .../config/security/WebSecutiryConfig.java | 104 +++ .../security/userdetail/MyUserDetail.java | 52 ++ .../userdetail/UserDetailService.java | 38 + .../controller/CaptchaController.java | 36 + .../controller/LoginController.java | 56 ++ .../hd/authorization/entity/LoginRequest.java | 25 + .../hd/authorization/entity/UserVo.java | 55 ++ .../authorization/service/CaptchaService.java | 11 + .../authorization/service/LoginService.java | 17 + .../service/ResourceService.java | 36 + .../service/impl/CaptchaServiceImpl.java | 55 ++ .../service/impl/LoginServiceImpl.java | 203 ++++++ .../utils/LoginRequesHeadertUtil.java | 33 + .../utils/Oauth2AccessTokenUtil.java | 42 ++ .../hd/authorization/utils/TokenUtil.java | 49 ++ ...itional-spring-configuration-metadata.json | 12 + .../src/main/resources/application.yml | 41 ++ .../src/main/resources/logback-spring.xml | 91 +++ .../AuthorizationServerApplicationTests.java | 13 + base-commons/common-core/pom.xml | 71 ++ .../hd/common/core/constant/HDConstant.java | 74 ++ .../core/dao/resource/ProxyOperaterDao.java | 12 + .../core/dao/resource/auth/AuthMenuDao.java | 12 + .../dao/resource/auth/AuthPermissionDao.java | 18 + .../core/dao/resource/auth/AuthRoleDao.java | 12 + .../resource/auth/AuthRoleResourceDao.java | 12 + .../core/dao/resource/auth/AuthUserDao.java | 12 + .../dao/resource/auth/AuthUserRoleDao.java | 12 + .../core/dao/resource/dict/AdmdvsInfoDao.java | 12 + .../core/dao/resource/dict/DictDao.java | 19 + .../core/dao/resource/dict/DictTypeDao.java | 12 + .../common/core/entity/BasePageRequest.java | 21 + .../hd/common/core/entity/LoginCacheInfo.java | 28 + .../evotech/hd/common/core/entity/Result.java | 164 +++++ .../core/entity/cloud/BatteryStation.java | 139 ++++ .../core/entity/cloud/BatteryStationDc.java | 88 +++ .../core/entity/cloud/BatteryStationDcc.java | 66 ++ .../core/entity/cloud/BatteryStationDj.java | 80 +++ .../cloud/BatteryStationHdFeeStandard.java | 95 +++ .../BatteryStationHdFeeStandardDetail.java | 85 +++ .../entity/cloud/BatteryStationRobot.java | 69 ++ .../core/entity/cloud/BatteryTrace.java | 75 ++ .../core/entity/cloud/OrderRecharge.java | 74 ++ .../core/entity/cloud/OrderSwapBattery.java | 178 +++++ .../entity/cloud/OrderSwapBatteryPre.java | 84 +++ .../entity/cloud/OrderSwapBatteryStep.java | 56 ++ .../common/core/entity/cloud/TradeDetail.java | 106 +++ .../common/core/entity/cloud/VehicleInfo.java | 121 ++++ .../cloud/VehicleWechatUserRelation.java | 69 ++ .../core/entity/cloud/WalletAccount.java | 88 +++ .../entity/cloud/WalletAccountDetail.java | 93 +++ .../core/entity/request/ListDictRequest.java | 32 + .../common/core/entity/resource/LogLogin.java | 73 ++ .../core/entity/resource/LogUpload.java | 62 ++ .../core/entity/resource/ProxyOperater.java | 96 +++ .../core/entity/resource/UploadFile.java | 72 ++ .../core/entity/resource/auth/AuthMenu.java | 81 +++ .../entity/resource/auth/AuthPermission.java | 69 ++ .../core/entity/resource/auth/AuthRole.java | 66 ++ .../resource/auth/AuthRoleResource.java | 49 ++ .../core/entity/resource/auth/AuthUser.java | 114 +++ .../entity/resource/auth/AuthUserRole.java | 53 ++ .../core/entity/resource/dict/AdmdvsInfo.java | 58 ++ .../core/entity/resource/dict/Dict.java | 59 ++ .../core/entity/resource/dict/DictType.java | 51 ++ .../evotech/hd/common/core/enums/CodeMsg.java | 100 +++ .../hd/common/core/utils/SnowflakeUtil.java | 22 + base-commons/common-mybatis/pom.xml | 51 ++ base-commons/common-redis/pom.xml | 34 + .../hd/common/redis/config/RedisConfig.java | 71 ++ .../hd/common/redis/utils/RedisUtil.java | 663 ++++++++++++++++++ base-commons/common-web/pom.xml | 72 ++ .../web/exception/GlobalExceptionHandler.java | 84 +++ .../web/exception/MyArgumentException.java | 41 ++ .../hd/common/web/filter/MyFilterConfig.java | 29 + .../filter/MyHttpServletRequestWrapper.java | 106 +++ .../common/web/filter/RequestBodyFilter.java | 50 ++ .../hd/common/web/swagger/SwaggerTips.java | 54 ++ .../common/web/thread/ThreadPoolConfig.java | 48 ++ .../web/thread/ThreadPoolProperties.java | 35 + .../evotech/hd/common/web/util/IpUtil.java | 68 ++ .../common/web/util/RequestContextUtil.java | 34 + base-commons/pom.xml | 19 + cloud-manage-server/.gitignore | 33 + cloud-manage-server/pom.xml | 100 +++ .../cloud/CloudManageServerApplication.java | 20 + .../controller/BatteryStationController.java | 72 ++ .../BatteryStationDcController.java | 87 +++ .../BatteryStationDccController.java | 61 ++ .../BatteryStationDjController.java | 61 ++ ...BatteryStationHdFeeStandardController.java | 60 ++ ...yStationHdFeeStandardDetailController.java | 60 ++ .../BatteryStationRobotController.java | 61 ++ .../controller/MessageMqttController.java | 39 ++ .../customer/VehicleController.java | 90 +++ .../order/OrderRechargeController.java | 64 ++ .../order/OrderSwapBatteryController.java | 95 +++ .../controller/order/TradeController.java | 63 ++ .../order/WalletAccountController.java | 85 +++ .../hd/cloud/dao/BatteryStationDao.java | 22 + .../hd/cloud/dao/BatteryStationDcDao.java | 16 + .../hd/cloud/dao/BatteryStationDccDao.java | 16 + .../hd/cloud/dao/BatteryStationDjDao.java | 16 + .../dao/BatteryStationHdFeeStandardDao.java | 16 + .../BatteryStationHdFeeStandardDetailDao.java | 16 + .../hd/cloud/dao/BatteryStationRobotDao.java | 16 + .../cloud/dao/BatteryStationSecretKeyDao.java | 12 + .../evotech/hd/cloud/dao/BatteryTraceDao.java | 12 + .../evotech/hd/cloud/dao/MessageMqttDao.java | 12 + .../hd/cloud/dao/OrderRechargeDao.java | 12 + .../hd/cloud/dao/OrderSwapBatteryDao.java | 12 + .../hd/cloud/dao/OrderSwapBatteryPreDao.java | 12 + .../hd/cloud/dao/OrderSwapBatteryStepDao.java | 12 + .../evotech/hd/cloud/dao/TradeDetailDao.java | 12 + .../evotech/hd/cloud/dao/VehicleInfoDao.java | 12 + .../dao/VehicleWechatUserRelationDao.java | 12 + .../hd/cloud/dao/WalletAccountDao.java | 12 + .../hd/cloud/dao/WalletAccountDetailDao.java | 12 + .../cloud/entity/BatteryStationSecretKey.java | 59 ++ .../evotech/hd/cloud/entity/MessageMqtt.java | 60 ++ .../PageListBatteryStationDcRequest.java | 21 + .../PageListBatteryStationDccRequest.java | 20 + .../PageListBatteryStationDjRequest.java | 21 + .../PageListBatteryStationRequest.java | 32 + .../request/PageListMessageMqttRequest.java | 26 + .../request/PageListRechargeOrderRequest.java | 45 ++ .../request/PageListSwapOrderRequest.java | 52 ++ .../entity/request/PageListTradeRequest.java | 29 + .../request/PageListVehicleRequest.java | 42 ++ .../entity/request/PageListWalletRequest.java | 28 + .../com/evotech/hd/cloud/mqtt/MqttInit.java | 54 ++ .../hd/cloud/mqtt/config/MqttConfig.java | 133 ++++ .../hd/cloud/mqtt/config/MqttProperties.java | 25 + .../hd/cloud/mqtt/config/MyMqttCallback.java | 71 ++ .../mqtt/enums/ConfirmFunctionTypesEnum.java | 46 ++ .../mqtt/enums/EventFunctionTypesEnum.java | 45 ++ .../cloud/mqtt/enums/MqttMessageTypeEnum.java | 45 ++ .../mqtt/enums/RequestFunctionTypesEnum.java | 66 ++ .../mqtt/enums/StateFunctionTypesEnum.java | 48 ++ .../hd/cloud/mqtt/message/MessageTopic.java | 29 + .../cloud/mqtt/message/MqttMessageHeader.java | 30 + .../hd/cloud/mqtt/message/MyMqttMessage.java | 22 + .../dto/newer/req/battery/BatteryData.java | 17 + .../dto/newer/req/battery/BatteryInfoReq.java | 15 + .../req/battery/BatteryInfoResponse.java | 22 + .../dto/newer/req/carinfo/CarInfoReq.java | 15 + .../newer/req/carinfo/CarInfoResponse.java | 25 + .../dto/newer/req/carinfo/VehicleData.java | 24 + .../dto/newer/req/order/CancelOrderReq.java | 12 + .../newer/req/order/CancelOrderResponse.java | 14 + .../newer/req/order/OrderByPlateNumReq.java | 17 + .../req/order/OrderByPlateNumResponse.java | 20 + .../dto/newer/req/order/OrderData.java | 22 + .../dto/newer/req/preorder/PreOrderReq.java | 33 + .../newer/req/preorder/PreOrderResponse.java | 14 + .../message/dto/newer/state/OrderStatus.java | 20 + .../dto/newer/state/OrderStatusData.java | 41 ++ .../message/dto/newer/state/SwapStep.java | 19 + .../cloud/mqtt/message/dto/older/BatData.java | 145 ++++ .../mqtt/message/dto/older/BatteryData.java | 14 + .../mqtt/message/dto/older/ChargeRecord.java | 59 ++ .../message/dto/older/ChargeRecordConf.java | 13 + .../message/dto/older/ChargeRecordDetail.java | 13 + .../mqtt/message/dto/older/FaultRecord.java | 19 + .../message/dto/older/FaultRecordConf.java | 13 + .../mqtt/message/dto/older/RateMode.java | 13 + .../mqtt/message/dto/older/RateModeSync.java | 16 + .../mqtt/message/dto/older/SwapRecord.java | 49 ++ .../message/dto/older/SwapRecordConf.java | 13 + .../mqtt/message/dto/older/VehicleSync.java | 15 + .../dto/older/req/RateModeSyncReq.java | 18 + .../dto/older/req/RateModeSyncResp.java | 13 + .../dto/older/req/RemoteSwapCheckReq.java | 17 + .../dto/older/req/RemoteSwapCheckResp.java | 24 + .../dto/older/req/RemoteSwapStartReq.java | 17 + .../dto/older/req/RemoteSwapStartResp.java | 23 + .../message/dto/older/req/VehicleSyncReq.java | 15 + .../dto/older/req/VehicleSyncResp.java | 11 + .../message/dto/older/state/ChargingData.java | 16 + .../dto/older/state/HdChargingData.java | 98 +++ .../message/dto/older/state/SwapState.java | 43 ++ .../message/dto/older/state/VehicleState.java | 30 + .../handle/EncryptKeyReqMessageService.java | 51 ++ .../message/handle/EventMessageService.java | 45 ++ .../handle/KeepaliveMessageService.java | 33 + .../message/handle/MessageUtilService.java | 215 ++++++ .../message/handle/MqttMessageHandle.java | 71 ++ .../message/handle/RequestMessageService.java | 110 +++ .../message/handle/StateMessageService.java | 74 ++ .../service/BatteryStationDcService.java | 25 + .../service/BatteryStationDccService.java | 19 + .../service/BatteryStationDjService.java | 19 + ...teryStationHdFeeStandardDetailService.java | 18 + .../BatteryStationHdFeeStandardService.java | 18 + .../service/BatteryStationRobotService.java | 18 + .../cloud/service/BatteryStationService.java | 22 + .../hd/cloud/service/MessageMqttService.java | 17 + .../cloud/service/OrderRechargeService.java | 19 + .../service/OrderSwapBatteryService.java | 29 + .../hd/cloud/service/TradeService.java | 19 + .../hd/cloud/service/VehicleService.java | 25 + .../cloud/service/WalletAccountService.java | 26 + .../impl/BatteryStationDcServiceImpl.java | 104 +++ .../impl/BatteryStationDccServiceImpl.java | 67 ++ .../impl/BatteryStationDjServiceImpl.java | 67 ++ ...StationHdFeeStandardDetailServiceImpl.java | 63 ++ ...atteryStationHdFeeStandardServiceImpl.java | 70 ++ .../impl/BatteryStationRobotServiceImpl.java | 64 ++ .../impl/BatteryStationServiceImpl.java | 108 +++ .../service/impl/MessageMqttServiceImpl.java | 59 ++ .../impl/OrderRechargeServiceimpl.java | 74 ++ .../impl/OrderSwapBatteryServiceImpl.java | 136 ++++ .../cloud/service/impl/TradeServiceImpl.java | 75 ++ .../service/impl/VehicleServiceImpl.java | 115 +++ .../impl/WalletAccountServiceImpl.java | 125 ++++ .../hd/cloud/utils/AESEncryptionUtil.java | 5 + .../hd/cloud/utils/RSADecryptionUtil.java | 5 + .../src/main/resources/application.yml | 55 ++ .../src/main/resources/logback-spring.xml | 90 +++ .../mapper/BatteryStationDcMapper.xml | 38 + .../mapper/BatteryStationDccMapper.xml | 31 + .../mapper/BatteryStationDjMapper.xml | 34 + ...atteryStationHdFeeStandardDetailMapper.xml | 35 + .../BatteryStationHdFeeStandardMapper.xml | 42 ++ .../resources/mapper/BatteryStationMapper.xml | 83 +++ .../mapper/BatteryStationRobotMapper.xml | 33 + .../com/evotech/hd/cloud/AesDecryTest.java | 32 + .../CloudManageServerApplicationTests.java | 13 + .../com/evotech/hd/cloud/DecryptionTest.java | 26 + .../test/java/com/evotech/hd/cloud/Test1.java | 11 + gateway-server/.gitignore | 33 + gateway-server/pom.xml | 131 ++++ .../hd/gateway/GatewayServerApplication.java | 18 + .../evotech/hd/gateway/config/CorsConfig.java | 45 ++ .../hd/gateway/filter/AccessLogFilter.java | 248 +++++++ .../hd/gateway/filter/HeaderHandleFilter.java | 61 ++ .../hd/gateway/log/GatewayLogService.java | 66 ++ .../hd/gateway/log/entity/GatewayLog.java | 65 ++ .../gateway/oauth2/AuthorizationManager.java | 120 ++++ .../gateway/oauth2/MyAccessDeniedHandler.java | 45 ++ .../oauth2/MyAuthenticationEntryPoint.java | 81 +++ .../hd/gateway/oauth2/MyJwtValidator.java | 21 + .../evotech/hd/gateway/oauth2/RSAKeyPair.java | 17 + .../gateway/oauth2/ResourceServerConfig.java | 138 ++++ .../exception/GlobalExceptionAutoConfig.java | 63 ++ .../exception/GlobalExceptionHandler.java | 61 ++ .../oauth2/exception/GlobalExceptionType.java | 40 ++ .../hd/gateway/thread/ThreadPoolConfig.java | 48 ++ .../gateway/thread/ThreadPoolProperties.java | 36 + .../com/evotech/hd/gateway/utils/IpUtil.java | 65 ++ .../hd/gateway/utils/ResponseUtils.java | 30 + .../evotech/hd/gateway/utils/TokenUtil.java | 57 ++ ...itional-spring-configuration-metadata.json | 5 + .../src/main/resources/application.yml | 48 ++ .../src/main/resources/logback-spring.xml | 92 +++ .../src/main/resources/static/favicon.ico | Bin 0 -> 10342 bytes .../GatewayServerApplicationTests.java | 13 + pom.xml | 163 +++++ resource-server/.gitignore | 33 + resource-server/pom.xml | 80 +++ .../resource/ResourceServerApplication.java | 20 + .../controller/AdmdvsInfoController.java | 36 + .../controller/AuthUserController.java | 86 +++ .../controller/BatteryTypeController.java | 62 ++ .../controller/CarTypeController.java | 63 ++ .../controller/CompanyController.java | 63 ++ .../resource/controller/DictController.java | 108 +++ .../controller/FileUpLoadController.java | 73 ++ .../hd/resource/controller/IDController.java | 33 + .../controller/LogLoginController.java | 48 ++ .../controller/LoginInfoController.java | 32 + .../resource/controller/MenuController.java | 62 ++ .../controller/PermissionController.java | 62 ++ .../controller/ProxyOperaterController.java | 62 ++ .../resource/controller/RoleController.java | 92 +++ .../controller/StationTypeController.java | 62 ++ .../controller/SystemManagerController.java | 46 ++ .../hd/resource/dao/BatteryTypeDao.java | 12 + .../evotech/hd/resource/dao/CarTypeDao.java | 12 + .../evotech/hd/resource/dao/CompanyDao.java | 12 + .../evotech/hd/resource/dao/LogLoginDao.java | 12 + .../evotech/hd/resource/dao/LogUploadDao.java | 12 + .../hd/resource/dao/StationTypeDao.java | 12 + .../hd/resource/dao/SystemManagerDao.java | 12 + .../hd/resource/dao/UploadFileDao.java | 12 + .../hd/resource/entity/BatteryType.java | 82 +++ .../evotech/hd/resource/entity/CarType.java | 64 ++ .../evotech/hd/resource/entity/Company.java | 97 +++ .../evotech/hd/resource/entity/DictInfo.java | 28 + .../hd/resource/entity/StationType.java | 69 ++ .../hd/resource/entity/SystemManager.java | 96 +++ .../request/DelAddRoleSourceRequest.java | 21 + .../entity/request/ListAdmdvsRequest.java | 16 + .../entity/request/ListDictTypeRequest.java | 19 + .../entity/request/ListFileRequest.java | 28 + .../entity/request/ListUserRequest.java | 27 + .../request/PageListProxyOperaterRequest.java | 26 + .../resource/service/AdmdvsInfoService.java | 13 + .../hd/resource/service/AuthUserService.java | 26 + .../resource/service/BatteryTypeService.java | 19 + .../hd/resource/service/CarTypeService.java | 19 + .../hd/resource/service/CompanyService.java | 19 + .../hd/resource/service/DictService.java | 32 + .../resource/service/FileUpLoadService.java | 23 + .../hd/resource/service/LogLoginService.java | 15 + .../hd/resource/service/LoginInfoService.java | 67 ++ .../hd/resource/service/MenuService.java | 18 + .../resource/service/PermissionService.java | 18 + .../service/ProxyOperaterService.java | 19 + .../hd/resource/service/RoleService.java | 28 + .../resource/service/StationTypeService.java | 20 + .../service/SystemManagerService.java | 14 + .../service/impl/AdmdvsInfoServiceImpl.java | 54 ++ .../service/impl/AuthUserServiceImpl.java | 132 ++++ .../service/impl/BatteryTypeServiceImpl.java | 64 ++ .../service/impl/CarTypeServiceImpl.java | 66 ++ .../service/impl/CompanyServiceImpl.java | 68 ++ .../service/impl/DictServiceImpl.java | 130 ++++ .../service/impl/FileUpLoadServiceImpl.java | 194 +++++ .../service/impl/LogLoginServiceImpl.java | 42 ++ .../service/impl/MenuServiceImpl.java | 97 +++ .../service/impl/PermissionServiceImpl.java | 90 +++ .../impl/ProxyOperaterServiceImpl.java | 74 ++ .../service/impl/RoleServiceImpl.java | 177 +++++ .../service/impl/StationTypeServiceImpl.java | 65 ++ .../impl/SystemManagerServiceImpl.java | 43 ++ .../evotech/hd/resource/utils/AdmdvsUtil.java | 43 ++ .../evotech/hd/resource/utils/MenuUtil.java | 44 ++ .../src/main/resources/application.yml | 44 ++ .../src/main/resources/logback-spring.xml | 90 +++ .../main/resources/mapper/AuthMenuMapper.xml | 46 ++ .../resources/mapper/AuthPermissionMapper.xml | 41 ++ .../main/resources/mapper/AuthRoleMapper.xml | 25 + .../mapper/AuthRoleResourceMapper.xml | 20 + .../main/resources/mapper/AuthUserMapper.xml | 36 + .../resources/mapper/AuthUserRoleMapper.xml | 20 + .../src/main/resources/mapper/DictMapper.xml | 56 ++ .../ResourceServerApplicationTests.java | 33 + wechat-server/.gitignore | 33 + wechat-server/pom.xml | 93 +++ .../hd/wechat/WechatServerApplication.java | 19 + .../hd/wechat/config/WechatConfig.java | 31 + .../hd/wechat/config/XcxProperties.java | 31 + .../hd/wechat/controller/LoginController.java | 46 ++ .../controller/WechatPayController.java | 92 +++ .../evotech/hd/wechat/dao/WechatUserDao.java | 12 + .../hd/wechat/entity/LoginResponse.java | 23 + .../evotech/hd/wechat/entity/WechatUser.java | 68 ++ .../hd/wechat/service/AccessTokenService.java | 38 + .../hd/wechat/service/LoginService.java | 13 + .../hd/wechat/service/WechatPayService.java | 25 + .../wechat/service/impl/LoginServiceImpl.java | 115 +++ .../service/impl/WechatPayServiceImpl.java | 227 ++++++ .../wechat/utils/wechatpay/WechatPayUtil.java | 28 + .../hd/wechat/utils/xcx/AccessTokenUtil.java | 32 + .../hd/wechat/utils/xcx/LoginUtil.java | 77 ++ .../hd/wechat/utils/xcx/PhoneNumberUtil.java | 31 + ...itional-spring-configuration-metadata.json | 42 ++ .../src/main/resources/application.yml | 58 ++ .../src/main/resources/logback-spring.xml | 90 +++ .../resources/static/key/apiclient_cert.pem | 25 + .../resources/static/key/apiclient_key.pem | 28 + .../wechat/WechatServerApplicationTests.java | 23 + .../com/evotech/hd/wechat/WechatSignTest.java | 23 + 388 files changed, 20094 insertions(+) create mode 100644 .gitignore create mode 100644 admin-server/.gitignore create mode 100644 admin-server/pom.xml create mode 100644 admin-server/src/main/java/com/evotech/hd/admin/AdminServerApplication.java create mode 100644 admin-server/src/main/java/com/evotech/hd/admin/config/NotifierConfig.java create mode 100644 admin-server/src/main/java/com/evotech/hd/admin/config/PrintConfig.java create mode 100644 admin-server/src/main/resources/application.yml create mode 100644 admin-server/src/main/resources/logback-spring.xml create mode 100644 authorization-server/.gitignore create mode 100644 authorization-server/pom.xml create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/AuthorizationServerApplication.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/AuthorizationServerConfig.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/MyAccessToken.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/MyAuthenticationFailureHandler.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/MyAuthenticationSuccessHandler.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/MyOAuth2TokenJwtCustomizer.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/RSAKeyPair.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/passwordmode/OAuth2AuthenticationProviderUtils.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/passwordmode/OAuth2EndpointUtils.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/passwordmode/OAuth2PasswordAuthenticationConverter.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/passwordmode/OAuth2PasswordAuthenticationProvider.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/passwordmode/OAuth2PasswordAuthenticationToken.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/config/security/MyAccessDeniedHandler.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/config/security/MyAuthenticationEntryPoint.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/config/security/WebSecutiryConfig.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/config/security/userdetail/MyUserDetail.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/config/security/userdetail/UserDetailService.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/controller/CaptchaController.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/controller/LoginController.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/entity/LoginRequest.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/entity/UserVo.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/service/CaptchaService.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/service/LoginService.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/service/ResourceService.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/service/impl/CaptchaServiceImpl.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/service/impl/LoginServiceImpl.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/utils/LoginRequesHeadertUtil.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/utils/Oauth2AccessTokenUtil.java create mode 100644 authorization-server/src/main/java/com/evotech/hd/authorization/utils/TokenUtil.java create mode 100644 authorization-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json create mode 100644 authorization-server/src/main/resources/application.yml create mode 100644 authorization-server/src/main/resources/logback-spring.xml create mode 100644 authorization-server/src/test/java/com/evotech/hd/authorization/AuthorizationServerApplicationTests.java create mode 100644 base-commons/common-core/pom.xml create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/constant/HDConstant.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/ProxyOperaterDao.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/auth/AuthMenuDao.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/auth/AuthPermissionDao.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/auth/AuthRoleDao.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/auth/AuthRoleResourceDao.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/auth/AuthUserDao.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/auth/AuthUserRoleDao.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/dict/AdmdvsInfoDao.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/dict/DictDao.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/dict/DictTypeDao.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/BasePageRequest.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/LoginCacheInfo.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/Result.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStation.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationDc.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationDcc.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationDj.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationHdFeeStandard.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationHdFeeStandardDetail.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationRobot.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryTrace.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/OrderRecharge.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/OrderSwapBattery.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/OrderSwapBatteryPre.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/OrderSwapBatteryStep.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/TradeDetail.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/VehicleInfo.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/VehicleWechatUserRelation.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/WalletAccount.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/WalletAccountDetail.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/request/ListDictRequest.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/LogLogin.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/LogUpload.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/ProxyOperater.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/UploadFile.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/auth/AuthMenu.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/auth/AuthPermission.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/auth/AuthRole.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/auth/AuthRoleResource.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/auth/AuthUser.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/auth/AuthUserRole.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/dict/AdmdvsInfo.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/dict/Dict.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/dict/DictType.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/enums/CodeMsg.java create mode 100644 base-commons/common-core/src/main/java/com/evotech/hd/common/core/utils/SnowflakeUtil.java create mode 100644 base-commons/common-mybatis/pom.xml create mode 100644 base-commons/common-redis/pom.xml create mode 100644 base-commons/common-redis/src/main/java/com/evotech/hd/common/redis/config/RedisConfig.java create mode 100644 base-commons/common-redis/src/main/java/com/evotech/hd/common/redis/utils/RedisUtil.java create mode 100644 base-commons/common-web/pom.xml create mode 100644 base-commons/common-web/src/main/java/com/evotech/hd/common/web/exception/GlobalExceptionHandler.java create mode 100644 base-commons/common-web/src/main/java/com/evotech/hd/common/web/exception/MyArgumentException.java create mode 100644 base-commons/common-web/src/main/java/com/evotech/hd/common/web/filter/MyFilterConfig.java create mode 100644 base-commons/common-web/src/main/java/com/evotech/hd/common/web/filter/MyHttpServletRequestWrapper.java create mode 100644 base-commons/common-web/src/main/java/com/evotech/hd/common/web/filter/RequestBodyFilter.java create mode 100644 base-commons/common-web/src/main/java/com/evotech/hd/common/web/swagger/SwaggerTips.java create mode 100644 base-commons/common-web/src/main/java/com/evotech/hd/common/web/thread/ThreadPoolConfig.java create mode 100644 base-commons/common-web/src/main/java/com/evotech/hd/common/web/thread/ThreadPoolProperties.java create mode 100644 base-commons/common-web/src/main/java/com/evotech/hd/common/web/util/IpUtil.java create mode 100644 base-commons/common-web/src/main/java/com/evotech/hd/common/web/util/RequestContextUtil.java create mode 100644 base-commons/pom.xml create mode 100644 cloud-manage-server/.gitignore create mode 100644 cloud-manage-server/pom.xml create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/CloudManageServerApplication.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationController.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationDcController.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationDccController.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationDjController.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationHdFeeStandardController.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationHdFeeStandardDetailController.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationRobotController.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/MessageMqttController.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/customer/VehicleController.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/OrderRechargeController.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/OrderSwapBatteryController.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/TradeController.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/WalletAccountController.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationDao.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationDcDao.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationDccDao.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationDjDao.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationHdFeeStandardDao.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationHdFeeStandardDetailDao.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationRobotDao.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationSecretKeyDao.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryTraceDao.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/MessageMqttDao.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/OrderRechargeDao.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/OrderSwapBatteryDao.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/OrderSwapBatteryPreDao.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/OrderSwapBatteryStepDao.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/TradeDetailDao.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/VehicleInfoDao.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/VehicleWechatUserRelationDao.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/WalletAccountDao.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/WalletAccountDetailDao.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/BatteryStationSecretKey.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/MessageMqtt.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListBatteryStationDcRequest.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListBatteryStationDccRequest.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListBatteryStationDjRequest.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListBatteryStationRequest.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListMessageMqttRequest.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListRechargeOrderRequest.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListSwapOrderRequest.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListTradeRequest.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListVehicleRequest.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListWalletRequest.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/MqttInit.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/config/MqttConfig.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/config/MqttProperties.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/config/MyMqttCallback.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/enums/ConfirmFunctionTypesEnum.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/enums/EventFunctionTypesEnum.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/enums/MqttMessageTypeEnum.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/enums/RequestFunctionTypesEnum.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/enums/StateFunctionTypesEnum.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/MessageTopic.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/MqttMessageHeader.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/MyMqttMessage.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/battery/BatteryData.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/battery/BatteryInfoReq.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/battery/BatteryInfoResponse.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/carinfo/CarInfoReq.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/carinfo/CarInfoResponse.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/carinfo/VehicleData.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/order/CancelOrderReq.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/order/CancelOrderResponse.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/order/OrderByPlateNumReq.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/order/OrderByPlateNumResponse.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/order/OrderData.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/preorder/PreOrderReq.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/preorder/PreOrderResponse.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/state/OrderStatus.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/state/OrderStatusData.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/state/SwapStep.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/BatData.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/BatteryData.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/ChargeRecord.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/ChargeRecordConf.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/ChargeRecordDetail.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/FaultRecord.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/FaultRecordConf.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/RateMode.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/RateModeSync.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/SwapRecord.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/SwapRecordConf.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/VehicleSync.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/RateModeSyncReq.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/RateModeSyncResp.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/RemoteSwapCheckReq.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/RemoteSwapCheckResp.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/RemoteSwapStartReq.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/RemoteSwapStartResp.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/VehicleSyncReq.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/VehicleSyncResp.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/state/ChargingData.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/state/HdChargingData.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/state/SwapState.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/state/VehicleState.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/EncryptKeyReqMessageService.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/EventMessageService.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/KeepaliveMessageService.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/MessageUtilService.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/MqttMessageHandle.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/RequestMessageService.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/StateMessageService.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationDcService.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationDccService.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationDjService.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationHdFeeStandardDetailService.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationHdFeeStandardService.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationRobotService.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationService.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/MessageMqttService.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/OrderRechargeService.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/OrderSwapBatteryService.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/TradeService.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/VehicleService.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/WalletAccountService.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationDcServiceImpl.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationDccServiceImpl.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationDjServiceImpl.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationHdFeeStandardDetailServiceImpl.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationHdFeeStandardServiceImpl.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationRobotServiceImpl.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationServiceImpl.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/MessageMqttServiceImpl.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/OrderRechargeServiceimpl.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/OrderSwapBatteryServiceImpl.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/TradeServiceImpl.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/VehicleServiceImpl.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/WalletAccountServiceImpl.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/utils/AESEncryptionUtil.java create mode 100644 cloud-manage-server/src/main/java/com/evotech/hd/cloud/utils/RSADecryptionUtil.java create mode 100644 cloud-manage-server/src/main/resources/application.yml create mode 100644 cloud-manage-server/src/main/resources/logback-spring.xml create mode 100644 cloud-manage-server/src/main/resources/mapper/BatteryStationDcMapper.xml create mode 100644 cloud-manage-server/src/main/resources/mapper/BatteryStationDccMapper.xml create mode 100644 cloud-manage-server/src/main/resources/mapper/BatteryStationDjMapper.xml create mode 100644 cloud-manage-server/src/main/resources/mapper/BatteryStationHdFeeStandardDetailMapper.xml create mode 100644 cloud-manage-server/src/main/resources/mapper/BatteryStationHdFeeStandardMapper.xml create mode 100644 cloud-manage-server/src/main/resources/mapper/BatteryStationMapper.xml create mode 100644 cloud-manage-server/src/main/resources/mapper/BatteryStationRobotMapper.xml create mode 100644 cloud-manage-server/src/test/java/com/evotech/hd/cloud/AesDecryTest.java create mode 100644 cloud-manage-server/src/test/java/com/evotech/hd/cloud/CloudManageServerApplicationTests.java create mode 100644 cloud-manage-server/src/test/java/com/evotech/hd/cloud/DecryptionTest.java create mode 100644 cloud-manage-server/src/test/java/com/evotech/hd/cloud/Test1.java create mode 100644 gateway-server/.gitignore create mode 100644 gateway-server/pom.xml create mode 100644 gateway-server/src/main/java/com/evotech/hd/gateway/GatewayServerApplication.java create mode 100644 gateway-server/src/main/java/com/evotech/hd/gateway/config/CorsConfig.java create mode 100644 gateway-server/src/main/java/com/evotech/hd/gateway/filter/AccessLogFilter.java create mode 100644 gateway-server/src/main/java/com/evotech/hd/gateway/filter/HeaderHandleFilter.java create mode 100644 gateway-server/src/main/java/com/evotech/hd/gateway/log/GatewayLogService.java create mode 100644 gateway-server/src/main/java/com/evotech/hd/gateway/log/entity/GatewayLog.java create mode 100644 gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/AuthorizationManager.java create mode 100644 gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/MyAccessDeniedHandler.java create mode 100644 gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/MyAuthenticationEntryPoint.java create mode 100644 gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/MyJwtValidator.java create mode 100644 gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/RSAKeyPair.java create mode 100644 gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/ResourceServerConfig.java create mode 100644 gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/exception/GlobalExceptionAutoConfig.java create mode 100644 gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/exception/GlobalExceptionHandler.java create mode 100644 gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/exception/GlobalExceptionType.java create mode 100644 gateway-server/src/main/java/com/evotech/hd/gateway/thread/ThreadPoolConfig.java create mode 100644 gateway-server/src/main/java/com/evotech/hd/gateway/thread/ThreadPoolProperties.java create mode 100644 gateway-server/src/main/java/com/evotech/hd/gateway/utils/IpUtil.java create mode 100644 gateway-server/src/main/java/com/evotech/hd/gateway/utils/ResponseUtils.java create mode 100644 gateway-server/src/main/java/com/evotech/hd/gateway/utils/TokenUtil.java create mode 100644 gateway-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json create mode 100644 gateway-server/src/main/resources/application.yml create mode 100644 gateway-server/src/main/resources/logback-spring.xml create mode 100644 gateway-server/src/main/resources/static/favicon.ico create mode 100644 gateway-server/src/test/java/com/evotech/hd/gateway/GatewayServerApplicationTests.java create mode 100644 pom.xml create mode 100644 resource-server/.gitignore create mode 100644 resource-server/pom.xml create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/ResourceServerApplication.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/controller/AdmdvsInfoController.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/controller/AuthUserController.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/controller/BatteryTypeController.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/controller/CarTypeController.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/controller/CompanyController.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/controller/DictController.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/controller/FileUpLoadController.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/controller/IDController.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/controller/LogLoginController.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/controller/LoginInfoController.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/controller/MenuController.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/controller/PermissionController.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/controller/ProxyOperaterController.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/controller/RoleController.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/controller/StationTypeController.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/controller/SystemManagerController.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/dao/BatteryTypeDao.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/dao/CarTypeDao.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/dao/CompanyDao.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/dao/LogLoginDao.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/dao/LogUploadDao.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/dao/StationTypeDao.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/dao/SystemManagerDao.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/dao/UploadFileDao.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/entity/BatteryType.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/entity/CarType.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/entity/Company.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/entity/DictInfo.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/entity/StationType.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/entity/SystemManager.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/entity/request/DelAddRoleSourceRequest.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/entity/request/ListAdmdvsRequest.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/entity/request/ListDictTypeRequest.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/entity/request/ListFileRequest.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/entity/request/ListUserRequest.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/entity/request/PageListProxyOperaterRequest.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/AdmdvsInfoService.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/AuthUserService.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/BatteryTypeService.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/CarTypeService.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/CompanyService.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/DictService.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/FileUpLoadService.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/LogLoginService.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/LoginInfoService.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/MenuService.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/PermissionService.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/ProxyOperaterService.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/RoleService.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/StationTypeService.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/SystemManagerService.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/impl/AdmdvsInfoServiceImpl.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/impl/AuthUserServiceImpl.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/impl/BatteryTypeServiceImpl.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/impl/CarTypeServiceImpl.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/impl/CompanyServiceImpl.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/impl/DictServiceImpl.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/impl/FileUpLoadServiceImpl.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/impl/LogLoginServiceImpl.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/impl/MenuServiceImpl.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/impl/PermissionServiceImpl.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/impl/ProxyOperaterServiceImpl.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/impl/RoleServiceImpl.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/impl/StationTypeServiceImpl.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/service/impl/SystemManagerServiceImpl.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/utils/AdmdvsUtil.java create mode 100644 resource-server/src/main/java/com/evotech/hd/resource/utils/MenuUtil.java create mode 100644 resource-server/src/main/resources/application.yml create mode 100644 resource-server/src/main/resources/logback-spring.xml create mode 100644 resource-server/src/main/resources/mapper/AuthMenuMapper.xml create mode 100644 resource-server/src/main/resources/mapper/AuthPermissionMapper.xml create mode 100644 resource-server/src/main/resources/mapper/AuthRoleMapper.xml create mode 100644 resource-server/src/main/resources/mapper/AuthRoleResourceMapper.xml create mode 100644 resource-server/src/main/resources/mapper/AuthUserMapper.xml create mode 100644 resource-server/src/main/resources/mapper/AuthUserRoleMapper.xml create mode 100644 resource-server/src/main/resources/mapper/DictMapper.xml create mode 100644 resource-server/src/test/java/com/evotech/hd/resource/ResourceServerApplicationTests.java create mode 100644 wechat-server/.gitignore create mode 100644 wechat-server/pom.xml create mode 100644 wechat-server/src/main/java/com/evotech/hd/wechat/WechatServerApplication.java create mode 100644 wechat-server/src/main/java/com/evotech/hd/wechat/config/WechatConfig.java create mode 100644 wechat-server/src/main/java/com/evotech/hd/wechat/config/XcxProperties.java create mode 100644 wechat-server/src/main/java/com/evotech/hd/wechat/controller/LoginController.java create mode 100644 wechat-server/src/main/java/com/evotech/hd/wechat/controller/WechatPayController.java create mode 100644 wechat-server/src/main/java/com/evotech/hd/wechat/dao/WechatUserDao.java create mode 100644 wechat-server/src/main/java/com/evotech/hd/wechat/entity/LoginResponse.java create mode 100644 wechat-server/src/main/java/com/evotech/hd/wechat/entity/WechatUser.java create mode 100644 wechat-server/src/main/java/com/evotech/hd/wechat/service/AccessTokenService.java create mode 100644 wechat-server/src/main/java/com/evotech/hd/wechat/service/LoginService.java create mode 100644 wechat-server/src/main/java/com/evotech/hd/wechat/service/WechatPayService.java create mode 100644 wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/LoginServiceImpl.java create mode 100644 wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/WechatPayServiceImpl.java create mode 100644 wechat-server/src/main/java/com/evotech/hd/wechat/utils/wechatpay/WechatPayUtil.java create mode 100644 wechat-server/src/main/java/com/evotech/hd/wechat/utils/xcx/AccessTokenUtil.java create mode 100644 wechat-server/src/main/java/com/evotech/hd/wechat/utils/xcx/LoginUtil.java create mode 100644 wechat-server/src/main/java/com/evotech/hd/wechat/utils/xcx/PhoneNumberUtil.java create mode 100644 wechat-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json create mode 100644 wechat-server/src/main/resources/application.yml create mode 100644 wechat-server/src/main/resources/logback-spring.xml create mode 100644 wechat-server/src/main/resources/static/key/apiclient_cert.pem create mode 100644 wechat-server/src/main/resources/static/key/apiclient_key.pem create mode 100644 wechat-server/src/test/java/com/evotech/hd/wechat/WechatServerApplicationTests.java create mode 100644 wechat-server/src/test/java/com/evotech/hd/wechat/WechatSignTest.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a6cc829 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +.factorypath +.classpath +.project +*.class +.settings +pom.properties +**/target/** +mvnw +mvnw.cmd +maven-wrapper.properties \ No newline at end of file diff --git a/admin-server/.gitignore b/admin-server/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/admin-server/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/admin-server/pom.xml b/admin-server/pom.xml new file mode 100644 index 0000000..f8b45f7 --- /dev/null +++ b/admin-server/pom.xml @@ -0,0 +1,68 @@ + + + 4.0.0 + + com.evotech.hd + battery-cloud + 1.0.0-SNAPSHOT + + admin-server + 1.0.0 + admin-server + 监控和日志 + + 17 + + + + + org.springframework.boot + spring-boot-starter-web + + + de.codecentric + spring-boot-admin-starter-server + + + de.codecentric + spring-boot-admin-starter-client + + + + org.projectlombok + lombok + true + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + diff --git a/admin-server/src/main/java/com/evotech/hd/admin/AdminServerApplication.java b/admin-server/src/main/java/com/evotech/hd/admin/AdminServerApplication.java new file mode 100644 index 0000000..de11f48 --- /dev/null +++ b/admin-server/src/main/java/com/evotech/hd/admin/AdminServerApplication.java @@ -0,0 +1,18 @@ +package com.evotech.hd.admin; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; + +import de.codecentric.boot.admin.server.config.EnableAdminServer; + +@SpringBootApplication +@EnableDiscoveryClient +@EnableAdminServer +public class AdminServerApplication { + + public static void main(String[] args) { + SpringApplication.run(AdminServerApplication.class, args); + } + +} diff --git a/admin-server/src/main/java/com/evotech/hd/admin/config/NotifierConfig.java b/admin-server/src/main/java/com/evotech/hd/admin/config/NotifierConfig.java new file mode 100644 index 0000000..b2d930a --- /dev/null +++ b/admin-server/src/main/java/com/evotech/hd/admin/config/NotifierConfig.java @@ -0,0 +1,54 @@ +package com.evotech.hd.admin.config; + +import org.springframework.stereotype.Component; + +import de.codecentric.boot.admin.server.domain.entities.Instance; +import de.codecentric.boot.admin.server.domain.entities.InstanceRepository; +import de.codecentric.boot.admin.server.domain.events.InstanceEvent; +import de.codecentric.boot.admin.server.domain.events.InstanceStatusChangedEvent; +import de.codecentric.boot.admin.server.notify.AbstractStatusChangeNotifier; +import lombok.extern.slf4j.Slf4j; +import reactor.core.publisher.Mono; + +/** + * 自定义通知 + * 继承 AbstractStatusChangeNotifier 类,实现了 doNotify 方法, + */ +@Component +@Slf4j +public class NotifierConfig extends AbstractStatusChangeNotifier { + + public NotifierConfig(InstanceRepository repository) { + super(repository); + } + + @Override + protected Mono doNotify(InstanceEvent event, Instance instance) { + return Mono.fromRunnable(() -> { + if (event instanceof InstanceStatusChangedEvent) { + log.info("===>>>实例名称:"+instance.getRegistration().getName()); + log.info("===>>>实例服务地址:"+instance.getRegistration().getServiceUrl()); + String status = ((InstanceStatusChangedEvent) event).getStatusInfo().getStatus(); + switch (status) { + case "DOWN": + log.info("健康检查没通过!"); + break; + case "OFFLINE": + log.info("服务离线!"); + break; + case "UP": + log.info("服务上线!"); + break; + case "UNKNOWN": + log.info("服务未知异常!"); + break; + default: + log.info(status); + break; + } + + } + }); + } + +} diff --git a/admin-server/src/main/java/com/evotech/hd/admin/config/PrintConfig.java b/admin-server/src/main/java/com/evotech/hd/admin/config/PrintConfig.java new file mode 100644 index 0000000..c5b59d4 --- /dev/null +++ b/admin-server/src/main/java/com/evotech/hd/admin/config/PrintConfig.java @@ -0,0 +1,43 @@ +package com.evotech.hd.admin.config; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.core.annotation.Order; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; + +@Component +@Order(value = 100) +@Slf4j +public class PrintConfig implements ApplicationRunner { + + @Resource + private Environment env; + + @Override + public void run(ApplicationArguments args) { + int port = env.getProperty("server.port", Integer.class) == null?8080:env.getProperty("server.port", Integer.class); + String address = "127.0.0.1"; + try { + address = InetAddress.getLocalHost().getHostAddress(); + } catch (UnknownHostException e) { + address = "192.168.5.213"; + e.printStackTrace(); + } + String url = "http://" + address + ":" + port; + String path = env.getProperty("server.servlet.context-path"); + if (StringUtils.hasText(path)) { + url += path; + } + + log.info("\r\n===>>>项目已启动,访问地址:{}", url); + } + +} diff --git a/admin-server/src/main/resources/application.yml b/admin-server/src/main/resources/application.yml new file mode 100644 index 0000000..7e59615 --- /dev/null +++ b/admin-server/src/main/resources/application.yml @@ -0,0 +1,58 @@ +# 1.server +server: + port: 9099 + servlet: + context-path: /admonitor +# 2. log +logging: + config: classpath:logback-spring.xml + +# 3. spring +spring: + application: + name: admin-monitor + boot: + admin: + ui: + # 登陆页面标题 + title: 微服务监控 + # 登陆后,页面左上标题 + brand: 服务监控和日志 + # 配置一个账号和密码 +# security: +# user: +# name: zrb +# password: zrb123 + cloud: + nacos: + serverAddr: 192.168.5.213:8848 + username: nacos + password: nacos + discovery: + register-enabled: true + #server-addr: 10.10.1.6:8848 + #ip: 10.10.1.2 +# metadata: +# user: +# name: ${spring.security.user.name} +# password: ${spring.security.user.password} + # 因添加了context-path,admin-server要想发现正确路径,需要加这个 + metadata: + management: + context-path: ${server.servlet.context-path}/actuator + +#开放指定信息给服务器看 +management: + httpexchanges: + recording: + enabled: true + endpoints: + web: + exposure: + include: "*" + endpoint: + health: + show-details: always + # xml文件中配置的日志文件的名称 + logfile: + external-file: /logs/admin/admin-server.log \ No newline at end of file diff --git a/admin-server/src/main/resources/logback-spring.xml b/admin-server/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..0f06dc4 --- /dev/null +++ b/admin-server/src/main/resources/logback-spring.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + ${CONTEXT_NAME} + + + + + + DEBUG + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %replace(%caller{1}){'\t|Caller.{1}0|\r\n', ''} -- %msg%n + + UTF-8 + + + + + + + ${LOG_PATH}/${CONTEXT_NAME}.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{50}.%M\(%line\) -- %msg%n + UTF-8 + + + + + ${LOG_PATH}/${CONTEXT_NAME}-%d{yyyy-MM-dd}-%i.log + + ${MAX_HISTORY} + + + ${MAX_FILE_SIZE} + + + + + + + + 512 + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/authorization-server/.gitignore b/authorization-server/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/authorization-server/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/authorization-server/pom.xml b/authorization-server/pom.xml new file mode 100644 index 0000000..723b879 --- /dev/null +++ b/authorization-server/pom.xml @@ -0,0 +1,104 @@ + + + + 4.0.0 + + com.evotech.hd + battery-cloud + 1.0.0-SNAPSHOT + + authorization-server + authorization-server + 认证服务 + + + 17 + + + + + org.springframework.boot + spring-boot-starter-oauth2-authorization-server + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + com.evotech.hd + common-web + 1.0.0-SNAPSHOT + + + com.evotech.hd + common-redis + 1.0.0-SNAPSHOT + + + com.evotech.hd + common-mybatis + 1.0.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + cn.hutool + hutool-captcha + + + cn.hutool + hutool-http + + + cn.hutool + hutool-jwt + + + + + com.google.code.findbugs + jsr305 + 3.0.2 + + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/AuthorizationServerApplication.java b/authorization-server/src/main/java/com/evotech/hd/authorization/AuthorizationServerApplication.java new file mode 100644 index 0000000..041aed4 --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/AuthorizationServerApplication.java @@ -0,0 +1,19 @@ +package com.evotech.hd.authorization; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication +@EnableDiscoveryClient +@ComponentScan("com.evotech.hd.**") +@EnableFeignClients +public class AuthorizationServerApplication { + + public static void main(String[] args) { + SpringApplication.run(AuthorizationServerApplication.class, args); + } + +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/AuthorizationServerConfig.java b/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/AuthorizationServerConfig.java new file mode 100644 index 0000000..7159b26 --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/AuthorizationServerConfig.java @@ -0,0 +1,262 @@ +package com.evotech.hd.authorization.config.oauth2; + +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.support.lob.DefaultLobHandler; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.Customizer; +import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.jackson2.SecurityJackson2Modules; +import org.springframework.security.oauth2.jwt.JwtDecoder; +import org.springframework.security.oauth2.jwt.NimbusJwtEncoder; +import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationConsentService; +import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService; +import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService; +import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; +import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository; +import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; +import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; +import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer; +import org.springframework.security.oauth2.server.authorization.jackson2.OAuth2AuthorizationServerJackson2Module; +import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings; +import org.springframework.security.oauth2.server.authorization.token.JwtGenerator; +import org.springframework.security.oauth2.server.authorization.token.OAuth2AccessTokenGenerator; +import org.springframework.security.oauth2.server.authorization.token.OAuth2RefreshTokenGenerator; +import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.util.StringUtils; +import org.springframework.security.oauth2.server.authorization.token.DelegatingOAuth2TokenGenerator; + +import com.evotech.hd.authorization.config.oauth2.passwordmode.OAuth2PasswordAuthenticationConverter; +import com.evotech.hd.authorization.config.oauth2.passwordmode.OAuth2PasswordAuthenticationProvider; +import com.fasterxml.jackson.databind.Module; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.nimbusds.jose.jwk.JWKSet; +import com.nimbusds.jose.jwk.RSAKey; +import com.nimbusds.jose.jwk.source.ImmutableJWKSet; +import com.nimbusds.jose.jwk.source.JWKSource; +import com.nimbusds.jose.proc.SecurityContext; + +import jakarta.annotation.Resource; + +@Configuration +public class AuthorizationServerConfig { + + Logger log = LoggerFactory.getLogger(this.getClass()); + + private static final String KEY_ID = "jnGZxjHC54hP4ZnXrrEedtNweQ6aK29w"; + + @Resource + private MyOAuth2TokenJwtCustomizer jwtCustomizer; + @Resource + private RSAKeyPair rsaKeyPair; + + /** + * 授权服务器端点配置 + */ + @Bean + @Order(1) + SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http, + AuthenticationManager authenticationManager, + OAuth2AuthorizationService authorizationService, + OAuth2TokenGenerator tokenGenerator) throws Exception { + // 这是 http 的默认配置,可以点进去看一下,我们为了加入自己的密码模式,需要把 + OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); +// OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer(); +// RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher(); +// http.securityMatcher(endpointsMatcher) +// .authorizeHttpRequests(authorizeRequests -> authorizeRequests.anyRequest().authenticated()) +// .csrf(csrf -> csrf.ignoringRequestMatchers(endpointsMatcher)) +// .apply(authorizationServerConfigurer); + + // 添加password模式 + http.getConfigurer(OAuth2AuthorizationServerConfigurer.class).tokenEndpoint(tokenEndpoint -> + tokenEndpoint + // 添加授权模式转换器(Converter) + .accessTokenRequestConverter(new OAuth2PasswordAuthenticationConverter()) + // 添加 授权模式提供者(Provider) + .authenticationProvider(new OAuth2PasswordAuthenticationProvider(authenticationManager, authorizationService, tokenGenerator)) + // 成功响应 + .accessTokenResponseHandler(new MyAuthenticationSuccessHandler()) + // 失败响应 + .errorResponseHandler(new MyAuthenticationFailureHandler())); + + // 开启OpenID Connect 1.0协议相关端点 + http.getConfigurer(OAuth2AuthorizationServerConfigurer.class).oidc(Customizer.withDefaults()); + + return http.build(); + } + + + /** + * 配置认证服务器请求地址 + */ + @Bean + @Order(2) + AuthorizationServerSettings authorizationServerSettings() { + // 什么都不配置,则使用默认地址 + return AuthorizationServerSettings.builder().build(); + } + + + // 客户端信息表:oauth2_registered_client + @Bean + @Order(3) + RegisteredClientRepository registeredClientRepository(JdbcTemplate jdbcTemplate) { + JdbcRegisteredClientRepository registeredClientRepository = new JdbcRegisteredClientRepository(jdbcTemplate); + return registeredClientRepository; + } + + + // 和 token表交互数据用的:oauth2_authorization + @Bean + OAuth2AuthorizationService authorizationService(JdbcTemplate jdbcTemplate, RegisteredClientRepository registeredClientRepository) { + + JdbcOAuth2AuthorizationService service = new JdbcOAuth2AuthorizationService(jdbcTemplate, registeredClientRepository); + JdbcOAuth2AuthorizationService.OAuth2AuthorizationRowMapper rowMapper = new JdbcOAuth2AuthorizationService.OAuth2AuthorizationRowMapper(registeredClientRepository); + rowMapper.setLobHandler(new DefaultLobHandler()); + ObjectMapper objectMapper = new ObjectMapper(); + ClassLoader classLoader = JdbcOAuth2AuthorizationService.class.getClassLoader(); + List modules = SecurityJackson2Modules.getModules(classLoader); + objectMapper.registerModules(modules); + objectMapper.registerModule(new OAuth2AuthorizationServerJackson2Module()); + // 使用刷新模式,需要从 oauth2_authorization 表反序列化attributes字段得到用户信息(SysUserDetails) +// objectMapper.addMixIn(SysUserDetails.class, SysUserMixin.class); + objectMapper.addMixIn(Long.class, Object.class); + + rowMapper.setObjectMapper(objectMapper); + service.setAuthorizationRowMapper(rowMapper); + return service; + } + + // 和授权记录表交互数据用的:oauth2_authorization_consent + @Bean + OAuth2AuthorizationConsentService authorizationConsentService(JdbcTemplate jdbcTemplate, RegisteredClientRepository registeredClientRepository) { + return new JdbcOAuth2AuthorizationConsentService(jdbcTemplate, registeredClientRepository); + } + + + @Bean + AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception { + return authenticationConfiguration.getAuthenticationManager(); + } + + + /** + * ========= Token部分 ======== + */ + + /** + * 配置 JWK,为JWT(id_token)提供加密密钥,用于加密/解密或签名/验签 + * JWK详细见:https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key-41 + */ + @Bean + JWKSource jwkSource() { + RSAPublicKey publicKey = null; + RSAPrivateKey privateKey = null; + String publicKeyBase64 = rsaKeyPair.getPublicKeyBase64(); + String privateKeyBase64 = rsaKeyPair.getPrivateKeyBase64(); + if (StringUtils.hasText(publicKeyBase64) && StringUtils.hasText(privateKeyBase64)) { + publicKey = getPublicKey(publicKeyBase64); + privateKey = getPrivateKey(privateKeyBase64); + } else { + KeyPair keyPair = generateRsaKey(); + publicKey = (RSAPublicKey) keyPair.getPublic(); + privateKey = (RSAPrivateKey) keyPair.getPrivate(); + log.warn("未设置生成token的秘钥!!!"); + log.info("生成临时秘钥:"); + log.info("\r\n===publicKey===" + + "\r\n" + + Base64.getEncoder().encodeToString(publicKey.getEncoded()) + + "\r\n===privateKey===" + + "\r\n" + + Base64.getEncoder().encodeToString(privateKey.getEncoded())); + } + + RSAKey rsaKey = new RSAKey.Builder(publicKey) + .privateKey(privateKey) + .keyID(KEY_ID) + .build(); + JWKSet jwkSet = new JWKSet(rsaKey); + return new ImmutableJWKSet<>(jwkSet); + } + + private RSAPublicKey getPublicKey(String publicKeyBase64) { + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyBase64)); + RSAPublicKey rsaPublicKey = null; + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + rsaPublicKey = (RSAPublicKey)keyFactory.generatePublic(keySpec); + } catch (Exception e) { + e.printStackTrace(); + } + + return rsaPublicKey; + } + + private RSAPrivateKey getPrivateKey(String privateKeyBase64) { + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyBase64)); + RSAPrivateKey rsaPrivateKey = null; + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + rsaPrivateKey = (RSAPrivateKey) keyFactory.generatePrivate(keySpec); + } catch (Exception e) { + e.printStackTrace(); + } + + return rsaPrivateKey; + } + + /** + * 生成RSA密钥对,给上面jwkSource() 方法的提供密钥对 + */ + private static KeyPair generateRsaKey() { + KeyPair keyPair; + try { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + keyPairGenerator.initialize(2048); + keyPair = keyPairGenerator.generateKeyPair(); + } catch (Exception ex) { + throw new IllegalStateException(ex); + } + return keyPair; + } + + /** + * 配置jwt解析器 + */ + @Bean + JwtDecoder jwtDecoder(JWKSource jwkSource) { + return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource); + } + + /** + * 配置token生成器 + */ + @Bean + OAuth2TokenGenerator tokenGenerator(JWKSource jwkSource) { + JwtGenerator jwtGenerator = new JwtGenerator(new NimbusJwtEncoder(jwkSource)); + // token 中加入自定义的字段内容 + jwtGenerator.setJwtCustomizer(jwtCustomizer); + + OAuth2AccessTokenGenerator accessTokenGenerator = new OAuth2AccessTokenGenerator(); + OAuth2RefreshTokenGenerator refreshTokenGenerator = new OAuth2RefreshTokenGenerator(); + return new DelegatingOAuth2TokenGenerator(jwtGenerator, accessTokenGenerator, refreshTokenGenerator); + } + +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/MyAccessToken.java b/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/MyAccessToken.java new file mode 100644 index 0000000..69429ef --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/MyAccessToken.java @@ -0,0 +1,18 @@ +package com.evotech.hd.authorization.config.oauth2; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class MyAccessToken { + + private String accessToken; + + private String refreshToken; + + private String tokenType; + + private long expiresIn; + +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/MyAuthenticationFailureHandler.java b/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/MyAuthenticationFailureHandler.java new file mode 100644 index 0000000..8c72ebb --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/MyAuthenticationFailureHandler.java @@ -0,0 +1,42 @@ +package com.evotech.hd.authorization.config.oauth2; + +import java.io.IOException; + +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.http.server.ServletServerHttpResponse; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.oauth2.core.OAuth2AuthenticationException; +import org.springframework.security.oauth2.core.OAuth2Error; +import org.springframework.security.web.authentication.AuthenticationFailureHandler; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.enums.CodeMsg; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler { + + private final HttpMessageConverter httpResponseConverter = new MappingJackson2HttpMessageConverter(); + + @Override + public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, + AuthenticationException exception) throws IOException, ServletException { + ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response); + Result res = new Result(); + if (exception instanceof UsernameNotFoundException) { + res.error(CodeMsg.USERNAME_OR_PASSWORD_ERROR); + } else if (exception instanceof OAuth2AuthenticationException) { + OAuth2Error error = ((OAuth2AuthenticationException) exception).getError(); + res.error(error.getErrorCode()); + } + + System.out.println("error走这个了: MyAuthenticationFailureHandler"); + + httpResponseConverter.write(res, null, httpResponse); + } + +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/MyAuthenticationSuccessHandler.java b/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/MyAuthenticationSuccessHandler.java new file mode 100644 index 0000000..1ee2f56 --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/MyAuthenticationSuccessHandler.java @@ -0,0 +1,63 @@ +package com.evotech.hd.authorization.config.oauth2; + +import java.io.IOException; +import java.time.temporal.ChronoUnit; +import java.util.Map; + +import org.springframework.core.convert.converter.Converter; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.http.server.ServletServerHttpResponse; +import org.springframework.security.core.Authentication; +import org.springframework.security.oauth2.core.OAuth2AccessToken; +import org.springframework.security.oauth2.core.OAuth2RefreshToken; +import org.springframework.security.oauth2.core.endpoint.DefaultOAuth2AccessTokenResponseMapConverter; +import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; +import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AccessTokenAuthenticationToken; +import org.springframework.security.web.authentication.AuthenticationSuccessHandler; +import org.springframework.util.CollectionUtils; + +import com.evotech.hd.common.core.entity.Result; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler { + + /** + * MappingJackson2HttpMessageConverter 是 Spring 框架提供的一个 HTTP 消息转换器,用于将 HTTP 请求和响应的 JSON 数据与 Java 对象之间进行转换 + */ + private final HttpMessageConverter accessTokenHttpResponseConverter = new MappingJackson2HttpMessageConverter(); + private Converter> accessTokenResponseParametersConverter = new DefaultOAuth2AccessTokenResponseMapConverter(); + + @Override + public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, + Authentication authentication) throws IOException, ServletException { + OAuth2AccessTokenAuthenticationToken accessTokenAuthentication = (OAuth2AccessTokenAuthenticationToken) authentication; + + OAuth2AccessToken accessToken = accessTokenAuthentication.getAccessToken(); + OAuth2RefreshToken refreshToken = accessTokenAuthentication.getRefreshToken(); + Map additionalParameters = accessTokenAuthentication.getAdditionalParameters(); + + OAuth2AccessTokenResponse.Builder builder =OAuth2AccessTokenResponse.withToken(accessToken.getTokenValue()).tokenType(accessToken.getTokenType()); + if (accessToken.getIssuedAt() != null && accessToken.getExpiresAt() != null) { + builder.expiresIn(ChronoUnit.SECONDS.between(accessToken.getIssuedAt(), accessToken.getExpiresAt())); + } + if (refreshToken != null) { + builder.refreshToken(refreshToken.getTokenValue()); + } + if (!CollectionUtils.isEmpty(additionalParameters)) { + builder.additionalParameters(additionalParameters); + } + OAuth2AccessTokenResponse accessTokenResponse = builder.build(); + + Map tokenResponseParameters = accessTokenResponseParametersConverter.convert(accessTokenResponse); + ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response); + + + this.accessTokenHttpResponseConverter.write(new Result().success(tokenResponseParameters), null, httpResponse); + + } + +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/MyOAuth2TokenJwtCustomizer.java b/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/MyOAuth2TokenJwtCustomizer.java new file mode 100644 index 0000000..efc01c3 --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/MyOAuth2TokenJwtCustomizer.java @@ -0,0 +1,32 @@ +package com.evotech.hd.authorization.config.oauth2; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.core.Authentication; +import org.springframework.security.oauth2.jwt.JwtClaimsSet; +import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext; +import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer; + +import com.evotech.hd.authorization.config.security.userdetail.MyUserDetail; + +/** + * 自定义Token包含的字段信息, + * 通过context拿到authentication和其他信息,然后再拿到Principal(userDetails数据)或者其他 + */ +@Configuration +public class MyOAuth2TokenJwtCustomizer implements OAuth2TokenCustomizer { + + @Override + public void customize(JwtEncodingContext context) { + JwtClaimsSet.Builder claims = context.getClaims(); + System.out.println("自定义token字段"); + Authentication authentication = context.getPrincipal(); + MyUserDetail detail = (MyUserDetail) authentication.getPrincipal(); + claims.claim("uid", detail.getUid()); + claims.claim("rcodes", detail.getRcodes()); + } + + + + + +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/RSAKeyPair.java b/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/RSAKeyPair.java new file mode 100644 index 0000000..12c956c --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/RSAKeyPair.java @@ -0,0 +1,25 @@ +package com.evotech.hd.authorization.config.oauth2; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +public class RSAKeyPair { + + @Value("${security.token.public_key_base64:null}") + private String publicKeyBase64; + + @Value("${security.token.private_key_base64:null}") + private String privateKeyBase64; + + public String getPublicKeyBase64() { + return publicKeyBase64; + } + + public String getPrivateKeyBase64() { + return privateKeyBase64; + } + + + +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/passwordmode/OAuth2AuthenticationProviderUtils.java b/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/passwordmode/OAuth2AuthenticationProviderUtils.java new file mode 100644 index 0000000..9f8742c --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/passwordmode/OAuth2AuthenticationProviderUtils.java @@ -0,0 +1,79 @@ +package com.evotech.hd.authorization.config.oauth2.passwordmode; + +import org.springframework.security.core.Authentication; +import org.springframework.security.oauth2.core.ClaimAccessor; +import org.springframework.security.oauth2.core.OAuth2AccessToken; +import org.springframework.security.oauth2.core.OAuth2AuthenticationException; +import org.springframework.security.oauth2.core.OAuth2ErrorCodes; +import org.springframework.security.oauth2.core.OAuth2RefreshToken; +import org.springframework.security.oauth2.core.OAuth2Token; +import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; +import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationCode; +import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken; +import org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat; +import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenContext; + +public class OAuth2AuthenticationProviderUtils { + + private OAuth2AuthenticationProviderUtils() { + } + + public static OAuth2ClientAuthenticationToken getAuthenticatedClientElseThrowInvalidClient(Authentication authentication) { + OAuth2ClientAuthenticationToken clientPrincipal = null; + if (OAuth2ClientAuthenticationToken.class.isAssignableFrom(authentication.getPrincipal().getClass())) { + clientPrincipal = (OAuth2ClientAuthenticationToken) authentication.getPrincipal(); + } + if (clientPrincipal != null && clientPrincipal.isAuthenticated()) { + return clientPrincipal; + } + throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_CLIENT); + } + + public static OAuth2Authorization invalidate(OAuth2Authorization authorization, T token) { + + // @formatter:off + OAuth2Authorization.Builder authorizationBuilder = OAuth2Authorization.from(authorization) + .token(token, + (metadata) -> + metadata.put(OAuth2Authorization.Token.INVALIDATED_METADATA_NAME, true)); + + if (OAuth2RefreshToken.class.isAssignableFrom(token.getClass())) { + authorizationBuilder.token( + authorization.getAccessToken().getToken(), + (metadata) -> + metadata.put(OAuth2Authorization.Token.INVALIDATED_METADATA_NAME, true)); + + OAuth2Authorization.Token authorizationCode = + authorization.getToken(OAuth2AuthorizationCode.class); + if (authorizationCode != null && !authorizationCode.isInvalidated()) { + authorizationBuilder.token( + authorizationCode.getToken(), + (metadata) -> + metadata.put(OAuth2Authorization.Token.INVALIDATED_METADATA_NAME, true)); + } + } + // @formatter:on + + return authorizationBuilder.build(); + } + + public static OAuth2AccessToken accessToken(OAuth2Authorization.Builder builder, T token, + OAuth2TokenContext accessTokenContext) { + + OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, token.getTokenValue(), + token.getIssuedAt(), token.getExpiresAt(), accessTokenContext.getAuthorizedScopes()); + OAuth2TokenFormat accessTokenFormat = accessTokenContext.getRegisteredClient() + .getTokenSettings() + .getAccessTokenFormat(); + builder.token(accessToken, (metadata) -> { + if (token instanceof ClaimAccessor claimAccessor) { + metadata.put(OAuth2Authorization.Token.CLAIMS_METADATA_NAME, claimAccessor.getClaims()); + } + metadata.put(OAuth2Authorization.Token.INVALIDATED_METADATA_NAME, false); + metadata.put(OAuth2TokenFormat.class.getName(), accessTokenFormat.getValue()); + }); + + return accessToken; + } + +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/passwordmode/OAuth2EndpointUtils.java b/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/passwordmode/OAuth2EndpointUtils.java new file mode 100644 index 0000000..f7372fa --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/passwordmode/OAuth2EndpointUtils.java @@ -0,0 +1,101 @@ +package com.evotech.hd.authorization.config.oauth2.passwordmode; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.security.oauth2.core.OAuth2AuthenticationException; +import org.springframework.security.oauth2.core.OAuth2Error; +import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; +import org.springframework.security.oauth2.core.endpoint.PkceParameterNames; +import org.springframework.util.Assert; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.util.StringUtils; + +import jakarta.servlet.http.HttpServletRequest; + +public class OAuth2EndpointUtils { + + public static final String ACCESS_TOKEN_REQUEST_ERROR_URI = "https://datatracker.ietf.org/doc/html/rfc6749#section-5.2"; + + private OAuth2EndpointUtils() { + } + + public static MultiValueMap getFormParameters(HttpServletRequest request) { + Map parameterMap = request.getParameterMap(); + MultiValueMap parameters = new LinkedMultiValueMap<>(); + parameterMap.forEach((key, values) -> { + String queryString = StringUtils.hasText(request.getQueryString()) ? request.getQueryString() : ""; + // If not query parameter then it's a form parameter + if (!queryString.contains(key) && values.length > 0) { + for (String value : values) { + parameters.add(key, value); + } + } + }); + return parameters; + } + + public static MultiValueMap getQueryParameters(HttpServletRequest request) { + Map parameterMap = request.getParameterMap(); + MultiValueMap parameters = new LinkedMultiValueMap<>(); + parameterMap.forEach((key, values) -> { + String queryString = StringUtils.hasText(request.getQueryString()) ? request.getQueryString() : ""; + if (queryString.contains(key) && values.length > 0) { + for (String value : values) { + parameters.add(key, value); + } + } + }); + return parameters; + } + + public static Map getParametersIfMatchesAuthorizationCodeGrantRequest(HttpServletRequest request, + String... exclusions) { + if (!matchesAuthorizationCodeGrantRequest(request)) { + return Collections.emptyMap(); + } + MultiValueMap multiValueParameters = "GET".equals(request.getMethod()) + ? getQueryParameters(request) : getFormParameters(request); + for (String exclusion : exclusions) { + multiValueParameters.remove(exclusion); + } + + Map parameters = new HashMap<>(); + multiValueParameters.forEach( + (key, value) -> parameters.put(key, (value.size() == 1) ? value.get(0) : value.toArray(new String[0]))); + + return parameters; + } + + public static boolean matchesAuthorizationCodeGrantRequest(HttpServletRequest request) { + return AuthorizationGrantType.AUTHORIZATION_CODE.getValue() + .equals(request.getParameter(OAuth2ParameterNames.GRANT_TYPE)) + && request.getParameter(OAuth2ParameterNames.CODE) != null; + } + + public static boolean matchesPkceTokenRequest(HttpServletRequest request) { + return matchesAuthorizationCodeGrantRequest(request) + && request.getParameter(PkceParameterNames.CODE_VERIFIER) != null; + } + + public static void throwError(String errorCode, String parameterName, String errorUri) { + OAuth2Error error = new OAuth2Error(errorCode, "OAuth 2.0 Parameter: " + parameterName, errorUri); + throw new OAuth2AuthenticationException(error); + } + + public static String normalizeUserCode(String userCode) { + Assert.hasText(userCode, "userCode cannot be empty"); + StringBuilder sb = new StringBuilder(userCode.toUpperCase().replaceAll("[^A-Z\\d]+", "")); + Assert.isTrue(sb.length() == 8, "userCode must be exactly 8 alpha/numeric characters"); + sb.insert(4, '-'); + return sb.toString(); + } + + public static boolean validateUserCode(String userCode) { + return (userCode != null && userCode.toUpperCase().replaceAll("[^A-Z\\d]+", "").length() == 8); + } + +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/passwordmode/OAuth2PasswordAuthenticationConverter.java b/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/passwordmode/OAuth2PasswordAuthenticationConverter.java new file mode 100644 index 0000000..41db04e --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/passwordmode/OAuth2PasswordAuthenticationConverter.java @@ -0,0 +1,82 @@ +package com.evotech.hd.authorization.config.oauth2.passwordmode; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.springframework.lang.Nullable; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.core.OAuth2ErrorCodes; +import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; +import org.springframework.security.web.authentication.AuthenticationConverter; +import org.springframework.util.MultiValueMap; +import org.springframework.util.StringUtils; + +import jakarta.servlet.http.HttpServletRequest; + +/** + * 限定必须要传的参数 + * 只是要这些参数,并没有对参数值校验 + */ +public class OAuth2PasswordAuthenticationConverter implements AuthenticationConverter { + + @Nullable + @Override + public Authentication convert(HttpServletRequest request) { + // 1. 提取表单参数,准备校验用,用的这个方法就是复制的sas自带的 + MultiValueMap parameters = OAuth2EndpointUtils.getFormParameters(request); + // 2. 授权类型参数 (必须) +// String grantType = request.getParameter(OAuth2ParameterNames.GRANT_TYPE); + String grantType = parameters.getFirst(OAuth2ParameterNames.GRANT_TYPE); + if (!OAuth2PasswordAuthenticationToken.PASSWORD.getValue().equals(grantType)) { + return null; + } + // 3. 令牌申请访问范围参数 (可选) + String scope = parameters.getFirst(OAuth2ParameterNames.SCOPE); + if (StringUtils.hasText(scope) && parameters.get(OAuth2ParameterNames.SCOPE).size() != 1) { + OAuth2EndpointUtils.throwError( + OAuth2ErrorCodes.INVALID_REQUEST, + OAuth2ParameterNames.SCOPE, + OAuth2EndpointUtils.ACCESS_TOKEN_REQUEST_ERROR_URI); + } + + Set requestedScopes = null; + if (StringUtils.hasText(scope)) { + requestedScopes = new HashSet<>(Arrays.asList(StringUtils.delimitedListToStringArray(scope, " "))); + } + // 4. 账号密码参数校验 + // 4.1 用户名参数 (必须) + String username = parameters.getFirst(OAuth2ParameterNames.USERNAME); + if (!StringUtils.hasText(username) || parameters.get(OAuth2ParameterNames.USERNAME).size() != 1) { + OAuth2EndpointUtils.throwError( + OAuth2ErrorCodes.INVALID_REQUEST, + OAuth2ParameterNames.USERNAME, + OAuth2EndpointUtils.ACCESS_TOKEN_REQUEST_ERROR_URI); + } + + // 4.2 密码参数 (必须) + String password = parameters.getFirst(OAuth2ParameterNames.PASSWORD); + if (!StringUtils.hasText(password) || parameters.get(OAuth2ParameterNames.PASSWORD).size() != 1) { + OAuth2EndpointUtils.throwError( + OAuth2ErrorCodes.INVALID_REQUEST, + OAuth2ParameterNames.PASSWORD, + OAuth2EndpointUtils.ACCESS_TOKEN_REQUEST_ERROR_URI); + } + + // 5. 客户端凭据信息,在header 中填写的那个 + Authentication clientPrincipal = SecurityContextHolder.getContext().getAuthentication(); + + // 6. 参数封装成additionalParameters放到OAuth2PasswordAuthenticationToken中传给 PasswordAuthenticationProvider 用于验证值 + Map additionalParameters = new HashMap<>(); + parameters.forEach((key, value) -> { + if (!key.equals(OAuth2ParameterNames.GRANT_TYPE) && !key.equals(OAuth2ParameterNames.SCOPE)) { + additionalParameters.put(key, value.get(0)); + } + }); + return new OAuth2PasswordAuthenticationToken(clientPrincipal, requestedScopes, additionalParameters); + } + +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/passwordmode/OAuth2PasswordAuthenticationProvider.java b/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/passwordmode/OAuth2PasswordAuthenticationProvider.java new file mode 100644 index 0000000..9e25343 --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/passwordmode/OAuth2PasswordAuthenticationProvider.java @@ -0,0 +1,186 @@ +package com.evotech.hd.authorization.config.oauth2.passwordmode; + +import java.security.Principal; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.security.oauth2.core.ClaimAccessor; +import org.springframework.security.oauth2.core.ClientAuthenticationMethod; +import org.springframework.security.oauth2.core.OAuth2AccessToken; +import org.springframework.security.oauth2.core.OAuth2AuthenticationException; +import org.springframework.security.oauth2.core.OAuth2Error; +import org.springframework.security.oauth2.core.OAuth2ErrorCodes; +import org.springframework.security.oauth2.core.OAuth2RefreshToken; +import org.springframework.security.oauth2.core.OAuth2Token; +import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; +import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; +import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; +import org.springframework.security.oauth2.server.authorization.OAuth2TokenType; +import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AccessTokenAuthenticationToken; +import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken; +import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; +import org.springframework.security.oauth2.server.authorization.context.AuthorizationServerContextHolder; +import org.springframework.security.oauth2.server.authorization.token.DefaultOAuth2TokenContext; +import org.springframework.security.oauth2.server.authorization.token.DefaultOAuth2TokenContext.Builder; +import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator; +import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; + +import jakarta.annotation.Resource; + +/** + * 参考授权码(主要)"OAuth2AuthorizationCodeAuthenticationProvider"和客户端"OAuth2ClientCredentialsAuthenticationProvider" + */ +public class OAuth2PasswordAuthenticationProvider implements AuthenticationProvider { + + @Resource + private PasswordEncoder passwordEncoder; + + // 这部分代码和OAuth2ClientCredentialsAuthenticationProvider类似,只是添加了AuthenticationManager + private static final String ERROR_URI = "https://datatracker.ietf.org/doc/html/rfc6749#section-5.2"; + + private final AuthenticationManager authenticationManager; + private final OAuth2AuthorizationService authorizationService; + private final OAuth2TokenGenerator tokenGenerator; + + + public OAuth2PasswordAuthenticationProvider(AuthenticationManager authenticationManager, + OAuth2AuthorizationService authorizationService, + OAuth2TokenGenerator tokenGenerator) { + + Assert.notNull(authorizationService, "authorizationService cannot be null"); + Assert.notNull(tokenGenerator, "tokenGenerator cannot be null"); + this.authenticationManager = authenticationManager; + this.authorizationService = authorizationService; + this.tokenGenerator = tokenGenerator; + } + + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + +// PasswordAuthenticationToken + OAuth2PasswordAuthenticationToken passwordAuthenticationToken = (OAuth2PasswordAuthenticationToken) authentication; + + // coverter中最后生成的token,包含3部分内容,在这里拿出来,下面用 + Map additionalParameters = passwordAuthenticationToken.getAdditionalParameters(); + OAuth2ClientAuthenticationToken clientPrincipal = OAuth2AuthenticationProviderUtils.getAuthenticatedClientElseThrowInvalidClient(passwordAuthenticationToken); + RegisteredClient registeredClient = clientPrincipal.getRegisteredClient(); + + // 1. 验证客户端是否支持密码模式类型(grant_type=password) + if (!registeredClient.getAuthorizationGrantTypes().contains(passwordAuthenticationToken.getGrantType())) { + throw new OAuth2AuthenticationException(OAuth2ErrorCodes.UNSUPPORTED_GRANT_TYPE); + } + // 2. 校验范围scope + Set authorizedScopes = registeredClient.getScopes(); + Set requestedScopes = passwordAuthenticationToken.getScopes(); + if (!CollectionUtils.isEmpty(requestedScopes )) { + Set unauthorizedScopes = requestedScopes.stream() + .filter(scope -> !registeredClient.getScopes().contains(scope)) + .collect(Collectors.toSet()); + if (!CollectionUtils.isEmpty(unauthorizedScopes)) { + throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_SCOPE); + } + authorizedScopes = new LinkedHashSet<>(requestedScopes); + } + // 3 用户名密码校验 + String username = (String) additionalParameters.get(OAuth2ParameterNames.USERNAME); + String password = (String) additionalParameters.get(OAuth2ParameterNames.PASSWORD); + // 我们不自己校验了,用oauth2的方法校验 +// MyUserDetail userDetail = userDetailsService.loadUserByUsername(username); +// if (userDetail == null) { +// throw new OAuth2AuthenticationException("用户不存在!"); +// } +// if (!passwordEncoder.matches(password, userDetail.getPassword())) { +// throw new OAuth2AuthenticationException("密码不正确!"); +// } + + UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(username, password); + Authentication usernamePasswordAuthentication = null; + try { + usernamePasswordAuthentication = authenticationManager.authenticate(usernamePasswordAuthenticationToken); + } catch (AuthenticationException e) { + e.printStackTrace(); + throw new OAuth2AuthenticationException("账号或密码错误"); + } + // 处理userDetails的时候,我们没有添加权限信息,这拿不到数据 +// Collection authorities = usernamePasswordAuthentication.getAuthorities(); +// for (GrantedAuthority authoriti : authorities) { +// } + + // 4. 生成token + // 4.1 填充token需要的上下文数据,按照授权码模式来的 + Builder tokenContextBuilder = DefaultOAuth2TokenContext.builder() + .registeredClient(registeredClient) + // 身份验证成功的认证信息(用户名、权限等信息) + .principal(usernamePasswordAuthentication) + .authorizationServerContext(AuthorizationServerContextHolder.getContext()) + .authorizedScopes(authorizedScopes) + // 授权类型 + .authorizationGrantType(passwordAuthenticationToken.getGrantType()) + // 授权具体对象 + .authorizationGrant(passwordAuthenticationToken) + ; + // 4.2 生成访问令牌(Access Token) + DefaultOAuth2TokenContext tokenContext = tokenContextBuilder.tokenType(OAuth2TokenType.ACCESS_TOKEN).build(); + OAuth2Token generatedAccessToken = this.tokenGenerator.generate(tokenContext); + if (generatedAccessToken == null) { + OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.SERVER_ERROR, + "The token generator failed to generate the access token.", ERROR_URI); + throw new OAuth2AuthenticationException(error); + } + OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, + generatedAccessToken.getTokenValue(), generatedAccessToken.getIssuedAt(), + generatedAccessToken.getExpiresAt(), tokenContext.getAuthorizedScopes()); + + // 4. 生成刷新令牌(Refresh Token) + OAuth2RefreshToken refreshToken = null; + if (registeredClient.getAuthorizationGrantTypes().contains(AuthorizationGrantType.REFRESH_TOKEN) && + // Do not issue refresh token to public client + !clientPrincipal.getClientAuthenticationMethod().equals(ClientAuthenticationMethod.NONE)) { + tokenContext = tokenContextBuilder.tokenType(OAuth2TokenType.REFRESH_TOKEN).build(); + OAuth2Token generatedRefreshToken = this.tokenGenerator.generate(tokenContext); + if (!(generatedRefreshToken instanceof OAuth2RefreshToken)) { + OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.SERVER_ERROR, + "The token generator failed to generate the refresh token.", ERROR_URI); + throw new OAuth2AuthenticationException(error); + } + refreshToken = (OAuth2RefreshToken) generatedRefreshToken; + } + + + // 5. 组装数据入库 + OAuth2Authorization.Builder authorizationBuilder = OAuth2Authorization.withRegisteredClient(registeredClient) + .principalName(clientPrincipal.getName()) + .authorizationGrantType(passwordAuthenticationToken.getGrantType()) + .authorizedScopes(authorizedScopes) + .attribute(Principal.class.getName(), usernamePasswordAuthentication); + if (generatedAccessToken instanceof ClaimAccessor) { + authorizationBuilder.token(accessToken, (metadata) -> metadata.put(OAuth2Authorization.Token.CLAIMS_METADATA_NAME, ((ClaimAccessor) generatedAccessToken).getClaims())); + } else { + authorizationBuilder.accessToken(accessToken); + authorizationBuilder.refreshToken(refreshToken); + } + OAuth2Authorization authorization = authorizationBuilder.build(); + // 入库 + this.authorizationService.save(authorization); + additionalParameters = Collections.emptyMap(); + + return new OAuth2AccessTokenAuthenticationToken(registeredClient, clientPrincipal, accessToken, refreshToken, additionalParameters); + } + + @Override + public boolean supports(Class authentication) { + return OAuth2PasswordAuthenticationToken.class.isAssignableFrom(authentication); + } + +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/passwordmode/OAuth2PasswordAuthenticationToken.java b/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/passwordmode/OAuth2PasswordAuthenticationToken.java new file mode 100644 index 0000000..5e5009d --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/config/oauth2/passwordmode/OAuth2PasswordAuthenticationToken.java @@ -0,0 +1,55 @@ +package com.evotech.hd.authorization.config.oauth2.passwordmode; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.springframework.lang.Nullable; +import org.springframework.security.core.Authentication; +import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; +import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationGrantAuthenticationToken; + + +/** + * 这个token就是传递数据用的一个实体,想要什么数据可以写成变量 + * 在converter生成时赋值,在provider中拿出来用 + */ +public class OAuth2PasswordAuthenticationToken extends OAuth2AuthorizationGrantAuthenticationToken { + + private static final long serialVersionUID = -7029686994815546552L; + + public static final AuthorizationGrantType PASSWORD = new AuthorizationGrantType("password"); + + private final Set scopes; + + /** + * 密码模式身份验证令牌 + * + * @param clientPrincipal 客户端信息 + * @param scopes 令牌申请访问范围 + * @param additionalParameters 自定义额外参数(用户名和密码等) + */ + protected OAuth2PasswordAuthenticationToken(Authentication clientPrincipal, @Nullable Set scopes, + @Nullable Map additionalParameters) { + super(PASSWORD, clientPrincipal, additionalParameters); + this.scopes = Collections.unmodifiableSet((scopes != null) ? new HashSet<>(scopes) : Collections.emptySet()); + } + + + /** + * 这个方法 父类中直接返回了空字符串, + * 我们可以根据自己的需要重写,可以返回密码 + */ + @Override + public Object getCredentials() { + return this.getAdditionalParameters().get(OAuth2ParameterNames.PASSWORD); + } + + + public Set getScopes() { + return this.scopes; + } + +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/config/security/MyAccessDeniedHandler.java b/authorization-server/src/main/java/com/evotech/hd/authorization/config/security/MyAccessDeniedHandler.java new file mode 100644 index 0000000..00be4da --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/config/security/MyAccessDeniedHandler.java @@ -0,0 +1,36 @@ +package com.evotech.hd.authorization.config.security; + +import java.io.IOException; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.http.server.ServletServerHttpResponse; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.web.access.AccessDeniedHandler; + +import com.evotech.hd.common.core.entity.Result; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +/** + * 登陆了,没有权限时,触发异常 返回信息 + */ +public class MyAccessDeniedHandler implements AccessDeniedHandler { + + private final HttpMessageConverter httpResponseConverter = new MappingJackson2HttpMessageConverter(); + + @Override + public void handle(HttpServletRequest request, HttpServletResponse response, + AccessDeniedException accessDeniedException) throws IOException, ServletException { + System.out.println("=====无权限的异常处理"); + ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response); + + Result res = new Result().error(accessDeniedException.getLocalizedMessage()); + + + httpResponseConverter.write(res, null, httpResponse); + + } + +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/config/security/MyAuthenticationEntryPoint.java b/authorization-server/src/main/java/com/evotech/hd/authorization/config/security/MyAuthenticationEntryPoint.java new file mode 100644 index 0000000..6b8b602 --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/config/security/MyAuthenticationEntryPoint.java @@ -0,0 +1,40 @@ +package com.evotech.hd.authorization.config.security; + +import java.io.IOException; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.http.server.ServletServerHttpResponse; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.oauth2.server.resource.InvalidBearerTokenException; +import org.springframework.security.web.AuthenticationEntryPoint; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.enums.CodeMsg; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +/** + * 未认证(没有登录)时,返回异常 信息 + */ +public class MyAuthenticationEntryPoint implements AuthenticationEntryPoint { + + private final HttpMessageConverter httpResponseConverter = new MappingJackson2HttpMessageConverter(); + + @Override + public void commence(HttpServletRequest request, HttpServletResponse response, + AuthenticationException authException) throws IOException, ServletException { + if (authException instanceof InvalidBearerTokenException) { + System.out.println(authException.getMessage()); + } + authException.printStackTrace(); + ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response); + + Result res = new Result().error(CodeMsg.AUTHENTICATION_FAILED); + + httpResponseConverter.write(res, null, httpResponse); + + } + +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/config/security/WebSecutiryConfig.java b/authorization-server/src/main/java/com/evotech/hd/authorization/config/security/WebSecutiryConfig.java new file mode 100644 index 0000000..5c4dbac --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/config/security/WebSecutiryConfig.java @@ -0,0 +1,104 @@ +package com.evotech.hd.authorization.config.security; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.security.config.Customizer; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; + +import com.evotech.hd.authorization.config.security.userdetail.UserDetailService; + +@Configuration +public class WebSecutiryConfig { + + + @Bean + UserDetailsService userDetailsService() { + UserDetailService userDetail = new UserDetailService(); + return userDetail; + } + + + @Bean + PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + + /** + * Spring Security 安全过滤器链配置 + */ + @Bean + @Order(1) + SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception { + + // 1. 开启认证,提前排除 不需要认证的 + http.authorizeHttpRequests(authorize -> { + authorize + // 路径不用加context-path + .requestMatchers("/oauth2/**").permitAll() + // 登陆图形验证码 + .requestMatchers("/captcha/**").permitAll() + // 登陆 + .requestMatchers("/login/**").permitAll() + .anyRequest().authenticated(); + }) + + + + ; + // 2. 登陆方式:默认是使用security提供表单的登陆页面和方式,我们这里关闭 + http.formLogin(Customizer.withDefaults()); +// http.formLogin(AbstractHttpConfigurer::disable); + + // 3. 登出配置 +// http.logout(logout -> logout.logoutSuccessHandler(new MyLogoutSuccessHandler())); + + // 4. security异常错误配置 + http.exceptionHandling(exception -> { + // 未认证时 访问接口,返回错误 + exception.authenticationEntryPoint(new MyAuthenticationEntryPoint()); + // 未授权时,返回错误,一般资源服务器 才会用到这个 + exception.accessDeniedHandler(new MyAccessDeniedHandler()); + }); + + + + + + // 5. csrf是默认开启的,此时对于post请求,会需要一个"_csrf"的隐藏字段传递,为了前端方便,这个关了 + http.csrf(csrf -> csrf.disable()); + + // 6. 跨域处理 + http.cors(Customizer.withDefaults()); + + // 7. session管理,设置同一个账号只能登陆一次.单体服务这个管用,微服务 不能用 +// http.sessionManagement(session -> session.maximumSessions(1).expiredSessionStrategy(new MySessionInformationExpiredStrategy())); + + return http.build(); + } + + /** + * Spring Security 排除路径 + */ + @Bean + WebSecurityCustomizer webSecurityCustomizer() { + return (web) -> + // 不走过滤器链(swagger和静态资源js、css、html) + web.ignoring().requestMatchers( + "/webjars/**", + "/doc.html", + "/swagger-resources/**", + "/v3/api-docs/**", + "/swagger-ui/**", + // admin监控 + "/actuator/**", + "/instances/**" + ); + } + +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/config/security/userdetail/MyUserDetail.java b/authorization-server/src/main/java/com/evotech/hd/authorization/config/security/userdetail/MyUserDetail.java new file mode 100644 index 0000000..85ff00e --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/config/security/userdetail/MyUserDetail.java @@ -0,0 +1,52 @@ +package com.evotech.hd.authorization.config.security.userdetail; + +import java.util.Collection; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import com.evotech.hd.common.core.entity.resource.auth.AuthUser; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = false) +public class MyUserDetail extends AuthUser implements UserDetails { + + private static final long serialVersionUID = 786868339462173799L; + + @Override + public Collection getAuthorities() { + + return null; + } + + @Override + public String getUsername() { + return this.getUname(); + } + + @Override + public boolean isAccountNonExpired() { + return UserDetails.super.isAccountNonExpired(); + } + + @Override + public boolean isAccountNonLocked() { + return UserDetails.super.isAccountNonLocked(); + } + + @Override + public boolean isCredentialsNonExpired() { + return UserDetails.super.isCredentialsNonExpired(); + } + + @Override + public boolean isEnabled() { + return this.getStatus() == 1; + } + + + +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/config/security/userdetail/UserDetailService.java b/authorization-server/src/main/java/com/evotech/hd/authorization/config/security/userdetail/UserDetailService.java new file mode 100644 index 0000000..5d0e419 --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/config/security/userdetail/UserDetailService.java @@ -0,0 +1,38 @@ +package com.evotech.hd.authorization.config.security.userdetail; + +import org.springframework.security.authentication.DisabledException; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import com.evotech.hd.authorization.service.ResourceService; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.auth.AuthUser; +import com.evotech.hd.common.core.enums.CodeMsg; + +import cn.hutool.core.bean.BeanUtil; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class UserDetailService implements UserDetailsService { + + @Resource + private ResourceService resourceService; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + Result result = resourceService.loadUserByName(username); + if(!CodeMsg.SUCCESS.getCode().equals(result.getCode())) { + throw new UsernameNotFoundException("账号或密码错误!"); + } + AuthUser user = BeanUtil.toBean(result.getData(), AuthUser.class) ; + MyUserDetail userDetail = new MyUserDetail(); + BeanUtil.copyProperties(user, userDetail, false); + if (!userDetail.isEnabled()) { + throw new DisabledException("账号状态异常!"); + } + + return userDetail; + } + +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/controller/CaptchaController.java b/authorization-server/src/main/java/com/evotech/hd/authorization/controller/CaptchaController.java new file mode 100644 index 0000000..1d324d0 --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/controller/CaptchaController.java @@ -0,0 +1,36 @@ +package com.evotech.hd.authorization.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.authorization.service.CaptchaService; +import com.evotech.hd.common.core.entity.Result; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; + +@Tag(name = "验证码") +@RestController +@RequestMapping("/captcha") +public class CaptchaController { + + @Resource + private CaptchaService captchaService; + + + @Operation(summary = "获取") + @GetMapping("/get") + public Result getCaptcha() { + return captchaService.getCaptcha(); + } + + @Operation(summary = "校验", description = "code格式 -- captchaId:code") + @PostMapping("/check") + public Result checkCaptcha(String code) { + return captchaService.checkCaptcha(code); + } + +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/controller/LoginController.java b/authorization-server/src/main/java/com/evotech/hd/authorization/controller/LoginController.java new file mode 100644 index 0000000..c4f907a --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/controller/LoginController.java @@ -0,0 +1,56 @@ +package com.evotech.hd.authorization.controller; + +import org.apache.http.auth.AuthenticationException; +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.authorization.entity.LoginRequest; +import com.evotech.hd.authorization.entity.UserVo; +import com.evotech.hd.authorization.service.LoginService; +import com.evotech.hd.common.core.entity.Result; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; + +@Tag(name = "登陆") +@RestController +@RequestMapping("/login") +public class LoginController { + + @Resource + private LoginService loginService; + + @Operation(summary = "登陆") + @PostMapping("/oauthlogin") + @Parameters( + + ) + @Parameter(name="Authorization", example = "Basic eXRoZDpZVEhEMTIz") + public Result oauthLogin(@RequestHeader String Authorization, @Valid @ParameterObject LoginRequest lr, HttpServletRequest request) throws AuthenticationException { + return loginService.oauthLogin(lr, request); + } + + @Operation(summary = "登出") + @DeleteMapping("/oauthlogout") + public Result AuthLogout(HttpServletRequest request) { + return loginService.logout(request); + } + + + @Operation(summary = "检验token") + @PostMapping("/checktoken") + public Result checkToken(String token) throws AuthenticationException { + return loginService.checkToken(token); + } + + +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/entity/LoginRequest.java b/authorization-server/src/main/java/com/evotech/hd/authorization/entity/LoginRequest.java new file mode 100644 index 0000000..c1423ed --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/entity/LoginRequest.java @@ -0,0 +1,25 @@ +package com.evotech.hd.authorization.entity; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +@Data +public class LoginRequest { + + @Schema(description = "账号", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "账号不能为空") + private String username; + + @Schema(description = "密码", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "密码不能为空") + private String password; + + @Schema(description = "验证码", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "验证码不能为空") + private String code; + + + +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/entity/UserVo.java b/authorization-server/src/main/java/com/evotech/hd/authorization/entity/UserVo.java new file mode 100644 index 0000000..1aae704 --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/entity/UserVo.java @@ -0,0 +1,55 @@ +package com.evotech.hd.authorization.entity; + +import java.io.Serializable; +import java.util.List; + +import com.evotech.hd.authorization.config.oauth2.MyAccessToken; +import com.evotech.hd.common.core.entity.resource.auth.AuthRole; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import lombok.Data; + +@Data +@Schema(name = "登陆时返回前端的对象") +@ApiResponse +public class UserVo implements Serializable { + + private static final long serialVersionUID = 1L; + + private String uid; + + @Schema(name = "账号") + private String uname; + + @Schema(name = "姓名") + private String name; + + @Schema(description = "账号类型:1-开发者,2-运营方,3-客户") + private Integer type; + + @Schema(description = "关联方代码") + private String typeRelateCode; + + @Schema(name = "邮箱") + private String email; + + @Schema(name = "手机") + private String mobile; + + @Schema(name = "性别") + private String sex; + + @Schema(name = "头像") + private String avatar; + + @Schema(name = "token") + private MyAccessToken token; + + @Schema(name = "角色") + List roleList; + + @Schema(name = "权限") + List permCodeList; + +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/service/CaptchaService.java b/authorization-server/src/main/java/com/evotech/hd/authorization/service/CaptchaService.java new file mode 100644 index 0000000..997c758 --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/service/CaptchaService.java @@ -0,0 +1,11 @@ +package com.evotech.hd.authorization.service; + +import com.evotech.hd.common.core.entity.Result; + +public interface CaptchaService { + + public Result getCaptcha(); + + public Result checkCaptcha(String code); + +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/service/LoginService.java b/authorization-server/src/main/java/com/evotech/hd/authorization/service/LoginService.java new file mode 100644 index 0000000..3846870 --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/service/LoginService.java @@ -0,0 +1,17 @@ +package com.evotech.hd.authorization.service; + +import org.apache.http.auth.AuthenticationException; + +import com.evotech.hd.authorization.entity.LoginRequest; +import com.evotech.hd.authorization.entity.UserVo; +import com.evotech.hd.common.core.entity.Result; +import jakarta.servlet.http.HttpServletRequest; + +public interface LoginService { + + public Result oauthLogin(LoginRequest lr, HttpServletRequest request) throws AuthenticationException; + + public Result logout(HttpServletRequest request); + + public Result checkToken(String token) throws AuthenticationException; +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/service/ResourceService.java b/authorization-server/src/main/java/com/evotech/hd/authorization/service/ResourceService.java new file mode 100644 index 0000000..5b3ca20 --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/service/ResourceService.java @@ -0,0 +1,36 @@ +package com.evotech.hd.authorization.service; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; + +import com.evotech.hd.common.core.entity.LoginCacheInfo; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.LogLogin; +import com.evotech.hd.common.core.entity.resource.auth.AuthUser; + +import jakarta.validation.constraints.NotNull; + +@FeignClient(value = "resource-server") +public interface ResourceService { + + + @GetMapping(value = "/resource/user/userbyname", + consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE}) + public Result loadUserByName(@RequestParam("uname") String userName); + + @PostMapping(value = "/resource/user/userpermbyid", + consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE}) + public Result userPermById(@NotNull @RequestParam("uid") String userId, @RequestParam("type")Integer type); + + @PostMapping(value = "/resource/loginlog/add", + consumes = {MediaType.APPLICATION_JSON_VALUE}) + public Result addLoginLog(@RequestBody LogLogin log); + + @GetMapping(value = "/resource/logininfo/get", + consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE}) + public Result loginInfo(@RequestParam("uid") String uid); +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/service/impl/CaptchaServiceImpl.java b/authorization-server/src/main/java/com/evotech/hd/authorization/service/impl/CaptchaServiceImpl.java new file mode 100644 index 0000000..0d772ba --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/service/impl/CaptchaServiceImpl.java @@ -0,0 +1,55 @@ +package com.evotech.hd.authorization.service.impl; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import com.evotech.hd.authorization.service.CaptchaService; +import com.evotech.hd.common.core.constant.HDConstant; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.redis.utils.RedisUtil; + +import cn.hutool.captcha.CaptchaUtil; +import cn.hutool.captcha.LineCaptcha; +import cn.hutool.captcha.generator.RandomGenerator; +import cn.hutool.core.util.IdUtil; +import jakarta.annotation.Resource; + +@Service +public class CaptchaServiceImpl implements CaptchaService { + + @Resource + private RedisUtil redisUtil; + @Value("${yt.captcha.expire:300}") + private Integer captchaExpire; + + @Override + public Result getCaptcha() { + RandomGenerator randomGenerator = new RandomGenerator("0123456789", 4); + LineCaptcha captcha = CaptchaUtil.createLineCaptcha(200, 100, 4, 30); + captcha.setGenerator(randomGenerator); + captcha.createCode(); + String code = captcha.getCode(); + String imageBase64Data = captcha.getImageBase64Data(); + String captchaId = IdUtil.fastSimpleUUID(); + redisUtil.set(HDConstant.CAPTCHA_REDIS_PREFIX + captchaId, code, captchaExpire); + return new Result().success("OK", captchaId + ":" + imageBase64Data); + } + + @Override + public Result checkCaptcha(String code) { + String[] codeArr = code.split(":"); + if (codeArr.length != 2) { + return new Result().error("验证码格式错误!"); + } + String captchaId = codeArr[0]; + code = codeArr[1]; + if (!redisUtil.hasKey(HDConstant.CAPTCHA_REDIS_PREFIX + captchaId)) { + return new Result().error("验证码错误或已过期"); + } + if (code.equals(redisUtil.get(HDConstant.CAPTCHA_REDIS_PREFIX + captchaId).toString())) { + return new Result().success(true); + } + return new Result().error("验证码错误!"); + } + +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/service/impl/LoginServiceImpl.java b/authorization-server/src/main/java/com/evotech/hd/authorization/service/impl/LoginServiceImpl.java new file mode 100644 index 0000000..13b7cbd --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/service/impl/LoginServiceImpl.java @@ -0,0 +1,203 @@ +package com.evotech.hd.authorization.service.impl; + +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.apache.http.auth.AuthenticationException; +import org.springframework.beans.BeanUtils; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import com.evotech.hd.authorization.config.oauth2.MyAccessToken; +import com.evotech.hd.authorization.entity.LoginRequest; +import com.evotech.hd.authorization.entity.UserVo; +import com.evotech.hd.authorization.service.ResourceService; +import com.evotech.hd.authorization.service.CaptchaService; +import com.evotech.hd.authorization.service.LoginService; +import com.evotech.hd.authorization.utils.LoginRequesHeadertUtil; +import com.evotech.hd.authorization.utils.Oauth2AccessTokenUtil; +import com.evotech.hd.authorization.utils.TokenUtil; +import com.evotech.hd.common.core.constant.HDConstant; +import com.evotech.hd.common.core.entity.LoginCacheInfo; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.LogLogin; +import com.evotech.hd.common.core.entity.resource.auth.AuthPermission; +import com.evotech.hd.common.core.entity.resource.auth.AuthRole; +import com.evotech.hd.common.core.entity.resource.auth.AuthUser; +import com.evotech.hd.common.core.enums.CodeMsg; +import com.evotech.hd.common.redis.utils.RedisUtil; +import com.evotech.hd.common.web.util.IpUtil; +import cn.hutool.http.useragent.UserAgent; +import cn.hutool.http.useragent.UserAgentUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; + +@Service +public class LoginServiceImpl implements LoginService { + + public static final Long DEFAULT_TOKEN_EXPIRATION = 7200L; + public static final String TOKEN_END_POINT = "/oauth2/token"; + + @Resource + private CaptchaService captchaService; + @Resource + private ResourceService resourceService; + @Resource + private RedisUtil redisUtil; + @Resource + private Environment env; + + + + @Override + public Result oauthLogin(LoginRequest lr, HttpServletRequest request) throws AuthenticationException { + // 1. 校验验证码 + Result res = captchaService.checkCaptcha(lr.getCode()); + if (res.getStatus() != 1) { + return new Result().error(res.getCode(), res.getMsg()); + } + // 2. 从请求头获取client信息 + Map oAuth2Client = LoginRequesHeadertUtil.getOAuth2Client(request); + if (oAuth2Client == null) { + return new Result().error("无客户端Client信息!"); + } + // 3. 获取token + String url = getTokenUrl(); + MyAccessToken token = Oauth2AccessTokenUtil.getToken(url, oAuth2Client.get("clientId"), oAuth2Client.get("clientSecret"), lr.getUsername(), lr.getPassword()); + + // 4.添加缓存 + UserVo uv = new UserVo(); + uv.setToken(token); + uv = addRedisCache(uv); + // 5. 添加登录记录 + Boolean loginLogFlag = true; + if (loginLogFlag) { + try { + writeLoginLog(request, uv); + } catch (Exception e) { + e.printStackTrace(); + } + } + + return new Result().success(uv); + } + + /** + * 拼接获取token的地址 + */ + private String getTokenUrl() { + int port = env.getProperty("server.port", Integer.class) == null?8080:env.getProperty("server.port", Integer.class); + String url = "http://127.0.0.1" + ":" + port; + String path = env.getProperty("server.servlet.context-path"); + url = StringUtils.hasText(path) ? url + path : url; + url = url + TOKEN_END_POINT; + return url; + } + + + private void writeLoginLog(HttpServletRequest request, UserVo uv) { + LogLogin loginLog = new LogLogin(); + Date d = new Date(); + loginLog.setUid(uv.getUid()); + loginLog.setUname(uv.getUname()); + loginLog.setName(uv.getName()); + loginLog.setLoginTime(d); + loginLog.setCtime(d); + loginLog.setRequestIp(IpUtil.getRemoteIP(request)); + String uaStr = request.getHeader("User-Agent"); + UserAgent ua = UserAgentUtil.parse(uaStr); + loginLog.setUa(uaStr); + loginLog.setBrowser(ua.getBrowser().toString()); + loginLog.setBrowserVersion(ua.getVersion()); + loginLog.setOperatingSystem(ua.getOs().toString()); + loginLog.setPlatForm(ua.getPlatform().toString()); + loginLog.setCreater("SYSTEM"); + resourceService.addLoginLog(loginLog); + } + + + /** + * 登陆缓存内容暂定 + * key: + * hd:login:jti:token + * hd:login:jti:user + * hd:login:jti:rcodes + * hd:login:jti:perms + * + */ + private UserVo addRedisCache(UserVo uv) { + String token = uv.getToken().getAccessToken(); + String uid = TokenUtil.getUserId(token); + + // 1. 请求数据 + Result res = resourceService.loginInfo(uid); + if (!CodeMsg.SUCCESS.getCode().equals(res.getCode())) { + throw new RuntimeException(res.getMsg()); + } + + // 2. 处理数据 + String jti = TokenUtil.getJti(token); + Object o = redisUtil.get(HDConstant.HD_CACHE_TOKEN_EXP_KEY); + Long tokenExp = o == null ? DEFAULT_TOKEN_EXPIRATION : Long.valueOf(o.toString()); + redisUtil.set(HDConstant.LOGIN_CACHE_KEY_PREFIX + jti + ":token", token, tokenExp); + + JSONObject jo = JSONUtil.parseObj(res.getData()); + AuthUser user = JSONUtil.toBean(jo.getJSONObject("user"), AuthUser.class); + BeanUtils.copyProperties(user, uv); + redisUtil.set(HDConstant.LOGIN_CACHE_KEY_PREFIX + jti + ":user", user, tokenExp); + + List roleList = JSONUtil.toList(jo.getJSONArray("roleList"), AuthRole.class); + uv.setRoleList(roleList); + String rcodes = roleList.stream().map(i -> i.getRcode()).collect(Collectors.joining(",")); + redisUtil.set(HDConstant.LOGIN_CACHE_KEY_PREFIX + jti + ":rcodes", rcodes, tokenExp); + + List rcodeList = roleList.stream().map(i -> i.getRcode()).toList(); + if (!rcodeList.contains(HDConstant.SYSTEM_MANAGER_ROLE_CODE)) { + List permissionList = JSONUtil.toList(jo.getJSONArray("permissionList"), AuthPermission.class); + List permUriList = permissionList.stream().map(i -> i.getUri()).toList(); + List permCodeList = permissionList.stream().map(i -> i.getCode()).toList(); + uv.setPermCodeList(permCodeList); + redisUtil.lSet(HDConstant.LOGIN_CACHE_KEY_PREFIX + jti + ":perms", permUriList.toArray(new String[permUriList.size()]), tokenExp); + } + + return uv; + } + + + + @Override + public Result logout(HttpServletRequest request) { + String authorization = request.getHeader(HDConstant.AUTHORIZATION_KEY); + if (authorization != null && authorization.contains(HDConstant.JWT_PREFIX)) { + String token = authorization.substring(HDConstant.JWT_PREFIX.length()); + String jti = TokenUtil.getJti(token); + redisUtil.del(HDConstant.LOGIN_CACHE_KEY_PREFIX + jti + ":token"); + redisUtil.del(HDConstant.LOGIN_CACHE_KEY_PREFIX + jti + ":user"); + redisUtil.del(HDConstant.LOGIN_CACHE_KEY_PREFIX + jti + ":rcodes"); + if (redisUtil.hasKey(HDConstant.LOGIN_CACHE_KEY_PREFIX + jti + ":perms")) { + redisUtil.del(HDConstant.LOGIN_CACHE_KEY_PREFIX + jti + ":perms"); + } + return new Result().success("退出成功"); + } else { + return new Result().error("无token"); + } + } + + + @Override + public Result checkToken(String token) throws AuthenticationException { + // TODO 发送到自带的token验证接口 验证 + + + return new Result().success(true); + } + + + + +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/utils/LoginRequesHeadertUtil.java b/authorization-server/src/main/java/com/evotech/hd/authorization/utils/LoginRequesHeadertUtil.java new file mode 100644 index 0000000..b046480 --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/utils/LoginRequesHeadertUtil.java @@ -0,0 +1,33 @@ +package com.evotech.hd.authorization.utils; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.HashMap; +import java.util.Map; + +import org.apache.logging.log4j.util.Strings; + +import com.evotech.hd.common.core.constant.HDConstant; + +import cn.hutool.core.util.StrUtil; +import jakarta.servlet.http.HttpServletRequest; + +public class LoginRequesHeadertUtil { + + + public static Map getOAuth2Client(HttpServletRequest request) { + // 从请求头获取 + String basic = request.getHeader(HDConstant.AUTHORIZATION_KEY); + if (StrUtil.isBlank(basic) || !basic.startsWith(HDConstant.BASIC_PREFIX)) { + return null; + } + basic = basic.replace(HDConstant.BASIC_PREFIX, Strings.EMPTY); + //client:secret + String basicPlainText = new String(Base64.getDecoder().decode(basic.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8); + Map m = new HashMap<>(); + m.put("clientId", basicPlainText.split(":")[0]); + m.put("clientSecret", basicPlainText.split(":")[1]); + return m; + } + +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/utils/Oauth2AccessTokenUtil.java b/authorization-server/src/main/java/com/evotech/hd/authorization/utils/Oauth2AccessTokenUtil.java new file mode 100644 index 0000000..deb675d --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/utils/Oauth2AccessTokenUtil.java @@ -0,0 +1,42 @@ +package com.evotech.hd.authorization.utils; + +import java.util.HashMap; +import java.util.Map; + +import com.evotech.hd.authorization.config.oauth2.MyAccessToken; +import com.evotech.hd.common.core.enums.CodeMsg; + +import cn.hutool.http.HttpUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; + +public class Oauth2AccessTokenUtil { + + + public static MyAccessToken getToken(String url, String clientId, String clientSecret, String username, String password) { + Map m = new HashMap(); + m.put("grant_type", "password"); + m.put("username", username); + m.put("password", password); + m.put("scope", "ALL"); + String body = HttpUtil + .createPost(url) + .basicAuth(clientId, clientSecret) + .form(m) + .execute() + .body(); + JSONObject jo = JSONUtil.parseObj(body); + if (CodeMsg.SUCCESS.getCode().equals(jo.getStr("code"))) { + JSONObject jo1 = jo.getJSONObject("data"); + MyAccessToken tokenRes = new MyAccessToken(); + tokenRes.setAccessToken(jo1.getStr("access_token")); + tokenRes.setExpiresIn(jo1.getLong("expires_in")); + tokenRes.setRefreshToken(jo1.getStr("refresh_token")); + tokenRes.setTokenType(jo1.getStr("token_type")); + return tokenRes; + } else { + throw new RuntimeException("生成token出错"); + } + } + +} diff --git a/authorization-server/src/main/java/com/evotech/hd/authorization/utils/TokenUtil.java b/authorization-server/src/main/java/com/evotech/hd/authorization/utils/TokenUtil.java new file mode 100644 index 0000000..665fbb6 --- /dev/null +++ b/authorization-server/src/main/java/com/evotech/hd/authorization/utils/TokenUtil.java @@ -0,0 +1,49 @@ +package com.evotech.hd.authorization.utils; + +import java.util.Date; + +import org.springframework.security.oauth2.jwt.JwtClaimNames; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.jwt.JWT; +import cn.hutool.jwt.JWTUtil; + +/** + * token解析工具类 + */ +public class TokenUtil { + + + public static JWT parseToJwt(String token) { + JWT parseToken = JWTUtil.parseToken(token); + return parseToken; + } + + + /** + * 从token中获取userId + */ + public static String getUserId(String token) { + String uid = parseToJwt(token).getPayloads().getStr("uid"); + return uid; + } + + + /** + * 从token中获取jti + */ + public static String getJti(String token) { + String jti = parseToJwt(token).getPayloads().getStr(JwtClaimNames.JTI).replaceAll("-", ""); + return jti; + } + + + /** + * 从token中获取过期时间 + */ + public static Date getExp(String token) { + String exp = parseToJwt(token).getPayloads().getStr(JwtClaimNames.EXP).toString(); + return DateUtil.date(Long.valueOf(exp) * 1000); + } + +} diff --git a/authorization-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/authorization-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 0000000..08d7e45 --- /dev/null +++ b/authorization-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,12 @@ +{"properties": [ + { + "name": "security.token.public_key_base64", + "type": "java.lang.String", + "description": "A description for 'security.token.public_key_base64'" + }, + { + "name": "security.token.private_key_base64", + "type": "java.lang.String", + "description": "A description for 'security.token.private_key_base64'" + } +]} \ No newline at end of file diff --git a/authorization-server/src/main/resources/application.yml b/authorization-server/src/main/resources/application.yml new file mode 100644 index 0000000..92585c5 --- /dev/null +++ b/authorization-server/src/main/resources/application.yml @@ -0,0 +1,41 @@ +security.token.public_key_base64: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA23qzsZ/51EA9PAYvGyGwlSYEZxnGmF3FxiraUvLyeiBawyGFCHprnmG+fr+80KmhGh1UMbNwuwIRgn8tEY9TjlfK7iNhsX1QGEjrL6LggDJeXlA/XN4kRPY9sW7+VQpr1MPJjB5tQYVkPLvv3L8v/7k5hcPEoHIFwQoOnYBuQqLkj38EQ/NlOQLKzhyDRFWSm+6WzQF46fTMRLzRpfuFhUBk9oF3B8Y/vAajY90QDw5xdV0uGreK6CgESldCzx6hh1AHiLLICINRKTNL1t+uhRaz/f0xm8baxaKzusv2relz69GADCQl/GrTArcfWXVXqvetFzsQOt35EBOpxl3nRwIDAQAB +security.token.private_key_base64: MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDberOxn/nUQD08Bi8bIbCVJgRnGcaYXcXGKtpS8vJ6IFrDIYUIemueYb5+v7zQqaEaHVQxs3C7AhGCfy0Rj1OOV8ruI2GxfVAYSOsvouCAMl5eUD9c3iRE9j2xbv5VCmvUw8mMHm1BhWQ8u+/cvy//uTmFw8SgcgXBCg6dgG5CouSPfwRD82U5AsrOHINEVZKb7pbNAXjp9MxEvNGl+4WFQGT2gXcHxj+8BqNj3RAPDnF1XS4at4roKARKV0LPHqGHUAeIssgIg1EpM0vW366FFrP9/TGbxtrForO6y/at6XPr0YAMJCX8atMCtx9ZdVeq960XOxA63fkQE6nGXedHAgMBAAECggEAGU5mDrp/31nC1btuzgWN6zyVcF/X9rSFO8qwHrVVgQBfBrXENYyMARiLEuk/t51/blfoX8ytWFquMyo/w5EPlM+JnfilaIYm6I3r1DPHB/EG0YAWNjqE2xC7X0yJdbu8YC1s/UN63H2pZ5lR2FWRDr7II6TFdKyA/lePBNkMnZEc6SueoCFxUVNjalE9XNwaBqTvS1omxh11m/I6y+V3YW3ymwFN4tXdIWv1NsM4l3HfAbAVreqSRPL9Z1HHPpAD06aWKZD4BqA1umHs31IkbgQ4RvsUu2XeXOI5a/T+7kXHItNk0u2ozM7H92M4VrEvMXAso7woqs9bHxBouaQVnQKBgQDiD3Iz2r/PRghARoZdO8vzzph4/p7DscjJmv3V/SqwWSVAkLVJbjEDB6omuar2EW7nxpW7yc9hwRLB5fEYIVUeUbkhTCY33WAikKYAkdGqAV9N/nI2euSavdluo9LB1FwuTz4yLXydPP+c97EiwAY4Xle0Zbg41g1DhAz6rqrnswKBgQD4jCBnDvb/GQROip0FDLSu63STLySwka/bP8OIC8x4UN6eI+heT9sPoxBBsUdHwSKUfOP1oKoW+fLYGyX/2Gn64M/5L6ds5e7yaIZFykNVU0ysItTuAFt9tsOEZtxhRZlaQb9F3RRkzd10rZB0s0Pueg9X19ncUvpHqn+aIyO4HQKBgFA+CVystk893anrHsCzfBbj661vPC3cypf9g0LVJbUJP7bmZuNU0OLxco1idHP6BjMRg47v+MQLQ7w+AdF963firGNMY3iLBRff3nzvRcwhxpGp0yLRhpoC785dKm+RENODX2FyUfyCbX1rUp4yKUMTAfDP9o9+M6EWm4DURWgPAoGAcxr6GqBclTFxxCn/pAoJV4TlvRA1LqyZw7EZDdVhAUt6fcRlZeAXtHsxGStPtpRkPl5EeEnK288vvxN7mqwQEMayqlV+dTlbWto7bPDKFCb6uDF9aSezN1o/2/6DC21fIuSV/3XubuzEJbgH0XP//t56YpUtaRLoo+37IFgrv6UCgYAsTEQkg8la0BgKL9maiubnqdbl9nwS6l4lJqtlNNLaWIkiePmsY1dlkY91oQbc+YH3IJFexX/viuzZBXBJm9Hnf/MG+VeUz0f6ldZ2tI8fYbXIu0YadNmh0nnEAsUMaG7wYK6xnXiklh0LSjZUfWGmC4x/s2s1ixQme5ZIO2IPKQ== +# 1.server +server: + port: 9101 + servlet: + context-path: /oauth2 +# 2. log +logging: + config: classpath:logback-spring.xml +# 3.spring +spring: + application: + name: oauth2-server + config: + import: + - nacos:${spring.application.name}.yaml?refreshEnabled=true + cloud: + nacos: + serverAddr: 192.168.5.213:8848 + username: nacos + password: nacos + discovery: + register-enabled: true + #server-addr: 10.10.1.6:8848 + #ip: 192.168.5.200 + metadata: + management: + context-path: ${server.servlet.context-path}/actuator +# 5.为springbootadmin开启所有检查 +management: + endpoints: + web: + exposure: + include: "*" + endpoint: + health: + show-details: always + # xml文件中配置的日志文件的名称 + logfile: + external-file: /logs/oauth2/oauth2-server.log \ No newline at end of file diff --git a/authorization-server/src/main/resources/logback-spring.xml b/authorization-server/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..67ba924 --- /dev/null +++ b/authorization-server/src/main/resources/logback-spring.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + ${CONTEXT_NAME} + + + + + + DEBUG + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %replace(%caller{1}){'\t|Caller.{1}0|\r\n', ''} -- %msg%n + + UTF-8 + + + + + + + ${LOG_PATH}/${CONTEXT_NAME}.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{50}.%M\(%line\) -- %msg%n + UTF-8 + + + + + ${LOG_PATH}/${CONTEXT_NAME}-%d{yyyy-MM-dd}-%i.log + + ${MAX_HISTORY} + + + ${MAX_FILE_SIZE} + + + + + + + + + + + 512 + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/authorization-server/src/test/java/com/evotech/hd/authorization/AuthorizationServerApplicationTests.java b/authorization-server/src/test/java/com/evotech/hd/authorization/AuthorizationServerApplicationTests.java new file mode 100644 index 0000000..7cdef9f --- /dev/null +++ b/authorization-server/src/test/java/com/evotech/hd/authorization/AuthorizationServerApplicationTests.java @@ -0,0 +1,13 @@ +package com.evotech.hd.authorization; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class AuthorizationServerApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/base-commons/common-core/pom.xml b/base-commons/common-core/pom.xml new file mode 100644 index 0000000..69d967b --- /dev/null +++ b/base-commons/common-core/pom.xml @@ -0,0 +1,71 @@ + + + + 4.0.0 + + com.evotech.hd + base-commons + 1.0.0-SNAPSHOT + + common-core + + + org.projectlombok + lombok + true + + + io.swagger.core.v3 + swagger-annotations-jakarta + + + + jakarta.validation + jakarta.validation-api + + + org.hibernate.validator + hibernate-validator + + + + + org.springframework + spring-context + + + + com.baomidou + mybatis-plus-annotation + + + + com.baomidou + mybatis-plus-core + + + + com.fasterxml.jackson.core + jackson-annotations + + + com.fasterxml.jackson.core + jackson-core + + + com.fasterxml.jackson.core + jackson-databind + + + + cn.hutool + hutool-core + + + + + + + \ No newline at end of file diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/constant/HDConstant.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/constant/HDConstant.java new file mode 100644 index 0000000..9c22bc1 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/constant/HDConstant.java @@ -0,0 +1,74 @@ +package com.evotech.hd.common.core.constant; + +public interface HDConstant { + + /** + * 系统管理员角色 + */ + String SYSTEM_MANAGER_ROLE_CODE = "SYSADMIN"; + + /** + * 认证请求头key + */ + String AUTHORIZATION_KEY = "Authorization"; + + /** + * JWT令牌前缀 + */ + String JWT_PREFIX = "Bearer "; + + /** + * Basic认证前缀 + */ + String BASIC_PREFIX = "Basic "; + + /** + * JWT载体key + */ + String JWT_PAYLOAD_KEY = "payload"; + + + /** + * jwt中添加的属性 + */ + String USER_ID_KEY = "uid"; + String ROLE_CODE_KEY = "rcodes"; + + + /** + * 登陆验证码缓存key + * hd:login:captcha: + captchaId + */ + String CAPTCHA_REDIS_PREFIX = "hd:login:captcha:"; + + /** + * 登陆缓存内容前缀 + * key: hd:login:jti:token + */ + String LOGIN_CACHE_KEY_PREFIX = "hd:login:"; + + /** + * 缓存系统token有效时间,s + */ + String HD_CACHE_TOKEN_EXP_KEY = "hd:cache:tokenExp"; + + /** + * 资源权限类型 + */ + String RESOURCE_TYPE_PERM = "PER"; + String RESOURCE_TYPE_MENU = "MENU"; + + + /** + * 交换数据非对称加密RSA秘钥前缀 + */ + String HD_STATION_SECRET_KEY_RSA_PREFIX = "hd:station:secretKey:rsa:"; + + + /** + * 交换数据对称加密AES秘钥前缀 + */ + String HD_STATION_SECRET_KEY_AES_PREFIX = "hd:station:secretKey:aes:"; + + +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/ProxyOperaterDao.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/ProxyOperaterDao.java new file mode 100644 index 0000000..2a18845 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/ProxyOperaterDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.common.core.dao.resource; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.resource.ProxyOperater; + +/** + * @author zrb + * @since 2024-10-15 + */ +public interface ProxyOperaterDao extends BaseMapper { + +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/auth/AuthMenuDao.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/auth/AuthMenuDao.java new file mode 100644 index 0000000..aafcb6a --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/auth/AuthMenuDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.common.core.dao.resource.auth; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.resource.auth.AuthMenu; + +/** + * @author zrb + * @since 2024-09-04 + */ +public interface AuthMenuDao extends BaseMapper { + +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/auth/AuthPermissionDao.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/auth/AuthPermissionDao.java new file mode 100644 index 0000000..9cf3537 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/auth/AuthPermissionDao.java @@ -0,0 +1,18 @@ +package com.evotech.hd.common.core.dao.resource.auth; + +import java.util.List; + +import org.apache.ibatis.annotations.Param; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.resource.auth.AuthPermission; + +/** + * @author zrb + * @since 2024-09-04 + */ +public interface AuthPermissionDao extends BaseMapper { + + List listPermByUid(@Param("uid") String uid); + +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/auth/AuthRoleDao.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/auth/AuthRoleDao.java new file mode 100644 index 0000000..cff2009 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/auth/AuthRoleDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.common.core.dao.resource.auth; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.resource.auth.AuthRole; + +/** + * @author zrb + * @since 2024-09-04 + */ +public interface AuthRoleDao extends BaseMapper { + +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/auth/AuthRoleResourceDao.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/auth/AuthRoleResourceDao.java new file mode 100644 index 0000000..fd9b20f --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/auth/AuthRoleResourceDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.common.core.dao.resource.auth; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.resource.auth.AuthRoleResource; + +/** + * @author zrb + * @since 2024-09-04 + */ +public interface AuthRoleResourceDao extends BaseMapper { + +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/auth/AuthUserDao.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/auth/AuthUserDao.java new file mode 100644 index 0000000..848286f --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/auth/AuthUserDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.common.core.dao.resource.auth; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.resource.auth.AuthUser; + +/** + * @author zrb + * @since 2024-09-04 + */ +public interface AuthUserDao extends BaseMapper { + +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/auth/AuthUserRoleDao.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/auth/AuthUserRoleDao.java new file mode 100644 index 0000000..56ef22f --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/auth/AuthUserRoleDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.common.core.dao.resource.auth; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.resource.auth.AuthUserRole; + +/** + * @author zrb + * @since 2024-09-04 + */ +public interface AuthUserRoleDao extends BaseMapper { + +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/dict/AdmdvsInfoDao.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/dict/AdmdvsInfoDao.java new file mode 100644 index 0000000..573832b --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/dict/AdmdvsInfoDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.common.core.dao.resource.dict; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.resource.dict.AdmdvsInfo; + +/** + * @author zrb + * @since 2024-09-05 + */ +public interface AdmdvsInfoDao extends BaseMapper { + +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/dict/DictDao.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/dict/DictDao.java new file mode 100644 index 0000000..79a2039 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/dict/DictDao.java @@ -0,0 +1,19 @@ +package com.evotech.hd.common.core.dao.resource.dict; + +import java.util.List; + +import org.apache.ibatis.annotations.Param; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.request.ListDictRequest; +import com.evotech.hd.common.core.entity.resource.dict.Dict; + +/** + * @author zrb + * @since 2024-09-05 + */ +public interface DictDao extends BaseMapper { + + List listDict(@Param("ldr") ListDictRequest ldr); + +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/dict/DictTypeDao.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/dict/DictTypeDao.java new file mode 100644 index 0000000..2f763a0 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/resource/dict/DictTypeDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.common.core.dao.resource.dict; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.resource.dict.DictType; + +/** + * @author zrb + * @since 2024-09-05 + */ +public interface DictTypeDao extends BaseMapper { + +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/BasePageRequest.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/BasePageRequest.java new file mode 100644 index 0000000..20d7d1b --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/BasePageRequest.java @@ -0,0 +1,21 @@ +package com.evotech.hd.common.core.entity; + + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import jakarta.validation.constraints.Min; +import lombok.Data; + +@Data +@Schema(name = "分页基类") +public class BasePageRequest { + + + @Schema(description = "每页条数", requiredMode = RequiredMode.REQUIRED, example = "10" ) + @Min(value = 1) + private Integer pageSize = 10; + @Schema(description = "页数", requiredMode = RequiredMode.REQUIRED, example = "1") + @Min(1) + private Integer pageNo = 1; + +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/LoginCacheInfo.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/LoginCacheInfo.java new file mode 100644 index 0000000..8e9819c --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/LoginCacheInfo.java @@ -0,0 +1,28 @@ +package com.evotech.hd.common.core.entity; + +import java.util.List; + +import com.evotech.hd.common.core.entity.resource.auth.AuthPermission; +import com.evotech.hd.common.core.entity.resource.auth.AuthRole; +import com.evotech.hd.common.core.entity.resource.auth.AuthUser; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +@Schema(name = "登陆时缓存数据") +public class LoginCacheInfo { + + @Schema(description = "token") + private String token; + + @Schema(description = "权限") + private AuthUser user; + + @Schema(description = "角色") + List roleList; + + @Schema(description = "权限") + List permissionList; + +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/Result.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/Result.java new file mode 100644 index 0000000..304e9f6 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/Result.java @@ -0,0 +1,164 @@ +package com.evotech.hd.common.core.entity; + +import java.io.Serializable; + +import com.evotech.hd.common.core.enums.CodeMsg; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * @author zrb + * @date 2024年9月2日17:25:54 + */ +@Data +@Schema(name = "请求返回对象") +public class Result implements Serializable { + + private static final long serialVersionUID = -7806513009135956518L; + + @Schema(description = "请求处理状态", example = "1") + private Integer status; + @Schema(description = "状态码", example = "1000") + private String code; + @Schema(description = "返回消息") + private String msg; + @Schema(description = "返回数据") + private Object data; + + private T obj; + + + public Result(Integer status, String code, String msg, Object data) { + this.status = status; + this.code = code; + this.msg = msg; + this.data = data; + } + + public Result(Integer status, String msg, Object data) { + this.status = status; + this.msg = msg; + this.data = data; + } + + public Result(Integer status) { + this.status = status; + } + + public Result() { + } + + public Result(Integer status, String code, String msg) { + this.status = status; + this.code = code; + this.msg = msg; + } + + public Result(Integer status, String msg) { + this.status = status; + this.msg = msg; + } + + public Result success(Object o) { + this.status = 1; + this.code = CodeMsg.SUCCESS.getCode(); + this.msg = CodeMsg.SUCCESS.getMsg(); + this.data = o; + return this; + } + + public Result success(String msg, Object o) { + this.status = 1; + this.code = CodeMsg.SUCCESS.getCode(); + this.msg = msg; + this.data = o; + return this; + } + + public Result success(String msg) { + this.status = 1; + this.code = CodeMsg.SUCCESS.getCode(); + this.msg = msg; + this.data = CodeMsg.SUCCESS.getMsg(); + return this; + } + + public Result success(String code, String msg, Object o) { + this.status = 1; + this.code = code; + this.msg = msg; + this.data = o; + return this; + } + + public Result success(CodeMsg cm, Object o) { + this.status = 0; + this.code = cm.getCode(); + this.msg = cm.getMsg(); + this.data = o; + return this; + } + + public Result error(String msg) { + this.status = 0; + this.code = CodeMsg.ERROR.getCode(); + this.msg = msg; + this.data = "ERROR"; + return this; + } + + public Result error(String code, String msg) { + this.status = 0; + this.code = code; + this.msg = msg; + this.data = "ERROR"; + return this; + } + + public Result error(CodeMsg cm) { + this.status = 0; + this.code = cm.getCode(); + this.msg = cm.getMsg(); + return this; + } + + public Result error(CodeMsg cm, Object o) { + return error(cm.getCode(), cm.getMsg(), o); + } + + public Result error(String code, String msg, Object o) { + this.status = 0; + this.code = code; + this.msg = msg; + this.data = o; + return this; + } + + public Result error(String msg, Object o) { + this.status = 0; + this.code = CodeMsg.ERROR.getCode(); + this.msg = msg; + this.data = o; + return this; + } + + + public Result exception(Object data) { + this.status = -1; + this.code = CodeMsg.ERROR.getCode(); + this.msg = CodeMsg.ERROR.getMsg(); + this.data = data==null?"未知异常":data; + return this; + } + + + public Result bussinessException(String code, String msg, Object o) { + this.status = -1; + this.code = code; + this.msg = msg; + this.data = o; + return this; + } + +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStation.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStation.java new file mode 100644 index 0000000..215234c --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStation.java @@ -0,0 +1,139 @@ +package com.evotech.hd.common.core.entity.cloud; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.Hidden; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +/** + * @author zrb + * @since 2024-10-15 + */ +@Data +@TableName("yt_t_battery_station") +@Schema(name = "BatteryStation", description = "换电站") +public class BatteryStation implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + @Hidden + private Integer pkId; + + @Schema(description = "归属运营商ID", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "无关联运营商信息") + private String proxyId; + + @Schema(description = "站点名称", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "站点名称不能为空") + private String name; + + @Schema(description = "站点编码", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "站点编码不能为空") + private String code; + + @Schema(description = "状态:1-正常营业,2-正常停运,3-故障停运,4-指令停运,9-其它", requiredMode = RequiredMode.REQUIRED) + private Integer status; + + @Schema(description = "站点类型ID") + private Integer type; + + @Schema(description = "地址") + private String address; + + @Schema(description = "地址-省") + private String addressProvince; + + @Schema(description = "地址-市") + private String addressCity; + + @Schema(description = "地址-区县") + private String addressArea; + + @Schema(description = "注册日期") + private String registerDate; + + @Schema(description = "联系人") + private String contacts; + + @Schema(description = "联系电话") + private String phone; + + @Schema(description = "删除标识:1-已删除,0-未删除") + private Integer delFlag; + + @Schema(description = "激活日期") + private String activeDate; + + @Schema(description = "经纬度信息") + private String locationPoint; + + @Schema(description = "全天营业:1-是,0-否") + private Integer openAllDay; + + @Schema(description = "通道数") + private Integer tdQuantity; + + @Schema(description = "机器人数量") + private Integer jqrQuantity; + + @Schema(description = "充电机数量") + private Integer cdjQuantity; + + @Schema(description = "电池仓数量") + private Integer dccQuantity; + + @Schema(description = "电池数量") + private Integer dcQuantity; + + @Schema(description = "创建人") + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; + + + @Schema(description = "电池列表", hidden = true) + @TableField(exist = false) + private List dcList; + + @Schema(description = "电池仓列表", hidden = true) + @TableField(exist = false) + private List dccList; + + @Schema(description = "电机列表", hidden = true) + @TableField(exist = false) + private List djList; + + @Schema(description = "机器人列表", hidden = true) + @TableField(exist = false) + private List robotList; + + @Schema(description = "换电费用标准", hidden = true) + @TableField(exist = false) + private List feeStandardList; + +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationDc.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationDc.java new file mode 100644 index 0000000..32963ec --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationDc.java @@ -0,0 +1,88 @@ +package com.evotech.hd.common.core.entity.cloud; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-10-17 + */ +@Getter +@Setter +@TableName("yt_t_battery_station_dc") +@Schema(name = "电站-电池") +public class BatteryStationDc implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + @Schema(hidden = true) + private Integer pkId; + + @Schema(description = "电池型号编码", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "型号编码不能为空") + private String typeCode; + + @Schema(description = "电池编码", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "电池编码不能为空") + private String batCode; + + @Schema(description = "生产日期", example = "yyyyMMdd") + private String productionDate; + + @Schema(description = "注册时间", example = "yyyyMMdd") + private String registrationDate; + + @Schema(description = "初始来源:1-站,2-车", requiredMode = RequiredMode.REQUIRED) + @NotNull(message = "初始来源不能为空") + private Integer sourceFrom; + + @Schema(description = "站码或车牌照") + private String sourceCode; + + @Schema(description = "状态:1-出租中,2-充电中,3-充电完毕,4-故障,5-其它", requiredMode = RequiredMode.REQUIRED) + @NotNull(message = "状态不能为空") + private Integer status; + + @Schema(description = "换电站编码") + private String stationCode; + + @Schema(description = "换电站编码") + private String stationName; + + @Schema(description = "当前电量") + private Integer soc; + + @Schema(description = "删除标志:1-已删除,0-未删除", hidden = true) + private Integer delFlag; + + @Schema(description = "创建人") + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationDcc.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationDcc.java new file mode 100644 index 0000000..c811c1a --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationDcc.java @@ -0,0 +1,66 @@ +package com.evotech.hd.common.core.entity.cloud; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-10-17 + */ +@Getter +@Setter +@TableName("yt_t_battery_station_dcc") +@Schema(name = "电站-电池仓") +public class BatteryStationDcc implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + @Schema(hidden = true) + private Integer pkId; + + @Schema(description = "换电站编码", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "换电站编码不能为空") + private String stationCode; + + @Schema(description = "换电站编码") + private String stationName; + + @Schema(description = "电池仓序号", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "电池仓序号不能为空") + private String dccNo; + + @Schema(description = "状态:1-正常,2-检修, 3-坏", requiredMode = RequiredMode.REQUIRED) + @NotNull(message = "状态不能为空") + private Integer status; + + @Schema(description = "创建人") + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationDj.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationDj.java new file mode 100644 index 0000000..22c15b1 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationDj.java @@ -0,0 +1,80 @@ +package com.evotech.hd.common.core.entity.cloud; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-10-17 + */ +@Getter +@Setter +@TableName("yt_t_battery_station_dj") +@Schema(name = "电站-电机") +public class BatteryStationDj implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + @Schema(hidden = true) + private Integer pkId; + + @Schema(description = "换电站编码", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "换电站编码不能为空") + private String stationCode; + + @Schema(description = "换电站编码") + private String stationName; + + @Schema(description = "充电机编码", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "充电机编码不能为空") + private String code; + + @Schema(description = "充电机软件版本", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "充电机软件版本不能为空") + private String version; + + @Schema(description = "电池仓序号") + private String dccNo; + + @Schema(description = "充电连接类型:1-连接器,2-充电枪", requiredMode = RequiredMode.REQUIRED) + @NotNull(message = "充电连接类型不能为空") + private Integer switchType; + + @Schema(description = "状态:1-正常,2-检修, 3-坏", requiredMode = RequiredMode.REQUIRED) + @NotNull(message = "状态不能为空") + private Integer status; + + @Schema(description = "充电枪数量") + private Integer gunNum; + + @Schema(description = "创建人") + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationHdFeeStandard.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationHdFeeStandard.java new file mode 100644 index 0000000..5a9b447 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationHdFeeStandard.java @@ -0,0 +1,95 @@ +package com.evotech.hd.common.core.entity.cloud; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import cn.hutool.core.date.DatePattern; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-10-17 + */ +@Getter +@Setter +@TableName("yt_t_battery_station_hd_fee_standard") +@Schema(name = "电站-换电费用标准") +public class BatteryStationHdFeeStandard implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + @Schema(hidden = true) + private Integer pkId; + + @Schema(description = "费用标准名称") + private String name; + + @Schema(description = "换电站编码", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "换电站编码不能为空") + private String stationCode; + + @Schema(description = "换电站编码") + private String stationName; + + @Schema(description = "开始日期", requiredMode = RequiredMode.REQUIRED, example = DatePattern.PURE_DATE_PATTERN) + @NotBlank(message = "开始时间不能为空") + private String dayBegin; + + @Schema(description = "结束日期", requiredMode = RequiredMode.REQUIRED, example = DatePattern.PURE_DATE_PATTERN) + @NotBlank(message = "结束时间不能为空") + private String dayEnd; + + @Schema(description = "正常换电服务费") + private BigDecimal commonRemainFee; + + @Schema(description = "换电时正常电量范围") + private String commonRemainSocRange; + + @Schema(description = "换电时电量剩余过多的soc界定") + private Integer moreRemainSoc; + + @Schema(description = "换电时电量剩余过多的服务费") + private BigDecimal moreRemainFee; + + @Schema(description = "换电时电量剩余一般的soc界定") + private Integer fewRemainSoc; + + @Schema(description = "换电时电量剩余一般的服务费") + private BigDecimal fewRemainFee; + + @Schema(description = "创建人") + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; + + @Schema(description = "换电费用标准细节", hidden = true) + @TableField(exist = false) + private List detailList; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationHdFeeStandardDetail.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationHdFeeStandardDetail.java new file mode 100644 index 0000000..3be232e --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationHdFeeStandardDetail.java @@ -0,0 +1,85 @@ +package com.evotech.hd.common.core.entity.cloud; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import cn.hutool.core.date.DatePattern; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalTime; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-10-17 + */ +@Getter +@Setter +@TableName("yt_t_battery_station_hd_fee_standard_detail") +@Schema(name = "电站-换电费用标准细节") +public class BatteryStationHdFeeStandardDetail implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + @Schema(hidden = true) + private Integer pkId; + + @Schema(description = "换电站编码", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "换电站编码不能为空") + private String stationCode; + + @Schema(description = "收费规则ID", requiredMode = RequiredMode.REQUIRED) + @NotNull + private Integer standardId; + + @Schema(description = "每公里收费") + private BigDecimal eachKmFee; + + @Schema(description = "每SOC收费") + private BigDecimal eachSocFee; + + @Schema(description = "每度电收费") + private BigDecimal eachKwhFee; + + @Schema(description = "开始时间", requiredMode = RequiredMode.REQUIRED, example = DatePattern.NORM_TIME_PATTERN) + @NotNull + @DateTimeFormat(pattern = DatePattern.NORM_TIME_PATTERN) + private LocalTime timeBegin; + + @Schema(description = "结束时间", requiredMode = RequiredMode.REQUIRED, example = DatePattern.NORM_TIME_PATTERN) + @NotNull + @DateTimeFormat(pattern = DatePattern.NORM_TIME_PATTERN) + private LocalTime timeEnd; + + @Schema(description = "谷段服务费") + private BigDecimal timeServiceFee; + + @Schema(description = "创建人") + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationRobot.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationRobot.java new file mode 100644 index 0000000..fbb9d03 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationRobot.java @@ -0,0 +1,69 @@ +package com.evotech.hd.common.core.entity.cloud; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-10-17 + */ +@Getter +@Setter +@TableName("yt_t_battery_station_robot") +@Schema(name = "电站-机器人") +public class BatteryStationRobot implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + @Schema(hidden = true) + private Integer pkId; + + @Schema(description = "换电站编码", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "换电站编码不能为空") + private String stationCode; + + @Schema(description = "换电站编码") + private String stationName; + + @Schema(description = "机器人编码", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "机器人编码不能为空") + private String code; + + @Schema(description = "状态:1-正常", requiredMode = RequiredMode.REQUIRED) + @NotNull(message = "状态不能为空") + private Integer status; + + @Schema(description = "运行模式:1-就地,2-远程") + private Integer runMode; + + @Schema(description = "创建人") + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryTrace.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryTrace.java new file mode 100644 index 0000000..c855911 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryTrace.java @@ -0,0 +1,75 @@ +package com.evotech.hd.common.core.entity.cloud; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +/** + * @author zrb + * @since 2024-12-06 + */ +@Data +@TableName("yt_t_battery_trace") +@Schema(name = "电池追溯表") +public class BatteryTrace implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + @Schema(hidden = true) + private Integer pkId; + + @Schema(description = "电池编码", requiredMode = RequiredMode.REQUIRED) + @NotBlank + private String batCode; + + @Schema(description = "轨迹点类型:1-电站,2-车辆", requiredMode = RequiredMode.REQUIRED) + @NotNull + private Integer pointType; + + @Schema(description = "开始时间", example = "yyyy-MM-dd HH:mm:ss", requiredMode = RequiredMode.REQUIRED) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date beginTime; + + @Schema(description = "轨迹点编码", requiredMode = RequiredMode.REQUIRED) + @NotBlank + private String pointCode; + + @Schema(description = "轨迹点名称", requiredMode = RequiredMode.REQUIRED) + @NotBlank + private String pointName; + + @Schema(description = "结束时间", example = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date endTime; + + @Schema(description = "创建人") + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/OrderRecharge.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/OrderRecharge.java new file mode 100644 index 0000000..8afd5b0 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/OrderRecharge.java @@ -0,0 +1,74 @@ +package com.evotech.hd.common.core.entity.cloud; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-11-22 + */ +@Getter +@Setter +@TableName("yt_t_order_recharge") +@Schema(name = "充值订单") +public class OrderRecharge implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + @Schema(hidden = true) + private Integer pkId; + + @Schema(description = "订单时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date orderTime; + + @Schema(description = "订单编码", hidden = true) + private String orderNo; + + @Schema(description = "换电站编码") + private String stationCode; + + @Schema(description = "换电站名称") + private String stationName; + + @Schema(description = "钱包账户账号") + private String accountCode; + + @Schema(description = "充值账号ID") + private String userId; + + @Schema(description = "交易编码") + private String tradeNo; + + @Schema(description = "删除状态:1-已删除,0-未删除", hidden = true) + private Integer delFlag; + + @Schema(description = "创建人") + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/OrderSwapBattery.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/OrderSwapBattery.java new file mode 100644 index 0000000..0c22712 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/OrderSwapBattery.java @@ -0,0 +1,178 @@ +package com.evotech.hd.common.core.entity.cloud; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +/** + * @author zrb + * @since 2024-11-22 + */ +@Data +@TableName("yt_t_order_swap_battery") +@Schema(name = "换电订单信息表") +public class OrderSwapBattery implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + @Schema(hidden = true) + private Integer pkId; + + @Schema(description = "预约订单ID") + private Integer orderPreId; + + @Schema(description = "预约用户") + private String orderPreUid; + + @Schema(description = "预约用户名称") + private String orderPreUname; + + @Schema(description = "预约用户手机") + private String orderPrePhone; + + @Schema(description = "类型:1-换电,2-充电", requiredMode = RequiredMode.REQUIRED) + @NotNull(message = "订单类型不能为空") + private Integer orderType; + + @Schema(description = "订单编码", hidden = true) + private String orderNo; + + @Schema(description = "车牌号", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "车牌号不能为空") + private String plateNum; + + @Schema(description = "订单时间", example = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date orderTime; + + @Schema(description = "换电站编码", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "换电站编码不能为空") + private String stationCode; + + @Schema(description = "换电站名称", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "换电站名称不能为空") + private String stationName; + + @Schema(description = "金额账号") + private String accountCode; + + @Schema(description = "订单金额") + private Integer amount; + + @Schema(description = "订单状态:1-已创建,2-换电中,3-换电完成,4-充电中,5-充电完成,6-待结算,7-已完成,9-已取消") + private Integer status; + + @Schema(description = "计算费用方式:1-ODO,2-SOC,3-按电量") + private Integer feeType; + + @Schema(description = "基础费用") + private Integer basicFee; + + @Schema(description = "服务开始时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date serviceTimeBegin; + + @Schema(description = "服务结束时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date serviceTimeEnd; + + @Schema(description = "服务费") + private Integer serviceFee; + + @Schema(description = "上次租赁电池时车辆里程") + private BigDecimal lastRentBatCarOdo; + + @Schema(description = "归还电池时车辆里程") + private BigDecimal nowReturnBatCarOdo; + + @Schema(description = "按ODO换电费") + private BigDecimal odoAmount; + + @Schema(description = "充电开始时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date chargeTimeBegin; + + @Schema(description = "充电结束时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date chargeTimeEnd; + + @Schema(description = "总充电量") + private BigDecimal electAmount; + + @Schema(description = "租借电池包仓位") + private Integer rentBatNo; + + @Schema(description = "租用电池包编码") + private String rentBatCode; + + @Schema(description = "租用电池包SOC") + private Integer rentBatSoc; + + @Schema(description = "归还电池包编码") + private String returnBatCode; + + @Schema(description = "归还电池包仓位") + private Integer returnBatNo; + + @Schema(description = "归还电池包SOC") + private Integer returnBatSoc; + + @Schema(description = "归还电池租出时soc") + private Integer returnBatRentSoc; + + @Schema(description = "归还电池租出的换电站编码") + private String returnBatRentStationCode; + + @Schema(description = "归还电池租出的换电站") + private String returnBatRentStationName; + + @Schema(description = "换电模式:1-全自动,2-半自动,3-人工干预 ") + private Integer changeMode; + + @Schema(description = "换电车道 1-A 车道;2-B 车道") + private Integer changeLane; + + @Schema(description = "删除状态:1-已删除,0-未删除", hidden = true) + private Integer delFlag; + + @Schema(description = "交易编码", hidden = true) + private String tradeNo; + + @Schema(description = "备注信息") + private String remark; + + @Schema(description = "创建人") + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/OrderSwapBatteryPre.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/OrderSwapBatteryPre.java new file mode 100644 index 0000000..2c1a28b --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/OrderSwapBatteryPre.java @@ -0,0 +1,84 @@ +package com.evotech.hd.common.core.entity.cloud; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import lombok.Data; + +/** + * @author zrb + * @since 2024-12-04 + */ +@Data +@TableName("yt_t_order_swap_battery_pre") +@Schema(name = "换电预约订单") +public class OrderSwapBatteryPre implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + @Schema(description = "ID", hidden = true) + private Integer pkId; + + @Schema(description = "来源:1-小程序,2-云端,3-站端", requiredMode = RequiredMode.REQUIRED) + private Integer from; + + @Schema(description = "来源是站端时,记录发送Id,其他来源不需要", hidden = true) + private String sourceId; + + @Schema(description = "预约人编码") + private String ucode; + + @Schema(description = "预约人姓名") + private String uname; + + @Schema(description = "手机号码") + private String phone; + + @Schema(description = "车牌号") + private String plateNum; + + @Schema(description = "换电站编码") + private String stationCode; + + @Schema(description = "换电站名称") + private String stationName; + + @Schema(description = "预约时间", hidden = true) + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date reservationTime; + + @Schema(description = "预约换电日期", example = "yyyyMMdd", requiredMode = RequiredMode.REQUIRED) + private String swapDay; + + @Schema(description = "预约换电时间段", example = "8:00-10:00") + private String swapDuration; + + @Schema(description = "状态:1-预约成功,2-到店使用,3-取消,4-过期", hidden = true) + private Integer status; + + @Schema(description = "创建人") + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/OrderSwapBatteryStep.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/OrderSwapBatteryStep.java new file mode 100644 index 0000000..d3c84e5 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/OrderSwapBatteryStep.java @@ -0,0 +1,56 @@ +package com.evotech.hd.common.core.entity.cloud; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * @author zrb + * @since 2024-12-11 + */ +@Data +@TableName("yt_t_order_swap_battery_step") +@Schema(name = "换电步骤记录") +public class OrderSwapBatteryStep implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + @Schema(description = "ID", hidden = true) + private Integer pkId; + + @Schema(description = "订单编码") + private String orderNo; + + @Schema(description = "步骤:1-车辆进站,2-车辆到达指定位置,3-对中机构,4-取新电,5-拆旧电,6-装新电,7-放旧电,8-完成") + private Integer step; + + @Schema(description = "步骤时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date stepTime; + + @Schema(description = "创建人") + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/TradeDetail.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/TradeDetail.java new file mode 100644 index 0000000..df9a4d3 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/TradeDetail.java @@ -0,0 +1,106 @@ +package com.evotech.hd.common.core.entity.cloud; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * @author zrb + * @since 2024-11-22 + */ +@Data +@TableName("yt_t_trade_detail") +@Schema(name = "交易信息表") +public class TradeDetail implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + @Schema(hidden = true) + private Integer pkId; + + @Schema(description = "换电站编码") + private String stationCode; + + @Schema(description = "账号编码") + private String accountCode; + + @Schema(description = "账号") + private String accountName; + + @Schema(description = "交易编码") + private String outTradeNo; + + @Schema(description = "交易类型:1-充值,2-订单消费,3-提现") + private Integer tradeType; + + @Schema(description = "支付方式:1-账户余额,2-微信,3-支付宝,4-网银,5 -充电补偿") + private Integer payType; + + @Schema(description = "订单数量") + private Integer orderCount; + + @Schema(description = "订单编码") + private String orderNums; + + @Schema(description = "交易金额") + private Integer tradeAmount; + + @Schema(description = "交易前账户余额") + private Integer preAccountAmount; + + @Schema(description = "交易后账户余额") + private Integer afterAccountAmount; + + @Schema(description = "优惠券编码") + private String couponCode; + + @Schema(description = "优惠金额") + private Integer giftAmount; + + @Schema(description = "微信支付订单号") + private String transactionId; + + @Schema(description = "支付结果: 0-未支付, 1-已支付, 2-支付失败") + private Integer payResult; + + @Schema(description = "在微信等支付网关创建支付订单时失败,返回的失败原因") + private String payMsg; + + @Schema(description = "删除标识,1-已删除,0-未删除") + private Integer delFlag; + + @Schema(description = "创建人") + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; + + @Schema(description = "退款结果: 0-未退款, 1-退款中,2-已退款, 3-退款失败") + private Integer refundResult; + + @Schema(description = "在微信等退款网关创建退款订单时失败,返回的失败原因") + private String refundMsg; + + @Schema(description = "退款返回数据") + private String refundReturn; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/VehicleInfo.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/VehicleInfo.java new file mode 100644 index 0000000..5b7aafe --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/VehicleInfo.java @@ -0,0 +1,121 @@ +package com.evotech.hd.common.core.entity.cloud; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +/** + * @author zrb + * @since 2024-11-22 + */ +@Data +@TableName("yt_t_vehicle_info") +@Schema(name = "车辆信息表") +public class VehicleInfo implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + @Schema(hidden = true) + private Integer pkId; + + @Schema(description = "型号编码", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "型号编码不能为空") + private String typeCode; + + @Schema(description = "车辆识别代码VIN号", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "VIN号不能为空") + private String vinNo; + + @Schema(description = "车架号", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "车架号不能为空") + private String frameworkNo; + + @Schema(description = "车主类型:1-个人,2-企业", requiredMode = RequiredMode.REQUIRED) + @NotNull(message = "车主类型不能为空") + private Integer ownerType; + + @Schema(description = "车主ID") + private String ownerId; + + @Schema(description = "车主名称", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "车主名称不能为空") + private String ownerName; + + @Schema(description = "车牌号", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "车牌号不能为空") + private String plateNum; + + @Schema(description = "引擎号", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "引擎号不能为空") + private String engineNo; + + @Schema(description = "座位数") + private Integer seatsCount; + + @Schema(description = "车身颜色") + private String carColor; + + @Schema(description = "车籍/归属地") + private String carArea; + + @Schema(description = "出厂日期") + private String productionDate; + + @Schema(description = "购车日期") + private String purchaseDate; + + @Schema(description = "上牌日期") + private String boardDate; + + @Schema(description = "首次登记日期") + private String registrationDate; + + @Schema(description = "消费方式:1-电量,2-里程", requiredMode = RequiredMode.REQUIRED) + @NotNull(message = "消费方式不能为空") + private Integer usageType; + + @Schema(description = "总里程") + private BigDecimal totalMileage; + + @Schema(description = "联系电话") + private String phone; + + @Schema(description = "删除状态,1-已删除,0-未删除", hidden = true) + private Integer delFlag; + + @Schema(description = "公司名称") + private String cname; + + @Schema(description = "组织机构代码") + private String ccode; + + @Schema(description = "创建人") + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/VehicleWechatUserRelation.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/VehicleWechatUserRelation.java new file mode 100644 index 0000000..50bbf6b --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/VehicleWechatUserRelation.java @@ -0,0 +1,69 @@ +package com.evotech.hd.common.core.entity.cloud; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +/** + * @author zrb + * @since 2024-11-22 + */ +@Data +@TableName("yt_t_vehicle_wechat_user_relation") +@Schema(name = "车辆和用户关系") +public class VehicleWechatUserRelation implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + @Schema(hidden = true) + private Integer pkId; + + @Schema(description = "用户编码", requiredMode = RequiredMode.REQUIRED) + private String ucode; + + @Schema(description = "用户名称", requiredMode = RequiredMode.REQUIRED) + private String uname; + + @Schema(description = "微信用户标识") + private String openid; + + @Schema(description = "车牌号", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "车牌号不能为空") + private String plateNum; + + @Schema(description = "车主类型:1-个人,2-企业", requiredMode = RequiredMode.REQUIRED) + @NotNull(message = "车主类型不能为空") + private Integer ownerType; + + @Schema(description = "关联人手机号", requiredMode = RequiredMode.REQUIRED) + private String phone; + + @Schema(description = "创建人") + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/WalletAccount.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/WalletAccount.java new file mode 100644 index 0000000..6d2287d --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/WalletAccount.java @@ -0,0 +1,88 @@ +package com.evotech.hd.common.core.entity.cloud; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +/** + * @author zrb + * @since 2024-11-22 + */ +@Data +@TableName("yt_t_wallet_account") +@Schema(name = "资金钱包账户表") +public class WalletAccount implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + @Schema(hidden = true) + private Integer pkId; + + @Schema(description = "户主类型:1-个人,2-企业", requiredMode = RequiredMode.REQUIRED) + @NotNull(message = "类型不能为空") + private Integer ownerType; + + @Schema(description = "户主ID", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "用户编码不能为空") + private String ownerId; + + @Schema(description = "编码", hidden = true) + private String code; + + @Schema(description = "账户总金额,分:总金额=充值金额+赠送金额") + private Integer totalAmount; + + @Schema(description = "充值余额,分") + private Integer rechargeAmount; + + @Schema(description = "赠送金额,分") + private Integer giftAmount; + + @Schema(description = "积分余额") + private Integer point; + + @Schema(description = "押金") + private Integer deposit; + + @Schema(description = "SN码") + private String snCode; + + @Schema(description = "租金") + private Integer rent; + + @Schema(description = "状态") + private Boolean status; + + @Schema(description = "引入站点", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "站点编码不能为空") + private String stationCode; + + @Schema(description = "创建人") + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/WalletAccountDetail.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/WalletAccountDetail.java new file mode 100644 index 0000000..1762d20 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/WalletAccountDetail.java @@ -0,0 +1,93 @@ +package com.evotech.hd.common.core.entity.cloud; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +/** + * @author zrb + * @since 2024-11-22 + */ +@Data +@TableName("yt_t_wallet_account_detail") +@Schema(name = "资金账户明细") +public class WalletAccountDetail implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + @Schema(hidden = true) + private Integer pkId; + + @Schema(description = "编码", requiredMode = RequiredMode.REQUIRED) + @NotBlank + private String code; + + @Schema(description = "交易编码", requiredMode = RequiredMode.REQUIRED) + @NotBlank + private String tradeNo; + + @Schema(description = "交易前账户总金额,分:总金额=充值金额+赠送金额", requiredMode = RequiredMode.REQUIRED) + @NotNull + private Integer preTotalAmount; + + @Schema(description = "交易前充值余额,分", requiredMode = RequiredMode.REQUIRED) + @NotNull + private Integer preRechargeAmount; + + @Schema(description = "交易前赠送金额,分", requiredMode = RequiredMode.REQUIRED) + @NotNull + private Integer preGiftAmount; + + @Schema(description = "交易总金额,分:总金额=充值金额+赠送金额", requiredMode = RequiredMode.REQUIRED) + @NotNull + private Integer tradeTotalAmount; + + @Schema(description = "交易充值余额,分", requiredMode = RequiredMode.REQUIRED) + @NotNull + private Integer tradeRechargeAmount; + + @Schema(description = "交易赠送金额,分", requiredMode = RequiredMode.REQUIRED) + @NotNull + private Integer tradeGiftAmount; + + @Schema(description = "交易后总金额,分:总金额=充值金额+赠送金额", requiredMode = RequiredMode.REQUIRED) + @NotNull + private Integer afterTotalAmount; + + @Schema(description = "交易后充值余额,分", requiredMode = RequiredMode.REQUIRED) + @NotNull + private Integer afterRechargeAmount; + + @Schema(description = "交易后赠送金额,分", requiredMode = RequiredMode.REQUIRED) + @NotNull + private Integer afterGiftAmount; + + @Schema(description = "创建人") + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/request/ListDictRequest.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/request/ListDictRequest.java new file mode 100644 index 0000000..a53201e --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/request/ListDictRequest.java @@ -0,0 +1,32 @@ +package com.evotech.hd.common.core.entity.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +@Schema(name = "查询字典参数") +public class ListDictRequest { + + @Schema(description = "字典类型id") + private String typeId; + + @Schema(description = "字典类型名") + private String typeName; + + @Schema(description = "字典类型编码") + private String typeCode; + + @Schema(description = "字典id") + private String dictId; + + @Schema(description = "字典名") + private String dictName; + + @Schema(description = "字典编码") + private String dictCode; + + @Schema(description = "字典值") + private String dictValue; + + +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/LogLogin.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/LogLogin.java new file mode 100644 index 0000000..a1cf9d0 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/LogLogin.java @@ -0,0 +1,73 @@ +package com.evotech.hd.common.core.entity.resource; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +/** + * @author zrb + * @date 2024年9月6日08:35:28 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("yt_log_login") +@Schema(name = "登录日志", description = "登录日志") +public class LogLogin implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + private Integer pkId; + + @Schema(description = "登录人ID") + private String uid; + + @Schema(description = "操作IP") + private String requestIp; + + @Schema(description = "登录人姓名") + private String name; + + @Schema(description = "账号") + private String uname; + + @Schema(description = "登录描述") + private String description; + + @Schema(description = "登录时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date loginTime; + + @Schema(description = "浏览器请求头") + private String ua; + + @Schema(description = "浏览器名称") + private String browser; + + @Schema(description = "浏览器版本") + private String browserVersion; + + @Schema(description = "操作系统") + private String operatingSystem; + + @Schema(description = "平台") + private String platForm; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "创建者") + private String creater; + +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/LogUpload.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/LogUpload.java new file mode 100644 index 0000000..614ac2f --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/LogUpload.java @@ -0,0 +1,62 @@ +package com.evotech.hd.common.core.entity.resource; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-11-01 + */ +@Getter +@Setter +@TableName("hd_resource.yt_log_upload") +@Schema(name = "上传记录表") +public class LogUpload implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId("pk_id") + private String pkId; + + @Schema(description = "公司编码") + private String ccode; + + @Schema(description = "运营商编码") + private String pocode; + + @Schema(description = "自定义类型,会新建此文件夹,默认值 hd") + private String type; + + @Schema(description = "本次上传内容,不填取第一个文件名字") + private String name; + + @Schema(description = "数量") + private Integer amount; + + @Schema(description = "状态:1-成功") + private Integer status; + + @Schema(description = "用户") + private String user; + + @Schema(description = "文件路径") + private String filePath; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "创建者") + private String creater; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/ProxyOperater.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/ProxyOperater.java new file mode 100644 index 0000000..8258653 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/ProxyOperater.java @@ -0,0 +1,96 @@ +package com.evotech.hd.common.core.entity.resource; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-10-15 + */ +@Getter +@Setter +@TableName("yt_t_proxy_operater") +@Schema(name = "代理运营商信息") +public class ProxyOperater implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "ID", hidden = true) + @TableId(value = "pk_id", type = IdType.AUTO) + private Integer pkId; + + @Schema(description = "区划名称", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "区划名称不能为空") + private String division; + + @Schema(description = "区划编码", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "区划编码不能为空") + private String divisionNo; + + @Schema(description = "运营商名称", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "运营商名称不能为空") + private String poname; + + @Schema(description = "运营商组织机构代码", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "运营商组织机构代码不能为空") + private String pocode; + + @Schema(description = "地址") + private String address; + + @Schema(description = "地址-省") + private String addressProvince; + + @Schema(description = "地址-市") + private String addressCity; + + @Schema(description = "地址-区县") + private String addressArea; + + @Schema(description = "联系人") + private String contacts; + + @Schema(description = "联系电话") + private String phone; + + @Schema(description = "状态:1-启用,0-禁用") + private Integer status; + + @Schema(description = "只读:1-是,0-否") + private Integer readonly; + + @Schema(description = "删除标识:1-已删除,0-未删除", hidden = true) + private Integer delFlag; + + @Schema(description = "换电站数量") + private Integer stationCount; + + @Schema(description = "创建人") + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/UploadFile.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/UploadFile.java new file mode 100644 index 0000000..ba82162 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/UploadFile.java @@ -0,0 +1,72 @@ +package com.evotech.hd.common.core.entity.resource; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-11-01 + */ +@Getter +@Setter +@TableName("hd_resource.yt_t_upload_file") +@Schema(name = "上传文件表") +public class UploadFile implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + private Integer pkId; + + @Schema(description = "公司编码") + private String ccode; + + @Schema(description = "运营商编码") + private String pocode; + + @Schema(description = "数据类型") + private String type; + + @Schema(description = "上传ID") + private String uploadId; + + @Schema(description = "文件原名") + private String fileOriginalName; + + @Schema(description = "文件类型") + private String fileType; + + @Schema(description = "文件大小") + private Long fileSize; + + @Schema(description = "文件最终名字") + private String fileFinalName; + + @Schema(description = "文件路径") + private String filePath; + + @Schema(description = "路径+名称") + private String pathName; + + @Schema(description = "地址") + private String fileUrl; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "创建者") + private String creater; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/auth/AuthMenu.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/auth/AuthMenu.java new file mode 100644 index 0000000..2ab143d --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/auth/AuthMenu.java @@ -0,0 +1,81 @@ +package com.evotech.hd.common.core.entity.resource.auth; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-09-04 + */ +@Getter +@Setter +@TableName("yt_auth_menu") +@Schema(name = "菜单") +public class AuthMenu implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "主键", hidden = true) + @TableId(value = "pk_id", type = IdType.AUTO) + private Integer pkId; + + @Schema(description = "菜单名称") + private String name; + + @Schema(description = "功能描述") + private String mark; + + @Schema(description = "对应路由组件component") + private String component; + + @Schema(description = "对应路由path") + private String path; + + @Schema(description = "状态") + private Integer status; + + @Schema(description = "排序") + private Integer sort; + + @Schema(description = "菜单图标") + private String icon; + + @Schema(description = "菜单类型:系统-1,目录-2,页面-3") + private String type; + + @Schema(description = "父级菜单id") + private Integer parentId; + + @Schema(description = "创建人") + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; + + @Schema(description = "子目录", hidden = true) + @TableField(exist = false) + private List subMenuList; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/auth/AuthPermission.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/auth/AuthPermission.java new file mode 100644 index 0000000..5eb2c52 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/auth/AuthPermission.java @@ -0,0 +1,69 @@ +package com.evotech.hd.common.core.entity.resource.auth; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-09-04 + */ +@Getter +@Setter +@TableName("yt_auth_permission") +@Schema(name = "资源权限") +public class AuthPermission implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "ID", hidden = true) + @TableId(value = "pk_id", type = IdType.AUTO) + private Integer pkId; + + @Schema(description = "资源编码:页面:操作") + private String code; + + @Schema(description = "接口名称") + private String name; + + @Schema(description = "菜单ID") + private Integer menuId; + + @Schema(description = "允许访问路径,gateway-允许网关访问,private-不允许网关访问") + private String allow; + + @Schema(description = "uri路径") + private String uri; + + @Schema(description = "请求方式:GET/POST/DEL/PUSH") + private String requestType; + + @Schema(description = "接口描述") + private String mark; + + @Schema(description = "创建人id") + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/auth/AuthRole.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/auth/AuthRole.java new file mode 100644 index 0000000..f967976 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/auth/AuthRole.java @@ -0,0 +1,66 @@ +package com.evotech.hd.common.core.entity.resource.auth; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-09-04 + */ +@Getter +@Setter +@TableName("yt_auth_role") +@Schema(name = "角色") +public class AuthRole implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "id", hidden = true) + @TableId(value = "pk_id", type = IdType.AUTO) + private Integer pkId; + + @Schema(description = "角色名称") + private String name; + + @Schema(description = "角色编码") + private String rcode; + + @Schema(description = "功能描述") + private String mark; + + @Schema(description = "状态") + private Integer status; + + @Schema(description = "角色类型:1-开发者,2-运营方,3-客户") + private Integer type; + + @Schema(description = "是否内置角色,内置角色不允许修改") + private Integer readonly; + + @Schema(description = "创建人") + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/auth/AuthRoleResource.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/auth/AuthRoleResource.java new file mode 100644 index 0000000..2e3a67f --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/auth/AuthRoleResource.java @@ -0,0 +1,49 @@ +package com.evotech.hd.common.core.entity.resource.auth; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-09-04 + */ +@Getter +@Setter +@TableName("yt_auth_role_resource") +@Schema(name = "角色的权限") +public class AuthRoleResource implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "主键") + @TableId(value = "pk_id", type = IdType.AUTO) + private Integer pkId; + + @Schema(description = "角色编码") + private String rcode; + + @Schema(description = "权限类型:SYS-系统,MENU-菜单,PER-资源权限") + private String resourceType; + + @Schema(description = "权限id") + private Integer resourceId; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "创建人", hidden = true) + private String creater; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/auth/AuthUser.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/auth/AuthUser.java new file mode 100644 index 0000000..c7858df --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/auth/AuthUser.java @@ -0,0 +1,114 @@ +package com.evotech.hd.common.core.entity.resource.auth; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +/** + * @author zrb + * @since 2024-09-04 + */ +@Data +@TableName("yt_auth_user") +@Schema(name = "账号") +public class AuthUser implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "主键", hidden = true) + @TableId(value = "pk_id", type = IdType.AUTO) + private Integer pkId; + + @Schema(description = "用户ID") + private String uid; + + @Schema(description = "账号", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "账号不能为空") + private String uname; + + @Schema(description = "账号类型:1-开发者,2-运营方,3-客户", requiredMode = RequiredMode.REQUIRED) + private Integer type; + + @Schema(description = "关联方代码") + private String typeRelateCode; + + @Schema(description = "姓名") + private String name; + + @Schema(description = "密码", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "密码不能为空") + private String password; + + @Schema(description = "邮箱") + private String email; + + @Schema(description = "手机") + private String phone; + + @Schema(description = "性别") + private String sex; + + @Schema(description = "状态:1-启用,0-禁用", requiredMode = RequiredMode.REQUIRED) + @NotNull + private Integer status; + + @Schema(description = "是否内置账号,内置账号不允许动") + private Integer readonly; + + @Schema(description = "删除标识:1-已删除,0-未删除", hidden = true) + private Integer delFlag; + + @Schema(description = "头像") + private String avatar; + + @Schema(description = "最后一次输错密码时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date passwordErrorLastTime; + + @Schema(description = "密码错误次数", hidden = true) + private Integer passwordErrorNum; + + @Schema(description = "密码过期时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date passwordExpireTime; + + @Schema(description = "最后登录时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date lastLoginTime; + + @Schema(description = "创建人", hidden = true) + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; + + @Schema(description = "角色编码", hidden = true) + @TableField(exist = false) + private String rcodes; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/auth/AuthUserRole.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/auth/AuthUserRole.java new file mode 100644 index 0000000..58ca0bc --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/auth/AuthUserRole.java @@ -0,0 +1,53 @@ +package com.evotech.hd.common.core.entity.resource.auth; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-09-04 + */ +@Getter +@Setter +@TableName("yt_auth_user_role") +@Schema(name = "账号角色关系") +public class AuthUserRole implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + private Integer pkId; + + @Schema(description = "用户ID") + @NotBlank + private String uid; + + @Schema(description = "角色编码") + @NotBlank + private String rcode; + + @Schema(description = "创建人") + private String creater; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "修改时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/dict/AdmdvsInfo.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/dict/AdmdvsInfo.java new file mode 100644 index 0000000..9c30865 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/dict/AdmdvsInfo.java @@ -0,0 +1,58 @@ +package com.evotech.hd.common.core.entity.resource.dict; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-09-05 + */ +@Getter +@Setter +@TableName("yt_d_admdvs_info") +@Schema(name = "行政区划信息表") +public class AdmdvsInfo implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId("pk_id") + private Integer pkId; + + @Schema(description = "区划代码") + private String admdvsNo; + + @Schema(description = "区划名称") + private String admdvsName; + + @Schema(description = "父级代码") + private String pno; + + @Schema(description = "等级,1-省;2-市;3-区县") + private Integer level; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; + + @Schema(description = "子区划", hidden = true) + @TableField(exist = false) + private List subAdmdvsInfoList; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/dict/Dict.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/dict/Dict.java new file mode 100644 index 0000000..6f2d22b --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/dict/Dict.java @@ -0,0 +1,59 @@ +package com.evotech.hd.common.core.entity.resource.dict; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-09-05 + */ +@Getter +@Setter +@TableName("hd_resource.yt_d_dict") +@Schema(name = "字典") +public class Dict implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "主键", hidden = true) + @TableId(value = "pk_id", type = IdType.AUTO) + private Integer pkId; + + @Schema(description = "字典名称") + private String dictName; + + @Schema(description = "字典编码") + private String dictCode; + + @Schema(description = "字典值") + private String dictValue; + + @Schema(description = "排序") + private Integer sort; + + @Schema(description = "类型ID") + private Integer typeId; + + private String typeCode; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/dict/DictType.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/dict/DictType.java new file mode 100644 index 0000000..b540a84 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/resource/dict/DictType.java @@ -0,0 +1,51 @@ +package com.evotech.hd.common.core.entity.resource.dict; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-09-05 + */ +@Getter +@Setter +@TableName("hd_resource.yt_d_dict_type") +@Schema(name = "字典类型") +public class DictType implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "主键", hidden = true) + @TableId(value = "pk_id", type = IdType.AUTO) + private Integer pkId; + + @Schema(description = "类型名称") + private String typeName; + + @Schema(description = "类型编码") + private String typeCode; + + @Schema(description = "描述") + private String mark; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/enums/CodeMsg.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/enums/CodeMsg.java new file mode 100644 index 0000000..2025d83 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/enums/CodeMsg.java @@ -0,0 +1,100 @@ +package com.evotech.hd.common.core.enums; + +/** + * 100 Continue 继续。客户端应继续其请求 + 101 Switching Protocols 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议 + 200 OK 请求成功。一般用于GET与POST请求 + 201 Created 已创建。成功请求并创建了新的资源 + 202 Accepted 已接受。已经接受请求,但未处理完成 + 203 Non-Authoritative Information 非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本 + 204 No Content 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档 + 205 Reset Content 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域 + 206 Partial Content 部分内容。服务器成功处理了部分GET请求 + 300 Multiple Choices 多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择 + 301 Moved Permanently 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替 + 302 Found 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI + 303 See Other 查看其它地址。与301类似。使用GET和POST请求查看 + 304 Not Modified 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源 + 305 Use Proxy 使用代理。所请求的资源必须通过代理访问 + 306 Unused 已经被废弃的HTTP状态码 + 307 Temporary Redirect 临时重定向。与302类似。使用GET请求重定向 + 400 Bad Request 客户端请求的语法错误,服务器无法理解 + 401 Unauthorized 请求要求用户的身份认证 + 402 Payment Required 保留,将来使用 + 403 Forbidden 服务器理解请求客户端的请求,但是拒绝执行此请求 + 404 Not Found 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面 + 405 Method Not Allowed 客户端请求中的方法被禁止 + 406 Not Acceptable 服务器无法根据客户端请求的内容特性完成请求 + 407 Proxy Authentication Required 请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权 + 408 Request Time-out 服务器等待客户端发送的请求时间过长,超时 + 409 Conflict 服务器完成客户端的 PUT 请求时可能返回此代码,服务器处理请求时发生了冲突 + 410 Gone 客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置 + 411 Length Required 服务器无法处理客户端发送的不带Content-Length的请求信息 + 412 Precondition Failed 客户端请求信息的先决条件错误 + 413 Request Entity Too Large 由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息 + 414 Request-URI Too Large 请求的URI过长(URI通常为网址),服务器无法处理 + 415 Unsupported Media Type 服务器无法处理请求附带的媒体格式 + 416 Requested range not satisfiable 客户端请求的范围无效 + 417 Expectation Failed 服务器无法满足Expect的请求头信息 + 500 Internal Server Error 服务器内部错误,无法完成请求 + 501 Not Implemented 服务器不支持请求的功能,无法完成请求 + 502 Bad Gateway 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应 + 503 Service Unavailable 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中 + 504 Gateway Time-out 充当网关或代理的服务器,未及时从远端服务器获取请求 + 505 HTTP Version not supported 服务器不支持请求的HTTP协议的版本,无法完成处理 + */ +public enum CodeMsg { + // 统一回复 + SUCCESS("1000", "OK"), + ERROR("4000", "ERROR"), + // 系统错误 S + USERNAME_OR_PASSWORD_ERROR("S0400", "用户名或密码错误!"), + PASSWORD_ENTER_EXCEED_LIMIT("S0401", "用户输入密码次数超限!"), + USER_NOT_LOGIN("S0402", "用户未登陆!"), + AUTHENTICATION_FAILED("S0403", "认证失败!"), + TOKEN_INVALID("S0404", "无效token!"), + TOKEN_EXPIRED("S0405", "token已过期!"), + ACCESS_DENY("S0406", "访问未授权!"), + ACCESS_SCOPE_ERROR("S0407", "客户端权限范围出错"), + GATEWAY_EXECUTION_TIMEOUT("S0408", "网关执行超时"), + GATEWAY_EXECUTION_ERROR("S0409", "网关执行出错"), + // 业务错误 B + BUSSINESS_ERROR("B0400", "业务出错"), + PARAM_IS_NULL("B0401", "请求参数为空"), + PARAM_ERROR("B0402", "用户请求参数错误"), + UPLOAD_FILE_ERROR("B0403", "用户上传文件异常"), + UPLOAD_FILE_TYPE_NOT_MATCH("B0404", "用户上传文件类型不匹配"), + UPLOAD_FILE_SIZE_EXCEEDS("B0405", "用户上传文件太大"), + + // 数据库错误 D + DATABASE_ERROR("D0400", "数据库服务出错"), + DATA_EXIST("D0401", "此数据已存在!"), + DATABASE_RESULT_NULL("D0402", "查询结果为空"), + DATABASE_TABLE_NOT_EXIST("D0403", "表不存在"), + DATABASE_COLUMN_NOT_EXIST("D0404", "列不存在"), + SQL_RUN_ERROR("D0405", "sql运行异常"), + REDIS_ERROR("D0410", "REDIS数据出错"), + + // 小程序 w + WECHAT_LOGIN_ERROR("W0400", "小程序登录出错"), + WECHAT_SERRION_ERROR("W0401", "小程序登录态错误"), + WECHAT_API_ERROR("W0402", "小程序接口调用异常"); + + String code; + + String msg; + + public String getCode() { + return code; + } + + public String getMsg() { + return msg; + } + + CodeMsg(String code, String msg) { + this.code = code; + this.msg = msg; + } + +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/utils/SnowflakeUtil.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/utils/SnowflakeUtil.java new file mode 100644 index 0000000..f95833d --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/utils/SnowflakeUtil.java @@ -0,0 +1,22 @@ +package com.evotech.hd.common.core.utils; + +import cn.hutool.core.lang.Snowflake; +import cn.hutool.core.util.IdUtil; + +/** + * @author zrb + * @date 2024年9月5日10:25:58 + */ +public class SnowflakeUtil { + + public static final Snowflake sf = IdUtil.getSnowflake(1, 1); + + public static Long getId() { + return sf.nextId(); + } + + public static String getIdStr() { + return sf.nextIdStr(); + } + +} diff --git a/base-commons/common-mybatis/pom.xml b/base-commons/common-mybatis/pom.xml new file mode 100644 index 0000000..cc1aeaa --- /dev/null +++ b/base-commons/common-mybatis/pom.xml @@ -0,0 +1,51 @@ + + + + 4.0.0 + + com.evotech.hd + base-commons + 1.0.0-SNAPSHOT + + common-mybatis + + + com.mysql + mysql-connector-j + runtime + + + com.baomidou + mybatis-plus-spring-boot3-starter + + + + + + \ No newline at end of file diff --git a/base-commons/common-redis/pom.xml b/base-commons/common-redis/pom.xml new file mode 100644 index 0000000..fd98086 --- /dev/null +++ b/base-commons/common-redis/pom.xml @@ -0,0 +1,34 @@ + + + + 4.0.0 + + com.evotech.hd + base-commons + 1.0.0-SNAPSHOT + + common-redis + + + + + org.springframework.boot + spring-boot-starter-data-redis + + + com.fasterxml.jackson.core + jackson-annotations + + + com.fasterxml.jackson.core + jackson-core + + + com.fasterxml.jackson.core + jackson-databind + + + + \ No newline at end of file diff --git a/base-commons/common-redis/src/main/java/com/evotech/hd/common/redis/config/RedisConfig.java b/base-commons/common-redis/src/main/java/com/evotech/hd/common/redis/config/RedisConfig.java new file mode 100644 index 0000000..5da0a50 --- /dev/null +++ b/base-commons/common-redis/src/main/java/com/evotech/hd/common/redis/config/RedisConfig.java @@ -0,0 +1,71 @@ +package com.evotech.hd.common.redis.config; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +/** + * @author zrb + * @date 2024年9月3日17:13:42 + */ +@Configuration +public class RedisConfig { + /** + * 其实SpringBoot自动帮我们在容器中生成了一个RedisTemplate和一个StringRedisTemplate。 + * 但是,这个RedisTemplate的泛型是,写代码不方便,需要写好多类型转换的代码;我们需要一个泛型为形式的RedisTemplate + * 同时,设置key-value的序列化方式 + */ + @Bean + RedisTemplate redisTemplate(RedisConnectionFactory factory) { + RedisTemplate template = new RedisTemplate(); + template.setConnectionFactory(factory); + /* + * 设置序列化参数 + */ + // 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值 + ObjectMapper om = new ObjectMapper(); + // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public + om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常 + om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL); + // 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值 + Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(om, Object.class); + + + StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); + // key采用String的序列化方式 + template.setKeySerializer(stringRedisSerializer); + // value序列化方式 + template.setValueSerializer(jackson2JsonRedisSerializer); + // hash的key也采用String的序列化方式 + template.setHashKeySerializer(stringRedisSerializer); + // hash的value序列化方式采用jackson + template.setHashValueSerializer(jackson2JsonRedisSerializer); + + // RedisTemplate的初始化,我们上面没有设置到的参数会在这个方法中设置成默认的,若没有这个,缺少设置有时会报错 + template.afterPropertiesSet(); + return template; + } + + /*** + * 添加了这个类,SpringBoot不会帮我们自动生成StringRedisTemplate,为了方便程序中使用,我们自己生成一个放到容器中 + * stringRedisTemplate默认采用的是String的序列化策略 + * @param redisConnectionFactory + * @return + */ + @Bean + StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) { + StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(); + stringRedisTemplate.setConnectionFactory(redisConnectionFactory); + return stringRedisTemplate; + } +} \ No newline at end of file diff --git a/base-commons/common-redis/src/main/java/com/evotech/hd/common/redis/utils/RedisUtil.java b/base-commons/common-redis/src/main/java/com/evotech/hd/common/redis/utils/RedisUtil.java new file mode 100644 index 0000000..f8942aa --- /dev/null +++ b/base-commons/common-redis/src/main/java/com/evotech/hd/common/redis/utils/RedisUtil.java @@ -0,0 +1,663 @@ +package com.evotech.hd.common.redis.utils; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +/** + * @author zrb + * @date 2024年9月3日17:15:36 + */ +@Component +public class RedisUtil { + + /** + * 注入redisTemplate bean + */ + @Autowired + private RedisTemplate redisTemplate; + + /** + * 指定缓存失效时间 + * + * @param key 键 + * @param time 时间(秒) + * @return + */ + public boolean expire(String key, long time) { + try { + if (time > 0) { + redisTemplate.expire(key, time, TimeUnit.SECONDS); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 根据key获取过期时间 + * + * @param key 键 不能为null + * @return 时间(秒) 返回0代表为永久有效 + */ + public long getExpire(String key) { + return redisTemplate.getExpire(key, TimeUnit.SECONDS); + } + + /** + * 判断key是否存在 + * + * @param key 键 + * @return true 存在 false不存在 + */ + public boolean hasKey(String key) { + try { + return redisTemplate.hasKey(key); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 删除缓存 + * + * @param key 可以传一个值 或多个 + */ + @SuppressWarnings("unchecked") + public void del(String... key) { + if (key != null && key.length > 0) { + if (key.length == 1) { + redisTemplate.delete(key[0]); + } else { + redisTemplate.delete((List) CollectionUtils.arrayToList(key)); + } + } + } + // ============================String(字符串)============================= + + /** + * 普通缓存获取 + * + * @param key 键 + * @return 值 + */ + public Object get(String key) { + return key == null ? null : redisTemplate.opsForValue().get(key); + } + + /** + * 普通缓存放入 + * + * @param key 键 + * @param value 值 + * @return true成功 false失败 + */ + public boolean set(String key, Object value) { + try { + redisTemplate.opsForValue().set(key, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 普通缓存放入并设置时间 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 + * @return true成功 false 失败 + */ + public boolean set(String key, Object value, long time) { + try { + if (time > 0) { + redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); + } else { + set(key, value); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 递增 + * + * @param key 键 + * @param delta 要增加几(大于0) + * @return + */ + public long incr(String key, long delta) { + if (delta < 0) { + throw new RuntimeException("递增因子必须大于0"); + } + return redisTemplate.opsForValue().increment(key, delta); + } + + /** + * 递减 + * + * @param key 键 + * @param delta 要减少几(小于0) + * @return + */ + public long decr(String key, long delta) { + if (delta < 0) { + throw new RuntimeException("递减因子必须大于0"); + } + return redisTemplate.opsForValue().increment(key, -delta); + } + // ================================Hash(哈希)================================= + + /** + * HashGet + * + * @param key 键 不能为null + * @param item 项 不能为null + * @return 值 + */ + public Object hget(String key, String item) { + return redisTemplate.opsForHash().get(key, item); + } + + /** + * 获取hashKey对应的所有键值 + * + * @param key 键 + * @return 对应的多个键值 + */ + public Map hmget(String key) { + return redisTemplate.opsForHash().entries(key); + } + + /** + * HashSet + * + * @param key 键 + * @param map 对应多个键值 + * @return true 成功 false 失败 + */ + public boolean hmset(String key, Map map) { + try { + redisTemplate.opsForHash().putAll(key, map); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * HashSet 并设置时间 + * + * @param key 键 + * @param map 对应多个键值 + * @param time 时间(秒) + * @return true成功 false失败 + */ + public boolean hmset(String key, Map map, long time) { + try { + redisTemplate.opsForHash().putAll(key, map); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * + * @param key 键 + * @param item 项 + * @param value 值 + * @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value) { + try { + redisTemplate.opsForHash().put(key, item, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * + * @param key 键 + * @param item 项 + * @param value 值 + * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 + * @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value, long time) { + try { + redisTemplate.opsForHash().put(key, item, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 删除hash表中的值 + * + * @param key 键 不能为null + * @param item 项 可以使多个 不能为null + */ + public void hdel(String key, Object... item) { + redisTemplate.opsForHash().delete(key, item); + } + + /** + * 判断hash表中是否有该项的值 + * + * @param key 键 不能为null + * @param item 项 不能为null + * @return true 存在 false不存在 + */ + public boolean hHasKey(String key, String item) { + return redisTemplate.opsForHash().hasKey(key, item); + } + + /** + * hash递增 如果不存在,就会创建一个 并把新增后的值返回 + * + * @param key 键 + * @param item 项 + * @param by 要增加几(大于0) + * @return + */ + public double hincr(String key, String item, double by) { + return redisTemplate.opsForHash().increment(key, item, by); + } + + /** + * hash递减 + * + * @param key 键 + * @param item 项 + * @param by 要减少记(小于0) + * @return + */ + public double hdecr(String key, String item, double by) { + return redisTemplate.opsForHash().increment(key, item, -by); + } + // ============================Set(集合)============================= + + /** + * 根据key获取Set中的所有值 + * + * @param key 键 + * @return + */ + public Set sGet(String key) { + try { + return redisTemplate.opsForSet().members(key); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 根据value从一个set中查询,是否存在 + * + * @param key 键 + * @param value 值 + * @return true 存在 false不存在 + */ + public boolean sHasKey(String key, Object value) { + try { + return redisTemplate.opsForSet().isMember(key, value); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将数据放入set缓存 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSet(String key, Object... values) { + try { + return redisTemplate.opsForSet().add(key, values); + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 将set数据放入缓存 + * + * @param key 键 + * @param time 时间(秒) + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSetAndTime(String key, long time, Object... values) { + try { + Long count = redisTemplate.opsForSet().add(key, values); + if (time > 0) { + expire(key, time); + } + return count; + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 获取set缓存的长度 + * + * @param key 键 + * @return + */ + public long sGetSetSize(String key) { + try { + return redisTemplate.opsForSet().size(key); + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 移除值为value的 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 移除的个数 + */ + public long setRemove(String key, Object... values) { + try { + Long count = redisTemplate.opsForSet().remove(key, values); + return count; + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + // ===============================List(列表)================================= + + /** + * 获取list缓存的内容 + * + * @param key 键 + * @param start 开始 + * @param end 结束 0 到 -1代表所有值 + * @return + */ + public List lGet(String key, long start, long end) { + try { + return redisTemplate.opsForList().range(key, start, end); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 获取list缓存的长度 + * + * @param key 键 + * @return + */ + public long lGetListSize(String key) { + try { + return redisTemplate.opsForList().size(key); + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 通过索引 获取list中的值 + * + * @param key 键 + * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 + * @return + */ + public Object lGetIndex(String key, long index) { + try { + return redisTemplate.opsForList().index(key, index); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @return + */ + public boolean lSet(String key, Object value) { + try { + redisTemplate.opsForList().rightPush(key, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, Object value, long time) { + try { + redisTemplate.opsForList().rightPush(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将list放入缓存 + * 要放数组,放list就是个bug,list先转数组 + * @param key 键 + * @param value 值 + * @return + */ + public boolean lSet(String key, Object[] value) { + try { + redisTemplate.opsForList().rightPushAll(key, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将list放入缓存 + * 要放数组,放list就是个bug,list先转数组 + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, Object[] value, long time) { + try { + redisTemplate.opsForList().rightPushAll(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 移出并获取列表的第一个元素 + * + * @param key + * @return 删除的元素 + */ + public Object lLeftPop(String key) { + return redisTemplate.opsForList().leftPop(key); + } + + /** + * 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止 + * + * @param key + * @param timeout + * 等待时间 + * @param unit + * 时间单位 + * @return + */ + public Object lBLeftPop(String key, long timeout, TimeUnit unit) { + return redisTemplate.opsForList().leftPop(key, timeout, unit); + } + + /** + * 移除并获取列表最后一个元素 + * + * @param key + * @return 删除的元素 + */ + public Object lRightPop(String key) { + return redisTemplate.opsForList().rightPop(key); + } + + /** + * 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止 + * + * @param key + * @param timeout + * 等待时间 + * @param unit + * 时间单位 + * @return + */ + public Object lBRightPop(String key, long timeout, TimeUnit unit) { + return redisTemplate.opsForList().rightPop(key, timeout, unit); + } + + /** + * 移除列表的最后一个元素,并将该元素添加到另一个列表并返回 + * + * @param sourceKey + * @param destinationKey + * @return + */ + public Object lRightPopAndLeftPush(String sourceKey, String destinationKey) { + return redisTemplate.opsForList().rightPopAndLeftPush(sourceKey, + destinationKey); + } + + /** + * 从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止 + * + * @param sourceKey + * @param destinationKey + * @param timeout + * @param unit + * @return + */ + public Object lBRightPopAndLeftPush(String sourceKey, String destinationKey, + long timeout, TimeUnit unit) { + return redisTemplate.opsForList().rightPopAndLeftPush(sourceKey, + destinationKey, timeout, unit); + } + + /** + * 根据索引修改list中的某条数据 + * + * @param key 键 + * @param index 索引 + * @param value 值 + * @return + */ + public boolean lUpdateIndex(String key, long index, Object value) { + try { + redisTemplate.opsForList().set(key, index, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 移除N个值为value + * + * @param key 键 + * @param count 移除多少个 + * @param value 值 + * @return 移除的个数 + */ + public long lRemove(String key, long count, Object value) { + try { + Long remove = redisTemplate.opsForList().remove(key, count, value); + return remove; + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 根据正则表达式获取key列表 + * + * @param patternKey 正则表达式 + * @return 匹配key列表 + */ + public Set keys(String patternKey) { + try { + Set keys = redisTemplate.keys(patternKey); + return keys; + } catch (Exception e) { + e.printStackTrace(); + return new HashSet<>(); + } + } + +} diff --git a/base-commons/common-web/pom.xml b/base-commons/common-web/pom.xml new file mode 100644 index 0000000..31b86f8 --- /dev/null +++ b/base-commons/common-web/pom.xml @@ -0,0 +1,72 @@ + + + + 4.0.0 + + com.evotech.hd + base-commons + 1.0.0-SNAPSHOT + + common-web + + + + com.evotech.hd + common-core + 1.0.0-SNAPSHOT + + + + org.projectlombok + lombok + true + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework + spring-jdbc + + + + com.github.xiaoymin + knife4j-openapi3-jakarta-spring-boot-starter + + + + jakarta.servlet + jakarta.servlet-api + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + de.codecentric + spring-boot-admin-starter-client + + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + + + + org.springframework.boot + spring-boot-configuration-processor + + + + \ No newline at end of file diff --git a/base-commons/common-web/src/main/java/com/evotech/hd/common/web/exception/GlobalExceptionHandler.java b/base-commons/common-web/src/main/java/com/evotech/hd/common/web/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..17c7d6e --- /dev/null +++ b/base-commons/common-web/src/main/java/com/evotech/hd/common/web/exception/GlobalExceptionHandler.java @@ -0,0 +1,84 @@ +package com.evotech.hd.common.web.exception; + +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.enums.CodeMsg; + +import jakarta.servlet.http.HttpServletRequest; +import lombok.extern.slf4j.Slf4j; + +/** + * 全局异常处理 + * @author zrb + */ + +/** + * @RestControllerAdvice注解和controller相对应, + * 若用controller,则此处用ControllerAdvice, + * 若用RestController,此处用@RestControllerAdvice + */ +@RestControllerAdvice +@Slf4j +public class GlobalExceptionHandler { + + /** + * 处理空指针的异常 + * @param req + * @param e + */ + @ExceptionHandler(value = NullPointerException.class) + public Result exceptionHandler(HttpServletRequest req, NullPointerException e) { + log.error("空指针异常:", e); + return new Result().bussinessException(CodeMsg.ERROR.getCode(), e.getMessage(), null); + } + + + /** + * Http请求消息异常 + */ + @ExceptionHandler(value = HttpMessageNotReadableException.class) + public Result exceptionHandler(HttpServletRequest req, HttpMessageNotReadableException e) { + log.error("http请求参数解析异常:", e); + return new Result().bussinessException(CodeMsg.PARAM_ERROR.getCode(), "http请求参数解析异常", e.getMessage()); + } + + /** + * 参数校验异常 + * @param req + * @param e + */ + @ExceptionHandler(value = MyArgumentException.class) + public Result exceptionHandler(HttpServletRequest req, MyArgumentException e) { + log.error("请求参数异常:", e); + return new Result().bussinessException(CodeMsg.PARAM_ERROR.getCode(), CodeMsg.PARAM_ERROR.getMsg(), e.getParamArr()); + } + + + /** + * 这个异常的意思就是在更新(update或insert)数据库时,新的数据违反了完整性, + * 例如主键重复,我这里的问题是数据库的id字段未设置自增,默认值也没设,在插入的时候就出现了这个异常 + * @param req + * @param e + */ + @ExceptionHandler(value = DataIntegrityViolationException.class) + public Result exceptionHandler(HttpServletRequest req, DataIntegrityViolationException e) { + log.error("sql语句异常:", e); + return new Result().bussinessException(CodeMsg.SQL_RUN_ERROR.getCode(), e.getCause().toString(), null); + } + + /** + * 自己抛出的运行异常 + * @param req + * @param e + */ + @ExceptionHandler(value = Exception.class) + public Result exceptionHandler(HttpServletRequest req, RuntimeException e) { + log.error("捕获运行异常:", e); + return new Result().bussinessException(CodeMsg.ERROR.getCode(), e instanceof RuntimeException?e.getMessage():e.toString(), null); + } + +} diff --git a/base-commons/common-web/src/main/java/com/evotech/hd/common/web/exception/MyArgumentException.java b/base-commons/common-web/src/main/java/com/evotech/hd/common/web/exception/MyArgumentException.java new file mode 100644 index 0000000..4aea354 --- /dev/null +++ b/base-commons/common-web/src/main/java/com/evotech/hd/common/web/exception/MyArgumentException.java @@ -0,0 +1,41 @@ +package com.evotech.hd.common.web.exception; + +public class MyArgumentException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + /** + * 请求的参数数据,若参数校验不通过,此字段存储请求参数,返回前端 + */ + private String[] paramArr; + + public String[] getParamArr() { + return paramArr; + } + + public void setParamArr(String[] paramArr) { + this.paramArr = paramArr; + } + + public MyArgumentException() { + super(); + } + + public MyArgumentException(String message) { + super(message); + } + + public MyArgumentException(String message, String params) { + super(message); + this.paramArr = params.split(","); + } + + public MyArgumentException(String message, Throwable cause) { + super(message, cause); + } + + public MyArgumentException(Throwable cause) { + super(cause); + } + +} diff --git a/base-commons/common-web/src/main/java/com/evotech/hd/common/web/filter/MyFilterConfig.java b/base-commons/common-web/src/main/java/com/evotech/hd/common/web/filter/MyFilterConfig.java new file mode 100644 index 0000000..e81c0b0 --- /dev/null +++ b/base-commons/common-web/src/main/java/com/evotech/hd/common/web/filter/MyFilterConfig.java @@ -0,0 +1,29 @@ +package com.evotech.hd.common.web.filter; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import jakarta.servlet.Filter; + +@Configuration +public class MyFilterConfig { + + @Autowired + private RequestBodyFilter requestBodyFilter; + + /** + * 将过滤器注册到FilterRegistrationBean中 + * 进行简单配置 + */ + @Bean + FilterRegistrationBean myFilterRegistration() { + FilterRegistrationBean registration = new FilterRegistrationBean<>(); + registration.setFilter(requestBodyFilter); + registration.addUrlPatterns("/*"); + registration.setName("requestBodyFilter"); + return registration; + } + +} diff --git a/base-commons/common-web/src/main/java/com/evotech/hd/common/web/filter/MyHttpServletRequestWrapper.java b/base-commons/common-web/src/main/java/com/evotech/hd/common/web/filter/MyHttpServletRequestWrapper.java new file mode 100644 index 0000000..2a15e0c --- /dev/null +++ b/base-commons/common-web/src/main/java/com/evotech/hd/common/web/filter/MyHttpServletRequestWrapper.java @@ -0,0 +1,106 @@ +package com.evotech.hd.common.web.filter; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.nio.CharBuffer; +import java.nio.charset.Charset; + +import jakarta.servlet.ReadListener; +import jakarta.servlet.ServletInputStream; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; + +/** + * 自定义request对象,将body处理后,放到这个对象里面, + * 一定要重写getReader()和getInputStream()方法,将body放进去, + * 这样后面的controller才能从这个request的getReader()和getInputStream() + * 方法中拿到新的body对象 + * @author zrb + */ +public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper { + + private byte[] body; + + public MyHttpServletRequestWrapper(HttpServletRequest request) { + super(request); + + final StringBuilder builder = new StringBuilder(); + // 缓存按 8192 大小 + final CharBuffer buffer = CharBuffer.allocate(2 << 12); + BufferedReader reader = null; + try { + reader = request.getReader(); + while (-1 != reader.read(buffer)) { + builder.append(buffer.flip()); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + reader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + String bodyStr = builder.toString(); + try { + bodyStr = URLDecoder.decode(bodyStr, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + throw new RuntimeException("body解码出错!"); + } + body = bodyStr.getBytes(Charset.defaultCharset()); + } + + + + public byte[] getBody() { + return body; + } + + + + @Override + public BufferedReader getReader() throws IOException { + return new BufferedReader(new InputStreamReader(getInputStream())); + } + + + @Override + public ServletInputStream getInputStream() throws IOException { + final ByteArrayInputStream bais = new ByteArrayInputStream(body); + return new ServletInputStream() { + @Override + public boolean isFinished() { + return bais.available() == 0; + } + + @Override + public boolean isReady() { + return true; + } + + @Override + public void setReadListener(ReadListener readListener) { + + } + + @Override + public int read() throws IOException { + return bais.read(); + } + }; + + + } + + + + + +} diff --git a/base-commons/common-web/src/main/java/com/evotech/hd/common/web/filter/RequestBodyFilter.java b/base-commons/common-web/src/main/java/com/evotech/hd/common/web/filter/RequestBodyFilter.java new file mode 100644 index 0000000..f71d44f --- /dev/null +++ b/base-commons/common-web/src/main/java/com/evotech/hd/common/web/filter/RequestBodyFilter.java @@ -0,0 +1,50 @@ +package com.evotech.hd.common.web.filter; + +import java.io.IOException; +import org.apache.http.entity.ContentType; +import org.springframework.http.HttpMethod; +import org.springframework.stereotype.Component; + +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; + +/** + * gateway转发参数时,有特殊符号如 * +等经过了urlencode,无法正确接收, + * 加过滤器将 body进行urldecode + * + * 注意的问题:RequestBody注解的数据, + * 要通过request的getReader和getInputStream()方法来获取流数据,然后转变为字符串的 + * 但是流读取一次后就关闭了,在filter中读取了以后,controller中就拿不到数据了 + * 为此,我们自定义一个HttpServletRequestWrapper对象,将拿到的数据在放到这个对象中, + * 并将这个对象从chain.doFilter()方法中继续传下去,后续就能继续读取了 + * + * @author zrb + * + */ +@Component +public class RequestBodyFilter implements Filter { + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + HttpServletRequest req = (HttpServletRequest) request; + String contextPath = request.getServletContext().getContextPath(); + boolean b1 = HttpMethod.POST.name().equals(req.getMethod()); + boolean b2 = ContentType.APPLICATION_JSON.getMimeType().equals(request.getContentType()); + boolean b3 = request.getParameterMap().isEmpty(); + boolean b4 = contextPath.contains("/audit") || + contextPath.contains("/rule"); + if (b1 && b2 && b3 && b4) { + MyHttpServletRequestWrapper requestWrapper = new MyHttpServletRequestWrapper(req); + chain.doFilter(requestWrapper, response); + } else { + chain.doFilter(request, response); + } + + } + +} diff --git a/base-commons/common-web/src/main/java/com/evotech/hd/common/web/swagger/SwaggerTips.java b/base-commons/common-web/src/main/java/com/evotech/hd/common/web/swagger/SwaggerTips.java new file mode 100644 index 0000000..c8da9a5 --- /dev/null +++ b/base-commons/common-web/src/main/java/com/evotech/hd/common/web/swagger/SwaggerTips.java @@ -0,0 +1,54 @@ +package com.evotech.hd.common.web.swagger; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.core.annotation.Order; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; + +/** + * 项目启动后查看swagger情况 + */ +@ConditionalOnProperty(prefix = "knife4j", name = "enable", matchIfMissing = false) +@Component +@Order(value = 99) +@Slf4j +public class SwaggerTips implements ApplicationRunner { + + @Resource + private Environment env; + + /** + * 项目启动后,若开启了swagger,输出swagger地址 + */ + @Override + public void run(ApplicationArguments args) throws Exception { + Boolean b = env.getProperty("knife4j.enable", Boolean.class); + if (b != null && b) { + int port = env.getProperty("server.port", Integer.class) == null?8080:env.getProperty("server.port", Integer.class); + String address = "127.0.0.1"; + try { + address = InetAddress.getLocalHost().getHostAddress(); + } catch (UnknownHostException e) { + address = "192.168.5.213"; + e.printStackTrace(); + } + String url = "http://" + address + ":" + port; + String path = env.getProperty("server.servlet.context-path"); + + if (StringUtils.hasText(path)) { + url += path; + } + log.info("\r\nswagger已开启,访问地址:{}", url + "/doc.html"); + } + } + +} diff --git a/base-commons/common-web/src/main/java/com/evotech/hd/common/web/thread/ThreadPoolConfig.java b/base-commons/common-web/src/main/java/com/evotech/hd/common/web/thread/ThreadPoolConfig.java new file mode 100644 index 0000000..9e37621 --- /dev/null +++ b/base-commons/common-web/src/main/java/com/evotech/hd/common/web/thread/ThreadPoolConfig.java @@ -0,0 +1,48 @@ +package com.evotech.hd.common.web.thread; + +import java.util.concurrent.ThreadPoolExecutor; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +@ConditionalOnProperty(prefix = "threadpool", name = "enable", matchIfMissing = false) +@Configuration +public class ThreadPoolConfig { + + + @Bean + @ConditionalOnClass({ThreadPoolProperties.class}) + ThreadPoolProperties tpProperties() { + return new ThreadPoolProperties(); + } + + @Bean + ThreadPoolTaskExecutor taskExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setCorePoolSize(tpProperties().getCorePoolSize()); + executor.setMaxPoolSize(tpProperties().getMaxPoolSize()); + executor.setQueueCapacity(tpProperties().getQueueCapacity()); + executor.setThreadNamePrefix(tpProperties().getThreadNamePrefix()); + // 设置线程保持活跃的时间(默认:60) + executor.setKeepAliveSeconds(tpProperties().getKeepAliveTime()); + // 当任务完成后,长时间无待处理任务时,销毁线程池 + executor.setWaitForTasksToCompleteOnShutdown(tpProperties().isWaitForTasksToCompleteOnShutdown()); + executor.setAwaitTerminationSeconds(tpProperties().getAwaitTerminationSeconds()); + // 设置任务拒绝策略 + /** + * 4种 + * ThreadPoolExecutor类有几个内部实现类来处理这类情况: + - AbortPolicy 丢弃任务,抛RejectedExecutionException + - CallerRunsPolicy 由该线程调用线程运行。直接调用Runnable的run方法运行。 + - DiscardPolicy 抛弃策略,直接丢弃这个新提交的任务 + - DiscardOldestPolicy 抛弃旧任务策略,从队列中踢出最先进入队列(最后一个执行)的任务 + * 实现RejectedExecutionHandler接口,可自定义处理器 + */ + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + return executor; + } + +} diff --git a/base-commons/common-web/src/main/java/com/evotech/hd/common/web/thread/ThreadPoolProperties.java b/base-commons/common-web/src/main/java/com/evotech/hd/common/web/thread/ThreadPoolProperties.java new file mode 100644 index 0000000..37361af --- /dev/null +++ b/base-commons/common-web/src/main/java/com/evotech/hd/common/web/thread/ThreadPoolProperties.java @@ -0,0 +1,35 @@ +package com.evotech.hd.common.web.thread; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +import lombok.Data; + + + +@ConditionalOnProperty(prefix = "threadpool", name = "enable", matchIfMissing = false) +@ConfigurationProperties(prefix = "threadpool", ignoreUnknownFields = true) +@Data +@Component +public class ThreadPoolProperties { + + private boolean enable; + + private int corePoolSize; + + private int maxPoolSize; + + private int keepAliveTime; + + private int queueCapacity; + + private String threadNamePrefix; + + private boolean allowCoreThreadTimeout; + + private boolean waitForTasksToCompleteOnShutdown; + + private int awaitTerminationSeconds; + +} diff --git a/base-commons/common-web/src/main/java/com/evotech/hd/common/web/util/IpUtil.java b/base-commons/common-web/src/main/java/com/evotech/hd/common/web/util/IpUtil.java new file mode 100644 index 0000000..a502a7e --- /dev/null +++ b/base-commons/common-web/src/main/java/com/evotech/hd/common/web/util/IpUtil.java @@ -0,0 +1,68 @@ +package com.evotech.hd.common.web.util; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +import jakarta.servlet.http.HttpServletRequest; + +/** + * + * @author zrb + * @date 2024年9月6日09:03:11 + */ +public class IpUtil { + + private static final String IP_UNKNOWN = "unknown"; + private static final String IP_LOCAL = "127.0.0.1"; + private static final int IP_LEN = 15; + + /** + * 获取客户端真实ip + * location / { + ... + # 后端的Web服务器可以通过X-Forwarded-For获取用户真实IP + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + ... + } + */ + public static String getRemoteIP(HttpServletRequest request) { +// HttpHeaders headers = request.getHeaders(); + String ipAddress = request.getHeader("x-forwarded-for"); + if (ipAddress == null || ipAddress.length() == 0 || IP_UNKNOWN.equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("Proxy-Client-IP"); + } + if (ipAddress == null || ipAddress.length() == 0 || IP_UNKNOWN.equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("WL-Proxy-Client-IP"); + } + if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("HTTP_CLIENT_IP"); + } + if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("HTTP_X_FORWARDED_FOR"); + } + if (ipAddress == null || ipAddress.length() == 0 || IP_UNKNOWN.equalsIgnoreCase(ipAddress)) { + ipAddress = request.getRemoteAddr(); + if (IP_LOCAL.equals(ipAddress)) { + // 根据网卡取本机配置的IP + try { + InetAddress inet = InetAddress.getLocalHost(); + ipAddress = inet.getHostAddress(); + } catch (UnknownHostException e) { + + } + } + } + + // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割 + if (ipAddress != null && ipAddress.length() > IP_LEN) { + int index = ipAddress.indexOf(","); + if (index > 0) { + ipAddress = ipAddress.substring(0, index); + } + } + return ipAddress; + } + +} diff --git a/base-commons/common-web/src/main/java/com/evotech/hd/common/web/util/RequestContextUtil.java b/base-commons/common-web/src/main/java/com/evotech/hd/common/web/util/RequestContextUtil.java new file mode 100644 index 0000000..8190789 --- /dev/null +++ b/base-commons/common-web/src/main/java/com/evotech/hd/common/web/util/RequestContextUtil.java @@ -0,0 +1,34 @@ +package com.evotech.hd.common.web.util; + +import org.springframework.util.StringUtils; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import com.evotech.hd.common.core.constant.HDConstant; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +public class RequestContextUtil { + + public static ServletRequestAttributes requestAttributes() { + return (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + } + + public static HttpServletRequest httpServletRequest() { + return requestAttributes().getRequest(); + } + + public static HttpServletResponse httpServletResponse() { + return requestAttributes().getResponse(); + } + + public static String getToken() { + String authorization = httpServletRequest().getHeader(HDConstant.AUTHORIZATION_KEY); + if (StringUtils.hasLength(authorization) && authorization.contains(HDConstant.JWT_PREFIX)) { + return authorization.substring(HDConstant.JWT_PREFIX.length()); + } + return null; + } + +} diff --git a/base-commons/pom.xml b/base-commons/pom.xml new file mode 100644 index 0000000..a2a5a4f --- /dev/null +++ b/base-commons/pom.xml @@ -0,0 +1,19 @@ + + + + 4.0.0 + + com.evotech.hd + battery-cloud + 1.0.0-SNAPSHOT + + base-commons + pom + + common-core + common-web + common-mybatis + common-redis + + \ No newline at end of file diff --git a/cloud-manage-server/.gitignore b/cloud-manage-server/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/cloud-manage-server/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/cloud-manage-server/pom.xml b/cloud-manage-server/pom.xml new file mode 100644 index 0000000..6cf32e5 --- /dev/null +++ b/cloud-manage-server/pom.xml @@ -0,0 +1,100 @@ + + + + 4.0.0 + + com.evotech.hd + battery-cloud + 1.0.0-SNAPSHOT + + cloud-manage-server + cloud-manage-server + 云平台服务 + + + 17 + + + + com.evotech.hd + common-web + 1.0.0-SNAPSHOT + + + + com.evotech.hd + common-mybatis + 1.0.0-SNAPSHOT + + + + com.evotech.hd + common-redis + 1.0.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-integration + + + org.springframework.integration + spring-integration-mqtt + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + + com.baomidou + dynamic-datasource-spring-boot3-starter + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + cn.hutool + hutool-json + + + cn.hutool + hutool-crypto + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/CloudManageServerApplication.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/CloudManageServerApplication.java new file mode 100644 index 0000000..631cb48 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/CloudManageServerApplication.java @@ -0,0 +1,20 @@ +package com.evotech.hd.cloud; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication(exclude = DataSourceAutoConfiguration.class) +@EnableDiscoveryClient +@ComponentScan("com.evotech.hd.**") +@MapperScan({"com.evotech.hd.cloud.dao.**", "com.evotech.hd.common.core.dao.**"}) +public class CloudManageServerApplication { + + public static void main(String[] args) { + SpringApplication.run(CloudManageServerApplication.class, args); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationController.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationController.java new file mode 100644 index 0000000..c07bcf6 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationController.java @@ -0,0 +1,72 @@ +package com.evotech.hd.cloud.controller; + +import java.util.List; +import java.util.Map; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.cloud.entity.request.PageListBatteryStationRequest; +import com.evotech.hd.cloud.service.BatteryStationService; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.BatteryStation; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; + +@Tag(name = "换电站") +@ApiSupport(order = 11) +@RestController +@RequestMapping("/batterystation") +public class BatteryStationController { + + @Resource + private BatteryStationService batteryStationService; + + @Operation(summary = "增加") + @PostMapping("/add") + @ApiOperationSupport(order = 1) + public Result add(@Valid @ParameterObject BatteryStation bs) { + return batteryStationService.add(bs); + } + + @Operation(summary = "删除") + @PostMapping("/del") + @ApiOperationSupport(order = 2) + public Result delete(Integer id) { + return batteryStationService.delete(id); + } + + @Operation(summary = "修改") + @PostMapping({"/update"}) + @ApiOperationSupport(order = 3) + public Result update(@ParameterObject BatteryStation bs) { + return batteryStationService.update(bs); + } + + @Operation(summary = "查询") + @GetMapping("/list") + @ApiOperationSupport(order = 4) + public Result> list(@ParameterObject PageListBatteryStationRequest plbsr) { + return batteryStationService.list(plbsr); + } + + + @Operation(summary = "站点秘钥") + @PostMapping("/rsa_secret_key") + @ApiOperationSupport(order = 5) + public Result> RsaSecretKey(@NotBlank @RequestParam String stationCode) { + return batteryStationService.RsaSecretKey(stationCode); + } + + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationDcController.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationDcController.java new file mode 100644 index 0000000..0126cb4 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationDcController.java @@ -0,0 +1,87 @@ +package com.evotech.hd.cloud.controller; + +import java.util.List; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.cloud.entity.request.PageListBatteryStationDcRequest; +import com.evotech.hd.cloud.service.BatteryStationDcService; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.BatteryStationDc; +import com.evotech.hd.common.core.entity.cloud.BatteryTrace; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; + +@Tag(name = "换电站电池") +@ApiSupport(order = 12) +@RestController +@RequestMapping("/batterystation/dc") +public class BatteryStationDcController { + + + @Resource + private BatteryStationDcService batteryStationDcService; + + @Operation(summary = "增加") + @PostMapping("/add") + @ApiOperationSupport(order = 1) + public Result add(@Valid @ParameterObject BatteryStationDc bsdc) { + return batteryStationDcService.add(bsdc); + } + + @Operation(summary = "删除") + @PostMapping("/del") + @ApiOperationSupport(order = 2) + public Result delete(Integer id) { + return batteryStationDcService.delete(id); + } + + @Operation(summary = "修改") + @PostMapping({"/update"}) + @ApiOperationSupport(order = 3) + public Result update(@ParameterObject BatteryStationDc bsdc) { + return batteryStationDcService.update(bsdc); + } + + @Operation(summary = "查询") + @GetMapping("/list") + @ApiOperationSupport(order = 4) + public Result> list(@ParameterObject PageListBatteryStationDcRequest plbsdcr) { + return batteryStationDcService.list(plbsdcr); + } + + + @Operation(summary = "追溯") + @GetMapping("/trace/list") + @ApiOperationSupport(order = 5) + public Result> listTrace(@NotBlank String batteryCode) { + return batteryStationDcService.listTrace(batteryCode); + } + + + @Operation(summary = "增加追溯") + @PostMapping("/trace/add") + @ApiOperationSupport(order = 6) + public Result addTrace(@Valid @ParameterObject BatteryTrace bt) { + return batteryStationDcService.addTrace(bt); + } + + + @Operation(summary = "删除追溯") + @PostMapping("/trace/del") + @ApiOperationSupport(order = 7) + public Result deleteTrace(Integer id) { + return batteryStationDcService.deleteTrace(id); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationDccController.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationDccController.java new file mode 100644 index 0000000..9720b6a --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationDccController.java @@ -0,0 +1,61 @@ +package com.evotech.hd.cloud.controller; + +import java.util.List; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.cloud.entity.request.PageListBatteryStationDccRequest; +import com.evotech.hd.cloud.service.BatteryStationDccService; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.BatteryStationDcc; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; + +@Tag(name = "换电站电池仓") +@ApiSupport(order = 13) +@RestController +@RequestMapping("/batterystation/dcc") +public class BatteryStationDccController { + + + @Resource + private BatteryStationDccService batteryStationDccService; + + @Operation(summary = "增加") + @PostMapping("/add") + @ApiOperationSupport(order = 1) + public Result add(@Valid @ParameterObject BatteryStationDcc bsdcc) { + return batteryStationDccService.add(bsdcc); + } + + @Operation(summary = "删除") + @PostMapping("/del") + @ApiOperationSupport(order = 2) + public Result delete(Integer id) { + return batteryStationDccService.delete(id); + } + + @Operation(summary = "修改") + @PostMapping({"/update"}) + @ApiOperationSupport(order = 3) + public Result update(@ParameterObject BatteryStationDcc bsdcc) { + return batteryStationDccService.update(bsdcc); + } + + @Operation(summary = "查询") + @GetMapping("/list") + @ApiOperationSupport(order = 4) + public Result> list(@ParameterObject PageListBatteryStationDccRequest plbsDccr) { + return batteryStationDccService.list(plbsDccr); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationDjController.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationDjController.java new file mode 100644 index 0000000..9268486 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationDjController.java @@ -0,0 +1,61 @@ +package com.evotech.hd.cloud.controller; + +import java.util.List; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.cloud.entity.request.PageListBatteryStationDjRequest; +import com.evotech.hd.cloud.service.BatteryStationDjService; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.BatteryStationDj; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; + +@Tag(name = "换电站电机") +@ApiSupport(order = 14) +@RestController +@RequestMapping("/batterystation/dj") +public class BatteryStationDjController { + + + @Resource + private BatteryStationDjService batteryStationDjService; + + @Operation(summary = "增加") + @PostMapping("/add") + @ApiOperationSupport(order = 1) + public Result add(@Valid BatteryStationDj bsdj) { + return batteryStationDjService.add(bsdj); + } + + @Operation(summary = "删除") + @PostMapping("/del") + @ApiOperationSupport(order = 2) + public Result delete(Integer id) { + return batteryStationDjService.delete(id); + } + + @Operation(summary = "修改") + @PostMapping({"/update"}) + @ApiOperationSupport(order = 3) + public Result update(@ParameterObject BatteryStationDj bsdj) { + return batteryStationDjService.update(bsdj); + } + + @Operation(summary = "查询") + @GetMapping("/list") + @ApiOperationSupport(order = 4) + public Result> list(@ParameterObject PageListBatteryStationDjRequest plbsdjr) { + return batteryStationDjService.list(plbsdjr); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationHdFeeStandardController.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationHdFeeStandardController.java new file mode 100644 index 0000000..086f472 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationHdFeeStandardController.java @@ -0,0 +1,60 @@ +package com.evotech.hd.cloud.controller; + +import java.util.List; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.cloud.service.BatteryStationHdFeeStandardService; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.BatteryStationHdFeeStandard; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; + +@Tag(name = "换电站费用标准") +@ApiSupport(order = 16) +@RestController +@RequestMapping("/batterystation/fee") +public class BatteryStationHdFeeStandardController { + + + @Resource + private BatteryStationHdFeeStandardService batteryStationHdFeeStandardService; + + @Operation(summary = "增加") + @PostMapping("/add") + @ApiOperationSupport(order = 1) + public Result add(@Valid @ParameterObject BatteryStationHdFeeStandard bsfs) { + return batteryStationHdFeeStandardService.add(bsfs); + } + + @Operation(summary = "删除") + @PostMapping("/del") + @ApiOperationSupport(order = 2) + public Result delete(Integer id) { + return batteryStationHdFeeStandardService.delete(id); + } + + @Operation(summary = "修改") + @PostMapping({"/update"}) + @ApiOperationSupport(order = 3) + public Result update(@ParameterObject BatteryStationHdFeeStandard bsfs) { + return batteryStationHdFeeStandardService.update(bsfs); + } + + @Operation(summary = "查询") + @GetMapping("/list") + @ApiOperationSupport(order = 4) + public Result> list(String stationCode) { + return batteryStationHdFeeStandardService.list(stationCode); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationHdFeeStandardDetailController.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationHdFeeStandardDetailController.java new file mode 100644 index 0000000..c881d0a --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationHdFeeStandardDetailController.java @@ -0,0 +1,60 @@ +package com.evotech.hd.cloud.controller; + +import java.util.List; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.cloud.service.BatteryStationHdFeeStandardDetailService; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.BatteryStationHdFeeStandardDetail; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; + +@Tag(name = "换电站费用标准明细") +@ApiSupport(order = 17) +@RestController +@RequestMapping("/batterystation/fee/detail") +public class BatteryStationHdFeeStandardDetailController { + + + @Resource + private BatteryStationHdFeeStandardDetailService batteryStationHdFeeStandardDetailService; + + @Operation(summary = "增加") + @PostMapping("/add") + @ApiOperationSupport(order = 1) + public Result add(@Valid @ParameterObject BatteryStationHdFeeStandardDetail bsfsd) { + return batteryStationHdFeeStandardDetailService.add(bsfsd); + } + + @Operation(summary = "删除") + @PostMapping("/del") + @ApiOperationSupport(order = 2) + public Result delete(Integer id) { + return batteryStationHdFeeStandardDetailService.delete(id); + } + + @Operation(summary = "修改") + @PostMapping({"/update"}) + @ApiOperationSupport(order = 3) + public Result update(@ParameterObject BatteryStationHdFeeStandardDetail bsfsd) { + return batteryStationHdFeeStandardDetailService.update(bsfsd); + } + + @Operation(summary = "查询") + @GetMapping("/list") + @ApiOperationSupport(order = 4) + public Result> list(Integer standardId) { + return batteryStationHdFeeStandardDetailService.list(standardId); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationRobotController.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationRobotController.java new file mode 100644 index 0000000..43dbd2a --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/BatteryStationRobotController.java @@ -0,0 +1,61 @@ +package com.evotech.hd.cloud.controller; + +import java.util.List; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.cloud.service.BatteryStationRobotService; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.BatteryStationRobot; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; + +@Tag(name = "换电站机器人") +@ApiSupport(order = 15) +@RestController +@RequestMapping("/batterystation/robot") +public class BatteryStationRobotController { + + + @Resource + private BatteryStationRobotService batteryStationRobotService; + + @Operation(summary = "增加") + @PostMapping("/add") + @ApiOperationSupport(order = 1) + public Result add(@Valid @ParameterObject BatteryStationRobot bsr) { + return batteryStationRobotService.add(bsr); + } + + @Operation(summary = "删除") + @PostMapping("/del") + @ApiOperationSupport(order = 2) + public Result delete(Integer id) { + return batteryStationRobotService.delete(id); + } + + @Operation(summary = "修改") + @PostMapping({"/update"}) + @ApiOperationSupport(order = 3) + public Result update(@ParameterObject BatteryStationRobot bsr) { + return batteryStationRobotService.update(bsr); + } + + @Operation(summary = "查询") + @GetMapping("/list") + @ApiOperationSupport(order = 4) + public Result> list(@NotBlank String stationCode) { + return batteryStationRobotService.list(stationCode); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/MessageMqttController.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/MessageMqttController.java new file mode 100644 index 0000000..c64bf45 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/MessageMqttController.java @@ -0,0 +1,39 @@ +package com.evotech.hd.cloud.controller; + +import java.util.List; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.cloud.entity.MessageMqtt; +import com.evotech.hd.cloud.entity.request.PageListMessageMqttRequest; +import com.evotech.hd.cloud.service.MessageMqttService; +import com.evotech.hd.common.core.entity.Result; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; + +@Tag(name = "MQTT消息") +@ApiSupport(order = 9) +@RestController +@RequestMapping("/mqttmessage") +public class MessageMqttController { + + + @Resource + private MessageMqttService messageMqttService; + + + @Operation(summary = "查询") + @GetMapping("/list") + @ApiOperationSupport(order = 1) + public Result> list(@ParameterObject PageListMessageMqttRequest plmmr) { + return messageMqttService.list(plmmr); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/customer/VehicleController.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/customer/VehicleController.java new file mode 100644 index 0000000..4a59509 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/customer/VehicleController.java @@ -0,0 +1,90 @@ +package com.evotech.hd.cloud.controller.customer; + +import java.util.List; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.cloud.entity.request.PageListVehicleRequest; +import com.evotech.hd.cloud.service.VehicleService; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.VehicleInfo; +import com.evotech.hd.common.core.entity.cloud.VehicleWechatUserRelation; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; + + + +@Tag(name = "车辆管理") +@ApiSupport(order = 21) +@RestController +@RequestMapping("/vehicle") +public class VehicleController { + + + @Resource + private VehicleService vehicleService; + + + @Operation(summary = "增加") + @PostMapping("/add") + @ApiOperationSupport(order = 1) + public Result add(@Valid @ParameterObject VehicleInfo vi) { + return vehicleService.add(vi); + } + + @Operation(summary = "删除") + @PostMapping("/del") + @ApiOperationSupport(order = 2) + public Result delete(Integer id) { + return vehicleService.delete(id); + } + + @Operation(summary = "修改") + @PostMapping({"/update"}) + @ApiOperationSupport(order = 3) + public Result update(@ParameterObject VehicleInfo vi) { + return vehicleService.update(vi); + } + + @Operation(summary = "查询") + @GetMapping("/list") + @ApiOperationSupport(order = 4) + public Result> list(@ParameterObject PageListVehicleRequest plvr) { + return vehicleService.list(plvr); + } + + @Operation(summary = "微信用户关联") + @PostMapping("/wechatuser/relation/add") + @ApiOperationSupport(order = 5) + public Result addWechatUserRelation(@Valid @ParameterObject VehicleWechatUserRelation relation) { + return vehicleService.addWechatUserRelation(relation); + } + + + @Operation(summary = "删除微信用户关联") + @PostMapping("/wechatuser/relation/del") + @ApiOperationSupport(order = 6) + public Result deleteWechatUserRelation(Integer id) { + return vehicleService.deleteWechatUserRelation(id); + } + + + @Operation(summary = "查询微信用户车辆") + @GetMapping("/wechatuser/relation/list") + @ApiOperationSupport(order = 7) + public Result> listWechatUserRelation(@NotBlank @RequestParam String openid) { + return vehicleService.listWechatUserRelation(openid, null); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/OrderRechargeController.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/OrderRechargeController.java new file mode 100644 index 0000000..760f2a6 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/OrderRechargeController.java @@ -0,0 +1,64 @@ +package com.evotech.hd.cloud.controller.order; + +import java.util.List; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.cloud.entity.request.PageListRechargeOrderRequest; +import com.evotech.hd.cloud.service.OrderRechargeService; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.OrderRecharge; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; + + +@Tag(name = "交易详情") +@ApiSupport(order = 25) +@RestController +@RequestMapping("/order/recharge") +public class OrderRechargeController { + + + @Resource + private OrderRechargeService orderRechargeService; + + + + @Operation(summary = "增加") + @PostMapping("/add") + @ApiOperationSupport(order = 1) + public Result add(@Valid @ParameterObject OrderRecharge or) { + return orderRechargeService.add(or); + } + + @Operation(summary = "删除") + @PostMapping("/del") + @ApiOperationSupport(order = 2) + public Result delete(Integer id) { + return orderRechargeService.delete(id); + } + + @Operation(summary = "修改") + @PostMapping({"/update"}) + @ApiOperationSupport(order = 3) + public Result update(@ParameterObject OrderRecharge or) { + return orderRechargeService.update(or); + } + + @Operation(summary = "查询") + @GetMapping("/list") + @ApiOperationSupport(order = 4) + public Result> list(@ParameterObject PageListRechargeOrderRequest plror) { + return orderRechargeService.list(plror); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/OrderSwapBatteryController.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/OrderSwapBatteryController.java new file mode 100644 index 0000000..2926c64 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/OrderSwapBatteryController.java @@ -0,0 +1,95 @@ +package com.evotech.hd.cloud.controller.order; + +import java.util.List; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.cloud.entity.request.PageListSwapOrderRequest; +import com.evotech.hd.cloud.service.OrderSwapBatteryService; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery; +import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryPre; +import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryStep; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; + +@Tag(name = "换电订单") +@ApiSupport(order = 22) +@RestController +@RequestMapping("/order/swap") +public class OrderSwapBatteryController { + + @Resource + private OrderSwapBatteryService orderSwapBatteryService; + + + @Operation(summary = "增加预约") + @PostMapping("/pre/add") + @ApiOperationSupport(order = 1) + public Result addPre(@Valid @ParameterObject OrderSwapBatteryPre osbp) { + return orderSwapBatteryService.addPre(osbp); + } + + @Operation(summary = "取消预约") + @PostMapping("/pre/cancel") + @ApiOperationSupport(order = 2) + public Result cancelPre(@NotNull Integer id) { + return orderSwapBatteryService.cancelPre(id, null); + } + + @Operation(summary = "查询预约") + @GetMapping("/pre/list") + @ApiOperationSupport(order = 3) + public Result> listPre(String plateNum, Integer status, String userId) { + return orderSwapBatteryService.listPre(plateNum, status, userId); + } + + + + @Operation(summary = "增加") + @PostMapping("/add") + @ApiOperationSupport(order = 4) + public Result add(@Valid @ParameterObject OrderSwapBattery osb) { + return orderSwapBatteryService.add(osb); + } + + @Operation(summary = "删除") + @PostMapping("/del") + @ApiOperationSupport(order = 5) + public Result delete(Integer id) { + return orderSwapBatteryService.delete(id); + } + + @Operation(summary = "修改") + @PostMapping({"/update"}) + @ApiOperationSupport(order = 6) + public Result update(@ParameterObject OrderSwapBattery osb) { + return orderSwapBatteryService.update(osb); + } + + @Operation(summary = "查询") + @GetMapping("/list") + @ApiOperationSupport(order = 7) + public Result> list(@ParameterObject PageListSwapOrderRequest plsor) { + return orderSwapBatteryService.list(plsor); + } + + @Operation(summary = "查询换电步骤") + @GetMapping("/step/list") + @ApiOperationSupport(order = 8) + public Result> listStep(@NotBlank String orderNo) { + return orderSwapBatteryService.listStep(orderNo); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/TradeController.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/TradeController.java new file mode 100644 index 0000000..2e69a89 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/TradeController.java @@ -0,0 +1,63 @@ +package com.evotech.hd.cloud.controller.order; + +import java.util.List; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.cloud.entity.request.PageListTradeRequest; +import com.evotech.hd.cloud.service.TradeService; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.TradeDetail; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; + + +@Tag(name = "交易详情") +@ApiSupport(order = 23) +@RestController +@RequestMapping("/trade") +public class TradeController { + + + @Resource + private TradeService tradeService; + + + @Operation(summary = "增加") + @PostMapping("/add") + @ApiOperationSupport(order = 1) + public Result add(@Valid @ParameterObject TradeDetail td) { + return tradeService.add(td); + } + + @Operation(summary = "删除") + @PostMapping("/del") + @ApiOperationSupport(order = 2) + public Result delete(Integer id) { + return tradeService.delete(id); + } + + @Operation(summary = "修改") + @PostMapping({"/update"}) + @ApiOperationSupport(order = 3) + public Result update(@ParameterObject TradeDetail td) { + return tradeService.update(td); + } + + @Operation(summary = "查询") + @GetMapping("/list") + @ApiOperationSupport(order = 4) + public Result> list(@ParameterObject PageListTradeRequest pltr) { + return tradeService.list(pltr); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/WalletAccountController.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/WalletAccountController.java new file mode 100644 index 0000000..ce69357 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/WalletAccountController.java @@ -0,0 +1,85 @@ +package com.evotech.hd.cloud.controller.order; + +import java.util.List; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.cloud.entity.request.PageListWalletRequest; +import com.evotech.hd.cloud.service.WalletAccountService; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.WalletAccount; +import com.evotech.hd.common.core.entity.cloud.WalletAccountDetail; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; + + +@Tag(name = "资金账户管理") +@ApiSupport(order = 24) +@RestController +@RequestMapping("/wallet") +public class WalletAccountController { + + @Resource + private WalletAccountService walletAccountService; + + @Operation(summary = "增加") + @PostMapping("/add") + @ApiOperationSupport(order = 1) + public Result add(@Valid @ParameterObject WalletAccount wa) { + return walletAccountService.add(wa); + } + + @Operation(summary = "删除") + @PostMapping("/del") + @ApiOperationSupport(order = 2) + public Result delete(Integer id, String code) { + return walletAccountService.delete(id, code); + } + + @Operation(summary = "修改") + @PostMapping({"/update"}) + @ApiOperationSupport(order = 3) + public Result update(@ParameterObject WalletAccount wa) { + return walletAccountService.update(wa); + } + + @Operation(summary = "查询") + @GetMapping("/list") + @ApiOperationSupport(order = 4) + public Result> list(@ParameterObject PageListWalletRequest plwr) { + return walletAccountService.list(plwr); + } + + + @Operation(summary = "增加明细") + @PostMapping("/detail/add") + @ApiOperationSupport(order = 5) + public Result addDetail(@Valid @ParameterObject WalletAccountDetail wad) { + return walletAccountService.addDetail(wad); + } + + @Operation(summary = "删除明细") + @PostMapping("/detail/del") + @ApiOperationSupport(order = 6) + public Result deleteDetail(Integer id, String code) { + return walletAccountService.deleteDetail(id, code); + } + + + @Operation(summary = "查询明细") + @GetMapping("/detail/list") + @ApiOperationSupport(order = 7) + public Result> listDetail(@ParameterObject PageListWalletRequest plwr) { + return walletAccountService.listDetail(plwr); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationDao.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationDao.java new file mode 100644 index 0000000..8b0ae40 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationDao.java @@ -0,0 +1,22 @@ +package com.evotech.hd.cloud.dao; + +import java.util.List; + +import org.apache.ibatis.annotations.Param; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.evotech.hd.cloud.entity.request.PageListBatteryStationRequest; +import com.evotech.hd.common.core.entity.cloud.BatteryStation; + +/** + * @author zrb + * @since 2024-10-15 + */ +public interface BatteryStationDao extends BaseMapper { + + List listStation(Page page, @Param("plbsr") PageListBatteryStationRequest plbsr); + + List listStation(@Param("plbsr") PageListBatteryStationRequest plbsr); + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationDcDao.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationDcDao.java new file mode 100644 index 0000000..14d0c14 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationDcDao.java @@ -0,0 +1,16 @@ +package com.evotech.hd.cloud.dao; + +import java.util.List; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.cloud.BatteryStationDc; + +/** + * @author zrb + * @since 2024-10-17 + */ +public interface BatteryStationDcDao extends BaseMapper { + + List getDcByStationCode(String stationCode); + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationDccDao.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationDccDao.java new file mode 100644 index 0000000..0cfa0b5 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationDccDao.java @@ -0,0 +1,16 @@ +package com.evotech.hd.cloud.dao; + +import java.util.List; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.cloud.BatteryStationDcc; + +/** + * @author zrb + * @since 2024-10-17 + */ +public interface BatteryStationDccDao extends BaseMapper { + + List getDccByStationCode(String stationCode); + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationDjDao.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationDjDao.java new file mode 100644 index 0000000..de1d07b --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationDjDao.java @@ -0,0 +1,16 @@ +package com.evotech.hd.cloud.dao; + +import java.util.List; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.cloud.BatteryStationDj; + +/** + * @author zrb + * @since 2024-10-17 + */ +public interface BatteryStationDjDao extends BaseMapper { + + List getDjByStationCode(String stationCode); + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationHdFeeStandardDao.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationHdFeeStandardDao.java new file mode 100644 index 0000000..18d02a7 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationHdFeeStandardDao.java @@ -0,0 +1,16 @@ +package com.evotech.hd.cloud.dao; + +import java.util.List; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.cloud.BatteryStationHdFeeStandard; + +/** + * @author zrb + * @since 2024-10-17 + */ +public interface BatteryStationHdFeeStandardDao extends BaseMapper { + + List listFeeStandard(String stationCode); + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationHdFeeStandardDetailDao.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationHdFeeStandardDetailDao.java new file mode 100644 index 0000000..887691e --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationHdFeeStandardDetailDao.java @@ -0,0 +1,16 @@ +package com.evotech.hd.cloud.dao; + +import java.util.List; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.cloud.BatteryStationHdFeeStandardDetail; + +/** + * @author zrb + * @since 2024-10-17 + */ +public interface BatteryStationHdFeeStandardDetailDao extends BaseMapper { + + List getDetailById(Integer id); + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationRobotDao.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationRobotDao.java new file mode 100644 index 0000000..ce549ff --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationRobotDao.java @@ -0,0 +1,16 @@ +package com.evotech.hd.cloud.dao; + +import java.util.List; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.cloud.BatteryStationRobot; + +/** + * @author zrb + * @since 2024-10-17 + */ +public interface BatteryStationRobotDao extends BaseMapper { + + List getRobotByStationCode(String stationCode); + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationSecretKeyDao.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationSecretKeyDao.java new file mode 100644 index 0000000..4818b57 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryStationSecretKeyDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.cloud.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.cloud.entity.BatteryStationSecretKey; + +/** + * @author zrb + * @since 2024-11-05 + */ +public interface BatteryStationSecretKeyDao extends BaseMapper { + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryTraceDao.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryTraceDao.java new file mode 100644 index 0000000..4bf8b35 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/BatteryTraceDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.cloud.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.cloud.BatteryTrace; + +/** + * @author zrb + * @since 2024-12-06 + */ +public interface BatteryTraceDao extends BaseMapper { + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/MessageMqttDao.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/MessageMqttDao.java new file mode 100644 index 0000000..5e3cdde --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/MessageMqttDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.cloud.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.cloud.entity.MessageMqtt; + +/** + * @author zrb + * @since 2024-11-06 + */ +public interface MessageMqttDao extends BaseMapper { + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/OrderRechargeDao.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/OrderRechargeDao.java new file mode 100644 index 0000000..400b138 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/OrderRechargeDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.cloud.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.cloud.OrderRecharge; + +/** + * @author zrb + * @since 2024-11-22 + */ +public interface OrderRechargeDao extends BaseMapper { + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/OrderSwapBatteryDao.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/OrderSwapBatteryDao.java new file mode 100644 index 0000000..c04d5f6 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/OrderSwapBatteryDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.cloud.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery; + +/** + * @author zrb + * @since 2024-11-22 + */ +public interface OrderSwapBatteryDao extends BaseMapper { + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/OrderSwapBatteryPreDao.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/OrderSwapBatteryPreDao.java new file mode 100644 index 0000000..29f050e --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/OrderSwapBatteryPreDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.cloud.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryPre; + +/** + * @author zrb + * @since 2024-12-04 + */ +public interface OrderSwapBatteryPreDao extends BaseMapper { + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/OrderSwapBatteryStepDao.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/OrderSwapBatteryStepDao.java new file mode 100644 index 0000000..b874c00 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/OrderSwapBatteryStepDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.cloud.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryStep; + +/** + * @author zrb + * @since 2024-12-11 + */ +public interface OrderSwapBatteryStepDao extends BaseMapper { + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/TradeDetailDao.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/TradeDetailDao.java new file mode 100644 index 0000000..967e65d --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/TradeDetailDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.cloud.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.cloud.TradeDetail; + +/** + * @author zrb + * @since 2024-11-22 + */ +public interface TradeDetailDao extends BaseMapper { + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/VehicleInfoDao.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/VehicleInfoDao.java new file mode 100644 index 0000000..1646929 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/VehicleInfoDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.cloud.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.cloud.VehicleInfo; + +/** + * @author zrb + * @since 2024-11-22 + */ +public interface VehicleInfoDao extends BaseMapper { + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/VehicleWechatUserRelationDao.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/VehicleWechatUserRelationDao.java new file mode 100644 index 0000000..bb15450 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/VehicleWechatUserRelationDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.cloud.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.cloud.VehicleWechatUserRelation; + +/** + * @author zrb + * @since 2024-11-22 + */ +public interface VehicleWechatUserRelationDao extends BaseMapper { + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/WalletAccountDao.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/WalletAccountDao.java new file mode 100644 index 0000000..ea0d32e --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/WalletAccountDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.cloud.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.cloud.WalletAccount; + +/** + * @author zrb + * @since 2024-11-22 + */ +public interface WalletAccountDao extends BaseMapper { + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/WalletAccountDetailDao.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/WalletAccountDetailDao.java new file mode 100644 index 0000000..d47dbfd --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/dao/WalletAccountDetailDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.cloud.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.cloud.WalletAccountDetail; + +/** + * @author zrb + * @since 2024-11-22 + */ +public interface WalletAccountDetailDao extends BaseMapper { + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/BatteryStationSecretKey.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/BatteryStationSecretKey.java new file mode 100644 index 0000000..142b184 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/BatteryStationSecretKey.java @@ -0,0 +1,59 @@ +package com.evotech.hd.cloud.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-11-05 + */ +@Getter +@Setter +@TableName("yt_t_battery_station_secret_key") +@Schema(name = "换电站交换数据秘钥") +public class BatteryStationSecretKey implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + private Integer pkId; + + @Schema(description = "站点编码") + private String stationCode; + + @Schema(description = "秘钥类型:1-RSA非对称加密秘钥,2-AES对称加密秘钥") + private Integer type; + + @Schema(description = "公钥") + private String publicKey; + + @Schema(description = "私钥") + private String privateKey; + + @Schema(description = "创建人") + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/MessageMqtt.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/MessageMqtt.java new file mode 100644 index 0000000..9d48006 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/MessageMqtt.java @@ -0,0 +1,60 @@ +package com.evotech.hd.cloud.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-11-06 + */ +@Getter +@Setter +@TableName("yt_t_message_mqtt") +@Schema(name = "mqtt记录信息表") +public class MessageMqtt implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + private Integer pkId; + + @Schema(description = "换电站") + private String stationCode; + + @Schema(description = "传送方向") + private String direction; + + @Schema(description = "消息ID") + private String messageId; + + @Schema(description = "qos") + private Integer qos; + + @Schema(description = "消息类型: 状态信息类、事件记录类、请求与响应类") + private String type; + + @Schema(description = "方法 stationInfo") + private String messageFunction; + + @Schema(description = "消息的topic") + private String topic; + + @Schema(description = "内容,解密后的") + private String content; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListBatteryStationDcRequest.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListBatteryStationDcRequest.java new file mode 100644 index 0000000..6b14a23 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListBatteryStationDcRequest.java @@ -0,0 +1,21 @@ +package com.evotech.hd.cloud.entity.request; + +import com.evotech.hd.common.core.entity.BasePageRequest; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + + +@Data +@Schema(name = "查询电池请求参数", hidden = true) +@EqualsAndHashCode(callSuper=false) +public class PageListBatteryStationDcRequest extends BasePageRequest { + + @Schema(description = "归属运营商ID") + private String proxyId; + + @Schema(description = "站点编码") + private String stationCode; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListBatteryStationDccRequest.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListBatteryStationDccRequest.java new file mode 100644 index 0000000..5ca9342 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListBatteryStationDccRequest.java @@ -0,0 +1,20 @@ +package com.evotech.hd.cloud.entity.request; + +import com.evotech.hd.common.core.entity.BasePageRequest; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@Schema(name = "查询换电池仓请求参数", hidden = true) +@EqualsAndHashCode(callSuper=false) +public class PageListBatteryStationDccRequest extends BasePageRequest { + + @Schema(description = "归属运营商ID") + private String proxyId; + + @Schema(description = "站点编码") + private String stationCode; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListBatteryStationDjRequest.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListBatteryStationDjRequest.java new file mode 100644 index 0000000..7779e86 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListBatteryStationDjRequest.java @@ -0,0 +1,21 @@ +package com.evotech.hd.cloud.entity.request; + +import com.evotech.hd.common.core.entity.BasePageRequest; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + + +@Data +@Schema(name = "查询电机请求参数", hidden = true) +@EqualsAndHashCode(callSuper=false) +public class PageListBatteryStationDjRequest extends BasePageRequest { + + @Schema(description = "归属运营商ID") + private String proxyId; + + @Schema(description = "站点编码") + private String stationCode; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListBatteryStationRequest.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListBatteryStationRequest.java new file mode 100644 index 0000000..d54f734 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListBatteryStationRequest.java @@ -0,0 +1,32 @@ +package com.evotech.hd.cloud.entity.request; + +import com.evotech.hd.common.core.entity.BasePageRequest; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + + +@Data +@Schema(name = "查询换电站请求参数", hidden = true) +@EqualsAndHashCode(callSuper=false) +public class PageListBatteryStationRequest extends BasePageRequest { + + + private Integer pkId; + + @Schema(description = "归属运营商ID") + private String proxyId; + + @Schema(description = "站点名称") + private String name; + + @Schema(description = "站点编码") + private String code; + + @Schema(description = "状态:1-正常营业,2-正常停运,3-故障停运,4-指令停运,9-其它") + private Integer status; + + @Schema(description = "站点类型ID") + private Integer type; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListMessageMqttRequest.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListMessageMqttRequest.java new file mode 100644 index 0000000..dfa4bb2 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListMessageMqttRequest.java @@ -0,0 +1,26 @@ +package com.evotech.hd.cloud.entity.request; + +import com.evotech.hd.common.core.entity.BasePageRequest; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@Schema(name = "查询MQTT消息请求参数", hidden = true) +@EqualsAndHashCode(callSuper = false) +public class PageListMessageMqttRequest extends BasePageRequest { + + @Schema(description = "换电站") + private String stationCode; + + @Schema(description = "传送方向") + private String direction; + + @Schema(description = "消息类型: 状态信息类、事件记录类、请求与响应类") + private String type; + + @Schema(description = "方法 stationInfo") + private String messageFunction; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListRechargeOrderRequest.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListRechargeOrderRequest.java new file mode 100644 index 0000000..83a99b9 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListRechargeOrderRequest.java @@ -0,0 +1,45 @@ +package com.evotech.hd.cloud.entity.request; + +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import com.evotech.hd.common.core.entity.BasePageRequest; +import com.fasterxml.jackson.annotation.JsonFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + + +@Data +@Schema(name = "查询充值订单请求参数", hidden = true) +@EqualsAndHashCode(callSuper=false) +public class PageListRechargeOrderRequest extends BasePageRequest { + + @Schema(description = "订单时间开始", example = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date orderTimeBegin; + + @Schema(description = "订单时间结束") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date orderTimeEnd; + + @Schema(description = "换电站编码") + private String stationCode; + + @Schema(description = "换电站名称") + private String stationName; + + @Schema(description = "钱包账户账号") + private String accountCode; + + @Schema(description = "交易编码") + private String tradeNo; + + @Schema(description = "订单编码") + private String orderNo; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListSwapOrderRequest.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListSwapOrderRequest.java new file mode 100644 index 0000000..1ea9455 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListSwapOrderRequest.java @@ -0,0 +1,52 @@ +package com.evotech.hd.cloud.entity.request; + +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import com.evotech.hd.common.core.entity.BasePageRequest; +import com.fasterxml.jackson.annotation.JsonFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + + +@Data +@Schema(name = "查询换电订单请求参数", hidden = true) +@EqualsAndHashCode(callSuper=false) +public class PageListSwapOrderRequest extends BasePageRequest { + + + @Schema(description = "订单编码") + private String orderNo; + + @Schema(description = "车牌号") + private String plateNum; + + @Schema(description = "订单时间开始", example = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date orderTimeBegin; + + @Schema(description = "订单时间结束") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date orderTimeEnd; + + @Schema(description = "换电站编码") + private String stationCode; + + @Schema(description = "换电站名称") + private String stationName; + + @Schema(description = "换电车主ID") + private String userId; + + @Schema(description = "交易编码") + private String tradeNo; + + + + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListTradeRequest.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListTradeRequest.java new file mode 100644 index 0000000..70302f6 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListTradeRequest.java @@ -0,0 +1,29 @@ +package com.evotech.hd.cloud.entity.request; + +import com.evotech.hd.common.core.entity.BasePageRequest; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@Schema(name = "查询交易请求参数", hidden = true) +@EqualsAndHashCode(callSuper = false) +public class PageListTradeRequest extends BasePageRequest { + + @Schema(description = "换电站编码") + private String stationCode; + + @Schema(description = "账号编码") + private String accountCode; + + @Schema(description = "账号") + private String accountName; + + @Schema(description = "交易编码") + private String outTradeNo; + + @Schema(description = "交易类型:1-充值,2-订单消费,3-提现") + private Integer tradeType; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListVehicleRequest.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListVehicleRequest.java new file mode 100644 index 0000000..0517de9 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListVehicleRequest.java @@ -0,0 +1,42 @@ +package com.evotech.hd.cloud.entity.request; + +import com.evotech.hd.common.core.entity.BasePageRequest; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@Schema(name = "查询车辆请求参数", hidden = true) +@EqualsAndHashCode(callSuper=false) +public class PageListVehicleRequest extends BasePageRequest { + + + @Schema(description = "型号编码") + private String typeCode; + + @Schema(description = "车辆识别代码VIN号") + private String vinNo; + + @Schema(description = "车架号") + private String frameworkNo; + + @Schema(description = "车主类型:1-个人,2-企业") + private Integer ownerType; + + @Schema(description = "车主ID") + private String ownerId; + + @Schema(description = "车主名称") + private String ownerName; + + @Schema(description = "车牌号") + private String plateNum; + + @Schema(description = "联系电话") + private String phone; + + @Schema(description = "引擎号") + private String engineNo; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListWalletRequest.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListWalletRequest.java new file mode 100644 index 0000000..166b15d --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/request/PageListWalletRequest.java @@ -0,0 +1,28 @@ +package com.evotech.hd.cloud.entity.request; + +import com.evotech.hd.common.core.entity.BasePageRequest; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + + +@Data +@Schema(name = "查询资金账户请求参数", hidden = true) +@EqualsAndHashCode(callSuper=false) +public class PageListWalletRequest extends BasePageRequest { + + + @Schema(description = "户主类型:1-个人,2-企业") + private Integer ownerType; + + @Schema(description = "户主ID") + private String ownerId; + + @Schema(description = "编码") + private String code; + + @Schema(description = "引入站点") + private String stationCode; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/MqttInit.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/MqttInit.java new file mode 100644 index 0000000..391b401 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/MqttInit.java @@ -0,0 +1,54 @@ +package com.evotech.hd.cloud.mqtt; + +import java.util.List; + +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.evotech.hd.cloud.dao.BatteryStationDao; +import com.evotech.hd.cloud.mqtt.config.MqttConfig; +import com.evotech.hd.common.core.entity.cloud.BatteryStation; + +import jakarta.annotation.Resource; + +@Component +@Order(value = 20) +public class MqttInit implements ApplicationRunner { + + + @Resource + private MqttConfig mqttConfig; + @Resource + private BatteryStationDao batteryStationDao; + + + private String[] mqttMessageTypeArr = {"state", "event", "request", "response", "keepalive", "encryptKeyReq"}; + + @Override + public void run(ApplicationArguments args) throws Exception { + // 连接mqtt + mqttConfig.connect(); + // 订阅主题 + List stationList = batteryStationDao.selectList(new QueryWrapper().eq("del_flag", 0)); + if (stationList.isEmpty()) { + return; + } + List stationCodeList = stationList.stream().map(i -> i.getCode()).toList(); + for (int i = 0; i < stationCodeList.size(); i++) { + String stationCode = stationCodeList.get(i); + String topic = "ZZHD/" + stationCode + "/S2M/"; + for (int j = 0; j < mqttMessageTypeArr.length; j++) { + mqttConfig.subscribe(topic + mqttMessageTypeArr[j]); + } + } + + } + + + + + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/config/MqttConfig.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/config/MqttConfig.java new file mode 100644 index 0000000..695c088 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/config/MqttConfig.java @@ -0,0 +1,133 @@ +package com.evotech.hd.cloud.mqtt.config; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Date; + +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttConnectOptions; +import org.eclipse.paho.client.mqttv3.MqttDeliveryToken; +import org.eclipse.paho.client.mqttv3.MqttException; +import org.eclipse.paho.client.mqttv3.MqttMessage; +import org.eclipse.paho.client.mqttv3.MqttTopic; +import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; + +@Configuration +@Slf4j +public class MqttConfig { + + @Resource + private Environment env; + + private MqttClient cloudClient; + + @Bean + MqttProperties mpProperties() { + return new MqttProperties(); + } + + + /** + * 客户端连接服务端 + */ + public void connect() { + int port = env.getProperty("server.port", Integer.class) == null?8080:env.getProperty("server.port", Integer.class); + String address = "127.0.0.1"; + try { + address = InetAddress.getLocalHost().getHostAddress(); + } catch (UnknownHostException e) { + address = "192.168.5.213"; + e.printStackTrace(); + } + String clientId = address + "-" + port + "-" + DateUtil.format(new Date(), DatePattern.PURE_DATETIME_FORMATTER); + try { + cloudClient = new MqttClient(mpProperties().getUrl(), clientId, new MemoryPersistence()); + //连接设置 + MqttConnectOptions options = connectOptions(); + //设置回调 + cloudClient.setCallback(new MyMqttCallback()); + cloudClient.connect(options); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("连接MQTT服务出错:" + e.getMessage()); + } + } + + private MqttConnectOptions connectOptions() { + MqttConnectOptions options = new MqttConnectOptions(); + /** + * 1. 这个类是代理类,其实是MqttAsyncClient干活。它 + * 使用无阻塞运行在后台的轻量级链接server。基于Tcp,包含了ssl; + * 2. 为了确保消息通过网络被送达和重启客户端带有质量标志的消息要求被保存直到重新被送达。 + * mqtt提供了一种自己持久化机制来保存这些消息。MqttDefaultFilePersistence是默认方式, + * 如果为null则为瞬时消息保存在内存中。MqttClientPersistence可以自己现实接口; + * 3. 如果在connecting中MqttConnectOptions.setCleanSession(boolean)这个flag, + * 为true也就说,如果client掉线disconnect,下次重连,将清空内存persistence消息, + * 如果为false,就会使用持久化机制去重传 + */ + options.setCleanSession(true); + //设置连接用户名 + options.setUserName(mpProperties().getUsername()); + //设置连接密码 + options.setPassword(mpProperties().getPassword().toCharArray()); + //设置超时时间,单位为秒 + options.setConnectionTimeout(mpProperties().getConnectionTimeout()); + //设置心跳时间 单位为秒, + options.setKeepAliveInterval(mpProperties().getKeepAliveInterval()); + //设置遗嘱消息的话题,若客户端和服务器之间的连接意外断开,服务器将发布客户端的遗嘱信息 +// options.setWill("willTopic", (clientId + "与服务器断开连接").getBytes(), 0, false); + return options; + } + + + public void publish(String message, String topic) { + MqttMessage mqttMessage = new MqttMessage(); + /** + * Qos 0 : 这个消息最多发送一次,不能被持久化到磁盘,不能通过网络被传递,一般内部消息转换 + * Qos 1 : 这个消息至少发送一次,能被重传,能持久化,能通过网络传递,需要实现MqttConnectOptions中的持久化,否则,挂了以后,不能重传。 + * Qos 2 : 这个消息精准只发一次,能持久化,能通过网络传递,客户端和服务器都会收到消息确认 + */ + mqttMessage.setQos(2); + // 是否保留最后一条消息 + mqttMessage.setRetained(false); + // 消息内容 + mqttMessage.setPayload(message.getBytes()); + // 主题的目的地,用于发布/订阅信息 + MqttTopic mqttTopic = cloudClient.getTopic(topic); + // 提供一种机制来跟踪消息的传递进度 + // 用于在以非阻塞方式(在后台运行)执行发布是跟踪消息的传递进度 + MqttDeliveryToken token; + try { + // 将指定消息发布到主题,但不等待消息传递完成,返回的token可用于跟踪消息的传递状态 + // 一旦此方法干净地返回,消息就已被客户端接受发布,当连接可用,将在后台完成消息传递。 + token = mqttTopic.publish(mqttMessage); + token.waitForCompletion(); + } catch (MqttException e) { + e.printStackTrace(); + } + } + + + /** + * 订阅主题 + */ + public void subscribe(String topic) { + try { + cloudClient.subscribe(topic, mpProperties().getQos()); + log.info("\r\n=====>>>MQTT订阅主题 {} 成功...", topic); + } catch (MqttException e) { + e.printStackTrace(); + log.error("\r\n=====>>>MQTT订阅主题 {} 失败。。。", topic); + } + } + + + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/config/MqttProperties.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/config/MqttProperties.java new file mode 100644 index 0000000..be38abe --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/config/MqttProperties.java @@ -0,0 +1,25 @@ +package com.evotech.hd.cloud.mqtt.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +import lombok.Data; + +@ConfigurationProperties(prefix = "mqtt", ignoreUnknownFields = true) +@Data +@Component +public class MqttProperties { + + private String username; + + private String password; + + private String url; + + private int qos = 2; + + private int connectionTimeout = 30; + + private int keepAliveInterval = 60; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/config/MyMqttCallback.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/config/MyMqttCallback.java new file mode 100644 index 0000000..d8233b9 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/config/MyMqttCallback.java @@ -0,0 +1,71 @@ +package com.evotech.hd.cloud.mqtt.config; + +import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; +import org.eclipse.paho.client.mqttv3.MqttCallbackExtended; +import org.eclipse.paho.client.mqttv3.MqttMessage; +import org.springframework.stereotype.Component; + +import com.evotech.hd.cloud.mqtt.message.MessageTopic; +import com.evotech.hd.cloud.mqtt.message.handle.MqttMessageHandle; + +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; + +@Component +@Slf4j +public class MyMqttCallback implements MqttCallbackExtended { + + @Resource + private MqttMessageHandle messageHandle; + + + + + + /** + * 建立连接后 + */ + @Override + public void connectComplete(boolean reconnect, String serverURI) { + log.info("\r\n=====>>>MQTT连接成功:{}", serverURI); + + } + + + /** + * 与服务器断开的回调 + */ + @Override + public void connectionLost(Throwable cause) { + log.error("\r\n=====>>>MQTT与服务器断开连接:{}", cause.getMessage()); + cause.printStackTrace(); + } + + /** + * 消息到达的回调 + */ + @Override + public void messageArrived(String topic, MqttMessage message) throws Exception { + log.info("\r\n=====>>>MQTT接收到消息主题:{}---{}", topic, message); + String[] topicArr = topic.split("/"); + if ("ZZHD".equals(topicArr[0]) && topicArr.length == 4) { + MessageTopic mt = new MessageTopic(); + mt.setDataDirection(topicArr[2]); + mt.setMessageType(topicArr[3]); + mt.setStationCode(topicArr[1]); + messageHandle.handle(mt, message); + } + } + + /** + * 消息发布成功的回调 + */ + @Override + public void deliveryComplete(IMqttDeliveryToken token) { + // 入库 TODO + + } + + + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/enums/ConfirmFunctionTypesEnum.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/enums/ConfirmFunctionTypesEnum.java new file mode 100644 index 0000000..c19969f --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/enums/ConfirmFunctionTypesEnum.java @@ -0,0 +1,46 @@ +package com.evotech.hd.cloud.mqtt.enums; + +import java.util.Arrays; + +public enum ConfirmFunctionTypesEnum { + + FUN_CHARGE_RECORD_CONF("chargeRecordConf", "chargeRecord", "充电事件记录确认"), + FUN_SWAP_RECORD_CONF("swapRecordConf", "swapRecord", "换电事件记录确认"), + FUN_FAULT_RECORD_CONF("faultRecordConf", "faultRecord", "故障告警事件记录确认"); + + String function; + String reFunction; + String functionName; + + + ConfirmFunctionTypesEnum(String function, String reFunction, String functionName) { + this.function = function; + this.reFunction = reFunction; + this.functionName = functionName; + } + + public String getFunction() { + return function; + } + + public String getReFunction() { + return reFunction; + } + + public String getFunctionName() { + return functionName; + } + + + + public static ConfirmFunctionTypesEnum getFunctionType(String function) { + if (function == "") { + return null; + } + return Arrays.stream(ConfirmFunctionTypesEnum.values()) + .filter(i -> i.function.equals(function)) + .findFirst().orElse(null); + } + + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/enums/EventFunctionTypesEnum.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/enums/EventFunctionTypesEnum.java new file mode 100644 index 0000000..c63af61 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/enums/EventFunctionTypesEnum.java @@ -0,0 +1,45 @@ +package com.evotech.hd.cloud.mqtt.enums; + +import java.util.Arrays; + +public enum EventFunctionTypesEnum { + + FUN_CHARGE_RECORD("chargeRecord", "chargeRecordConf", "充电事件记录"), + FUN_SWAP_RECORD("swapRecord", "swapRecordConf", "换电事件记录"), + FUN_WARN_RECORD("faultRecord", "faultRecordConf", "故障告警事件记录"); + + String function; + String reFunction; + String functionName; + + + EventFunctionTypesEnum(String function, String reFunction, String functionName) { + this.function = function; + this.reFunction = reFunction; + this.functionName = functionName; + } + + public String getFunction() { + return function; + } + + public String getReFunction() { + return reFunction; + } + + public String getFunctionName() { + return functionName; + } + + + public static EventFunctionTypesEnum getFunctionType(String function) { + if (function == "") { + return null; + } + return Arrays.stream(EventFunctionTypesEnum.values()) + .filter(i -> i.function.equals(function)) + .findFirst().orElse(null); + } + + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/enums/MqttMessageTypeEnum.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/enums/MqttMessageTypeEnum.java new file mode 100644 index 0000000..4f6f529 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/enums/MqttMessageTypeEnum.java @@ -0,0 +1,45 @@ +package com.evotech.hd.cloud.mqtt.enums; + +/** + * 如下 8 种类型: + 1)state 换电站状态类信息,站控发送,支持变化实时上送、周期上送和查询上 +送三种方式,云平台无需回复。云平台可根据需要随时向站控系统召唤状态类信息。 + 2)event 事件类信息,站控发送,包括故障告警事件记录、充换电事件记录等, 事件发生时上送,需接收者回复确认,站控 15 秒内收不到回复则要重复发送,直到收 +到云平台的回复。云平台可通过召唤历史事件流水号的方式,检查事件是否丢失。 + 3)confirm 事件确认回复,云平台收到事件后的回复信息。 + 4)request 主动请求,云平台、站控均可发起请求。 + 5)response 收到请求后,接收者的回复。 + 6)keepalive 心跳报文,站控周期发送,周期30秒,云平台收到后立即回复。报文内容为当前时标字符串:“yyyy-MM-dd hh:mm:ss”。云平台和站控连续 3 个周期收不到对方的任何报文,则认为通信中断。通信中断后,站控不发送心跳外的任何报文,直到收到心跳回复报文。 + 7)encryptKeyReq 站控发送,请求密钥。 + 8)encryptKeyResp 云平台回复站控的密钥请求。 + * + */ +public enum MqttMessageTypeEnum { + + STATE(1, "state"), + EVENT(2, "event"), + CONFIRM(3, "confirm"), + REQUEST(4, "request"), + RESPONSE(5, "response"), + KEEPALIVE(6, "keepalive"), + ENCRYREQ(7, "encryptKeyReq"), + ENCRYRESP(8, "encryptKeyResp"); + + + int id; + String type; + + public int getId() { + return id; + } + + public String getType() { + return type; + } + + MqttMessageTypeEnum(int id, String type) { + this.id = id; + this.type = type; + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/enums/RequestFunctionTypesEnum.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/enums/RequestFunctionTypesEnum.java new file mode 100644 index 0000000..c915e1f --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/enums/RequestFunctionTypesEnum.java @@ -0,0 +1,66 @@ +package com.evotech.hd.cloud.mqtt.enums; + +import java.util.Arrays; + +public enum RequestFunctionTypesEnum { + + // 原交换数据 +// FUN_VEHICLE_REQ("vehicleStateReq", "vehicleStateResp", "车辆进站信息"), + +// FUN_REMOTE_SWAP_SCAN_REQ("remoteSwapScanReq", "remoteSwapScanResp", "司机扫码情况"), +// FUN_REMOTE_SWAP_SCAN_RESP( "remoteSwapScanResp", "remoteSwapCheckReq", "站端司机扫码情况回复"), +// FUN_REMOTE_SWAP_CHECK_REQ("remoteSwapCheckReq", "remoteSwapCheckResp", "远方换电启动条件校验"), +// FUN_REMOTE_SWAP_CHECK_RESP("remoteSwapCheckResp", "remoteSwapStartReq", "远方换电启动条件校验回复"), +// FUN_REMOTE_SWAP_START_REQ("remoteSwapStartReq", "remoteSwapStartResp", "远方换电启动命令"), +// FUN_REMOTE_SWAP_START_RESP("remoteSwapStartResp", "", "远方换电启动命令回复"), +// FUN_REMOTE_SWAP_CANCEL_REQ("remoteSwapCancelReq", "remoteSwapCancelResp", "站端取消订单"), +// FUN_REMOTE_SWAP_CANCEL_RESP("remoteSwapCancelResp", "remoteSwapCancelReq", "云端对站端取消订单回复"), +// FUN_VEHICLE_STATE_REQ("vehicleStateReq", "vehicleStateResp", "站端换电车辆状态获取"), +// FUN_VEHICLE_STATE_RESP("vehicleStateResp", "vehicleStateReq", "站端换电车辆状态回复"), +// FUN_BATTERY_CHECK_REQ("batteryCheckReq", "batteryCheckResp", "站端对电池包校验"), +// FUN_BATTERY_CHECK_RESP("batteryCheckResp", "batteryCheckReq", "云端对电池包校验回复"), +// FUN_RATE_MODE_SYNC_REQ("reteModeSyncReq", "reteModeSyncResp", "费率模型同步请求"), +// FUN_RATE_MODE_SYNC_RESP("reteModeSyncResp", "reteModeSyncReq", "费率模型同步请求回复"), +// FUN_VEHICLE_SYNC_REQ("vehicleSyncReq", "vehicleSyncResp", "车辆信息同步请求"), +// FUN_VEHICLE_SYNC_RESP("vehicleSyncResp", "vehicleSyncReq", "车辆信息同步请求回复"); + + // 新交互请求 + FUN_CARINFO("carInfo", "carInfoResponse", "站端请求用户车辆数据"), + FUN_BATTERYINFO("batteryInfo", "batteryInfoResponse", "站端请求电池数据"), + FUN_PREORDER("preOrder", "preOrderResponse", "站端预约订单"), + FUN_ORDERBYPLATENUM("orderByPlateNum", "orderByPlateNumResponse", "站端用车牌号查询订单"), + FUN_CANCELORDER("cancelOrder", "cancelOrderResponse", "站端取消订单"); + + String function; + String reFunction; + String functionName; + + + RequestFunctionTypesEnum(String function, String reFunction, String functionName) { + this.function = function; + this.reFunction = reFunction; + this.functionName = functionName; + } + + public String getFunction() { + return function; + } + + public String getReFunction() { + return reFunction; + } + + public String getFunctionName() { + return functionName; + } + + public static RequestFunctionTypesEnum getFunctionType(String function) { + if (function == "") { + return null; + } + return Arrays.stream(RequestFunctionTypesEnum.values()) + .filter(i -> i.function.equals(function)) + .findFirst().orElse(null); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/enums/StateFunctionTypesEnum.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/enums/StateFunctionTypesEnum.java new file mode 100644 index 0000000..b3cc4e0 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/enums/StateFunctionTypesEnum.java @@ -0,0 +1,48 @@ +package com.evotech.hd.cloud.mqtt.enums; + +import java.util.Arrays; + +public enum StateFunctionTypesEnum { + // 原交换数据 +// FUN_SWAP_STATE( "swapState", "", "换电过程实时状态"), +// FUN_CHARGING_DATA("chargingData", "", "充电过程实时信息"), + + // 新交互请求 + FUN_ORDERSTATUS("orderStatus", "", "站端反馈订单状态"), + FUN_SWAPSTEP("swapStep", "", "站端反馈换电步骤"), + FUN_BATTERYSTATUS("batteryStatus", "", "站端反馈电池状态"); + + String function; + String reFunction; + String functionName; + + + StateFunctionTypesEnum(String function, String reFunction, String functionName) { + this.function = function; + this.reFunction = reFunction; + this.functionName = functionName; + } + + public String getFunction() { + return function; + } + + public String getReFunction() { + return reFunction; + } + + public String getFunctionName() { + return functionName; + } + + + public static StateFunctionTypesEnum getFunctionType(String function) { + if (function == "") { + return null; + } + return Arrays.stream(StateFunctionTypesEnum.values()) + .filter(i -> i.function.equals(function)) + .findFirst().orElse(null); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/MessageTopic.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/MessageTopic.java new file mode 100644 index 0000000..fac75fe --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/MessageTopic.java @@ -0,0 +1,29 @@ +package com.evotech.hd.cloud.mqtt.message; + +import java.io.Serializable; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class MessageTopic implements Serializable { + + private static final long serialVersionUID = 7238663818955151985L; + + private String businessType = "ZZHD"; + + private String stationCode; + + private String dataDirection = "M2S"; + + private String messageType; + + @Override + public String toString() { + return businessType + "/" + stationCode + "/" + dataDirection + "/" + messageType; + } + + + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/MqttMessageHeader.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/MqttMessageHeader.java new file mode 100644 index 0000000..978662f --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/MqttMessageHeader.java @@ -0,0 +1,30 @@ +package com.evotech.hd.cloud.mqtt.message; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +@Schema(name = "MQTT消息头") +public class MqttMessageHeader { + + @Schema(description = "协议版本") + private String version; + + @Schema(description = "yyyy-MM-dd hh:mm:ss") + private String timeStamp; + + @Schema(description = "消息Id。confirm、reponse回复类报文为对应的请求或事件报文的 index") + private String index; + + @Schema(description = "数据类型") + private String function; + + @Schema(description = "") + private String userId; + + @Schema(description = "") + private String pwd; + + @Schema(description = "状态类信息上送原因:1-变化上送;2-周期上送;3-召唤上送 ") + private int reason; +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/MyMqttMessage.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/MyMqttMessage.java new file mode 100644 index 0000000..0de0f1d --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/MyMqttMessage.java @@ -0,0 +1,22 @@ +package com.evotech.hd.cloud.mqtt.message; + +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +@Schema(name = "MQTT消息") +public class MyMqttMessage { + + @Schema(description = "MQTT消息头") + private MqttMessageHeader header; + + @Schema(description = "MQTT消息体") + private JSONObject dataBody; + + @Override + public String toString() { + return JSONUtil.toJsonStr(this); + } +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/battery/BatteryData.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/battery/BatteryData.java new file mode 100644 index 0000000..d36737e --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/battery/BatteryData.java @@ -0,0 +1,17 @@ +package com.evotech.hd.cloud.mqtt.message.dto.newer.req.battery; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class BatteryData { + + private String batCode; + + @Schema(description = "生产日期", example = "yyyyMMdd") + private String productionDate; + + @Schema(description = "注册时间", example = "yyyyMMdd") + private String registrationDate; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/battery/BatteryInfoReq.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/battery/BatteryInfoReq.java new file mode 100644 index 0000000..e265c03 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/battery/BatteryInfoReq.java @@ -0,0 +1,15 @@ +package com.evotech.hd.cloud.mqtt.message.dto.newer.req.battery; + +import lombok.Data; + +/** + * 站端请求电池数据 + */ +@Data +public class BatteryInfoReq { + + private String batCode; + + private String batteryInfoRequestId; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/battery/BatteryInfoResponse.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/battery/BatteryInfoResponse.java new file mode 100644 index 0000000..91d9ae3 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/battery/BatteryInfoResponse.java @@ -0,0 +1,22 @@ +package com.evotech.hd.cloud.mqtt.message.dto.newer.req.battery; + +import java.util.List; + +import lombok.Data; + +@Data +public class BatteryInfoResponse { + + private String batteryInfoRequestId; + + private Integer total; + + private Integer pageSize; + + private Integer pageNo; + + private Integer isOver; + + private List batteryData; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/carinfo/CarInfoReq.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/carinfo/CarInfoReq.java new file mode 100644 index 0000000..23a57c0 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/carinfo/CarInfoReq.java @@ -0,0 +1,15 @@ +package com.evotech.hd.cloud.mqtt.message.dto.newer.req.carinfo; + +import lombok.Data; + +/** + * 站端请求用户车辆数据 + */ +@Data +public class CarInfoReq { + + private String plateNum; + + private String carInfoRequestId; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/carinfo/CarInfoResponse.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/carinfo/CarInfoResponse.java new file mode 100644 index 0000000..47caf6e --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/carinfo/CarInfoResponse.java @@ -0,0 +1,25 @@ +package com.evotech.hd.cloud.mqtt.message.dto.newer.req.carinfo; + +import java.util.List; + +import lombok.Data; + +/** + * 云端回复站端用户车辆数据 + */ +@Data +public class CarInfoResponse { + + private String carInfoRequestId; + + private Integer total; + + private Integer pageSize; + + private Integer pageNo; + + private Integer isOver; + + private List vehicleData; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/carinfo/VehicleData.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/carinfo/VehicleData.java new file mode 100644 index 0000000..56ba985 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/carinfo/VehicleData.java @@ -0,0 +1,24 @@ +package com.evotech.hd.cloud.mqtt.message.dto.newer.req.carinfo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class VehicleData { + + @Schema(description = "车牌号") + private String plateNum; + + @Schema(description = "车主类型:1-个人,2-企业") + private Integer ownerType; + + @Schema(description = "用户编码") + private String ucode; + + @Schema(description = "用户名称") + private String uname; + + @Schema(description = "关联人手机号") + private String phone; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/order/CancelOrderReq.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/order/CancelOrderReq.java new file mode 100644 index 0000000..28c3801 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/order/CancelOrderReq.java @@ -0,0 +1,12 @@ +package com.evotech.hd.cloud.mqtt.message.dto.newer.req.order; + +import lombok.Data; + +@Data +public class CancelOrderReq { + + private String orderNo; + + private String reason; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/order/CancelOrderResponse.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/order/CancelOrderResponse.java new file mode 100644 index 0000000..63a3225 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/order/CancelOrderResponse.java @@ -0,0 +1,14 @@ +package com.evotech.hd.cloud.mqtt.message.dto.newer.req.order; + +import lombok.Data; + +@Data +public class CancelOrderResponse { + + private String orderNo; + + private Integer code; + + private String msg; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/order/OrderByPlateNumReq.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/order/OrderByPlateNumReq.java new file mode 100644 index 0000000..2b0fa60 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/order/OrderByPlateNumReq.java @@ -0,0 +1,17 @@ +package com.evotech.hd.cloud.mqtt.message.dto.newer.req.order; + +import lombok.Data; + +/** + * 站端用车牌号换取订单 + */ +@Data +public class OrderByPlateNumReq { + + private String orderRequestId; + + private String plateNum; + + private String stationCode; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/order/OrderByPlateNumResponse.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/order/OrderByPlateNumResponse.java new file mode 100644 index 0000000..9234cb3 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/order/OrderByPlateNumResponse.java @@ -0,0 +1,20 @@ +package com.evotech.hd.cloud.mqtt.message.dto.newer.req.order; + +import java.io.Serializable; + +import lombok.Data; + +@Data +public class OrderByPlateNumResponse implements Serializable { + + private static final long serialVersionUID = 1L; + + private String orderRequestId; + + private Integer code; + + private String msg; + + private OrderData orderData; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/order/OrderData.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/order/OrderData.java new file mode 100644 index 0000000..80970d0 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/order/OrderData.java @@ -0,0 +1,22 @@ +package com.evotech.hd.cloud.mqtt.message.dto.newer.req.order; + +import java.util.Date; + +import lombok.Data; + +@Data +public class OrderData { + + private String plateNum; + + private String orderNo; + + private String stationCode; + + private String stationName; + + private Integer status; + + private Date orderTime; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/preorder/PreOrderReq.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/preorder/PreOrderReq.java new file mode 100644 index 0000000..84f3a18 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/preorder/PreOrderReq.java @@ -0,0 +1,33 @@ +package com.evotech.hd.cloud.mqtt.message.dto.newer.req.preorder; + +import java.util.Date; + +import lombok.Data; + +/** + * 站端预约订单 + */ +@Data +public class PreOrderReq { + + private String stationPreOrderId; + + private String plateNum; + + private String phone; + + private String stationCode; + + private String stationName; + + private String ucode; + + private String uname; + + private String swapDay; + + private String swapDuration; + + private Date reservationTime; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/preorder/PreOrderResponse.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/preorder/PreOrderResponse.java new file mode 100644 index 0000000..858612a --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/req/preorder/PreOrderResponse.java @@ -0,0 +1,14 @@ +package com.evotech.hd.cloud.mqtt.message.dto.newer.req.preorder; + +import lombok.Data; + +@Data +public class PreOrderResponse { + + private String stationPreOrderId; + + private Integer code; + + private String msg; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/state/OrderStatus.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/state/OrderStatus.java new file mode 100644 index 0000000..f3513d1 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/state/OrderStatus.java @@ -0,0 +1,20 @@ +package com.evotech.hd.cloud.mqtt.message.dto.newer.state; + +import java.util.Date; + +import lombok.Data; + +/** + * 订单状态 + */ +@Data +public class OrderStatus { + + private String orderNo; + + private Integer status; + + private Date statusTime; + + private OrderStatusData statusDate; +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/state/OrderStatusData.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/state/OrderStatusData.java new file mode 100644 index 0000000..f0ac6e5 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/state/OrderStatusData.java @@ -0,0 +1,41 @@ +package com.evotech.hd.cloud.mqtt.message.dto.newer.state; + +import java.math.BigDecimal; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class OrderStatusData { + + @Schema(description = "总充电量") + private BigDecimal electAmount; + + @Schema(description = "租借电池包仓位") + private Integer rentBatNo; + + @Schema(description = "租用电池包编码") + private String rentBatCode; + + @Schema(description = "租用电池包SOC") + private Integer rentBatSoc; + + @Schema(description = "归还电池包编码") + private String returnBatCode; + + @Schema(description = "归还电池包仓位") + private Integer returnBatNo; + + @Schema(description = "归还电池包SOC") + private Integer returnBatSoc; + + @Schema(description = "归还电池租出时soc") + private Integer returnBatRentSoc; + + @Schema(description = "换电模式:1-全自动,2-半自动,3-人工干预 ") + private Integer changeMode; + + @Schema(description = "换电车道 1-A 车道;2-B 车道") + private Integer changeLane; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/state/SwapStep.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/state/SwapStep.java new file mode 100644 index 0000000..7a9f016 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/newer/state/SwapStep.java @@ -0,0 +1,19 @@ +package com.evotech.hd.cloud.mqtt.message.dto.newer.state; + +import java.util.Date; + +import lombok.Data; + +/** + * 换电步骤 + */ +@Data +public class SwapStep { + + private String orderNo; + + private Integer step; + + private Date stepTime; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/BatData.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/BatData.java new file mode 100644 index 0000000..d8487d6 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/BatData.java @@ -0,0 +1,145 @@ +package com.evotech.hd.cloud.mqtt.message.dto.older; + +import lombok.Data; +import java.util.Date; +import java.util.List; + +@Data +public class BatData { + /** + * 主键 + */ + private String id; + + /** + * 电池包追溯码 + */ + private String batID; + + /** + * 充电机编号 + */ + private String chgID; + + /** + * 仓位序号 + */ + private Long cabinetNo; + + /** + * 枪编号 + */ + private Long gunNo; + + /** + * 电池包个数 + */ + private Long batPackCnt; + + /** + * 单体电压总个数 + */ + private Long batCellVoltCnt; + + /** + * 单体电压 + */ + private List batCellVoltList; + + /** + * 单体电压采样时间 + */ + private Date voltSampleTime; + + /** + * 探针温度总个数 + */ + private Long probeTempCnt; + + /** + * 探针温度 + */ + private List probeTempList; + + /** + * 探针温度采样时间 + */ + private Date tempSampleTime; + + /** + * 电池包SOH + */ + private Long soh; + + /** + * 电池包总电流,充电为负值,放电为正值单位-A + */ + private Float batTotalCurr; + + /** + * 电池包允许最大 回充电电流值 (脉冲)单位-A + */ + private Float batAvailMaxChgCurr; + + /** + * 电池包允许最大 放电电流值(脉 冲)单位-A + */ + private Float batAvailMaxDischgCurr; + + /** + * 电池包正极绝缘值单位-kohm + */ + private Float batPosiinsu; + + /** + * 电池包负极绝缘值单位-kohm + */ + private Float batNegainsu; + + /** + * 电池端高压(主继电器内侧)单位-V + */ + private Float batHighVoltInner; + + /** + * 母线端高压(主继电器外侧) 单位-V + */ + private Float batHighVoltOuter; + + /** + * TMS工作状态 0 关机;1 制冷;2 制热;3 自循环; + */ + private Long tmsState; + + /** + * TMS高压继电器状态0 断开;1 闭合;2~3 无效; + */ + private Long tmsRelayState; + + /** + * 出水温度(机组到电池)单位-°C + */ + private Long outletWaterTemp; + + /** + * 回水温度(电池到机组)单位-°C + */ + private Long inletWaterTemp; + + /** + * TMS需求功率单位-kW + */ + private Float tmsDemandPower; + + /** + * TMS故障码0 无故障; + */ + private Long tmsFaultCode; + + /** + * TMS故障码等级1 1 级故障; 2 2 级故障; 3 3 级故障; 0 无效; + */ + private Long tmsFaultLevel; + + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/BatteryData.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/BatteryData.java new file mode 100644 index 0000000..8185ffd --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/BatteryData.java @@ -0,0 +1,14 @@ +package com.evotech.hd.cloud.mqtt.message.dto.older; + +import lombok.Data; + +import java.util.List; + +@Data + +public class BatteryData { + + private int chgNum; + + private List chgList; +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/ChargeRecord.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/ChargeRecord.java new file mode 100644 index 0000000..5c5274b --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/ChargeRecord.java @@ -0,0 +1,59 @@ +package com.evotech.hd.cloud.mqtt.message.dto.older; + +import lombok.Data; + +import java.util.List; + +@Data +public class ChargeRecord{ + //充电机编号 + private String equipNo; + //充电流水号 + private String orderSn; + //充电枪编号 + private int gunNo; + //开始时间(格式-yyyy-MM-dd hh:mm:ss) + private String startTime; + //结束时间(格式-yyyy-MM-dd hh:mm:ss) + private String stopTime; + //开始 SOC + private float startSoc; + //结束 SOC + private float stopSoc; + //充电电量 + private float electAmount; + //电表起始值 + private float startElect; + //电表终止值 + private float stopElect; + //充电时长 + private int chgTime; + //电池箱 ID + private String batID; + //车牌号 + private String plateNo; + //VIN 号 + private String vin; + //停止充电原因 + private int stopReason; + //尖时段电量 + private float sharpElect; + //峰时段电量 + private float peakElect; + //平时段电量 + private float flatElect; + // 低谷时段电量 + private float valleyElect; + //深谷时段电量 + private float deepValleyElect; + //费率模型 ID + private String rateModelID; + //电量时段列表 + private List detailsList; + //换电流水号 + private String swapSn; + //充电切换旋钮(0-连接器;1-充电枪;) + private int chgSwitch; + //充电启动方式(1-站控自动启动,2-站控手动启动,3-架载机手动启动,4-云平台启动) + private int startType; +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/ChargeRecordConf.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/ChargeRecordConf.java new file mode 100644 index 0000000..281417b --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/ChargeRecordConf.java @@ -0,0 +1,13 @@ +package com.evotech.hd.cloud.mqtt.message.dto.older; + +import lombok.Data; + +@Data +public class ChargeRecordConf{ + //充电流水号 + private String orderSn; + //结果(1-成功 2-失败) + private int result; + //失败原因 + private String error; +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/ChargeRecordDetail.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/ChargeRecordDetail.java new file mode 100644 index 0000000..07f9c40 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/ChargeRecordDetail.java @@ -0,0 +1,13 @@ +package com.evotech.hd.cloud.mqtt.message.dto.older; + +import lombok.Data; + +@Data +public class ChargeRecordDetail{ + //费率类型(1-尖;2-峰;3-平;4-低谷;5-深谷) + private int rateType; + //开始时间(格式-yyyy-MM-dd hh:mm:ss) + private String startTime; + //结束时间(格式-yyyy-MM-dd hh:mm:ss) + private String stopTime; +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/FaultRecord.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/FaultRecord.java new file mode 100644 index 0000000..a3f521b --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/FaultRecord.java @@ -0,0 +1,19 @@ +package com.evotech.hd.cloud.mqtt.message.dto.older; + +import lombok.Data; + +@Data +public class FaultRecord{ + //故障类型(1-发生;2-恢复) + private int faultType; + //故障流水号 + private String orderSn; + //设备编号 + private String equipNo; + //设备类型(1-充电机;2-机器人) + private int equipType; + //故障代码 + private String faultCode; + //故障时间 + private String faultTime; +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/FaultRecordConf.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/FaultRecordConf.java new file mode 100644 index 0000000..afec825 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/FaultRecordConf.java @@ -0,0 +1,13 @@ +package com.evotech.hd.cloud.mqtt.message.dto.older; + +import lombok.Data; + +@Data +public class FaultRecordConf{ + //充电流水号 + private String orderSn; + //结果(1-成功 2-失败) + private int result; + //失败原因 + private String reason; +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/RateMode.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/RateMode.java new file mode 100644 index 0000000..de42d61 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/RateMode.java @@ -0,0 +1,13 @@ +package com.evotech.hd.cloud.mqtt.message.dto.older; + +import lombok.Data; + +@Data +public class RateMode{ + // 费率类型 1-尖;2-峰;3-平;4-低谷;5-深谷 + private int reteType; + // 电费单价 + private float electPrice; + // 服务费单价 + private float servicePrice; +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/RateModeSync.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/RateModeSync.java new file mode 100644 index 0000000..b7221cc --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/RateModeSync.java @@ -0,0 +1,16 @@ +package com.evotech.hd.cloud.mqtt.message.dto.older; + +import lombok.Data; + +@Data +public class RateModeSync{ + // 费率类型 1-尖;2-峰;3-平;4-低谷;5-深谷 + private int reteType; + // 费率索引 + private int index; + // 开始时间 格式-hh:mm + private String startTime; + // 结束时间 格式-hh:mm + private String stopTime; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/SwapRecord.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/SwapRecord.java new file mode 100644 index 0000000..be6030e --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/SwapRecord.java @@ -0,0 +1,49 @@ +package com.evotech.hd.cloud.mqtt.message.dto.older; + +import lombok.Data; + +@Data +public class SwapRecord{ + //机器人编号 + private String equipNo; + //换电流水号 + private String orderSn; + //开始时间 + private String startTime; + //结束时间 + private String stopTime; + //VIN 号 + private String vin; + //RFID 码 + private String rfidCode; + //车牌号 + private String plateNo; + //存车电池箱 ID + private String newBatID; + //存车电池仓位 + private int newCabinetNo; + //存车电池 Soc + private float newBatSoc; + //取车电池箱 ID + private String oldBatID; + //取车电池仓位 + private int oldCabinetNo; + //取车电池 Soc + private float oldBatSoc; + //换电类型(1-换仓;2-换电;) + private int swapType; + //换电模式(1-全自动;2-半自动;3-人工干预) + private int swapMode; + //换电启动方式(0-站控界面;1-离线二维码,不鉴权;2-离线二维码,只鉴权;3-离线二维码,鉴权且加密;4-离线二维码,云鉴权;17-微信小程序;) + private int swapStartType; + //换电车道(0-无;1-A 车道;2-B 车道;) + private int lane; + //人员 ID + private String userID; + //站点工况(1-运营;2-测试;3-检修) + private int stationMode; + //电量数据 + private Object electObj; + //ODO仪表盘里程 + private String odo; +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/SwapRecordConf.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/SwapRecordConf.java new file mode 100644 index 0000000..16c7c13 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/SwapRecordConf.java @@ -0,0 +1,13 @@ +package com.evotech.hd.cloud.mqtt.message.dto.older; + +import lombok.Data; + +@Data +public class SwapRecordConf{ + //换电流水号 + private String orderSn; + //结果(1-成功 2-失败) + private int result; + //失败原因 + private String reason; +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/VehicleSync.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/VehicleSync.java new file mode 100644 index 0000000..a98fa01 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/VehicleSync.java @@ -0,0 +1,15 @@ +package com.evotech.hd.cloud.mqtt.message.dto.older; + +import lombok.Data; + +@Data +public class VehicleSync{ + // vin + private String vin; + // 车牌号 + private String plateNo; + // 车队 + private String fleet; + // RFID码 + private String rfidCode; +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/RateModeSyncReq.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/RateModeSyncReq.java new file mode 100644 index 0000000..cca7cc8 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/RateModeSyncReq.java @@ -0,0 +1,18 @@ +package com.evotech.hd.cloud.mqtt.message.dto.older.req; + +import lombok.Data; + +import java.util.List; + +import com.evotech.hd.cloud.mqtt.message.dto.older.RateMode; +import com.evotech.hd.cloud.mqtt.message.dto.older.RateModeSync; + +@Data +public class RateModeSyncReq{ + // 费率模型 ID 费率模型 ID,采用数字编码,最多 40 位 + private String rateModelID; + // 费率信息列表 + private List rateList; + // 费率时段列表 + private List rateDetailsList; +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/RateModeSyncResp.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/RateModeSyncResp.java new file mode 100644 index 0000000..4aa77c2 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/RateModeSyncResp.java @@ -0,0 +1,13 @@ +package com.evotech.hd.cloud.mqtt.message.dto.older.req; + +import lombok.Data; + +@Data +public class RateModeSyncResp{ + // 费率模型ID + private String reteModelID; + // 结果 1成功 2失败 + private int result; + // 原因 0-功能不可用 201-已有命令正在执行 202-参数缺失 203-参数无效 204-执行超时 205-内部错误 1001-费率版本已存在 + private int reason; +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/RemoteSwapCheckReq.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/RemoteSwapCheckReq.java new file mode 100644 index 0000000..0dddb8a --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/RemoteSwapCheckReq.java @@ -0,0 +1,17 @@ +package com.evotech.hd.cloud.mqtt.message.dto.older.req; + +import lombok.Data; + +@Data +public class RemoteSwapCheckReq{ + // VIN 号 + private String vin; + // RFID 码 + private String rfidCode; + // 车牌号 + private String plateNo; + // 车道号 1-A 车道、2-B 车道 + private int lane; + // 人员 ID + private String userID; +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/RemoteSwapCheckResp.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/RemoteSwapCheckResp.java new file mode 100644 index 0000000..27e46e5 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/RemoteSwapCheckResp.java @@ -0,0 +1,24 @@ +package com.evotech.hd.cloud.mqtt.message.dto.older.req; + +import lombok.Data; + +@Data +public class RemoteSwapCheckResp{ + // VIN 号 + private String vin; + // RFID 码 + private String rfidCode; + // 车牌号 + private String plateNo; + // 车道号 1-A 车道、2-B 车道 + private int lane; + // 结果 1-允许;2-不允许 + private int result; + // 失败原因 1-站控本地模式;2-换电设备本地模式;3- 停车不到位;4-RFID 不一致;5-车机未连 接;6-换电中;7-RFID 未读取到;8-无可用 电池; + private int reason; + // 存车电池箱 ID 失败时不上送 + private String newBatID; + // 取车电池箱 ID 失败时不上送 + private String oldBatID; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/RemoteSwapStartReq.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/RemoteSwapStartReq.java new file mode 100644 index 0000000..1d14f4f --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/RemoteSwapStartReq.java @@ -0,0 +1,17 @@ +package com.evotech.hd.cloud.mqtt.message.dto.older.req; + +import lombok.Data; + +@Data +public class RemoteSwapStartReq{ + // VIN 号 + private String vin; + // RFID 码 + private String rfidCode; + // 车牌号 + private String plateNo; + // 车道号 1-A 车道、2-B 车道 + private int lane; + // 人员 ID + private String userID; +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/RemoteSwapStartResp.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/RemoteSwapStartResp.java new file mode 100644 index 0000000..069d871 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/RemoteSwapStartResp.java @@ -0,0 +1,23 @@ +package com.evotech.hd.cloud.mqtt.message.dto.older.req; + +import lombok.Data; + +@Data +public class RemoteSwapStartResp{ + // VIN 号 + private String vin; + // RFID 码 + private String rfidCode; + // 车牌号 + private String plateNo; + // 车道号 1-A 车道、2-B 车道 + private int lane; + // 人员 ID + private String userID; + // 结果 1-成功;2-失败 + private int result; + // 失败原因 1-站控本地模式;2-换电设备本地模式;3- 停车不到位;4-RFID 不一致;5-车机未连 接;6-换电中;7-RFID 未读取到;8-无可用 电池; + private int reason; + // 换电流水号 失败时不上送 订单编号 + private String orderSn; +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/VehicleSyncReq.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/VehicleSyncReq.java new file mode 100644 index 0000000..a4318b2 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/VehicleSyncReq.java @@ -0,0 +1,15 @@ +package com.evotech.hd.cloud.mqtt.message.dto.older.req; + +import lombok.Data; + +import java.util.List; + +import com.evotech.hd.cloud.mqtt.message.dto.older.VehicleSync; + +@Data +public class VehicleSyncReq{ + // 1 添加 VIN存在时更新数据 2删除 3更新VIN不存在是失败 4全部同步 删除站端 存储本次下发 + private int operType; + // 车辆列表 + private List vehicleList; +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/VehicleSyncResp.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/VehicleSyncResp.java new file mode 100644 index 0000000..f79516c --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/req/VehicleSyncResp.java @@ -0,0 +1,11 @@ +package com.evotech.hd.cloud.mqtt.message.dto.older.req; + +import lombok.Data; + +@Data +public class VehicleSyncResp{ + // 1成功 2失败 + private int ressult; + // 失败原因 + private String reason; +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/state/ChargingData.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/state/ChargingData.java new file mode 100644 index 0000000..5740313 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/state/ChargingData.java @@ -0,0 +1,16 @@ +package com.evotech.hd.cloud.mqtt.message.dto.older.state; + +import lombok.Data; + +import java.util.List; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Data +@Schema(name = "电池箱实时信息", hidden = true) +public class ChargingData { + + private int chgNum; + + private List chgList; +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/state/HdChargingData.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/state/HdChargingData.java new file mode 100644 index 0000000..6acea6a --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/state/HdChargingData.java @@ -0,0 +1,98 @@ +package com.evotech.hd.cloud.mqtt.message.dto.older.state; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; + +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * @author zls + * @date 2023-12-03 + */ +@Schema(name = "电池箱实时信息", hidden = true) +public class HdChargingData { + + @Schema(name = "主键") + private String id; + + @Schema(name = "站编码") + private String stationId; + + @Schema(name = "充电机编号") + private String chgID; + + @Schema(name = "枪编号顺") + private Long gunNo; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Schema(name = "充电时间", example = "yyyy-MM-dd HH:mm:ss") + private Date startTime; + + @Schema(name = "充电时长秒-s ") + private Long chgTime; + + @Schema(name = "充电机输出电压单位-V,小数点后一位") + private Float chgOutputVolt; + + @Schema(name = "充电机输出电流单位-A,小数点后一位") + private Float chgOutputCurr; + + @Schema(name = "充电电量单位-kWh,小数点后一位") + private Float chgQty; + + @Schema(name = "电池箱ID") + private String batID; + + @Schema(name = "soc") + private Long soc; + + @Schema(name = "电池箱所在仓位") + private Long cabinetNo; + + @Schema(name = "最高单体电压单位-V ") + private Float batMaxVolt; + + @Schema(name = "最高单体电压组号") + private Long batMaxVoltNo; + + @Schema(name = "最低单体电压单位-V ") + private Float batMinVolt; + + @Schema(name = "最低单体电压组号") + private Long batMinVoltNo; + + @Schema(name = "最高单体温度单位-°C ") + private Float batMaxTemp; + + @Schema(name = "最高单体温度组号") + private Long batMaxTempNo; + + @Schema(name = "最低单体温度单位-°C ") + private Float batMinTemp; + + @Schema(name = "最低单体温度组号") + private Long batMinTempNo; + + @Schema(name = "电压需求单位-V,小数点后一位 ") + private Float voltDemand; + + @Schema(name = "电流需求单位-A,小数点后一位") + private Float currDemand; + + @Schema(name = "充电模式") + private Long chgMode; + + @Schema(name = "剩余充电时长单位-min 从 BMS 获取") + private Long remainderChgTime; + + @Schema(name = "直流电表电量单位-kWh,小数点后一位") + private Float dcMeterElect; + + @Schema(name = "充电流水号") + private String chgSn; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Schema(name = "创建时间", example = "yyyy-MM-dd HH:mm:ss") + private Date creatDate; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/state/SwapState.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/state/SwapState.java new file mode 100644 index 0000000..2cc86b7 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/state/SwapState.java @@ -0,0 +1,43 @@ +package com.evotech.hd.cloud.mqtt.message.dto.older.state; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +@Schema(name = "换电过程实时状态", hidden = true) +public class SwapState { + + @Schema(description = "换电状态") + private int state; + + @Schema(description = "换电步骤") + private int swapStep; + + @Schema(description = "换电步骤描述") + private String swapStepDesc; + + @Schema(description = "吊具当前位置") + private int swapPlace; + + @Schema(description = "移动台位置") + private int movePlace; + + @Schema(description = "换电车道") + private int lane; + + @Schema(description = "车辆 VIN") + private String vin; + + @Schema(description = "换电流水号") + private String orderSn; + + @Schema(description = "换电模式") + private int swapMode; + + @Schema(description = "存车电池仓位") + private int newCabinetNo; + + @Schema(description = "取车电池仓位") + private int oldCabinetNo; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/state/VehicleState.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/state/VehicleState.java new file mode 100644 index 0000000..0b9c98d --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/dto/older/state/VehicleState.java @@ -0,0 +1,30 @@ +package com.evotech.hd.cloud.mqtt.message.dto.older.state; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +@Schema(name = "换电车辆状态", hidden = true) +public class VehicleState{ + + @Schema(description = "车辆状态1-无车/驶离;2-进站;3-行驶到位") + private int state; + // 换电车道 1-A 车道;2-B 车道 + private int lane; + // VIN + private String vin; + // 车辆 RFID 码 + private String rfidCode; + // 车牌号 + private String plateNo; + // 车辆连接状态 1-未连接;2-已连接 + private int vehicleConn; + // 锁止状态 0-未知;1-解锁;2-上锁 + private int lockState; + // 车载电池 ID + private String batID; + // 车载电池 SOC + private float soc; + // 在线车辆个数 当前与站控系统建立连接的 tbox 个数 + private int tboxOnline; +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/EncryptKeyReqMessageService.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/EncryptKeyReqMessageService.java new file mode 100644 index 0000000..0654c89 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/EncryptKeyReqMessageService.java @@ -0,0 +1,51 @@ +package com.evotech.hd.cloud.mqtt.message.handle; + +import org.eclipse.paho.client.mqttv3.MqttMessage; +import org.springframework.stereotype.Service; + +import com.evotech.hd.cloud.entity.MessageMqtt; +import com.evotech.hd.cloud.mqtt.enums.MqttMessageTypeEnum; +import com.evotech.hd.cloud.mqtt.message.MessageTopic; +import com.evotech.hd.cloud.service.MessageMqttService; +import cn.hutool.json.JSONObject; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; + +/** + * 请求密钥 处理 + */ +@Service +@Slf4j +public class EncryptKeyReqMessageService { + + @Resource + private MessageMqttService messageMqttService; + @Resource + private MessageUtilService messageUtilService; + + + public void encryptKeyReq(MessageTopic topic, MqttMessage message) { + // 1. 解密 + JSONObject jo = messageUtilService.decryptEncryptKeyReqMessage(topic, message); + String clientPublicKey = jo.getStr("publicKey"); + // 2. 保存MQTT消息 + MessageMqtt mm = new MessageMqtt(); + mm.setContent(jo.toJSONString(0)); + mm.setDirection(topic.getDataDirection()); + mm.setMessageFunction(""); + mm.setMessageId(message.getId() + ""); + mm.setQos(message.getQos()); + mm.setStationCode(topic.getStationCode()); + mm.setTopic(topic.toString()); + mm.setType(topic.getMessageType()); + messageMqttService.add(mm); + // 3. 生成数据:AES秘钥 + JSONObject aesJo = messageUtilService.setAesKey(topic.getStationCode()); + // 4. 发送MQTT消息 + topic.setDataDirection("M2S"); + topic.setMessageType(MqttMessageTypeEnum.ENCRYRESP.getType()); + messageUtilService.publishRSAMessage(topic, aesJo.toJSONString(0), clientPublicKey); + } + + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/EventMessageService.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/EventMessageService.java new file mode 100644 index 0000000..49f5634 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/EventMessageService.java @@ -0,0 +1,45 @@ +package com.evotech.hd.cloud.mqtt.message.handle; + +import org.springframework.stereotype.Service; + +import com.evotech.hd.cloud.mqtt.enums.EventFunctionTypesEnum; +import com.evotech.hd.cloud.mqtt.message.MessageTopic; +import com.evotech.hd.cloud.mqtt.message.MqttMessageHeader; +import cn.hutool.json.JSONObject; +import jakarta.annotation.Resource; + +@Service +public class EventMessageService { + + @Resource + private MessageUtilService messageUtilService; + + + /** + * event消息 处理 + */ + public void event(MessageTopic topic, MqttMessageHeader header, JSONObject dataBody) { + switch (EventFunctionTypesEnum.getFunctionType(header.getFunction())) { + case FUN_CHARGE_RECORD: + // TODO 写充电记录表 + // TODO 回复 confirm 消息 + // TODO 订单结算 + + break; + case FUN_SWAP_RECORD: + // TODO 写换电记录表 + // TODO 回复 confirm 消息 + // TODO 更新订单 + break; + case FUN_WARN_RECORD: + // TODO 写预警记录表 + // TODO 回复 confirm 消息 + // TODO 业务处理 + break; + + default: + break; + } + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/KeepaliveMessageService.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/KeepaliveMessageService.java new file mode 100644 index 0000000..ae0a981 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/KeepaliveMessageService.java @@ -0,0 +1,33 @@ +package com.evotech.hd.cloud.mqtt.message.handle; + +import java.util.Date; + +import org.eclipse.paho.client.mqttv3.MqttMessage; +import org.springframework.stereotype.Service; + +import com.evotech.hd.cloud.mqtt.config.MqttConfig; +import com.evotech.hd.cloud.mqtt.message.MessageTopic; + +import cn.hutool.core.date.DateUtil; +import jakarta.annotation.Resource; + + +/** + * Keepalive消息 处理 + */ +@Service +public class KeepaliveMessageService { + + + @Resource + private MqttConfig mqttConfig; + + + + public void keepAlive(MessageTopic topic, MqttMessage message) { + String msg = DateUtil.formatDateTime(new Date()); + String tp = topic.toString().replace("S2M", "M2S"); + mqttConfig.publish(msg, tp); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/MessageUtilService.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/MessageUtilService.java new file mode 100644 index 0000000..7efd932 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/MessageUtilService.java @@ -0,0 +1,215 @@ +package com.evotech.hd.cloud.mqtt.message.handle; + +import java.util.Base64; +import java.util.Date; + +import javax.crypto.SecretKey; + +import org.eclipse.paho.client.mqttv3.MqttMessage; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.evotech.hd.cloud.dao.BatteryStationSecretKeyDao; +import com.evotech.hd.cloud.entity.BatteryStationSecretKey; +import com.evotech.hd.cloud.entity.MessageMqtt; +import com.evotech.hd.cloud.mqtt.config.MqttConfig; +import com.evotech.hd.cloud.mqtt.message.MessageTopic; +import com.evotech.hd.cloud.mqtt.message.MqttMessageHeader; +import com.evotech.hd.cloud.mqtt.message.MyMqttMessage; +import com.evotech.hd.cloud.service.MessageMqttService; +import com.evotech.hd.common.core.constant.HDConstant; +import com.evotech.hd.common.redis.utils.RedisUtil; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.RandomUtil; +import cn.hutool.crypto.KeyUtil; +import cn.hutool.crypto.Mode; +import cn.hutool.crypto.Padding; +import cn.hutool.crypto.SecureUtil; +import cn.hutool.crypto.asymmetric.KeyType; +import cn.hutool.crypto.asymmetric.RSA; +import cn.hutool.crypto.symmetric.AES; +import cn.hutool.crypto.symmetric.SymmetricAlgorithm; +import cn.hutool.crypto.symmetric.SymmetricCrypto; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; + +@Service +@Slf4j +public class MessageUtilService { + + @Resource + private MessageMqttService messageMqttService; + @Resource + private RedisUtil redisUtil; + @Resource + private BatteryStationSecretKeyDao batteryStationSecretKeyDao; + @Resource + private MqttConfig mqttConfig; + + + + /** + * 记录MQTT消息 + * @param topic + * @param message + * @param jo + * @return + */ + public MqttMessageHeader addMqttMessage(MessageTopic topic, String messageId, int qos, JSONObject jo) { + MqttMessageHeader header = JSONUtil.toBean(jo.getJSONObject("header"), MqttMessageHeader.class); + MessageMqtt mm = new MessageMqtt(); + mm.setContent(jo.toJSONString(0)); + mm.setDirection(topic.getDataDirection()); + mm.setMessageFunction(header.getFunction()); + mm.setMessageId(messageId); + mm.setQos(qos); + mm.setStationCode(topic.getStationCode()); + mm.setTopic(topic.toString()); + mm.setType(topic.getMessageType()); + messageMqttService.add(mm); + return header; + } + + + /** + * 发送RSA加密消息 + * @param topic + * @param msg + * @param publicKey + */ + public void publishRSAMessage(MessageTopic topic, String msg, String publicKey) { + RSA rsa = SecureUtil.rsa(null, publicKey); + String encrypt = rsa.encryptBase64(msg, KeyType.PublicKey); + mqttConfig.publish(encrypt, topic.toString()); + } + + /** + * 发送 AES 加密消息 + * @param topic + * @param header + * @param dataBody + */ + public void publishAESMessage(MessageTopic topic, MqttMessageHeader header, JSONObject dataBody) { + // 1. 获取AES + JSONObject aesJo = getAESKey(topic.getStationCode()); + SymmetricCrypto aes = new AES(Mode.CBC, Padding.PKCS5Padding, aesJo.getStr("aesSecretKey").getBytes(), aesJo.getStr("aesIv").getBytes()); + // 2. 数据 + MyMqttMessage message = new MyMqttMessage(); + message.setHeader(header); + message.setDataBody(dataBody); + String encrypt = aes.encryptBase64(JSONUtil.toJsonStr(message)); + // 3. 发送MQTT消息 + mqttConfig.publish(encrypt, topic.toString()); + } + + + + /** + * 解密 请求秘钥的消息,此类消息是RSA类型 + * @param topic + * @param message + * @return + */ + public JSONObject decryptEncryptKeyReqMessage(MessageTopic topic, MqttMessage message) { + byte[] payload = message.getPayload(); + String privateKey = getRSAPrivateKey(topic.getStationCode()); + RSA rsa = SecureUtil.rsa(privateKey, null); + byte[] decrypt = rsa.decrypt(payload, KeyType.PrivateKey); + + return JSONUtil.parseObj(new String(decrypt)); + } + + /** + * 解密AES类型的消息 + * @param topic + * @param message + * @return + */ + public JSONObject decryptAesMessage(MessageTopic topic, MqttMessage message) { + JSONObject aesJo = getAESKey(topic.getStationCode()); + SymmetricCrypto aes = new AES(Mode.CBC, Padding.PKCS5Padding, aesJo.getStr("aesSecretKey").getBytes(), aesJo.getStr("aesIv").getBytes()); + byte[] decrypt = aes.decrypt(message.getPayload()); + + return JSONUtil.parseObj(new String(decrypt)); + } + + + /** + * 获取AES秘钥和IV + * @param stationCode + * @return + */ + public JSONObject getAESKey(String stationCode) { + JSONObject jo = new JSONObject(); + Object o1 = redisUtil.get(HDConstant.HD_STATION_SECRET_KEY_AES_PREFIX + stationCode + ":key"); + Object o2 = redisUtil.get(HDConstant.HD_STATION_SECRET_KEY_AES_PREFIX + stationCode + ":iv"); + if (!ObjectUtil.isEmpty(o1) && !ObjectUtil.isEmpty(o2)) { + jo.set("aesSecretKey", o1.toString()); + jo.set("aesIv", o2.toString()); + return jo; + } + BatteryStationSecretKey bssk = batteryStationSecretKeyDao.selectOne(new QueryWrapper().eq("type", 2).eq("station_code", stationCode)); + if (bssk == null) { + return setAesKey(stationCode); + } + redisUtil.set(HDConstant.HD_STATION_SECRET_KEY_AES_PREFIX + stationCode + ":key", bssk.getPublicKey()); + redisUtil.set(HDConstant.HD_STATION_SECRET_KEY_AES_PREFIX + stationCode + ":iv", bssk.getPrivateKey()); + jo.set("aesSecretKey", o1.toString()); + jo.set("aesIv", o2.toString()); + return jo; + } + + + /** + * 设置AES秘钥和IV + * @param stationCode + * @return + */ + public JSONObject setAesKey(String stationCode) { + SecretKey key = KeyUtil.generateKey(SymmetricAlgorithm.AES.getValue()); + String base64KeyStr = Base64.getEncoder().encodeToString(key.getEncoded()); + String iv = RandomUtil.randomString(12); + batteryStationSecretKeyDao.delete(new QueryWrapper().eq("type", 2).eq("station_code", stationCode)); + BatteryStationSecretKey bssk = new BatteryStationSecretKey(); + bssk.setStationCode(stationCode); + bssk.setType(2); + bssk.setPublicKey(base64KeyStr); + bssk.setPrivateKey(iv); + bssk.setCtime(new Date()); + batteryStationSecretKeyDao.insert(bssk); + redisUtil.set(HDConstant.HD_STATION_SECRET_KEY_AES_PREFIX + stationCode + ":key", bssk.getPublicKey()); + redisUtil.set(HDConstant.HD_STATION_SECRET_KEY_AES_PREFIX + stationCode + ":iv", bssk.getPrivateKey()); + JSONObject jo = new JSONObject(); + jo.set("aesSecretKey", base64KeyStr); + jo.set("aesIv", iv); + return jo; + } + + + + + + /** + * 获取RSA私钥 + * @param stationCode + * @return + */ + private String getRSAPrivateKey(String stationCode) { + Object o = redisUtil.get(HDConstant.HD_STATION_SECRET_KEY_RSA_PREFIX + stationCode + ":privatekey"); + if (!ObjectUtil.isEmpty(o)) { + return o.toString(); + } + BatteryStationSecretKey bssk = batteryStationSecretKeyDao + .selectOne(new QueryWrapper().eq("type", 1).eq("station_code", stationCode)); + if (bssk == null) { + log.error("\r\n=====>>>>> 换电站 {} 未设置安全密钥!", stationCode); + return null; + } + redisUtil.set(HDConstant.HD_STATION_SECRET_KEY_RSA_PREFIX + stationCode + ":privatekey", bssk.getPrivateKey()); + return bssk.getPrivateKey(); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/MqttMessageHandle.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/MqttMessageHandle.java new file mode 100644 index 0000000..76edf9f --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/MqttMessageHandle.java @@ -0,0 +1,71 @@ +package com.evotech.hd.cloud.mqtt.message.handle; + +import org.eclipse.paho.client.mqttv3.MqttMessage; +import org.springframework.stereotype.Component; + +import com.evotech.hd.cloud.mqtt.enums.MqttMessageTypeEnum; +import com.evotech.hd.cloud.mqtt.message.MessageTopic; +import com.evotech.hd.cloud.mqtt.message.MqttMessageHeader; + +import cn.hutool.json.JSONObject; +import jakarta.annotation.Resource; + +/** + * Mqtt消息处理 + */ +@Component +public class MqttMessageHandle { + + @Resource + private EncryptKeyReqMessageService encryptKeyReqService; + @Resource + private MessageUtilService messageUtilService; + @Resource + private KeepaliveMessageService keepaliveMessageService; + @Resource + private StateMessageService stateMessageService; + @Resource + private EventMessageService eventMessageService; + @Resource + private RequestMessageService requestMessageService; + + + public void handle(MessageTopic topic, MqttMessage message) { + // 1. 请求密钥RSA加密 单独处理 + if (MqttMessageTypeEnum.ENCRYREQ.getType().equals(topic.getMessageType())) { + encryptKeyReqService.encryptKeyReq(topic, message); + return; + } + // 2. keepalive不加密,单独处理 + if (MqttMessageTypeEnum.KEEPALIVE.getType().equals(topic.getMessageType())) { + keepaliveMessageService.keepAlive(topic, message); + return; + } + // 3. 其他 AES加密 + // 3.1 保存数据 + // 3.1.1 解密 + JSONObject jo = messageUtilService.decryptAesMessage(topic, message); + // 3.1.2 保存MQTT消息 + MqttMessageHeader header = messageUtilService.addMqttMessage(topic, message.getId()+"", message.getQos(), jo); + JSONObject dataBody = jo.getJSONObject("dataBody"); + // 3.2 分类处理 + // 3.2.1 state + if (MqttMessageTypeEnum.STATE.getType().equals(topic.getMessageType())) { + // 多线程处理 + stateMessageService.state(topic, header, dataBody); + return; + } + // 3.2.2 event + if (MqttMessageTypeEnum.EVENT.getType().equals(topic.getMessageType())) { + eventMessageService.event(topic, header, dataBody); + return; + } + // 3.2.3 request + if (MqttMessageTypeEnum.REQUEST.getType().equals(topic.getMessageType())) { + requestMessageService.request(topic, header, dataBody); + return; + } + + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/RequestMessageService.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/RequestMessageService.java new file mode 100644 index 0000000..b93adb0 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/RequestMessageService.java @@ -0,0 +1,110 @@ +package com.evotech.hd.cloud.mqtt.message.handle; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.evotech.hd.cloud.dao.VehicleWechatUserRelationDao; +import com.evotech.hd.cloud.mqtt.enums.MqttMessageTypeEnum; +import com.evotech.hd.cloud.mqtt.enums.RequestFunctionTypesEnum; +import com.evotech.hd.cloud.mqtt.message.MessageTopic; +import com.evotech.hd.cloud.mqtt.message.MqttMessageHeader; +import com.evotech.hd.cloud.mqtt.message.dto.newer.req.carinfo.CarInfoReq; +import com.evotech.hd.cloud.mqtt.message.dto.newer.req.carinfo.CarInfoResponse; +import com.evotech.hd.cloud.mqtt.message.dto.newer.req.carinfo.VehicleData; +import com.evotech.hd.common.core.entity.cloud.VehicleWechatUserRelation; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import jakarta.annotation.Resource; + +/** + * request消息 处理 + */ +@Service +public class RequestMessageService { + + @Resource + private VehicleWechatUserRelationDao vehicleWechatUserRelationDao; + @Resource + private MessageUtilService messageUtilService; + + + public void request(MessageTopic topic, MqttMessageHeader header, JSONObject dataBody) { + switch (RequestFunctionTypesEnum.getFunctionType(header.getFunction())) { + case FUN_CARINFO: + CarInfoReq carInfoReq = JSONUtil.toBean(dataBody, CarInfoReq.class); + handleCarInfo(topic, header, carInfoReq); + break; + case FUN_BATTERYINFO: + + + break; + case FUN_PREORDER: + + + break; + case FUN_ORDERBYPLATENUM: + + + break; + case FUN_CANCELORDER: + + + break; + + default: + break; + } + + } + + + /** + * CarInfo请求处理 + * @param topic + * @param header + * @param carInfoReq + */ + private void handleCarInfo(MessageTopic topic, MqttMessageHeader header, CarInfoReq carInfoReq) { + String plateNum = carInfoReq.getPlateNum(); + int pageNo = 0; + int pageSize = 500; + Page page = new Page(pageNo, pageSize); + do { + pageNo += 1; + page = new Page(pageNo, 500); + page = vehicleWechatUserRelationDao.selectPage(page, new QueryWrapper() + .eq(StringUtils.hasText(plateNum), "plate_num", plateNum)); + CarInfoResponse response = new CarInfoResponse(); + response.setCarInfoRequestId(carInfoReq.getCarInfoRequestId()); + response.setPageNo(Integer.valueOf(page.getCurrent() + "")); + response.setPageSize(Integer.valueOf(page.getSize() + "")); + response.setTotal(Integer.valueOf(page.getTotal() + "")); + response.setIsOver(page.getCurrent() < page.getPages()? 0 : 1); + List list = new ArrayList(); + if (page.getCurrent() > 0) { + list = page.getRecords().stream().map(i -> { + VehicleData vd = new VehicleData(); + BeanUtils.copyProperties(i, vd); + return vd; + }).toList(); + response.setVehicleData(list); + } + topic.setDataDirection("M2S"); + topic.setMessageType(MqttMessageTypeEnum.RESPONSE.getType()); + header.setFunction(RequestFunctionTypesEnum.FUN_CARINFO.getReFunction()); + header.setTimeStamp(DateUtil.format(new Date(), DatePattern.NORM_DATETIME_FORMATTER)); + messageUtilService.publishAESMessage(topic, header, JSONUtil.parseObj(response)); + } while (page.getCurrent() < page.getPages()); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/StateMessageService.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/StateMessageService.java new file mode 100644 index 0000000..85efcfd --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/handle/StateMessageService.java @@ -0,0 +1,74 @@ +package com.evotech.hd.cloud.mqtt.message.handle; + +import org.springframework.stereotype.Service; + +import com.evotech.hd.cloud.mqtt.enums.StateFunctionTypesEnum; +import com.evotech.hd.cloud.mqtt.message.MessageTopic; +import com.evotech.hd.cloud.mqtt.message.MqttMessageHeader; +import com.evotech.hd.cloud.mqtt.message.dto.newer.state.OrderStatus; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import jakarta.annotation.Resource; + + +/** + * state消息 处理 + */ +@Service +public class StateMessageService { + + @Resource + private MessageUtilService messageUtilService; + + public void state(MessageTopic topic, MqttMessageHeader header, JSONObject dataBody) { + switch (StateFunctionTypesEnum.getFunctionType(header.getFunction())) { + case FUN_ORDERSTATUS: + OrderStatus orderStatus = JSONUtil.toBean(dataBody, OrderStatus.class); + handleOrderStatus(orderStatus); + + break; + case FUN_SWAPSTEP: + // 记录换电步骤 + + break; + default: + break; + } + + + } + + private void handleOrderStatus(OrderStatus orderStatus) { + switch (orderStatus.getStatus()) { + case 2: + // 修改订单状态 + + // 添加换电步骤1-车辆进站 + + break; + case 3: + // 修改订单状态和数据 + + + break; + case 4: + // 修改订单状态 + + break; + case 5: + // 修改订单状态和数据 + + break; + default: + break; + } + } + + + + + + + + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationDcService.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationDcService.java new file mode 100644 index 0000000..4626d83 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationDcService.java @@ -0,0 +1,25 @@ +package com.evotech.hd.cloud.service; + +import java.util.List; + +import com.evotech.hd.cloud.entity.request.PageListBatteryStationDcRequest; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.BatteryStationDc; +import com.evotech.hd.common.core.entity.cloud.BatteryTrace; + +public interface BatteryStationDcService { + + public Result add(BatteryStationDc bsdc); + + public Result delete(Integer id); + + public Result update(BatteryStationDc bsdc); + + public Result> list(PageListBatteryStationDcRequest plbsdcr); + + public Result> listTrace(String batteryCode); + + public Result addTrace(BatteryTrace bt); + + public Result deleteTrace(Integer id); +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationDccService.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationDccService.java new file mode 100644 index 0000000..4b79ac1 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationDccService.java @@ -0,0 +1,19 @@ +package com.evotech.hd.cloud.service; + +import java.util.List; + +import com.evotech.hd.cloud.entity.request.PageListBatteryStationDccRequest; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.BatteryStationDcc; + +public interface BatteryStationDccService { + + public Result add(BatteryStationDcc bsdcc); + + public Result delete(Integer id); + + public Result update(BatteryStationDcc bsdcc); + + public Result> list(PageListBatteryStationDccRequest plbsDccr); + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationDjService.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationDjService.java new file mode 100644 index 0000000..0dc2378 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationDjService.java @@ -0,0 +1,19 @@ +package com.evotech.hd.cloud.service; + +import java.util.List; + +import com.evotech.hd.cloud.entity.request.PageListBatteryStationDjRequest; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.BatteryStationDj; + +public interface BatteryStationDjService { + + public Result add(BatteryStationDj bsdj); + + public Result delete(Integer id); + + public Result update(BatteryStationDj bsdj); + + public Result> list(PageListBatteryStationDjRequest plbsdjr); + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationHdFeeStandardDetailService.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationHdFeeStandardDetailService.java new file mode 100644 index 0000000..ec16780 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationHdFeeStandardDetailService.java @@ -0,0 +1,18 @@ +package com.evotech.hd.cloud.service; + +import java.util.List; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.BatteryStationHdFeeStandardDetail; + +public interface BatteryStationHdFeeStandardDetailService { + + public Result add(BatteryStationHdFeeStandardDetail bsfsd); + + public Result delete(Integer id); + + public Result update(BatteryStationHdFeeStandardDetail bsfsd); + + public Result> list(Integer standardId); + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationHdFeeStandardService.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationHdFeeStandardService.java new file mode 100644 index 0000000..602cdd1 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationHdFeeStandardService.java @@ -0,0 +1,18 @@ +package com.evotech.hd.cloud.service; + +import java.util.List; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.BatteryStationHdFeeStandard; + +public interface BatteryStationHdFeeStandardService { + + public Result add(BatteryStationHdFeeStandard bsfs); + + public Result delete(Integer id); + + public Result update(BatteryStationHdFeeStandard bsfs); + + public Result> list(String stationCode); + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationRobotService.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationRobotService.java new file mode 100644 index 0000000..556260d --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationRobotService.java @@ -0,0 +1,18 @@ +package com.evotech.hd.cloud.service; + +import java.util.List; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.BatteryStationRobot; + +public interface BatteryStationRobotService { + + public Result add(BatteryStationRobot bsr); + + public Result delete(Integer id); + + public Result update(BatteryStationRobot bsr); + + public Result> list(String stationCode); + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationService.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationService.java new file mode 100644 index 0000000..65122ae --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationService.java @@ -0,0 +1,22 @@ +package com.evotech.hd.cloud.service; + +import java.util.List; +import java.util.Map; + +import com.evotech.hd.cloud.entity.request.PageListBatteryStationRequest; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.BatteryStation; + +public interface BatteryStationService { + + public Result add(BatteryStation bs); + + public Result delete(Integer id); + + public Result update(BatteryStation bs); + + public Result> list(PageListBatteryStationRequest plbsr); + + public Result> RsaSecretKey(String stationCode); + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/MessageMqttService.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/MessageMqttService.java new file mode 100644 index 0000000..1a134f6 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/MessageMqttService.java @@ -0,0 +1,17 @@ +package com.evotech.hd.cloud.service; + +import java.util.List; + +import com.evotech.hd.cloud.entity.MessageMqtt; +import com.evotech.hd.cloud.entity.request.PageListMessageMqttRequest; +import com.evotech.hd.common.core.entity.Result; + +public interface MessageMqttService { + + public Result> list(PageListMessageMqttRequest plmmr); + + public Result add(MessageMqtt message); + + public Result del(); + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/OrderRechargeService.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/OrderRechargeService.java new file mode 100644 index 0000000..7a7cac9 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/OrderRechargeService.java @@ -0,0 +1,19 @@ +package com.evotech.hd.cloud.service; + +import java.util.List; + +import com.evotech.hd.cloud.entity.request.PageListRechargeOrderRequest; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.OrderRecharge; + +public interface OrderRechargeService { + + public Result add(OrderRecharge or); + + public Result delete(Integer id); + + public Result update(OrderRecharge or); + + public Result> list(PageListRechargeOrderRequest plror); + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/OrderSwapBatteryService.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/OrderSwapBatteryService.java new file mode 100644 index 0000000..289e154 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/OrderSwapBatteryService.java @@ -0,0 +1,29 @@ +package com.evotech.hd.cloud.service; + +import java.util.List; + +import com.evotech.hd.cloud.entity.request.PageListSwapOrderRequest; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery; +import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryPre; +import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryStep; + +public interface OrderSwapBatteryService { + + public Result addPre(OrderSwapBatteryPre osbp); + + public Result cancelPre(Integer id, Integer status); + + public Result> listPre(String plateNum, Integer status, String userId); + + public Result add(OrderSwapBattery osb); + + public Result delete(Integer id); + + public Result update(OrderSwapBattery osb); + + public Result> list(PageListSwapOrderRequest plsor); + + public Result> listStep(String orderNo); + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/TradeService.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/TradeService.java new file mode 100644 index 0000000..f9d6f47 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/TradeService.java @@ -0,0 +1,19 @@ +package com.evotech.hd.cloud.service; + +import java.util.List; + +import com.evotech.hd.cloud.entity.request.PageListTradeRequest; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.TradeDetail; + +public interface TradeService { + + public Result add(TradeDetail td); + + public Result delete(Integer id); + + public Result update(TradeDetail td); + + public Result> list(PageListTradeRequest pltr); + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/VehicleService.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/VehicleService.java new file mode 100644 index 0000000..92fbfa1 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/VehicleService.java @@ -0,0 +1,25 @@ +package com.evotech.hd.cloud.service; + +import java.util.List; + +import com.evotech.hd.cloud.entity.request.PageListVehicleRequest; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.VehicleInfo; +import com.evotech.hd.common.core.entity.cloud.VehicleWechatUserRelation; + +public interface VehicleService { + + public Result add(VehicleInfo vi); + + public Result delete(Integer id); + + public Result update(VehicleInfo vi); + + public Result> list(PageListVehicleRequest plvr); + + public Result addWechatUserRelation(VehicleWechatUserRelation relation); + + public Result deleteWechatUserRelation(Integer id); + + public Result> listWechatUserRelation(String openid, String plateNum); +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/WalletAccountService.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/WalletAccountService.java new file mode 100644 index 0000000..8ab110a --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/WalletAccountService.java @@ -0,0 +1,26 @@ +package com.evotech.hd.cloud.service; + +import java.util.List; + +import com.evotech.hd.cloud.entity.request.PageListWalletRequest; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.WalletAccount; +import com.evotech.hd.common.core.entity.cloud.WalletAccountDetail; + +public interface WalletAccountService { + + public Result add(WalletAccount wa); + + public Result delete(Integer id, String code); + + public Result update(WalletAccount wa); + + public Result> list(PageListWalletRequest plwr); + + public Result addDetail(WalletAccountDetail wad); + + public Result deleteDetail(Integer id, String code); + + public Result> listDetail(PageListWalletRequest plwr); + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationDcServiceImpl.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationDcServiceImpl.java new file mode 100644 index 0000000..6932ebe --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationDcServiceImpl.java @@ -0,0 +1,104 @@ +package com.evotech.hd.cloud.service.impl; + +import java.util.Date; +import java.util.List; + +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.evotech.hd.cloud.dao.BatteryStationDcDao; +import com.evotech.hd.cloud.dao.BatteryTraceDao; +import com.evotech.hd.cloud.entity.request.PageListBatteryStationDcRequest; +import com.evotech.hd.cloud.service.BatteryStationDcService; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.BatteryStationDc; +import com.evotech.hd.common.core.entity.cloud.BatteryTrace; +import com.evotech.hd.common.core.enums.CodeMsg; + +import jakarta.annotation.Resource; + + +@Service +public class BatteryStationDcServiceImpl implements BatteryStationDcService { + + @Resource + private BatteryStationDcDao batteryStationDcDao; + @Resource + private BatteryTraceDao batteryTraceDao; + + @Override + public Result add(BatteryStationDc bsdc) { + bsdc.setCtime(new Date()); + int n = batteryStationDcDao.insert(bsdc); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加电池出错!"); + } + + @Override + public Result delete(Integer id) { + BatteryStationDc bsdc = new BatteryStationDc(); + bsdc.setPkId(id); + bsdc.setDelFlag(1); + int n = batteryStationDcDao.updateById(bsdc); + if (n == 1) { + return new Result().success(n); + } + throw new RuntimeException("删除电池出错!"); + } + + @Override + public Result update(BatteryStationDc bsdc) { + int n = batteryStationDcDao.updateById(bsdc); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("更新换电站电池失败!"); + } + + @Override + public Result> list(PageListBatteryStationDcRequest plbsdcr) { + Page page = new Page(plbsdcr.getPageNo(), plbsdcr.getPageSize()); + page = batteryStationDcDao.selectPage(page, new QueryWrapper() + .eq(StringUtils.hasText(plbsdcr.getProxyId()), "proxy_id", plbsdcr.getProxyId()) + .eq(StringUtils.hasText(plbsdcr.getStationCode()), "station_code", plbsdcr.getStationCode())); + if (page.getRecords().isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(page); + } + + @Override + public Result> listTrace(String batteryCode) { + List list = batteryTraceDao.selectList(new QueryWrapper() + .eq("bat_code", batteryCode) + .orderByDesc("begin_time")); + if (list.isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(list); + } + + @Override + public Result addTrace(BatteryTrace bt) { + bt.setCtime(new Date()); + int n = batteryTraceDao.insert(bt); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加追溯出错!"); + } + + @Override + public Result deleteTrace(Integer id) { + int n = batteryTraceDao.deleteById(id); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("删除追溯失败!"); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationDccServiceImpl.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationDccServiceImpl.java new file mode 100644 index 0000000..c8596b5 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationDccServiceImpl.java @@ -0,0 +1,67 @@ +package com.evotech.hd.cloud.service.impl; + +import java.util.Date; +import java.util.List; + +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.evotech.hd.cloud.dao.BatteryStationDccDao; +import com.evotech.hd.cloud.entity.request.PageListBatteryStationDccRequest; +import com.evotech.hd.cloud.service.BatteryStationDccService; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.BatteryStationDcc; +import com.evotech.hd.common.core.enums.CodeMsg; + +import jakarta.annotation.Resource; + + +@Service +public class BatteryStationDccServiceImpl implements BatteryStationDccService { + + @Resource + private BatteryStationDccDao batteryStationDccDao; + + @Override + public Result add(BatteryStationDcc bsdcc) { + bsdcc.setCtime(new Date()); + int n = batteryStationDccDao.insert(bsdcc); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加电池仓出错!"); + } + + @Override + public Result delete(Integer id) { + int n = batteryStationDccDao.deleteById(id); + if (n == 1) { + return new Result().success(n); + } + throw new RuntimeException("删除换电站电池仓出错!"); + } + + @Override + public Result update(BatteryStationDcc bsdcc) { + int n = batteryStationDccDao.updateById(bsdcc); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("更新换电站电池仓失败!"); + } + + @Override + public Result> list(PageListBatteryStationDccRequest plbsDccr) { + Page page = new Page(plbsDccr.getPageNo(), plbsDccr.getPageSize()); + page = batteryStationDccDao.selectPage(page, new QueryWrapper() + .eq(StringUtils.hasText(plbsDccr.getProxyId()), "proxy_id", plbsDccr.getProxyId()) + .eq(StringUtils.hasText(plbsDccr.getStationCode()), "station_code", plbsDccr.getStationCode())); + if (page.getRecords().isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(page); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationDjServiceImpl.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationDjServiceImpl.java new file mode 100644 index 0000000..73a2cf5 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationDjServiceImpl.java @@ -0,0 +1,67 @@ +package com.evotech.hd.cloud.service.impl; + +import java.util.Date; +import java.util.List; + +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.evotech.hd.cloud.dao.BatteryStationDjDao; +import com.evotech.hd.cloud.entity.request.PageListBatteryStationDjRequest; +import com.evotech.hd.cloud.service.BatteryStationDjService; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.BatteryStationDj; +import com.evotech.hd.common.core.enums.CodeMsg; + +import jakarta.annotation.Resource; + + +@Service +public class BatteryStationDjServiceImpl implements BatteryStationDjService { + + @Resource + private BatteryStationDjDao batteryStationDjDao; + + @Override + public Result add(BatteryStationDj bsdj) { + bsdj.setCtime(new Date()); + int n = batteryStationDjDao.insert(bsdj); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加换电站电机出错!"); + } + + @Override + public Result delete(Integer id) { + int n = batteryStationDjDao.deleteById(id); + if (n == 1) { + return new Result().success(n); + } + throw new RuntimeException("删除换电站电机出错!"); + } + + @Override + public Result update(BatteryStationDj bsdj) { + int n = batteryStationDjDao.updateById(bsdj); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("更新换电站电机失败!"); + } + + @Override + public Result> list(PageListBatteryStationDjRequest plbsdjr) { + Page page = new Page(plbsdjr.getPageNo(), plbsdjr.getPageSize()); + page = batteryStationDjDao.selectPage(page, new QueryWrapper() + .eq(StringUtils.hasText(plbsdjr.getProxyId()), "proxy_id", plbsdjr.getProxyId()) + .eq(StringUtils.hasText(plbsdjr.getStationCode()), "station_code", plbsdjr.getStationCode())); + if (page.getRecords().isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(page); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationHdFeeStandardDetailServiceImpl.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationHdFeeStandardDetailServiceImpl.java new file mode 100644 index 0000000..b436a64 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationHdFeeStandardDetailServiceImpl.java @@ -0,0 +1,63 @@ +package com.evotech.hd.cloud.service.impl; + +import java.util.Date; +import java.util.List; + +import org.springframework.stereotype.Service; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.evotech.hd.cloud.dao.BatteryStationHdFeeStandardDetailDao; +import com.evotech.hd.cloud.service.BatteryStationHdFeeStandardDetailService; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.BatteryStationHdFeeStandardDetail; +import com.evotech.hd.common.core.enums.CodeMsg; + +import jakarta.annotation.Resource; + + +@Service +public class BatteryStationHdFeeStandardDetailServiceImpl implements BatteryStationHdFeeStandardDetailService { + + @Resource + private BatteryStationHdFeeStandardDetailDao batteryStationHdFeeStandardDetailDao; + + @Override + public Result add(BatteryStationHdFeeStandardDetail bsfsd) { + bsfsd.setCtime(new Date()); + int n = batteryStationHdFeeStandardDetailDao.insert(bsfsd); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加换电站费用标准明细出错!"); + } + + @Override + public Result delete(Integer id) { + int n = batteryStationHdFeeStandardDetailDao.deleteById(id); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("删除换电站费用标准明细出错!"); + } + + @Override + public Result update(BatteryStationHdFeeStandardDetail bsfsd) { + int n = batteryStationHdFeeStandardDetailDao.updateById(bsfsd); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("更新换电站费用标准明细失败!"); + } + + @Override + public Result> list(Integer standardId) { + List list = batteryStationHdFeeStandardDetailDao.selectList(new QueryWrapper() + .eq(standardId != null, "standard_id", standardId)); + if (list.isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(list); + } + + + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationHdFeeStandardServiceImpl.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationHdFeeStandardServiceImpl.java new file mode 100644 index 0000000..fda97da --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationHdFeeStandardServiceImpl.java @@ -0,0 +1,70 @@ +package com.evotech.hd.cloud.service.impl; + +import java.util.Date; +import java.util.List; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.evotech.hd.cloud.dao.BatteryStationHdFeeStandardDao; +import com.evotech.hd.cloud.dao.BatteryStationHdFeeStandardDetailDao; +import com.evotech.hd.cloud.service.BatteryStationHdFeeStandardService; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.BatteryStationHdFeeStandard; +import com.evotech.hd.common.core.entity.cloud.BatteryStationHdFeeStandardDetail; +import com.evotech.hd.common.core.enums.CodeMsg; + +import jakarta.annotation.Resource; + +@Service +public class BatteryStationHdFeeStandardServiceImpl implements BatteryStationHdFeeStandardService { + + @Resource + private BatteryStationHdFeeStandardDao batteryStationHdFeeStandardDao; + @Resource + private BatteryStationHdFeeStandardDetailDao batteryStationHdFeeStandardDetailDao; + + @Override + public Result add(BatteryStationHdFeeStandard bsfs) { + bsfs.setCtime(new Date()); + int n = batteryStationHdFeeStandardDao.insert(bsfs); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加换电站费用标准出错!"); + } + + @Override + @Transactional + public Result delete(Integer id) { + int n = batteryStationHdFeeStandardDao.deleteById(id); + if (n == 1) { + batteryStationHdFeeStandardDetailDao.delete(new QueryWrapper().eq("standard_id", id)); + return new Result().success(n); + } + return new Result().error("删除换电站费用标准出错!"); + } + + @Override + public Result update(BatteryStationHdFeeStandard bsfs) { + int n = batteryStationHdFeeStandardDao.updateById(bsfs); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("更新换电站费用标准失败!"); + } + + @Override + public Result> list(String stationCode) { + List list = batteryStationHdFeeStandardDao.listFeeStandard(stationCode); + if (list.isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(list); + } + + + + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationRobotServiceImpl.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationRobotServiceImpl.java new file mode 100644 index 0000000..f6b357f --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationRobotServiceImpl.java @@ -0,0 +1,64 @@ +package com.evotech.hd.cloud.service.impl; + +import java.util.Date; +import java.util.List; + +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.evotech.hd.cloud.dao.BatteryStationRobotDao; +import com.evotech.hd.cloud.service.BatteryStationRobotService; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.BatteryStationRobot; +import com.evotech.hd.common.core.enums.CodeMsg; + +import jakarta.annotation.Resource; + + +@Service +public class BatteryStationRobotServiceImpl implements BatteryStationRobotService { + + @Resource + private BatteryStationRobotDao batteryStationRobotDao; + + @Override + public Result add(BatteryStationRobot bsr) { + bsr.setCtime(new Date()); + int n = batteryStationRobotDao.insert(bsr); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加换电站机器人出错!"); + } + + @Override + public Result delete(Integer id) { + int n = batteryStationRobotDao.deleteById(id); + if (n == 1) { + return new Result().success(n); + } + throw new RuntimeException("删除换电站机器人出错!"); + } + + @Override + public Result update(BatteryStationRobot bsr) { + int n = batteryStationRobotDao.updateById(bsr); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("更新换电站机器人失败!"); + } + + @Override + public Result> list(String stationCode) { + List list = batteryStationRobotDao.selectList(new QueryWrapper() + .eq(StringUtils.hasText(stationCode), "station_code", stationCode)); + if (list.isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(list); + } + + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationServiceImpl.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationServiceImpl.java new file mode 100644 index 0000000..8f181ac --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationServiceImpl.java @@ -0,0 +1,108 @@ +package com.evotech.hd.cloud.service.impl; + +import java.security.KeyPair; +import java.util.Base64; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.evotech.hd.cloud.dao.BatteryStationDao; +import com.evotech.hd.cloud.dao.BatteryStationSecretKeyDao; +import com.evotech.hd.cloud.entity.BatteryStationSecretKey; +import com.evotech.hd.cloud.entity.request.PageListBatteryStationRequest; +import com.evotech.hd.cloud.service.BatteryStationService; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.BatteryStation; +import com.evotech.hd.common.core.enums.CodeMsg; + +import cn.hutool.crypto.KeyUtil; +import cn.hutool.crypto.asymmetric.AsymmetricAlgorithm; +import jakarta.annotation.Resource; + +@Service +public class BatteryStationServiceImpl implements BatteryStationService { + + @Resource + private BatteryStationDao batteryStationDao; + @Resource + private BatteryStationSecretKeyDao batteryStationSecretKeyDao; + + @Override + public Result add(BatteryStation bs) { + bs.setCtime(new Date()); + int n = batteryStationDao.insert(bs); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加换电站出错!"); + } + + @Override + @Transactional + public Result delete(Integer id) { + BatteryStation bs = new BatteryStation(); + bs.setPkId(id); + bs.setDelFlag(1); + int n = batteryStationDao.updateById(bs); + if (n == 1) { + return new Result().success(n); + } + throw new RuntimeException("删除换电站出错!"); + } + + @Override + public Result update(BatteryStation bs) { + int n = batteryStationDao.updateById(bs); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("更新换电站失败!"); + } + + @Override + public Result> list(PageListBatteryStationRequest plbsr) { + Page page = new Page(plbsr.getPageNo(), plbsr.getPageSize()); + List list = batteryStationDao.listStation(page, plbsr); + if (list.isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + +// page = batteryStationDao.selectPage(page, new QueryWrapper() +// .eq(StringUtils.hasText(plbsr.getProxyId()), "proxy_id", plbsr.getProxyId()) +// .like(StringUtils.hasText(plbsr.getCode()), "code", plbsr.getCode()) +// .like(StringUtils.hasText(plbsr.getName()), "name", plbsr.getName()) +// .eq(plbsr.getStatus() != null, "status", plbsr.getStatus()) +// .eq(plbsr.getType() != null, "type", plbsr.getType()) +// .ne("del_flag", 1)); +// if (page.getRecords().isEmpty()) { +// return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); +// } + return new Result>().success(page.setRecords(list)); + } + + @Override + public Result> RsaSecretKey(String stationCode) { + KeyPair keyPair = KeyUtil.generateKeyPair(AsymmetricAlgorithm.RSA_ECB_PKCS1.getValue()); + String privatekeyBase64String = Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded()); + String publickeyBase64String = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded()); + batteryStationSecretKeyDao.delete(new QueryWrapper().eq("type", 1).eq("station_code", stationCode)); + BatteryStationSecretKey bssk = new BatteryStationSecretKey(); + bssk.setStationCode(stationCode); + bssk.setType(1); + bssk.setPrivateKey(privatekeyBase64String); + bssk.setPublicKey(publickeyBase64String); + bssk.setCtime(new Date()); + batteryStationSecretKeyDao.insert(bssk); + + Map map = new HashMap(); + map.put("publickey", publickeyBase64String); + map.put("privatekey", privatekeyBase64String); + return new Result>().success(map); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/MessageMqttServiceImpl.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/MessageMqttServiceImpl.java new file mode 100644 index 0000000..2bd5ed3 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/MessageMqttServiceImpl.java @@ -0,0 +1,59 @@ +package com.evotech.hd.cloud.service.impl; + +import java.util.Date; +import java.util.List; + +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.evotech.hd.cloud.dao.MessageMqttDao; +import com.evotech.hd.cloud.entity.MessageMqtt; +import com.evotech.hd.cloud.entity.request.PageListMessageMqttRequest; +import com.evotech.hd.cloud.service.MessageMqttService; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.enums.CodeMsg; + +import jakarta.annotation.Resource; + + +@Service +public class MessageMqttServiceImpl implements MessageMqttService { + + + @Resource + private MessageMqttDao messageMqttDao; + + @Override + public Result> list(PageListMessageMqttRequest plmmr) { + Page page = new Page(plmmr.getPageNo(), plmmr.getPageSize()); + page = messageMqttDao.selectPage(page, new QueryWrapper() + .eq(StringUtils.hasText(plmmr.getStationCode()), "station_code", plmmr.getStationCode()) + .eq(StringUtils.hasText(plmmr.getDirection()), "direction", plmmr.getDirection()) + .eq(StringUtils.hasText(plmmr.getType()), "type", plmmr.getType()) + .eq(StringUtils.hasText(plmmr.getMessageFunction()), "message_function", plmmr.getMessageFunction()) + .orderByDesc("message_id")); + if (page.getRecords().isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(page); + } + + @Override + public Result add(MessageMqtt message) { + message.setCtime(new Date()); + int n = messageMqttDao.insert(message); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加消息日志出错!"); + } + + @Override + public Result del() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/OrderRechargeServiceimpl.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/OrderRechargeServiceimpl.java new file mode 100644 index 0000000..01a8a07 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/OrderRechargeServiceimpl.java @@ -0,0 +1,74 @@ +package com.evotech.hd.cloud.service.impl; + +import java.util.Date; +import java.util.List; + +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.evotech.hd.cloud.dao.OrderRechargeDao; +import com.evotech.hd.cloud.entity.request.PageListRechargeOrderRequest; +import com.evotech.hd.cloud.service.OrderRechargeService; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.OrderRecharge; +import com.evotech.hd.common.core.enums.CodeMsg; + +import jakarta.annotation.Resource; + +@Service +public class OrderRechargeServiceimpl implements OrderRechargeService { + + @Resource + private OrderRechargeDao orderRechargeDao; + + @Override + public Result add(OrderRecharge or) { + or.setCtime(new Date()); + int n = orderRechargeDao.insert(or); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加充值订单出错!"); + } + + @Override + public Result delete(Integer id) { + OrderRecharge or = new OrderRecharge(); + or.setPkId(id); + or.setDelFlag(1); + int n = orderRechargeDao.updateById(or); + if (n == 1) { + return new Result().success(n); + } + throw new RuntimeException("删除充值订单出错!"); + } + + @Override + public Result update(OrderRecharge or) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Result> list(PageListRechargeOrderRequest plror) { + Page page = new Page(plror.getPageNo(), plror.getPageSize()); + + page = orderRechargeDao.selectPage(page, new QueryWrapper() + .eq(StringUtils.hasText(plror.getOrderNo()), "order_no", plror.getOrderNo()) + .eq(StringUtils.hasText(plror.getAccountCode()), "account_code", plror.getAccountCode()) + .ge(plror.getOrderTimeBegin() != null, "order_time", plror.getOrderTimeBegin()) + .le(plror.getOrderTimeEnd() != null, "order_time", plror.getOrderTimeEnd()) + .eq(StringUtils.hasText(plror.getStationCode()), "station_code", plror.getStationCode()) + .like(StringUtils.hasText(plror.getStationName()), "station_name", plror.getStationName()) + .eq(StringUtils.hasText(plror.getTradeNo()), "trade_no", plror.getTradeNo()) + .ne("del_flag", 1) + .orderByDesc("pk_id")); + if (page.getRecords().isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(page); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/OrderSwapBatteryServiceImpl.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/OrderSwapBatteryServiceImpl.java new file mode 100644 index 0000000..4da78a2 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/OrderSwapBatteryServiceImpl.java @@ -0,0 +1,136 @@ +package com.evotech.hd.cloud.service.impl; + +import java.util.Date; +import java.util.List; + +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.evotech.hd.cloud.dao.OrderSwapBatteryDao; +import com.evotech.hd.cloud.dao.OrderSwapBatteryPreDao; +import com.evotech.hd.cloud.dao.OrderSwapBatteryStepDao; +import com.evotech.hd.cloud.entity.request.PageListSwapOrderRequest; +import com.evotech.hd.cloud.service.OrderSwapBatteryService; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery; +import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryPre; +import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryStep; +import com.evotech.hd.common.core.enums.CodeMsg; + +import jakarta.annotation.Resource; + +@Service +public class OrderSwapBatteryServiceImpl implements OrderSwapBatteryService { + + @Resource + private OrderSwapBatteryDao orderSwapBatteryDao; + @Resource + private OrderSwapBatteryPreDao orderSwapBatteryPreDao; + @Resource + private OrderSwapBatteryStepDao orderSwapBatteryStepDao; + + + @Override + public Result addPre(OrderSwapBatteryPre osbp) { + // 1. 检查车辆 + + // 2. 检查预约人 + + // 3. 添加预约 + int n = orderSwapBatteryPreDao.insert(osbp); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加预约换电订单出错!"); + } + + @Override + public Result cancelPre(Integer id, Integer status) { + OrderSwapBatteryPre osbp = new OrderSwapBatteryPre(); + osbp.setPkId(id); + osbp.setStatus(status != null? status : 2); + int n = orderSwapBatteryPreDao.updateById(osbp); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("取消预约换电订单失败!"); + } + + @Override + public Result> listPre(String plateNum, Integer status, String userId) { + List list = orderSwapBatteryPreDao.selectList(new QueryWrapper() + .eq(StringUtils.hasText(userId), "user_id", userId) + .eq(status != null, "status", status) + .eq(StringUtils.hasText(plateNum), "plate_num", plateNum) + .orderByDesc("pk_id")); + if (list.isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(list); + } + + @Override + public Result add(OrderSwapBattery osb) { + osb.setCtime(new Date()); + int n = orderSwapBatteryDao.insert(osb); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加换电订单出错!"); + } + + @Override + public Result delete(Integer id) { + OrderSwapBattery osb = new OrderSwapBattery(); + osb.setPkId(id); + osb.setDelFlag(1); + int n = orderSwapBatteryDao.updateById(osb); + if (n == 1) { + return new Result().success(n); + } + throw new RuntimeException("删除换电订单出错!"); + } + + @Override + public Result update(OrderSwapBattery osb) { + int n = orderSwapBatteryDao.updateById(osb); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("更新换电订单失败!"); + } + + @Override + public Result> list(PageListSwapOrderRequest plsor) { + Page page = new Page(plsor.getPageNo(), plsor.getPageSize()); + + page = orderSwapBatteryDao.selectPage(page, new QueryWrapper() + .eq(StringUtils.hasText(plsor.getOrderNo()), "order_no", plsor.getOrderNo()) + .like(StringUtils.hasText(plsor.getPlateNum()), "plate_num", plsor.getPlateNum()) + .ge(plsor.getOrderTimeBegin() != null, "order_time", plsor.getOrderTimeBegin()) + .le(plsor.getOrderTimeEnd() != null, "order_time", plsor.getOrderTimeEnd()) + .eq(StringUtils.hasText(plsor.getStationCode()), "station_code", plsor.getStationCode()) + .like(StringUtils.hasText(plsor.getStationName()), "station_name", plsor.getStationName()) + .eq(StringUtils.hasText(plsor.getUserId()), "user_id", plsor.getUserId()) + .eq(StringUtils.hasText(plsor.getTradeNo()), "trade_no", plsor.getTradeNo()) + .ne("del_flag", 1) + .orderByDesc("pk_id")); + if (page.getRecords().isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(page); + } + + @Override + public Result> listStep(String orderNo) { + List list = orderSwapBatteryStepDao.selectList(new QueryWrapper() + .eq("order_no", orderNo)); + if (list.isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(list); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/TradeServiceImpl.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/TradeServiceImpl.java new file mode 100644 index 0000000..676d045 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/TradeServiceImpl.java @@ -0,0 +1,75 @@ +package com.evotech.hd.cloud.service.impl; + +import java.util.Date; +import java.util.List; + +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.evotech.hd.cloud.dao.TradeDetailDao; +import com.evotech.hd.cloud.entity.request.PageListTradeRequest; +import com.evotech.hd.cloud.service.TradeService; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.TradeDetail; +import com.evotech.hd.common.core.enums.CodeMsg; + +import jakarta.annotation.Resource; + +@Service +public class TradeServiceImpl implements TradeService { + + @Resource + private TradeDetailDao tradeDetailDao; + + @Override + public Result add(TradeDetail td) { + td.setCtime(new Date()); + int n = tradeDetailDao.insert(td); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加交易出错!"); + } + + @Override + public Result delete(Integer id) { + TradeDetail td = new TradeDetail(); + td.setPkId(id); + td.setDelFlag(1); + int n = tradeDetailDao.updateById(td); + if (n == 1) { + return new Result().success(n); + } + throw new RuntimeException("删除交易出错!"); + } + + @Override + public Result update(TradeDetail td) { + int n = tradeDetailDao.updateById(td); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("更新交易失败!"); + } + + @Override + public Result> list(PageListTradeRequest pltr) { + Page page = new Page(pltr.getPageNo(), pltr.getPageSize()); + + page = tradeDetailDao.selectPage(page, new QueryWrapper() + .eq(StringUtils.hasText(pltr.getStationCode()), "station_code", pltr.getStationCode()) + .like(StringUtils.hasText(pltr.getAccountName()), "account_name", pltr.getAccountName()) + .eq(pltr.getTradeType() != null, "trade_type", pltr.getTradeType()) + .eq(StringUtils.hasText(pltr.getAccountCode()), "account_code", pltr.getAccountCode()) + .eq(StringUtils.hasText(pltr.getOutTradeNo()), "out_trade_no", pltr.getOutTradeNo()) + .ne("del_flag", 1) + .orderByDesc("pk_id")); + if (page.getRecords().isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(page); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/VehicleServiceImpl.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/VehicleServiceImpl.java new file mode 100644 index 0000000..2db9e6d --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/VehicleServiceImpl.java @@ -0,0 +1,115 @@ +package com.evotech.hd.cloud.service.impl; + +import java.util.Date; +import java.util.List; + +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.evotech.hd.cloud.dao.VehicleInfoDao; +import com.evotech.hd.cloud.dao.VehicleWechatUserRelationDao; +import com.evotech.hd.cloud.entity.request.PageListVehicleRequest; +import com.evotech.hd.cloud.service.VehicleService; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.VehicleInfo; +import com.evotech.hd.common.core.entity.cloud.VehicleWechatUserRelation; +import com.evotech.hd.common.core.enums.CodeMsg; + +import jakarta.annotation.Resource; + + +@Service +public class VehicleServiceImpl implements VehicleService { + + @Resource + private VehicleInfoDao vehicleInfoDao; + @Resource + private VehicleWechatUserRelationDao vehicleWechatUserRelationDao; + + @Override + public Result add(VehicleInfo vi) { + vi.setCtime(new Date()); + int n = vehicleInfoDao.insert(vi); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加车辆出错!"); + } + + @Override + public Result delete(Integer id) { + VehicleInfo vi = new VehicleInfo(); + vi.setPkId(id); + vi.setDelFlag(1); + int n = vehicleInfoDao.updateById(vi); + if (n == 1) { + return new Result().success(n); + } + throw new RuntimeException("删除车辆出错!"); + } + + @Override + public Result update(VehicleInfo vi) { + int n = vehicleInfoDao.updateById(vi); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("更新车辆失败!"); + } + + @Override + public Result> list(PageListVehicleRequest plvr) { + Page page = new Page(plvr.getPageNo(), plvr.getPageSize()); + + page = vehicleInfoDao.selectPage(page, new QueryWrapper() + .eq(StringUtils.hasText(plvr.getTypeCode()), "type_code", plvr.getTypeCode()) + .like(StringUtils.hasText(plvr.getPlateNum()), "plate_num", plvr.getPlateNum()) + .eq(plvr.getOwnerType() != null, "owner_type", plvr.getOwnerType()) + .eq(StringUtils.hasText(plvr.getVinNo()), "vin_no", plvr.getVinNo()) + .eq(StringUtils.hasText(plvr.getEngineNo()), "engine_no", plvr.getEngineNo()) + .eq(StringUtils.hasText(plvr.getFrameworkNo()), "framework_no", plvr.getFrameworkNo()) + .eq(StringUtils.hasText(plvr.getPhone()), "phone", plvr.getPhone()) + .ne("del_flag", 1) + .orderByAsc("plate_num")); + if (page.getRecords().isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(page); + } + + @Override + public Result addWechatUserRelation(VehicleWechatUserRelation relation) { + relation.setCtime(new Date()); + int n = vehicleWechatUserRelationDao.insert(relation); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加车辆用户关系出错!"); + } + + @Override + public Result deleteWechatUserRelation(Integer id) { + int n = vehicleWechatUserRelationDao.deleteById(id); + if (n == 1) { + return new Result().success(n); + } + throw new RuntimeException("删除车辆用户关系出错!"); + } + + @Override + public Result> listWechatUserRelation(String openid, String plateNum) { + List relationList = vehicleWechatUserRelationDao.selectList(new QueryWrapper().eq(StringUtils.hasText(openid), "openid", openid)); + if (relationList.isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + List plateNumList = relationList.stream().map(i -> i.getPlateNum()).toList(); + List list = vehicleInfoDao.selectList(new QueryWrapper().ne("del_flag", 1).in("plate_num", plateNumList)); + if (list.isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(list); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/WalletAccountServiceImpl.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/WalletAccountServiceImpl.java new file mode 100644 index 0000000..d986834 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/WalletAccountServiceImpl.java @@ -0,0 +1,125 @@ +package com.evotech.hd.cloud.service.impl; + +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.evotech.hd.cloud.dao.WalletAccountDao; +import com.evotech.hd.cloud.dao.WalletAccountDetailDao; +import com.evotech.hd.cloud.entity.request.PageListWalletRequest; +import com.evotech.hd.cloud.service.WalletAccountService; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.cloud.WalletAccount; +import com.evotech.hd.common.core.entity.cloud.WalletAccountDetail; +import com.evotech.hd.common.core.enums.CodeMsg; +import com.evotech.hd.common.core.utils.SnowflakeUtil; + +import cn.hutool.core.util.RandomUtil; +import jakarta.annotation.Resource; + + +@Service +public class WalletAccountServiceImpl implements WalletAccountService { + + @Resource + private WalletAccountDao walletAccountDao; + @Resource + private WalletAccountDetailDao walletAccountDetailDao; + + @Override + public Result add(WalletAccount wa) { + wa.setCtime(new Date()); + String prefix = "YTWA" + (wa.getOwnerType() == 1 ? "P" : "C"); + wa.setCode(prefix + SnowflakeUtil.getIdStr() + RandomUtil.randomStringUpper(6)); + int n = walletAccountDao.insert(wa); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加资金账户出错!"); + } + + @Override + public Result delete(Integer id, String code) { + Map m = new HashMap(); + m.put("pk_id", id); + m.put("code", code); + int n = walletAccountDao.deleteByMap(m); + if (n == 1) { + return new Result().success(n); + } + throw new RuntimeException("删除资金账户出错!-- " + n); + } + + @Override + public Result update(WalletAccount wa) { + WalletAccount wa1 = new WalletAccount(); + wa1.setGiftAmount(wa.getGiftAmount()); + wa1.setTotalAmount(wa.getTotalAmount()); + wa1.setRechargeAmount(wa.getRechargeAmount()); + int n = walletAccountDao.update(wa1, new QueryWrapper() + .eq("code", wa.getCode()) + .eq("pk_id", wa.getPkId())); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("更新资金账户失败!"); + } + + @Override + public Result> list(PageListWalletRequest plwr) { + Page page = new Page(plwr.getPageNo(), plwr.getPageSize()); + + page = walletAccountDao.selectPage(page, new QueryWrapper() + .eq(StringUtils.hasText(plwr.getCode()), "code", plwr.getCode()) + .eq(StringUtils.hasText(plwr.getStationCode()), "station_code", plwr.getStationCode()) + .eq(plwr.getOwnerType() != null, "owner_type", plwr.getOwnerType()) + .eq(StringUtils.hasText(plwr.getOwnerId()), "owner_id", plwr.getOwnerId()) + .orderByDesc("pk_id")); + if (page.getRecords().isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(page); + } + + @Override + public Result addDetail(WalletAccountDetail wad) { + wad.setCtime(new Date()); + int n = walletAccountDetailDao.insert(wad); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加资金账户明细出错!"); + } + + @Override + public Result deleteDetail(Integer id, String code) { + Map m = new HashMap(); + m.put("pk_id", id); + m.put("code", code); + int n = walletAccountDetailDao.deleteByMap(m); + if (n == 1) { + return new Result().success(n); + } + throw new RuntimeException("删除资金账户明细出错!-- " + n); + } + + @Override + public Result> listDetail(PageListWalletRequest plwr) { + Page page = new Page(plwr.getPageNo(), plwr.getPageSize()); + + page = walletAccountDetailDao.selectPage(page, new QueryWrapper() + .eq(StringUtils.hasText(plwr.getCode()), "code", plwr.getCode()) + .orderByDesc("pk_id")); + if (page.getRecords().isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(page); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/utils/AESEncryptionUtil.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/utils/AESEncryptionUtil.java new file mode 100644 index 0000000..c16fb11 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/utils/AESEncryptionUtil.java @@ -0,0 +1,5 @@ +package com.evotech.hd.cloud.utils; + +public class AESEncryptionUtil { + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/utils/RSADecryptionUtil.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/utils/RSADecryptionUtil.java new file mode 100644 index 0000000..0a76254 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/utils/RSADecryptionUtil.java @@ -0,0 +1,5 @@ +package com.evotech.hd.cloud.utils; + +public class RSADecryptionUtil { + +} diff --git a/cloud-manage-server/src/main/resources/application.yml b/cloud-manage-server/src/main/resources/application.yml new file mode 100644 index 0000000..4e1ff89 --- /dev/null +++ b/cloud-manage-server/src/main/resources/application.yml @@ -0,0 +1,55 @@ +# 1. server +server: + port: 9103 + servlet: + context-path: /cloud +# 2.log +logging: + config: classpath:logback-spring.xml + level: + '[com.evotech.hd.cloud.dao]': debug +# 3.spring +spring: + # 服务名称必须带上,不然nacos服务列表中没有,也不会有注册成功的信息 + application: + name: cloud-server + config: + import: + - nacos:${spring.application.name}.yaml?refreshEnabled=true + cloud: + nacos: + serverAddr: 192.168.5.213:8848 + username: nacos + password: nacos + discovery: + register-enabled: true + #server-addr: 10.10.1.6:8848 + #ip: 10.10.1.2 + # 因添加了context-path,admin-server要想发现正确路径,需要加这个 + metadata: + management: + context-path: ${server.servlet.context-path}/actuator + +# boot: +# admin: +# client: +# # admin-server地址 用了nacos,admin也注册到nacos了,会自动拉取服务,不用这个了 +## url: http://192.168.151.111:9009/admin +# # 配置admin-server的账号和密码 +# username: jdyl +# password: jdyl123 + # 添加这个,客户端就显示ip,而不是主机名,我用nacos是显示的主机名 +# instance: +# prefer-ip: true +# 为springbootadmin开启所有检查 +management: + endpoints: + web: + exposure: + include: "*" + endpoint: + health: + show-details: always + # xml文件中配置的日志文件的名称 + logfile: + external-file: /logs/cloud/cloud-server.log diff --git a/cloud-manage-server/src/main/resources/logback-spring.xml b/cloud-manage-server/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..e32581e --- /dev/null +++ b/cloud-manage-server/src/main/resources/logback-spring.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + ${CONTEXT_NAME} + + + + + + DEBUG + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %replace(%caller{1}){'\t|Caller.{1}0|\r\n', ''} -- %msg%n + + UTF-8 + + + + + + + ${LOG_PATH}/${CONTEXT_NAME}.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{50}.%M\(%line\) -- %msg%n + UTF-8 + + + + + ${LOG_PATH}/${CONTEXT_NAME}-%d{yyyy-MM-dd}-%i.log + + ${MAX_HISTORY} + + + ${MAX_FILE_SIZE} + + + + + + + + 512 + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cloud-manage-server/src/main/resources/mapper/BatteryStationDcMapper.xml b/cloud-manage-server/src/main/resources/mapper/BatteryStationDcMapper.xml new file mode 100644 index 0000000..a242814 --- /dev/null +++ b/cloud-manage-server/src/main/resources/mapper/BatteryStationDcMapper.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + pk_id, type_code, bat_code, production_date, registration_date, source_from, source_code, status, soc, del_flag, ctime, creater, uptime, updater + + + + + diff --git a/cloud-manage-server/src/main/resources/mapper/BatteryStationDccMapper.xml b/cloud-manage-server/src/main/resources/mapper/BatteryStationDccMapper.xml new file mode 100644 index 0000000..8195565 --- /dev/null +++ b/cloud-manage-server/src/main/resources/mapper/BatteryStationDccMapper.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + pk_id, station_code, dcc_no, status, ctime, creater, uptime, updater + + + + + diff --git a/cloud-manage-server/src/main/resources/mapper/BatteryStationDjMapper.xml b/cloud-manage-server/src/main/resources/mapper/BatteryStationDjMapper.xml new file mode 100644 index 0000000..724ff8c --- /dev/null +++ b/cloud-manage-server/src/main/resources/mapper/BatteryStationDjMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + pk_id, station_code, code, dcc_no, switch_type, status, gun_num, ctime, creater, uptime, updater + + + + + diff --git a/cloud-manage-server/src/main/resources/mapper/BatteryStationHdFeeStandardDetailMapper.xml b/cloud-manage-server/src/main/resources/mapper/BatteryStationHdFeeStandardDetailMapper.xml new file mode 100644 index 0000000..980b9c4 --- /dev/null +++ b/cloud-manage-server/src/main/resources/mapper/BatteryStationHdFeeStandardDetailMapper.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + pk_id, standard_id, each_km_fee, each_soc_fee, each_kwh_fee, time_begin, time_end, time_service_fee, ctime, creater, uptime, updater + + + + + diff --git a/cloud-manage-server/src/main/resources/mapper/BatteryStationHdFeeStandardMapper.xml b/cloud-manage-server/src/main/resources/mapper/BatteryStationHdFeeStandardMapper.xml new file mode 100644 index 0000000..53d4df5 --- /dev/null +++ b/cloud-manage-server/src/main/resources/mapper/BatteryStationHdFeeStandardMapper.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + pk_id, station_code, day_begin, day_end, common_remain_fee, common_remain_soc_range, more_remain_soc, more_remain_fee, few_remain_soc, few_remain_fee, ctime, creater, uptime, updater + + + + + diff --git a/cloud-manage-server/src/main/resources/mapper/BatteryStationMapper.xml b/cloud-manage-server/src/main/resources/mapper/BatteryStationMapper.xml new file mode 100644 index 0000000..666ffc5 --- /dev/null +++ b/cloud-manage-server/src/main/resources/mapper/BatteryStationMapper.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pk_id, proxy_id, name, code, status, type, address, address_province, address_city, address_area, register_date, contacts, phone, del_flag, active_date, location_point, open_all_day, td_quantity, jqr_quantity, cdj_quantity, dcc_quantity, dc_quantity, ctime, creater, uptime, updater + + + + + + diff --git a/cloud-manage-server/src/main/resources/mapper/BatteryStationRobotMapper.xml b/cloud-manage-server/src/main/resources/mapper/BatteryStationRobotMapper.xml new file mode 100644 index 0000000..274f746 --- /dev/null +++ b/cloud-manage-server/src/main/resources/mapper/BatteryStationRobotMapper.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + pk_id, station_code, code, status, run_mode, ctime, creater, uptime, updater + + + + + + diff --git a/cloud-manage-server/src/test/java/com/evotech/hd/cloud/AesDecryTest.java b/cloud-manage-server/src/test/java/com/evotech/hd/cloud/AesDecryTest.java new file mode 100644 index 0000000..e5225cc --- /dev/null +++ b/cloud-manage-server/src/test/java/com/evotech/hd/cloud/AesDecryTest.java @@ -0,0 +1,32 @@ +package com.evotech.hd.cloud; + +import java.util.Base64; + +import javax.crypto.SecretKey; + +import cn.hutool.crypto.KeyUtil; +import cn.hutool.crypto.Mode; +import cn.hutool.crypto.Padding; +import cn.hutool.crypto.symmetric.AES; +import cn.hutool.crypto.symmetric.SymmetricAlgorithm; +import cn.hutool.crypto.symmetric.SymmetricCrypto; + +public class AesDecryTest { + + public static void main(String[] args) { + + String key = "94kl35k25d3t2rk2"; + String iv = "k394kf44lf1pyq8k"; + SymmetricCrypto aes = new AES(Mode.CBC, Padding.PKCS5Padding, key.getBytes(), iv.getBytes()); + // 需要加密的数据 + String data = "2yKExCzIRWg6bLwf2zsTn83XhzTAvuQtW5svhO111zihn3oX/Jrf4UFrKCA5UbZy4SWRF5vtcyYXLr8oFof2xRDBXsvFRDFHYKmmkpN6Udk7ChB0sCNTzisaM/iqAtbybD8uC9HpHYCQsSVipUc//aUhgSNvhK7CewK1UjGKnyBvOvCUJiPGVtuKzX5Pf5KIrR1ozJ+moDq01+td8Du5lA3lXaHdLZ8WbmoqYd2T6r3PDVsh/yxC327mNsQrivK0yL3QUt4ZCuLV6G/nQTsxvNgAYprSNVejGCywDD2cWuA4f90bsxJEKFLJ+XUd9/IAJR50QGhwm0qzxWwZzszWU9+EJoDyp+gUUn9bY4u9V/I="; + + byte[] decrypt = aes.decrypt(Base64.getDecoder().decode(data)); + System.out.println(new String(decrypt)); + + SecretKey key1 = KeyUtil.generateKey(SymmetricAlgorithm.AES.getValue()); + System.out.println(Base64.getEncoder().encodeToString(key1.getEncoded())); + + } + +} diff --git a/cloud-manage-server/src/test/java/com/evotech/hd/cloud/CloudManageServerApplicationTests.java b/cloud-manage-server/src/test/java/com/evotech/hd/cloud/CloudManageServerApplicationTests.java new file mode 100644 index 0000000..42943ae --- /dev/null +++ b/cloud-manage-server/src/test/java/com/evotech/hd/cloud/CloudManageServerApplicationTests.java @@ -0,0 +1,13 @@ +package com.evotech.hd.cloud; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class CloudManageServerApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/cloud-manage-server/src/test/java/com/evotech/hd/cloud/DecryptionTest.java b/cloud-manage-server/src/test/java/com/evotech/hd/cloud/DecryptionTest.java new file mode 100644 index 0000000..3792a92 --- /dev/null +++ b/cloud-manage-server/src/test/java/com/evotech/hd/cloud/DecryptionTest.java @@ -0,0 +1,26 @@ +package com.evotech.hd.cloud; + +import cn.hutool.crypto.SecureUtil; +import cn.hutool.crypto.asymmetric.KeyType; +import cn.hutool.crypto.asymmetric.RSA; + +public class DecryptionTest { + + + public static String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAI5sS/GxCNQ6NhT4kelgOWn72OQP7X7DS+b0KCdFijXdS03plQt1nHsDwdRzqsB5q8TMZX/kj1Fxo6X0VWAYVsfUI7A1mRTO7nbKGdlCNvZR2nIUPJqUQOitffmgf45JP8B/Xq14KC7XH5tBKH2Z4oTKsVr+wjLIRgQ6Aqur77Z7AgMBAAECgYBu8mQy0lNraDFrIrwfzgrLyhoKh3HeNurw7jA9b4mcLliUSCsIM0WD+shK5RQWPnIVq5hCCd2vd1QhWnYLlso6UKTdHKyDIBGkoBZAQmorjAjzaD57pGQpSqn8dR13iSmtFsoDHlhrAC8qFtUPQS7DR0Or4F6rfq0ubTkZyoEBUQJBAOOyCC793SPHk9huqmZJyU/VdQvQbURupksg7H3SrYTiItzUcFatF8qYr0eV7p/UhqNGuC2j9J9QPK6OtLqeRckCQQCgIKKMIa30jH1frh6ne9cyC31nzpXJkmXFjpAXRyhelmCh6F1Pt0QdhR7H4QscqffixlQcVhvf9QRKyODbMMwjAkEA1mf+bMGASwDTpyoOKuOwPQyzerx5J8dJr9UA3DpWSprmWStx3SyBCrVb1/zHBpoJbhZZuCB7aMkVWwnmBRSkgQJADu+cWdfWYwYrt54FK/goNXnO47zoSdoG9it7E0DG6jO6pb+H3KSqjNpa6af7IlxUS+nV9KKvjO9MzDD6kFd34wJAAy+5VLb+mcP12R4Rop3mM+KtjzewFBcmtrNfblxLD2ryrDZY9K4WhND4L5aRHG9ao/ieNQKVCs/zyU2fszKzbA=="; + + public static void main(String[] args) throws Exception { + + String content = "Eno+9Tu24kP9e9mHtIkmzr/SAk5k3Tp3e0Wjl2WfTVae50gbAeo9gDaF7rx1jFUK6gzDcJWOmiPcCi6Cyw77Mx8TJ+dE+Bz0KnWmXbwoTqm6Y1XB+iGvstf7ZI2r7waQAb1jcjRrv0GdnbU6/Eux6sfPVwnoHdMq7YWFKr8tGL1jjKlWTiLYUB28qK63TJQ7qD8KTFXjFTTdXER9METJ/Q9H3Z142O7iLo6RGRMggKV1dg1IBtb3mKcySQ64I+xLlxNJADyvCEgMdQXE2/60/pVfBSxlMWvlq0TaLfWHxZggyoAwuzSKH2F5rj8M43i9AOOMbWzr2Aopd8jGNcMglQ=="; + +// RSA rsa = SecureUtil.rsa(Base64.getDecoder().decode(privateKey.getBytes()), null); + RSA rsa = SecureUtil.rsa(privateKey, null); + byte[] decrypt = rsa.decrypt(content, KeyType.PrivateKey); + System.out.println(new String(decrypt, "UTF-8")); + + } + + + + +} diff --git a/cloud-manage-server/src/test/java/com/evotech/hd/cloud/Test1.java b/cloud-manage-server/src/test/java/com/evotech/hd/cloud/Test1.java new file mode 100644 index 0000000..6647f3e --- /dev/null +++ b/cloud-manage-server/src/test/java/com/evotech/hd/cloud/Test1.java @@ -0,0 +1,11 @@ +package com.evotech.hd.cloud; + +public class Test1 { + + public static void main(String[] args) { + String topic = "ZZHD/91130133MA08JW7T7B0000120241015/S2M/encryptKeyReq"; + System.out.println(topic.contains("/S2M/encryptKeyReq")); + + } + +} diff --git a/gateway-server/.gitignore b/gateway-server/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/gateway-server/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/gateway-server/pom.xml b/gateway-server/pom.xml new file mode 100644 index 0000000..2ddd9f0 --- /dev/null +++ b/gateway-server/pom.xml @@ -0,0 +1,131 @@ + + + + 4.0.0 + + com.evotech.hd + battery-cloud + 1.0.0-SNAPSHOT + + gateway-server + gateway-server + 网关服务 + + + 17 + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + com.mysql + mysql-connector-j + runtime + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + com.evotech.hd + common-core + 1.0.0-SNAPSHOT + + + com.evotech.hd + common-redis + 1.0.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-oauth2-resource-server + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + + + + com.github.xiaoymin + knife4j-gateway-spring-boot-starter + + + + + cn.hutool + hutool-json + + + cn.hutool + hutool-jwt + + + org.springframework.boot + spring-boot-configuration-processor + + true + + + + de.codecentric + spring-boot-admin-starter-client + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + diff --git a/gateway-server/src/main/java/com/evotech/hd/gateway/GatewayServerApplication.java b/gateway-server/src/main/java/com/evotech/hd/gateway/GatewayServerApplication.java new file mode 100644 index 0000000..34bd639 --- /dev/null +++ b/gateway-server/src/main/java/com/evotech/hd/gateway/GatewayServerApplication.java @@ -0,0 +1,18 @@ +package com.evotech.hd.gateway; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication +@EnableDiscoveryClient +@ComponentScan("com.evotech.hd.**") +//@EnableFeignClients +public class GatewayServerApplication { + + public static void main(String[] args) { + SpringApplication.run(GatewayServerApplication.class, args); + } + +} diff --git a/gateway-server/src/main/java/com/evotech/hd/gateway/config/CorsConfig.java b/gateway-server/src/main/java/com/evotech/hd/gateway/config/CorsConfig.java new file mode 100644 index 0000000..7f45c53 --- /dev/null +++ b/gateway-server/src/main/java/com/evotech/hd/gateway/config/CorsConfig.java @@ -0,0 +1,45 @@ +package com.evotech.hd.gateway.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpHeaders; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.reactive.CorsWebFilter; +import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource; +import org.springframework.web.reactive.config.CorsRegistry; +import org.springframework.web.reactive.config.WebFluxConfigurer; + +@Configuration +public class CorsConfig implements WebFluxConfigurer { + + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**") + .allowCredentials(true) + .allowedOriginPatterns("*") + .allowedHeaders("*") + .allowedMethods("*") + .exposedHeaders(HttpHeaders.SET_COOKIE); + } + + + /** + * 跨域过滤器 + * @return + */ + @Bean + CorsWebFilter corsWebFilter() { + CorsConfiguration corsConfiguration = new CorsConfiguration(); + corsConfiguration.setAllowCredentials(true); + corsConfiguration.addAllowedHeader("*"); + corsConfiguration.addAllowedMethod("*"); + corsConfiguration.addAllowedOriginPattern("*"); + corsConfiguration.addExposedHeader(HttpHeaders.SET_COOKIE); + UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource(); + corsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration); + return new CorsWebFilter(corsConfigurationSource); + } + + + +} diff --git a/gateway-server/src/main/java/com/evotech/hd/gateway/filter/AccessLogFilter.java b/gateway-server/src/main/java/com/evotech/hd/gateway/filter/AccessLogFilter.java new file mode 100644 index 0000000..55341d9 --- /dev/null +++ b/gateway-server/src/main/java/com/evotech/hd/gateway/filter/AccessLogFilter.java @@ -0,0 +1,248 @@ +package com.evotech.hd.gateway.filter; + +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import org.reactivestreams.Publisher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.GlobalFilter; +import org.springframework.cloud.gateway.filter.factory.rewrite.CachedBodyOutputMessage; +import org.springframework.cloud.gateway.route.Route; +import org.springframework.cloud.gateway.support.BodyInserterContext; +import org.springframework.cloud.gateway.support.ServerWebExchangeUtils; +import org.springframework.core.Ordered; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.core.io.buffer.DataBufferFactory; +import org.springframework.core.io.buffer.DataBufferUtils; +import org.springframework.core.io.buffer.DefaultDataBufferFactory; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.codec.ServerCodecConfigurer; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.http.server.reactive.ServerHttpRequestDecorator; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.http.server.reactive.ServerHttpResponseDecorator; +import org.springframework.stereotype.Component; +import org.springframework.util.MultiValueMap; +import org.springframework.web.reactive.function.BodyInserter; +import org.springframework.web.reactive.function.BodyInserters; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.server.ServerWebExchange; + +import com.evotech.hd.gateway.log.GatewayLogService; +import com.evotech.hd.gateway.log.entity.GatewayLog; +import com.evotech.hd.gateway.utils.IpUtil; + +import cn.hutool.core.util.StrUtil; +import jakarta.annotation.Resource; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +/** + * 日志过滤器,用于记录日志 + * @author zrb + * @date 2024年9月6日17:13:16 + */ +@Component +public class AccessLogFilter implements GlobalFilter, Ordered { + + @Resource + private GatewayLogService logService; + + @Autowired + ServerCodecConfigurer codecConfigurer; + +// private final List> messageReaders = HandlerStrategies.withDefaults().messageReaders(); + + Logger log = LoggerFactory.getLogger(this.getClass()); + + + /** + * 方法返回的值必须要<-1, + * 否则标准的NettyWriteResponseFilter将在您的过滤器被调用的 + * 机会之前发送响应,即不会执行获取后端响应参数的方法 + */ + @Override + public int getOrder() { + return -99; + } + + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { + ServerHttpRequest request = exchange.getRequest(); + // 请求路径 + String requestPath = request.getPath().pathWithinApplication().value(); + Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR); + + GatewayLog gatewayLog = new GatewayLog(); + gatewayLog.setRequestUri(request.getURI().toString()); + gatewayLog.setRequestParams(request.getURI().getRawQuery()); + gatewayLog.setRequestBody(request.getBody().toString()); + gatewayLog.setRequestMethod(request.getMethod().name()); + gatewayLog.setRequestPath(requestPath); + gatewayLog.setRequestServer(route.getId()); + gatewayLog.setRequestTime(new Date()); + gatewayLog.setRemoteIp(IpUtil.getRemoteIP(request)); + + MediaType mediaType = request.getHeaders().getContentType(); + if (MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(mediaType) || MediaType.APPLICATION_JSON.isCompatibleWith(mediaType)) { + return writeBodyLog(exchange, chain, gatewayLog); + } else { + return writeBasicLog(exchange, chain, gatewayLog); + } + } + + + /** + * 解决 request body 只能读取一次问题, + * 参考: org.springframework.cloud.gateway.filter.factory.rewrite.ModifyRequestBodyGatewayFilterFactory + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + private Mono writeBodyLog(ServerWebExchange exchange, GatewayFilterChain chain, GatewayLog gatewayLog) { +// ServerRequest serverRequest = ServerRequest.create(exchange, messageReaders); + // 使用注入的 自定义配置,因在配置文件中设置了数据包大小限制 + ServerRequest serverRequest = ServerRequest.create(exchange, codecConfigurer.getReaders()); + + Mono modifiedBody = serverRequest.bodyToMono(String.class) + .flatMap(body -> { + gatewayLog.setRequestBody(body); + // zrb 2022年10月19日15:54:55 %号和+号特殊符号先转码,在decode + // 先不用 URLEncoder.encode(body, "UTF-8") 方法,不然所有请求转发完还要decode + /* + * 这里使用了一个特殊正则表达式,只编码 现在出现的 % 和 + 零宽负向先行断言(zero-widthnegative lookahead + * assertion), 模式为(?!pattern),代表字符串中的一个位置, 紧接该位置之后的字符序列不能匹配pattern。 + * %(?![0-9a-fA-F]{2})意思是'%'开始, 不匹配%后面两位为数字或字母(包括大小写)的字符; + * 这样就把正确的排除掉了,剩下的就是需要匹配替换的。 + */ + body = body.replaceAll("%(?![0-9a-fA-F]{2})", "%25"); + body = body.replaceAll("\\+", "%2B"); +// body = URLEncoder.encode(body, "UTF-8"); + return Mono.just(body); + }); + // 通过 BodyInserter 插入 body(支持修改body), 避免 request body 只能获取一次 + BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, String.class); + HttpHeaders headers = new HttpHeaders(); + headers.putAll(exchange.getRequest().getHeaders()); + // the new content type will be computed by bodyInserter + // and then set in the request decorator + headers.remove(HttpHeaders.CONTENT_LENGTH); + CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, headers); + return bodyInserter + .insert(outputMessage,new BodyInserterContext()) + .then(Mono.defer(() -> { + // 重新封装请求 + ServerHttpRequest decoratedRequest = requestDecorate(exchange, headers, outputMessage); + // 记录响应日志 + ServerHttpResponseDecorator decoratedResponse = recordResponseLog(exchange, gatewayLog); + // 记录普通的 + return chain + .filter(exchange.mutate().request(decoratedRequest).response(decoratedResponse).build()) + .then(Mono.fromRunnable(() -> { + // 打印日志 + if (!gatewayLog.getRequestPath().contains("/v2/api-docs") && !gatewayLog.getRequestPath().contains("/dict/")) { + logService.writeGatewayLog(gatewayLog); + } + })); + })); + } + + private Mono writeBasicLog(ServerWebExchange exchange, GatewayFilterChain chain, GatewayLog accessLog) { + StringBuilder builder = new StringBuilder(); + MultiValueMap queryParams = exchange.getRequest().getQueryParams(); + for (Map.Entry> entry : queryParams.entrySet()) { + builder.append(entry.getKey()).append("=").append(String.join(",", entry.getValue())); + } + accessLog.setRequestBody(builder.toString()); + //获取响应体 + ServerHttpResponseDecorator decoratedResponse = recordResponseLog(exchange, accessLog); + return chain.filter(exchange.mutate().response(decoratedResponse).build()) + .then(Mono.fromRunnable(() -> { + // 打印日志 + if (!accessLog.getRequestPath().contains("/v2/api-docs") && !accessLog.getRequestPath().contains("/dict/")) { + logService.writeGatewayLog(accessLog); + } + })); + } + + + /** + * 请求装饰器,重新计算 headers + */ + private ServerHttpRequestDecorator requestDecorate(ServerWebExchange exchange, HttpHeaders headers, + CachedBodyOutputMessage outputMessage) { + return new ServerHttpRequestDecorator(exchange.getRequest()) { + @Override + public HttpHeaders getHeaders() { + long contentLength = headers.getContentLength(); + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.putAll(super.getHeaders()); + if (contentLength > 0) { + httpHeaders.setContentLength(contentLength); + } else { + httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked"); + } + return httpHeaders; + } + + @Override + public Flux getBody() { + return outputMessage.getBody(); + } + }; + } + + + /** + * 获取响应数据 + * 通过 DataBufferFactory 解决响应体分段传输问题。 + */ + private ServerHttpResponseDecorator recordResponseLog(ServerWebExchange exchange, GatewayLog gatewayLog) { + ServerHttpResponse response = exchange.getResponse(); + DataBufferFactory bufferFactory = response.bufferFactory(); + return new ServerHttpResponseDecorator(response) { + @Override + public Mono writeWith(Publisher body) { + if (body instanceof Flux) { + Date responseTime = new Date(); + // 响应时间 + gatewayLog.setResponseTime(responseTime); + // 花费时间 + long executeTime = (responseTime.getTime() - gatewayLog.getRequestTime().getTime()); + gatewayLog.setTimeConsuming(executeTime); + // 获取响应类型,如果是 json 就打印 + String originalResponseContentType = exchange.getAttribute(ServerWebExchangeUtils.ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR); + if (this.getStatusCode().value() == HttpStatus.OK.value() && StrUtil.isNotBlank(originalResponseContentType) + && originalResponseContentType.contains("application/json")) { + Flux fluxBody = Flux.from(body); + return super.writeWith(fluxBody.buffer().map(dataBuffers -> { + // 合并多个流集合,解决返回体分段传输 + DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory(); + DataBuffer join = dataBufferFactory.join(dataBuffers); + byte[] content = new byte[join.readableByteCount()]; + join.read(content); + // 释放掉内存 + DataBufferUtils.release(join); + String responseResult = new String(content, StandardCharsets.UTF_8); + // 记录响应数据 + gatewayLog.setResponseData(responseResult); + + return bufferFactory.wrap(content); + })); + } else { + return super.writeWith(body); + } + } + // if body is not a flux. never got there. + return super.writeWith(body); + } + }; + } + + +} diff --git a/gateway-server/src/main/java/com/evotech/hd/gateway/filter/HeaderHandleFilter.java b/gateway-server/src/main/java/com/evotech/hd/gateway/filter/HeaderHandleFilter.java new file mode 100644 index 0000000..4a2d079 --- /dev/null +++ b/gateway-server/src/main/java/com/evotech/hd/gateway/filter/HeaderHandleFilter.java @@ -0,0 +1,61 @@ +package com.evotech.hd.gateway.filter; + +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.GlobalFilter; +import org.springframework.cloud.gateway.route.Route; +import org.springframework.cloud.gateway.support.ServerWebExchangeUtils; +import org.springframework.core.Ordered; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; +import org.springframework.web.server.ServerWebExchange; + +import com.evotech.hd.common.core.constant.HDConstant; +import com.evotech.hd.gateway.utils.TokenUtil; + +import reactor.core.publisher.Mono; + + +/** + * 将token中的数据解析一下, + * uid,rcodes放到请求头中 + * @author zrb + * @date 2024年9月6日17:14:38 + */ +@Component +public class HeaderHandleFilter implements GlobalFilter, Ordered { + + @Override + public int getOrder() { + return Integer.MAX_VALUE; + } + + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { + Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR); + // 对resource服务处理 + if (!"resource-route".equals(route.getId())) { + return chain.filter(exchange); + } + + String uid = ""; + String rcodes = ""; + ServerHttpRequest request = exchange.getRequest(); + String token = request.getHeaders().getFirst(HDConstant.AUTHORIZATION_KEY); + try { + if (StringUtils.hasText(token) && token.startsWith("Bearer ")) { + token = token.substring(HDConstant.JWT_PREFIX.length()); + uid = TokenUtil.getUserId(token); + rcodes = TokenUtil.getRcodes(token); + } + } catch (Exception e) { + e.printStackTrace(); + } + + request = request.mutate().header("uid", uid).header("rcodes", rcodes).build(); + exchange = exchange.mutate().request(request).build(); + + return chain.filter(exchange); + } + +} diff --git a/gateway-server/src/main/java/com/evotech/hd/gateway/log/GatewayLogService.java b/gateway-server/src/main/java/com/evotech/hd/gateway/log/GatewayLogService.java new file mode 100644 index 0000000..896297b --- /dev/null +++ b/gateway-server/src/main/java/com/evotech/hd/gateway/log/GatewayLogService.java @@ -0,0 +1,66 @@ +package com.evotech.hd.gateway.log; + + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +import com.evotech.hd.gateway.log.entity.GatewayLog; + +import org.springframework.scheduling.annotation.Async; +import org.springframework.scheduling.annotation.EnableAsync; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.json.JSONConfig; +import cn.hutool.json.JSONUtil; +import jakarta.annotation.Resource; + +/** + * + * @author zrb + * @date 2024年9月6日16:54:58 + *

@Async失效情况: + *

1. 异步方法使用static修饰 + *

2. 异步类没有使用@Component注解(或其他注解)导致spring无法扫描到异步类 + *

3. 异步方法不能与被调用的异步方法在同一个类中 + *

4. 类中需要使用@Autowired或@Resource等注解自动注入,不能自己手动new对象 + *

5. 如果使用SpringBoot框架必须在启动类中增加@EnableAsync注解 + * + */ + +@Service +@EnableAsync +public class GatewayLogService { + + Logger log = LoggerFactory.getLogger(this.getClass()); + + @Resource + private JdbcTemplate jdbcTemplate; + + @Value("${gateway.log.console:false}") + private boolean consoleLog; + + @Async("taskExecutor") + public void writeGatewayLog(GatewayLog glog) { + // 1. 打印 + if (consoleLog) { + JSONConfig config = JSONConfig.create(); + config.setDateFormat(DatePattern.NORM_DATETIME_MS_PATTERN); + config.setIgnoreNullValue(false); + log.info("\r\n ==>>>请求记录:" + JSONUtil.parseObj(JSONUtil.toJsonStr(glog, config))); + } + // 2. 记录 + String sql = "insert into `yt_log_gateway`(uid, request_time, remote_ip, " + + "request_server, request_method, request_uri, request_path, request_params, " + + "request_body, response_data, response_time, time_consuming) values (?,?,?,?,?,?,?,?,?,?,?,?)"; + Object a[]={ + glog.getUid(), glog.getRequestTime(), glog.getRemoteIp(), + glog.getRequestServer(), glog.getRequestMethod(), glog.getRequestUri(), + glog.getRequestPath(), glog.getRequestParams(), glog.getRequestBody(), + glog.getResponseData(), glog.getResponseTime(), glog.getTimeConsuming()}; + jdbcTemplate.update(sql, a); + } + +} diff --git a/gateway-server/src/main/java/com/evotech/hd/gateway/log/entity/GatewayLog.java b/gateway-server/src/main/java/com/evotech/hd/gateway/log/entity/GatewayLog.java new file mode 100644 index 0000000..fad9774 --- /dev/null +++ b/gateway-server/src/main/java/com/evotech/hd/gateway/log/entity/GatewayLog.java @@ -0,0 +1,65 @@ +package com.evotech.hd.gateway.log.entity; + + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import com.fasterxml.jackson.annotation.JsonFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-09-04 + */ +@Getter +@Setter +@Schema(name = "LogGateway", description = "网关日志") +public class GatewayLog implements Serializable { + + private static final long serialVersionUID = 1L; + + private Integer pkId; + + @Schema(description = "用户id") + private String uid; + + @Schema(description = "请求时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date requestTime; + + @Schema(description = "远程ip") + private String remoteIp; + + @Schema(description = "请求服务") + private String requestServer; + + @Schema(description = "请求方法") + private String requestMethod; + + @Schema(description = "请求路径") + private String requestUri; + + @Schema(description = "请求地址") + private String requestPath; + + @Schema(description = "请求参数") + private String requestParams; + + @Schema(description = "请求体") + private String requestBody; + + @Schema(description = "响应数据") + private String responseData; + + @Schema(description = "响应时间") + private Date responseTime; + + @Schema(description = "消耗时间:ms") + private Long timeConsuming; +} diff --git a/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/AuthorizationManager.java b/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/AuthorizationManager.java new file mode 100644 index 0000000..5616d6e --- /dev/null +++ b/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/AuthorizationManager.java @@ -0,0 +1,120 @@ +package com.evotech.hd.gateway.oauth2; + +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpMethod; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.security.authorization.AuthorizationDecision; +import org.springframework.security.authorization.ReactiveAuthorizationManager; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.oauth2.core.OAuth2AuthorizationException; +import org.springframework.security.oauth2.core.OAuth2Error; +import org.springframework.security.web.server.authorization.AuthorizationContext; +import org.springframework.stereotype.Component; + +import com.evotech.hd.common.core.constant.HDConstant; +import com.evotech.hd.common.core.enums.CodeMsg; +import com.evotech.hd.common.redis.utils.RedisUtil; +import com.evotech.hd.gateway.utils.TokenUtil; + +import cn.hutool.core.util.StrUtil; +import jakarta.annotation.Resource; +import reactor.core.publisher.Mono; + +/** + * 资源服务的权限管理器 + * 鉴权时统一抛出OAuth2AuthorizationException + */ +@Component +public class AuthorizationManager implements ReactiveAuthorizationManager { + + @Resource + private RedisUtil redisUtil; + @Resource + private RSAKeyPair rsaKeyPair; + + @Value("${yt.gateway.is_pass:false}") + private boolean isPass; + + + @Override + public Mono check(Mono mono, AuthorizationContext authorizationContext) { + if (isPass) { + return Mono.just(new AuthorizationDecision(true)); + } + ServerHttpRequest request = authorizationContext.getExchange().getRequest(); + String uri = request.getURI().toString(); + // 微信服务先放行,后面再加验证规则 + if (uri.contains("/gateway/wechat/")) { + return Mono.just(new AuthorizationDecision(true)); + } + // 1. 对应跨域的预检请求直接放行 + if (request.getMethod() == HttpMethod.OPTIONS) { + return Mono.just(new AuthorizationDecision(true)); + } + // 2. token验证 + /** + * 这个类主要是处理权限(Authorization)的,对于身份(authentication) + * 验证是在 @org.springframework.security.oauth2.server.resource.authentication.JwtReactiveAuthenticationManager + */ + String token = request.getHeaders().getFirst(HDConstant.AUTHORIZATION_KEY); + // 已经做过了decoder,下面这2个判断不会出现错误的 + if (StrUtil.isBlank(token)) { + throw new OAuth2AuthorizationException(new OAuth2Error(CodeMsg.USER_NOT_LOGIN.getCode(), CodeMsg.USER_NOT_LOGIN.getMsg(), uri)); + } + if (!StrUtil.startWithIgnoreCase(token, "Bearer ")) { + throw new OAuth2AuthorizationException(new OAuth2Error(CodeMsg.TOKEN_INVALID.getCode(), CodeMsg.TOKEN_INVALID.getMsg(), uri)); + } + + // 3. map中自定义权限校验 + return mono + .map(auth -> new AuthorizationDecision(checkAuthorities(token.substring(7), request, auth))) + .defaultIfEmpty(new AuthorizationDecision(false)); + } + + /** + * 校验权限和client状态 + * @param token + * @param request + * @param auth + */ + private boolean checkAuthorities(String token, ServerHttpRequest request, Authentication auth) { + String uri = request.getURI().toString(); + + // 0. Redis中含有JTI才可用 + String jti = TokenUtil.getJti(token); + if (!redisUtil.hasKey(HDConstant.LOGIN_CACHE_KEY_PREFIX + jti + ":token") ) { + throw new OAuth2AuthorizationException(new OAuth2Error(CodeMsg.TOKEN_INVALID.getCode(), CodeMsg.TOKEN_INVALID.getMsg(), uri)); + } + // 1. 检查客户端权限范围,暂且定scope为All才算正常client + @SuppressWarnings("unchecked") + Collection authorities = (Collection) auth.getAuthorities(); + List list = authorities.stream().map(e -> e.toString()).collect(Collectors.toList()); + if (!list.contains("SCOPE_ALL")) { + throw new OAuth2AuthorizationException(new OAuth2Error(CodeMsg.ACCESS_SCOPE_ERROR.getCode(), CodeMsg.ACCESS_SCOPE_ERROR.getMsg(), uri)); + } + // 2. SYSADMIN角色直接放行 + String rcodes = redisUtil.get(HDConstant.LOGIN_CACHE_KEY_PREFIX + jti + ":rcodes").toString(); + if (StrUtil.isBlank(rcodes)) { + throw new OAuth2AuthorizationException(new OAuth2Error(CodeMsg.BUSSINESS_ERROR.getCode(), "无账号缓存角色", uri)); + } + if (rcodes.contains(HDConstant.SYSTEM_MANAGER_ROLE_CODE)) { + return true; + } + // 3.权限验证 + List objectList = redisUtil.lGet(HDConstant.LOGIN_CACHE_KEY_PREFIX + jti + ":perms", 0, -1); + List permList = objectList.stream().map(i -> i.toString()).toList(); + String path = request.getURI().getPath().substring(8); + if (!permList.contains("gateway:" + path)) { + throw new OAuth2AuthorizationException(new OAuth2Error(CodeMsg.ACCESS_DENY.getCode(), CodeMsg.ACCESS_DENY.getMsg(), uri)); + } + return true; + } + + + +} diff --git a/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/MyAccessDeniedHandler.java b/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/MyAccessDeniedHandler.java new file mode 100644 index 0000000..d75ea3e --- /dev/null +++ b/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/MyAccessDeniedHandler.java @@ -0,0 +1,45 @@ +package com.evotech.hd.gateway.oauth2; + +import java.nio.charset.Charset; + +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.web.server.authorization.ServerAccessDeniedHandler; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.enums.CodeMsg; + +import cn.hutool.json.JSONUtil; +import reactor.core.publisher.Mono; + + +/** + * 自定义没有权限访问时的异常,没用到,因为自定义的权限校验 + * 参考{@link org.springframework.security.oauth2.server.resource.web.access.server.BearerTokenServerAccessDeniedHandler} + * @author zrb + * @date 2024年9月4日10:17:27 + */ +@Component +public class MyAccessDeniedHandler implements ServerAccessDeniedHandler { + + + @Override + public Mono handle(ServerWebExchange exchange, AccessDeniedException e) { +// log.error("\r\n===>>>" + this.getClass().getName()); + System.out.println("6666666666"); + e.printStackTrace(); + ServerHttpResponse response = exchange.getResponse(); + response.setStatusCode(HttpStatus.OK); + response.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); + String body= JSONUtil.toJsonStr(new Result().bussinessException(CodeMsg.ACCESS_DENY.getCode(), CodeMsg.ACCESS_DENY.getMsg(), e.getMessage())); + DataBuffer buffer = response.bufferFactory().wrap(body.getBytes(Charset.forName("UTF-8"))); + return response.writeWith(Mono.just(buffer)); + } + +} diff --git a/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/MyAuthenticationEntryPoint.java b/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/MyAuthenticationEntryPoint.java new file mode 100644 index 0000000..0569975 --- /dev/null +++ b/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/MyAuthenticationEntryPoint.java @@ -0,0 +1,81 @@ +package com.evotech.hd.gateway.oauth2; + +import java.net.URI; +import java.nio.charset.Charset; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.oauth2.jwt.BadJwtException; +import org.springframework.security.oauth2.jwt.JwtEncodingException; +import org.springframework.security.oauth2.jwt.JwtValidationException; +import org.springframework.security.oauth2.server.resource.InvalidBearerTokenException; +import org.springframework.security.web.server.ServerAuthenticationEntryPoint; +import org.springframework.web.server.ServerWebExchange; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.enums.CodeMsg; +import com.evotech.hd.gateway.utils.TokenUtil; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.json.JSONUtil; +import lombok.extern.slf4j.Slf4j; +import reactor.core.publisher.Mono; + +/** + * 这个主要处理身份认证(authentication)的异常,权限验证时的异常这里是不处理的 + * 自定义Token异常,主要处理token验证过程中的异常,因token验证是oauth2的,所以要改它的异常处理响应 + * 参考{@link org.springframework.security.oauth2.server.resource.web.server.BearerTokenServerAuthenticationEntryPoint} + * 重写了返回结果中的response内容: + * 1. response的HttpStatus改成ok + * 2. response返回内容改成{@link com.jdyl.medical.common.entity.Result} + * @author zrb + * @date 2024年9月4日10:21:02 + */ +@Slf4j +public class MyAuthenticationEntryPoint implements ServerAuthenticationEntryPoint { + + @Override + public Mono commence(ServerWebExchange exchange, AuthenticationException e) { + e.printStackTrace(); + ServerHttpResponse response = exchange.getResponse(); + Throwable cause = e.getCause(); + Result res = new Result().exception(e.getMessage()); + try { + if (cause instanceof JwtValidationException) { + if (cause.getMessage().contains("Jwt expired at")) { + String token = exchange.getRequest().getHeaders().getFirst("Authorization").substring(7); + String dateTime = DateUtil.formatDateTime(TokenUtil.getExp(token)); + res = new Result().bussinessException(CodeMsg.TOKEN_EXPIRED.getCode(), CodeMsg.TOKEN_EXPIRED.getMsg(), "Jwt expired at " + dateTime); + } else { + res = new Result().error(CodeMsg.TOKEN_INVALID.getCode(), CodeMsg.TOKEN_INVALID.getMsg(), cause.getMessage()); + } + } else if (cause instanceof BadJwtException || cause instanceof JwtEncodingException) { + res = new Result().error(CodeMsg.TOKEN_INVALID.getCode(), CodeMsg.TOKEN_INVALID.getMsg(), cause.getMessage()); + } else if (cause instanceof InvalidBearerTokenException) { + String token = exchange.getRequest().getHeaders().getFirst("Authorization").substring(7); + String dateTime = DateUtil.formatDateTime(TokenUtil.getExp(token)); + res = new Result().bussinessException(CodeMsg.TOKEN_EXPIRED.getCode(), CodeMsg.TOKEN_EXPIRED.getMsg(), "Jwt expired at " + dateTime); + } else { + res = new Result().error(CodeMsg.AUTHENTICATION_FAILED.getCode(), CodeMsg.AUTHENTICATION_FAILED.getMsg(), e.getMessage()); + } + } catch (Exception e1) { + log.info(e1.toString()); + res = new Result().error(CodeMsg.AUTHENTICATION_FAILED.getCode(), CodeMsg.AUTHENTICATION_FAILED.getMsg(), e.getMessage()); + } + response.setStatusCode(HttpStatus.OK); + response.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); + URI uri = exchange.getRequest().getURI(); + // 为了解决token过期时,前端不出现跨域错误,添加了一些header,注意Access-Control-Allow-Origin的值 + response.getHeaders().add("Access-Control-Allow-Origin", uri.getScheme() + "://" + uri.getHost()); + response.getHeaders().add("Access-Control-Allow-Credentials", "true"); + response.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD"); + response.getHeaders().add("Access-Control-Allow-Headers", HttpHeaders.AUTHORIZATION); + String body = JSONUtil.toJsonStr(res); + DataBuffer buffer = response.bufferFactory().wrap(body.getBytes(Charset.forName("UTF-8"))); + return response.writeWith(Mono.just(buffer)); + } + +} diff --git a/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/MyJwtValidator.java b/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/MyJwtValidator.java new file mode 100644 index 0000000..28af60f --- /dev/null +++ b/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/MyJwtValidator.java @@ -0,0 +1,21 @@ +package com.evotech.hd.gateway.oauth2; + +import org.springframework.security.oauth2.core.OAuth2TokenValidator; +import org.springframework.security.oauth2.core.OAuth2TokenValidatorResult; +import org.springframework.security.oauth2.jwt.Jwt; + +/** + * 这个是 配置jwtDecoder用的 + * 自定义JWT字段校验,暂时没用 + */ +public class MyJwtValidator implements OAuth2TokenValidator { + + @Override + public OAuth2TokenValidatorResult validate(Jwt token) { + System.out.println("===>>>开始走自定义decoder了"); + + // 校验成功,返回 + return OAuth2TokenValidatorResult.success(); + } + +} diff --git a/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/RSAKeyPair.java b/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/RSAKeyPair.java new file mode 100644 index 0000000..ae9564f --- /dev/null +++ b/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/RSAKeyPair.java @@ -0,0 +1,17 @@ +package com.evotech.hd.gateway.oauth2; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +public class RSAKeyPair { + + @Value("${security.token.public_key_base64:null}") + private String publicKeyBase64; + + public String getPublicKeyBase64() { + return publicKeyBase64; + } + + +} diff --git a/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/ResourceServerConfig.java b/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/ResourceServerConfig.java new file mode 100644 index 0000000..a0c3cee --- /dev/null +++ b/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/ResourceServerConfig.java @@ -0,0 +1,138 @@ +package com.evotech.hd.gateway.oauth2; + +import java.security.KeyFactory; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.Customizer; +import org.springframework.security.config.web.server.ServerHttpSecurity; +import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator; +import org.springframework.security.oauth2.core.OAuth2TokenValidator; +import org.springframework.security.oauth2.jwt.Jwt; +import org.springframework.security.oauth2.jwt.JwtValidators; +import org.springframework.security.oauth2.jwt.NimbusReactiveJwtDecoder; +import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder; +import org.springframework.security.web.server.SecurityWebFilterChain; +import jakarta.annotation.Resource; + + + +@Configuration +public class ResourceServerConfig { + + @Value("${security.oauth2.ignore_uri:{}}") + private String[] ignoreUriArr; + + @Resource + private AuthorizationManager authorizationManager; + @Resource + private RSAKeyPair rsaKeyPair; + + + + @Bean + SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) throws Exception { + // csrf关闭 + http.csrf(csrf -> csrf.disable()); + // 跨域处理 + http.cors(Customizer.withDefaults()); + http.httpBasic(httpBasicSpec -> httpBasicSpec.disable()); + // 资源服务器配置 + http.oauth2ResourceServer(server -> server + // 权限不通过时,自定义返回 + .accessDeniedHandler(new MyAccessDeniedHandler()) + // 未登录或者登陆验证失败时(token有问题),自定义返回 + .authenticationEntryPoint(new MyAuthenticationEntryPoint()) + // 使用jwt默认配置 +// .jwt(Customizer.withDefaults()) + // jwt的自定义校验,设置decoder或者converter + .jwt(jwt -> + jwt + // 当无法提供issuer-uri的时候,可以拿到jwk,包含有私钥 + // 可以不在这配置,在decoder中也可以配置从什么地方拿私钥验签 +// .jwkSetUri("http://127.0.0.1:9101/oauth2/oauth2/jwks") + .jwtDecoder(jwtDecoder()) + // 指定jwt权限验证时的配置:比如 权限使用哪个字段,权限有没有前缀 +// .jwtAuthenticationConverter(jwtAuthenticationConverter()) + ) + ); + + http.authorizeExchange(exchange -> + exchange + .pathMatchers(ignoreUriArr).permitAll() + .pathMatchers(ignoreFixedUris()).permitAll() +// .anyExchange().authenticated() + // 其他走自定义逻辑 + .anyExchange().access(authorizationManager) + ); + + return http.build(); + + } + + private String[] ignoreFixedUris() { + String[] uriArr = { + // swagger相关,请求"/favicon.ico"会报错,因为没有,我自己在/resources/static/底下放了一个 + "/gateway/*/v3/api-docs", + "/v3/api-docs/**", + "/swagger-resources/configuration/ui", + "/swagger-resources", + "/swagger-resources/configuration/security", + "/swagger-ui.html", + "/css/**", + "/js/**", + "/images/**", + "/webjars/**", + "/favicon.ico", + "/doc.html", + // admin监控 + "/actuator/**", + "/instances/**", + // 登陆相关 + "/gateway/oauth2/captcha/get", + "/gateway/oauth2/captcha/check", + "/gateway/oauth2/login/oauthlogin" + }; + return uriArr; + } + + + +// private JwtAuthenticationConverter jwtAuthenticationConverter() { +// JwtAuthenticationConverter converter = new JwtAuthenticationConverter(); +// JwtGrantedAuthoritiesConverter authoritiesConverter = new JwtGrantedAuthoritiesConverter(); +// authoritiesConverter.setAuthoritiesClaimName("perms"); +// authoritiesConverter.setAuthorityPrefix(""); +// converter.setJwtGrantedAuthoritiesConverter(authoritiesConverter); +// return converter; +// } + + // 创建JWT解码器 decoder + private ReactiveJwtDecoder jwtDecoder() { + String publicKeyBase64 = rsaKeyPair.getPublicKeyBase64(); + NimbusReactiveJwtDecoder jwtDecoder = NimbusReactiveJwtDecoder.withPublicKey(getPublicKey(publicKeyBase64)).build(); + OAuth2TokenValidator defaultValidator = JwtValidators.createDefault(); + OAuth2TokenValidator oauth2TokenValidator = new DelegatingOAuth2TokenValidator<>(defaultValidator); + jwtDecoder.setJwtValidator(oauth2TokenValidator); + return jwtDecoder; + } + + + private RSAPublicKey getPublicKey(String publicKeyBase64) { + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyBase64)); + RSAPublicKey rsaPublicKey = null; + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + rsaPublicKey = (RSAPublicKey)keyFactory.generatePublic(keySpec); + } catch (Exception e) { + e.printStackTrace(); + } + + return rsaPublicKey; + } + +} diff --git a/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/exception/GlobalExceptionAutoConfig.java b/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/exception/GlobalExceptionAutoConfig.java new file mode 100644 index 0000000..9799ba2 --- /dev/null +++ b/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/exception/GlobalExceptionAutoConfig.java @@ -0,0 +1,63 @@ +package com.evotech.hd.gateway.oauth2.exception; + +import java.util.stream.Collectors; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.boot.autoconfigure.web.WebProperties; +import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; +import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.web.reactive.error.ErrorAttributes; +import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.http.codec.ServerCodecConfigurer; +import org.springframework.web.reactive.result.view.ViewResolver; + + +/** + * 根据{@link}ErrorWebFluxAutoConfiguration的配置 重写 + * 主要是重写errorWebExceptionHandler()的逻辑 + * 里面不要DefaultErrorWebExceptionHandler了,用自己写的异常处理类替换 + */ +@Configuration(proxyBeanMethods = false) +//@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) +//@ConditionalOnClass(WebFluxConfigurer.class) +@AutoConfigureBefore(WebFluxAutoConfiguration.class) +@EnableConfigurationProperties({ ServerProperties.class, WebProperties.class }) +public class GlobalExceptionAutoConfig { + + + private final ServerProperties serverProperties; + + public GlobalExceptionAutoConfig(ServerProperties serverProperties) { + this.serverProperties = serverProperties; + } + + + // 要比 ErrorWebFluxAutoConfiguration 小,表示其优先调用 + @Bean + @Order(Ordered.HIGHEST_PRECEDENCE) + ErrorWebExceptionHandler errorWebExceptionHandler(ErrorAttributes errorAttributes, + WebProperties webProperties, ObjectProvider viewResolvers, + ServerCodecConfigurer serverCodecConfigurer, ApplicationContext applicationContext) { + // 使用自定义的异常处理类GlobalExceptionHandler + DefaultErrorWebExceptionHandler exceptionHandler = new GlobalExceptionHandler(errorAttributes, + webProperties.getResources(), this.serverProperties.getError(), applicationContext); + exceptionHandler.setViewResolvers(viewResolvers.orderedStream().collect(Collectors.toList())); + exceptionHandler.setMessageWriters(serverCodecConfigurer.getWriters()); + exceptionHandler.setMessageReaders(serverCodecConfigurer.getReaders()); + return exceptionHandler; + } + +// @Bean +// @ConditionalOnMissingBean(value = ErrorAttributes.class, search = SearchStrategy.CURRENT) +// public DefaultErrorAttributes errorAttributes() { +// return new DefaultErrorAttributes(); +// } +} diff --git a/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/exception/GlobalExceptionHandler.java b/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..fc7a7f1 --- /dev/null +++ b/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/exception/GlobalExceptionHandler.java @@ -0,0 +1,61 @@ +package com.evotech.hd.gateway.oauth2.exception; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.web.ErrorProperties; +import org.springframework.boot.autoconfigure.web.WebProperties.Resources; +import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler; +import org.springframework.boot.web.reactive.error.ErrorAttributes; +import org.springframework.context.ApplicationContext; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.reactive.function.BodyInserters; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; + +import reactor.core.publisher.Mono; + + +/** + * 异常处理操作,自定义异常中的内容 + * 重写了{@link}DefaultErrorWebExceptionHandler部分内容 + */ +public class GlobalExceptionHandler extends DefaultErrorWebExceptionHandler { + + @Autowired + private GlobalExceptionType globalExceptionType; + + + public GlobalExceptionHandler(ErrorAttributes errorAttributes, Resources resources, + ErrorProperties errorProperties, ApplicationContext applicationContext) { + super(errorAttributes, resources, errorProperties, applicationContext); + } + + + /** + * DefaultErrorWebExceptionHandler中是返回页面,这里改成直接返回renderErrorResponse + */ + @Override + protected RouterFunction getRoutingFunction(ErrorAttributes errorAttributes) { + return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse); + } + + /** + * 定义renderErrorResponse的body中的内容 + */ + @Override + protected Mono renderErrorResponse(ServerRequest request) { +// Map error = getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.ALL)); + Throwable throwable = getError(request); + return ServerResponse +// .status(super.getHttpStatus(error)) + .status(HttpStatus.OK) + .contentType(MediaType.APPLICATION_JSON) +// .body(BodyInserters.fromValue(new RuntimeException())) + .body(BodyInserters.fromValue(globalExceptionType.handle(throwable))) + ; + + } +} diff --git a/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/exception/GlobalExceptionType.java b/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/exception/GlobalExceptionType.java new file mode 100644 index 0000000..58cc07f --- /dev/null +++ b/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/exception/GlobalExceptionType.java @@ -0,0 +1,40 @@ +package com.evotech.hd.gateway.oauth2.exception; + +import org.springframework.security.oauth2.core.OAuth2AuthorizationException; +import org.springframework.security.oauth2.core.OAuth2Error; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.ExceptionHandler; + +import com.evotech.hd.common.core.entity.Result; + + +/** + * 统一异常 + * 主要处理自定义的权限鉴定时的异常,OAuth2AuthorizationException + */ +@Component +public class GlobalExceptionType { + + + @ExceptionHandler(value = {Exception.class}) + public Result handle(Throwable throwable) { + if (throwable instanceof OAuth2AuthorizationException) { + return oAuth2AuthorizationHandle((OAuth2AuthorizationException) throwable); + } else { + throwable.printStackTrace(); + return new Result().exception(throwable.getMessage()); + } + } + + + @ExceptionHandler(value = {OAuth2AuthorizationException.class}) + public Result oAuth2AuthorizationHandle(OAuth2AuthorizationException e) { + e.printStackTrace(); + OAuth2Error error = e.getError(); + return new Result().bussinessException(error.getErrorCode(), error.getDescription(), error.getUri()); + } + + + + +} diff --git a/gateway-server/src/main/java/com/evotech/hd/gateway/thread/ThreadPoolConfig.java b/gateway-server/src/main/java/com/evotech/hd/gateway/thread/ThreadPoolConfig.java new file mode 100644 index 0000000..26acdd0 --- /dev/null +++ b/gateway-server/src/main/java/com/evotech/hd/gateway/thread/ThreadPoolConfig.java @@ -0,0 +1,48 @@ +package com.evotech.hd.gateway.thread; + +import java.util.concurrent.ThreadPoolExecutor; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +@ConditionalOnProperty(prefix = "threadpool", name = "enable", matchIfMissing = false) +@Configuration +public class ThreadPoolConfig { + + + @Bean + @ConditionalOnClass({ThreadPoolProperties.class}) + ThreadPoolProperties tpProperties() { + return new ThreadPoolProperties(); + } + + @Bean + ThreadPoolTaskExecutor taskExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setCorePoolSize(tpProperties().getCorePoolSize()); + executor.setMaxPoolSize(tpProperties().getMaxPoolSize()); + executor.setQueueCapacity(tpProperties().getQueueCapacity()); + executor.setThreadNamePrefix(tpProperties().getThreadNamePrefix()); + // 设置线程保持活跃的时间(默认:60) + executor.setKeepAliveSeconds(tpProperties().getKeepAliveTime()); + // 当任务完成后,长时间无待处理任务时,销毁线程池 + executor.setWaitForTasksToCompleteOnShutdown(tpProperties().isWaitForTasksToCompleteOnShutdown()); + executor.setAwaitTerminationSeconds(tpProperties().getAwaitTerminationSeconds()); + // 设置任务拒绝策略 + /** + * 4种 + * ThreadPoolExecutor类有几个内部实现类来处理这类情况: + - AbortPolicy 丢弃任务,抛RejectedExecutionException + - CallerRunsPolicy 由该线程调用线程运行。直接调用Runnable的run方法运行。 + - DiscardPolicy 抛弃策略,直接丢弃这个新提交的任务 + - DiscardOldestPolicy 抛弃旧任务策略,从队列中踢出最先进入队列(最后一个执行)的任务 + * 实现RejectedExecutionHandler接口,可自定义处理器 + */ + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + return executor; + } + +} diff --git a/gateway-server/src/main/java/com/evotech/hd/gateway/thread/ThreadPoolProperties.java b/gateway-server/src/main/java/com/evotech/hd/gateway/thread/ThreadPoolProperties.java new file mode 100644 index 0000000..efae0bf --- /dev/null +++ b/gateway-server/src/main/java/com/evotech/hd/gateway/thread/ThreadPoolProperties.java @@ -0,0 +1,36 @@ +package com.evotech.hd.gateway.thread; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +import lombok.Data; + + + +@ConditionalOnProperty(prefix = "threadpool", name = "enable", matchIfMissing = false) +@ConfigurationProperties(prefix = "threadpool", ignoreUnknownFields = true) +@Data +@Component +public class ThreadPoolProperties { + + private boolean enable; + + + private int corePoolSize; + + private int maxPoolSize; + + private int keepAliveTime; + + private int queueCapacity; + + private String threadNamePrefix; + + private boolean allowCoreThreadTimeout; + + private boolean waitForTasksToCompleteOnShutdown; + + private int awaitTerminationSeconds; + +} diff --git a/gateway-server/src/main/java/com/evotech/hd/gateway/utils/IpUtil.java b/gateway-server/src/main/java/com/evotech/hd/gateway/utils/IpUtil.java new file mode 100644 index 0000000..dc3e7ec --- /dev/null +++ b/gateway-server/src/main/java/com/evotech/hd/gateway/utils/IpUtil.java @@ -0,0 +1,65 @@ +package com.evotech.hd.gateway.utils; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Optional; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.server.reactive.ServerHttpRequest; + +/** + * + * @author zrb + * @date 2024年9月4日09:06:55 + */ +public class IpUtil { + + private static final String IP_UNKNOWN = "unknown"; + private static final String IP_LOCAL = "127.0.0.1"; + private static final int IP_LEN = 15; + + /** + * 获取客户端真实ip + * location / { + ... + # 后端的Web服务器可以通过X-Forwarded-For获取用户真实IP + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + ... + } + */ + public static String getRemoteIP(ServerHttpRequest request) { + HttpHeaders headers = request.getHeaders(); + String ipAddress = headers.getFirst("x-forwarded-for"); + if (ipAddress == null || ipAddress.length() == 0 || IP_UNKNOWN.equalsIgnoreCase(ipAddress)) { + ipAddress = headers.getFirst("Proxy-Client-IP"); + } + if (ipAddress == null || ipAddress.length() == 0 || IP_UNKNOWN.equalsIgnoreCase(ipAddress)) { + ipAddress = headers.getFirst("WL-Proxy-Client-IP"); + } + if (ipAddress == null || ipAddress.length() == 0 || IP_UNKNOWN.equalsIgnoreCase(ipAddress)) { + ipAddress = Optional.ofNullable(request.getRemoteAddress()) + .map(address -> address.getAddress().getHostAddress()).orElse(""); + if (IP_LOCAL.equals(ipAddress)) { + // 根据网卡取本机配置的IP + try { + InetAddress inet = InetAddress.getLocalHost(); + ipAddress = inet.getHostAddress(); + } catch (UnknownHostException e) { + + } + } + } + + // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割 + if (ipAddress != null && ipAddress.length() > IP_LEN) { + int index = ipAddress.indexOf(","); + if (index > 0) { + ipAddress = ipAddress.substring(0, index); + } + } + return ipAddress; + } + +} diff --git a/gateway-server/src/main/java/com/evotech/hd/gateway/utils/ResponseUtils.java b/gateway-server/src/main/java/com/evotech/hd/gateway/utils/ResponseUtils.java new file mode 100644 index 0000000..11becf5 --- /dev/null +++ b/gateway-server/src/main/java/com/evotech/hd/gateway/utils/ResponseUtils.java @@ -0,0 +1,30 @@ +package com.evotech.hd.gateway.utils; + +import cn.hutool.json.JSONUtil; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.core.io.buffer.DataBufferUtils; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.server.reactive.ServerHttpResponse; + +import com.evotech.hd.common.core.entity.Result; + +import reactor.core.publisher.Mono; + +import java.nio.charset.StandardCharsets; + + +public class ResponseUtils { + + public static Mono writeResInfo(ServerHttpResponse response, Result result) { + response.getHeaders().set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); + response.getHeaders().set("Access-Control-Allow-Origin", "*"); + response.getHeaders().set("Cache-Control", "no-cache"); + String body = JSONUtil.toJsonStr(result); + + DataBuffer buffer = response.bufferFactory().wrap(body.getBytes(StandardCharsets.UTF_8)); + return response.writeWith(Mono.just(buffer)) + .doOnError(error -> DataBufferUtils.release(buffer)); + } + +} diff --git a/gateway-server/src/main/java/com/evotech/hd/gateway/utils/TokenUtil.java b/gateway-server/src/main/java/com/evotech/hd/gateway/utils/TokenUtil.java new file mode 100644 index 0000000..7f3a5a2 --- /dev/null +++ b/gateway-server/src/main/java/com/evotech/hd/gateway/utils/TokenUtil.java @@ -0,0 +1,57 @@ +package com.evotech.hd.gateway.utils; + +import java.util.Date; + +import org.springframework.security.oauth2.jwt.JwtClaimNames; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.jwt.JWT; +import cn.hutool.jwt.JWTUtil; + +/** + * token解析工具类 + */ +public class TokenUtil { + + + public static JWT parseToJwt(String token) { + JWT parseToken = JWTUtil.parseToken(token); + return parseToken; + } + + + /** + * 从token中获取userId + */ + public static String getUserId(String token) { + String uid = parseToJwt(token).getPayloads().getStr("uid"); + return uid; + } + + /** + * 从token中获取rcodes + */ + public static String getRcodes(String token) { + String uid = parseToJwt(token).getPayloads().getStr("rcodes"); + return uid; + } + + + /** + * 从token中获取jti + */ + public static String getJti(String token) { + String jti = parseToJwt(token).getPayloads().getStr(JwtClaimNames.JTI).replaceAll("-", ""); + return jti; + } + + + /** + * 从token中获取过期时间 + */ + public static Date getExp(String token) { + String exp = parseToJwt(token).getPayloads().getStr(JwtClaimNames.EXP).toString(); + return DateUtil.date(Long.valueOf(exp) * 1000); + } + +} diff --git a/gateway-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/gateway-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 0000000..0fbca9d --- /dev/null +++ b/gateway-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,5 @@ +{"properties": [{ + "name": "security.token.public_key_base64", + "type": "java.lang.String", + "description": "A description for 'security.token.public_key_base64'" +}]} \ No newline at end of file diff --git a/gateway-server/src/main/resources/application.yml b/gateway-server/src/main/resources/application.yml new file mode 100644 index 0000000..1b227a8 --- /dev/null +++ b/gateway-server/src/main/resources/application.yml @@ -0,0 +1,48 @@ +security.token.public_key_base64: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA23qzsZ/51EA9PAYvGyGwlSYEZxnGmF3FxiraUvLyeiBawyGFCHprnmG+fr+80KmhGh1UMbNwuwIRgn8tEY9TjlfK7iNhsX1QGEjrL6LggDJeXlA/XN4kRPY9sW7+VQpr1MPJjB5tQYVkPLvv3L8v/7k5hcPEoHIFwQoOnYBuQqLkj38EQ/NlOQLKzhyDRFWSm+6WzQF46fTMRLzRpfuFhUBk9oF3B8Y/vAajY90QDw5xdV0uGreK6CgESldCzx6hh1AHiLLICINRKTNL1t+uhRaz/f0xm8baxaKzusv2relz69GADCQl/GrTArcfWXVXqvetFzsQOt35EBOpxl3nRwIDAQAB +# 1.server +server: + port: 9100 + # 由于gateway中使用的 spring-boot-starter-webfulx 的依赖 和 spring-boot-starter-web依赖有所冲突, + # 所以去掉了spring-boot-starter-web, 此时项目的启动容器是Netty ,所以我们在application.yml中 + # 配置的server.servlet.context-path属性是没用的,他的actuator监控地址仍是http://ip:port/actuator + # 可以自己添加WebFilter过滤器,添加上这个 +# servlet: +# context-path: /gateway +# 2.log +logging: + config: classpath:logback-spring.xml + level: + '[org.springframework.cloud.gateway]': info +# '[org.springframework.jdbc.core]': debug +# 3.spring +spring: + # 服务名称必须带上,不然nacos服务列表中没有,也不会有注册成功的信息 + application: + name: gateway-server + # 设置转发数据包大小限制5M + codec: + max-in-memory-size: 10485760 + config: + import: + - nacos:${spring.application.name}.yaml?refreshEnabled=true + cloud: + nacos: + serverAddr: 192.168.5.213:8848 + username: nacos + password: nacos + discovery: + register-enabled: true + #server-addr: 10.10.1.6:8848 + #ip: 10.10.1.2 +# 5.为springbootadmin开启所有检查 +management: + endpoints: + web: + exposure: + include: "*" + endpoint: + health: + show-details: always + # xml文件中配置的日志文件的名称 + logfile: + external-file: /logs/gateway/gateway-server.log \ No newline at end of file diff --git a/gateway-server/src/main/resources/logback-spring.xml b/gateway-server/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..54b1e59 --- /dev/null +++ b/gateway-server/src/main/resources/logback-spring.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + ${CONTEXT_NAME} + + + + + + DEBUG + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %replace(%caller{1}){'\t|Caller.{1}0|\r\n', ''} -- %msg%n + + UTF-8 + + + + + + + ${LOG_PATH}/${CONTEXT_NAME}.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{50}.%M\(%line\) -- %msg%n + UTF-8 + + + + + ${LOG_PATH}/${CONTEXT_NAME}-%d{yyyy-MM-dd}-%i.log + + ${MAX_HISTORY} + + + ${MAX_FILE_SIZE} + + + + + + + + + + + 512 + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/gateway-server/src/main/resources/static/favicon.ico b/gateway-server/src/main/resources/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..e5a0eeb18e564483af9b0c1b6f1c885b82b63a89 GIT binary patch literal 10342 zcmeI0Kd#$25Qmj+o3u6%z}*(F7t%P*6LNvqrbuV2$pvzPz^YuNVwwIq#j4B+07gh#oN*|m=r4Ft{K1~G zKlL!#m6X(Az=DHtP=f&r4&)&v)L_7Z14?zP z*&DFnK#VD&1_Krxh=C>4V8DU{F}j2r3|Md=FH%Ac1}r#`mn)$L0~Q?c0G?j!X4qSB zAWkTu1_Krxh+|5q!GHw^;;a&CFkr!fIIx5o3|Md=PA#DZ0~Q=0ggs)3(ao}VAkHtL z1_KrxNQabAg8>T;q?1ah!GHw^(s3o!V8DU{>C6&pFkry}4X{VNB9>U)9DC{X5^6AD z!GQ!q2{jn7;6Q?-gc=N3a3BFwLJbBiIADi8l!E~a4!D6m(nI1EvBc>{W$d9G3|Mf0 z0QOK01}r#06niKK0~Q?cAnc(W3|Mf$!+8YdV8DU{`MrGkvUv6CRq^ofP`rNqx_JBc zZSnNdkR1KheI3?9}qMR~jEL$5_95%xg`wyQ5kmmL#0V zlKpj4W%V-gsdjg$_PSxcY}M&`^|4nY!l*w))NSp~`|&gu z_1E6g<8!=w5TD1ZrTMZ|FIK%}Lp#o9?j5r*T(G-q)bimy6Lq>;q9`fhdFj=XcBej_ z^SJMe*{6mFENT-A#BOe#v^`anZ*S(AMeR=WOFAUfs#fFqR_u36eThz^BTfaA-SK)q z#9GUCw;JQ49M_U-cH7C@L|Hvq*6#L_D{>h>Vyn>ubLBNY>12rP4p~E=M{dQ4R9|7Y zj<(EhN{F8PaoMx|#R_flZIwniF+v}_nNiD&R%o9jFDJfz*2vyuLogQ&S1YuA-WXa- zP>wryxSO1<(H1+0ktvVL-Xl@VPgiJnZzL~A7gRg(e=@z~g2~ki?TZZW7!?{dqmWGW z($f{%KBI(SW?skJY1E`@`S}`c%^g0P2|pR7(LuS`=xR>8%~O2Wh`+t5M_se5aW>Bx zXwVlSV=I8M4K7U-qe)7n=7?CF=+RvKZ#2wN4Ag(id8}6@k zcCM|FD}HXfOIQnr%&K=9-xn)mB)8koi*c2tzTJ5vb>{JJHNOlJrRi_*Nu~4R@W$fX zkVP6f5Bw9m`Cdq~UB{v)UbD)Un3w$!JySc!CDHD)Mn-a5Vma7-rgL|j?osx;^tX`WZi6sV1h(oJMV;V7m+2M|?|c@Ft;!`kIyGR{fsM%QKpN zQPkEL_KDO-jQBr{dosB9efW}i>|5VHMs1DWpsjwz4bipCJiDz#h@U(A_q#1UjLUTO zBvuAXeRCbD>I%OeA7;;6^3m?I_;eep`dA;*{9}k9=>B( zw(%xmtu5zl(-ryTAyNCvI@>p3=E3`+vCk_jEFZL`$+g&(!4vN>fk=NWPZ5Lm22BPskWaNhtZfAG3kpNbz`$sTP9l_kyD?iqt>_8x@7g_Wuj;}$+Z1S1V0XI zlTc09+ucNlg%fee;U(=4X)pDI1bKCWMa{PtU`#h%0kyFOn zU5H(cfSvy0ji@rQZq@&z)z{bC6K(&I9WwZ~dOSD$t=Rh5pA5uw{a7`}rds^} zq}4ycG-5QaS*q!ACTq7opAU7@wfT(QywAn2vx%6vE|K%OwMo0r>n#6Y71rUBsU-u3 zO2G>G$8=19uPH JJ+SD3zX9T>lDz-` literal 0 HcmV?d00001 diff --git a/gateway-server/src/test/java/com/evotech/hd/gateway/GatewayServerApplicationTests.java b/gateway-server/src/test/java/com/evotech/hd/gateway/GatewayServerApplicationTests.java new file mode 100644 index 0000000..26a1f76 --- /dev/null +++ b/gateway-server/src/test/java/com/evotech/hd/gateway/GatewayServerApplicationTests.java @@ -0,0 +1,13 @@ +package com.evotech.hd.gateway; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class GatewayServerApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..82bee49 --- /dev/null +++ b/pom.xml @@ -0,0 +1,163 @@ + + + + 4.0.0 + com.evotech.hd + battery-cloud + 1.0.0-SNAPSHOT + pom + battery-cloud-management + hdcloud-manager+weChat-miniProgram+weChat-officialAccount + + + + org.springframework.boot + spring-boot-starter-parent + 3.3.3 + + + + + + + + 17 + UTF-8 + UTF-8 + + 2023.0.1 + 2023.0.1.2 + 2.2.5.RELEASE + + 3.5.7 + 4.3.1 + + 3.35.0 + 3.3.4 + + 5.8.32 + 1.8.8 + 2.0.0 + + 5.1.4 + 4.5.0 + 2.2.23 + 3.4.0 + 5.3.0 + 2.4.1 + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring-cloud-alibaba.version} + pom + import + + + de.codecentric + spring-boot-admin-dependencies + ${spring-boot-admin.version} + pom + import + + + cn.hutool + hutool-bom + ${hutool.version} + pom + + import + + + + + + com.baomidou + mybatis-plus-spring-boot3-starter + ${mybatis-plus.version} + + + com.baomidou + mybatis-plus-annotation + ${mybatis-plus.version} + + + com.baomidou + mybatis-plus-core + ${mybatis-plus.version} + + + com.baomidou + dynamic-datasource-spring-boot3-starter + ${dynamic-datasource.version} + + + org.redisson + redisson-spring-boot-starter + ${redission.version} + + + + + + com.github.xiaoymin + knife4j-openapi3-jakarta-spring-boot-starter + ${knife4j.version} + + + io.swagger.core.v3 + swagger-annotations-jakarta + ${swagger.version} + + + com.github.xiaoymin + knife4j-gateway-spring-boot-starter + ${knife4j.version} + + + org.springframework.cloud + spring-cloud-starter-oauth2 + ${spring-cloud-starter-oauth2.version} + + + org.apache.commons + commons-jexl3 + ${jexl3.version} + + + org.apache.poi + poi-ooxml + ${poi.version} + + + com.xuxueli + xxl-job-core + ${xxl-job.version} + + + + + + base-commons + authorization-server + cloud-manage-server + gateway-server + resource-server + wechat-server + admin-server + + \ No newline at end of file diff --git a/resource-server/.gitignore b/resource-server/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/resource-server/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/resource-server/pom.xml b/resource-server/pom.xml new file mode 100644 index 0000000..450e0af --- /dev/null +++ b/resource-server/pom.xml @@ -0,0 +1,80 @@ + + + + 4.0.0 + + com.evotech.hd + battery-cloud + 1.0.0-SNAPSHOT + + resource-server + resource-server + 资源服务 + + + 17 + + + + + + com.evotech.hd + common-web + 1.0.0-SNAPSHOT + + + + com.evotech.hd + common-mybatis + 1.0.0-SNAPSHOT + + + + com.baomidou + dynamic-datasource-spring-boot3-starter + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + cn.hutool + hutool-json + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + diff --git a/resource-server/src/main/java/com/evotech/hd/resource/ResourceServerApplication.java b/resource-server/src/main/java/com/evotech/hd/resource/ResourceServerApplication.java new file mode 100644 index 0000000..68fb669 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/ResourceServerApplication.java @@ -0,0 +1,20 @@ +package com.evotech.hd.resource; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication(exclude = DataSourceAutoConfiguration.class) +@EnableDiscoveryClient +@ComponentScan("com.evotech.hd.**") +@MapperScan({"com.evotech.hd.resource.dao.**", "com.evotech.hd.common.core.dao.**"}) +public class ResourceServerApplication { + + public static void main(String[] args) { + SpringApplication.run(ResourceServerApplication.class, args); + } + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/controller/AdmdvsInfoController.java b/resource-server/src/main/java/com/evotech/hd/resource/controller/AdmdvsInfoController.java new file mode 100644 index 0000000..51506f5 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/controller/AdmdvsInfoController.java @@ -0,0 +1,36 @@ +package com.evotech.hd.resource.controller; + +import java.util.List; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.dict.AdmdvsInfo; +import com.evotech.hd.resource.entity.request.ListAdmdvsRequest; +import com.evotech.hd.resource.service.AdmdvsInfoService; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; + +@Tag(name = "行政区划") +@RestController +@RequestMapping("/admdvs") +@ApiSupport(order = 121) +public class AdmdvsInfoController { + + @Resource + private AdmdvsInfoService admdvsInfoService; + + + @Operation(summary = "查询", description = "查询") + @GetMapping("/treelist") + public Result> treeListAdmdvs(@ParameterObject ListAdmdvsRequest lar) { + return admdvsInfoService.treeListAdmdvs(lar); + } + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/controller/AuthUserController.java b/resource-server/src/main/java/com/evotech/hd/resource/controller/AuthUserController.java new file mode 100644 index 0000000..a4ea5ea --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/controller/AuthUserController.java @@ -0,0 +1,86 @@ +package com.evotech.hd.resource.controller; + +import java.util.List; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.auth.AuthUser; +import com.evotech.hd.common.core.entity.resource.auth.AuthUserRole; +import com.evotech.hd.resource.entity.request.ListUserRequest; +import com.evotech.hd.resource.service.AuthUserService; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; + +@Tag(name = "用户管理") +@RestController +@RequestMapping("/user") +@ApiSupport(order = 101) +public class AuthUserController { + + @Resource + private AuthUserService authUserService; + + + @GetMapping("/userbyname") + @Operation(summary = "登陆用查询接口", hidden = true) + public Result userByName(@RequestParam("uname") String uname) { + return authUserService.userByName(uname); + } + + @Operation(summary = "增加") + @PostMapping("/add") + @ApiOperationSupport(order = 1) + public Result add(@Valid @ParameterObject AuthUser user) { + return authUserService.add(user); + } + + @Operation(summary = "删除") + @PostMapping("/del") + @ApiOperationSupport(order = 2) + public Result delete(@NotNull String uid) { + return authUserService.delete(uid); + } + + @Operation(summary = "修改") + @PostMapping({"/update"}) + @ApiOperationSupport(order = 3) + public Result update(@ParameterObject AuthUser u) { + return authUserService.update(u); + } + + @Operation(summary = "查询") + @GetMapping("/list") + @ApiOperationSupport(order = 4) + public Result> list(@ParameterObject ListUserRequest lur) { + return authUserService.list(lur); + } + + + @Operation(summary = "用户分配角色") + @PostMapping("/adduserrole") + @ApiOperationSupport(order = 5) + public Result addUserRole(@Valid @ParameterObject AuthUserRole aur) { + return authUserService.addUserRole(aur); + } + + @Operation(summary = "用户删除角色") + @PostMapping("/deluserrole") + @ApiOperationSupport(order = 6) + public Result deleteUserRole(@RequestParam @NotBlank String uid, @RequestParam String rid) { + return authUserService.deleteUserRole(uid, rid); + } + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/controller/BatteryTypeController.java b/resource-server/src/main/java/com/evotech/hd/resource/controller/BatteryTypeController.java new file mode 100644 index 0000000..f19cd23 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/controller/BatteryTypeController.java @@ -0,0 +1,62 @@ +package com.evotech.hd.resource.controller; + +import java.util.List; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.common.core.entity.BasePageRequest; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.resource.entity.BatteryType; +import com.evotech.hd.resource.service.BatteryTypeService; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + +@Tag(name = "电池型号") +@RestController +@RequestMapping("/batterytype") +@ApiSupport(order = 123) +public class BatteryTypeController { + + @Resource + private BatteryTypeService batteryTypeService; + + + @Operation(summary = "增加类型") + @PostMapping("/add") + @ApiOperationSupport(order = 1) + public Result add(@Valid @ParameterObject BatteryType bt) { + return batteryTypeService.add(bt); + } + + @Operation(summary = "删除类型") + @PostMapping("/del") + @ApiOperationSupport(order = 2) + public Result delete(@NotNull Integer id) { + return batteryTypeService.delete(id); + } + + @Operation(summary = "修改类型") + @PostMapping({"/update"}) + @ApiOperationSupport(order = 3) + public Result update(@ParameterObject BatteryType bt) { + return batteryTypeService.update(bt); + } + + @Operation(summary = "查询类型") + @GetMapping("/list") + @ApiOperationSupport(order = 4) + public Result> list(@Valid @ParameterObject BasePageRequest bpr) { + return batteryTypeService.list(bpr); + } + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/controller/CarTypeController.java b/resource-server/src/main/java/com/evotech/hd/resource/controller/CarTypeController.java new file mode 100644 index 0000000..cae7fa9 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/controller/CarTypeController.java @@ -0,0 +1,63 @@ +package com.evotech.hd.resource.controller; + +import java.util.List; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.common.core.entity.BasePageRequest; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.resource.entity.CarType; +import com.evotech.hd.resource.service.CarTypeService; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + +@Tag(name = "车辆类型") +@RestController +@RequestMapping("/cartype") +@ApiSupport(order = 124) +public class CarTypeController { + + + @Resource + private CarTypeService carTypeService; + + + @Operation(summary = "增加类型") + @PostMapping("/add") + @ApiOperationSupport(order = 1) + public Result add(@Valid @ParameterObject CarType ct) { + return carTypeService.add(ct); + } + + @Operation(summary = "删除类型") + @PostMapping("/del") + @ApiOperationSupport(order = 2) + public Result delete(@NotNull Integer id) { + return carTypeService.delete(id); + } + + @Operation(summary = "修改类型") + @PostMapping({"/update"}) + @ApiOperationSupport(order = 3) + public Result update(@ParameterObject CarType ct) { + return carTypeService.update(ct); + } + + @Operation(summary = "查询类型") + @GetMapping("/list") + @ApiOperationSupport(order = 4) + public Result> list(@Valid @ParameterObject BasePageRequest bpr) { + return carTypeService.list(bpr); + } + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/controller/CompanyController.java b/resource-server/src/main/java/com/evotech/hd/resource/controller/CompanyController.java new file mode 100644 index 0000000..b01c7b7 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/controller/CompanyController.java @@ -0,0 +1,63 @@ +package com.evotech.hd.resource.controller; + +import java.util.List; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.common.core.entity.BasePageRequest; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.resource.entity.Company; +import com.evotech.hd.resource.service.CompanyService; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + +@Tag(name = "公司管理") +@RestController +@RequestMapping("/system/company") +@ApiSupport(order = 84) +public class CompanyController { + + + @Resource + private CompanyService companyService; + + + @Operation(summary = "增加") + @PostMapping("/add") + @ApiOperationSupport(order = 1) + public Result add(@Valid @ParameterObject Company company) { + return companyService.add(company); + } + + @Operation(summary = "删除") + @PostMapping("/del") + @ApiOperationSupport(order = 2) + public Result delete(@NotNull Integer id) { + return companyService.delete(id); + } + + @Operation(summary = "修改") + @PostMapping({"/update"}) + @ApiOperationSupport(order = 3) + public Result update(@ParameterObject Company company) { + return companyService.update(company); + } + + @Operation(summary = "查询") + @GetMapping("/list") + @ApiOperationSupport(order = 4) + public Result> list(@Valid @ParameterObject BasePageRequest bpr) { + return companyService.list(bpr); + } + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/controller/DictController.java b/resource-server/src/main/java/com/evotech/hd/resource/controller/DictController.java new file mode 100644 index 0000000..09a31d6 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/controller/DictController.java @@ -0,0 +1,108 @@ +package com.evotech.hd.resource.controller; + +import java.util.List; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.request.ListDictRequest; +import com.evotech.hd.common.core.entity.resource.dict.Dict; +import com.evotech.hd.common.core.entity.resource.dict.DictType; +import com.evotech.hd.resource.entity.DictInfo; +import com.evotech.hd.resource.entity.request.ListDictTypeRequest; +import com.evotech.hd.resource.service.DictService; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + +@Tag(name = "字典管理") +@ApiSupport(order = 100) +@RestController +@RequestMapping("/dict") +public class DictController { + + @Resource + private DictService dictService; + + + @Operation(summary = "增加类型") + @PostMapping("/addtype") + @ApiOperationSupport(order = 1) + public Result addType(@Valid @ParameterObject DictType dt) { + return dictService.addType(dt); + } + + @Operation(summary = "删除类型") + @PostMapping("/deltype") + @ApiOperationSupport(order = 2) + public Result deleteType(@NotNull Integer typeId) { + return dictService.deleteType(typeId); + } + + @Operation(summary = "修改类型") + @PostMapping({"/updatetype"}) + @ApiOperationSupport(order = 3) + public Result updateType(@ParameterObject DictType dt) { + return dictService.updateType(dt); + } + + @Operation(summary = "查询类型") + @GetMapping("/listtype") + @ApiOperationSupport(order = 4) + public Result> listType(@ParameterObject ListDictTypeRequest ldtr) { + return dictService.listType(ldtr); + } + + @Operation(summary = "增加字典") + @PostMapping("/adddict") + @ApiOperationSupport(order = 5) + public Result addDict(@Valid @ParameterObject Dict d) { + return dictService.addDict(d); + } + + @Operation(summary = "删除字典") + @PostMapping("/deldict") + @ApiOperationSupport(order = 6) + public Result deleteDict(@NotNull Integer dictId) { + return dictService.deleteDict(dictId); + } + + @Operation(summary = "修改字典") + @PostMapping({"/updatedict"}) + @ApiOperationSupport(order = 7) + public Result updateDict(@ParameterObject Dict d) { + return dictService.updateDict(d); + } + + + @Operation(summary = "查询字典") + @GetMapping("/listdict") + @ApiOperationSupport(order = 8) + public Result> listDict(@ParameterObject ListDictRequest listDictRequest) { + return dictService.listDict(listDictRequest); + } + + + @Operation(summary = "查询多组字典") + @GetMapping("/listdictinfo") + @ApiOperationSupport(order = 9) + public Result> listDictInfo(@NotNull @RequestParam("typeCode") String typeCode) { + return dictService.listDictInfo(typeCode); + } + + + + + + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/controller/FileUpLoadController.java b/resource-server/src/main/java/com/evotech/hd/resource/controller/FileUpLoadController.java new file mode 100644 index 0000000..1a63d80 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/controller/FileUpLoadController.java @@ -0,0 +1,73 @@ +package com.evotech.hd.resource.controller; + +import java.util.List; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.LogUpload; +import com.evotech.hd.common.core.entity.resource.UploadFile; +import com.evotech.hd.resource.entity.request.ListFileRequest; +import com.evotech.hd.resource.service.FileUpLoadService; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; + +@Tag(name = "上传接口") +@ApiSupport(order = 150) +@RestController +@RequestMapping("/file") +public class FileUpLoadController { + + @Resource + private FileUpLoadService fileUpLoadService; + + + @Operation(summary = "文件查询") + @GetMapping("/pagelistfile") + @ApiOperationSupport(order = 3) + public Result> listFile(@Valid @ParameterObject ListFileRequest lfr) { + return fileUpLoadService.listFile(lfr); + } + + @Operation(summary = "文件批量上传") + @PostMapping("/uploads") + @ApiOperationSupport(order = 2) + public Result filesUpLoad(@RequestPart MultipartFile[] fileArr, @RequestParam String ccode, @RequestParam String pocode, @RequestParam String type, @RequestParam String user, @RequestParam Boolean isAlterRandomName) { + return fileUpLoadService.filesUpLoad(fileArr, ccode, pocode, type, user, isAlterRandomName); + } + + @Operation(summary = "上传历史查询") + @GetMapping("/uploadslog") + @ApiOperationSupport(order = 1) + public Result> list(@ParameterObject ListFileRequest lfr) { + return fileUpLoadService.list(lfr); + } + + @Operation(summary = "文件删除") + @PostMapping("/del") + @ApiOperationSupport(order = 4) + public Result delete(String path, Integer fileId, String logId) { + return fileUpLoadService.delete(path, fileId, logId); + } + + + @Operation(summary = "单文件上传,无记录") + @PostMapping("/upload") + @ApiOperationSupport(order = 5) + public Result fileUpLoad(@RequestPart MultipartFile file, @RequestParam String user, @RequestParam Boolean isAlterRandomName) { + return fileUpLoadService.fileUpLoad(file, user, isAlterRandomName); + } + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/controller/IDController.java b/resource-server/src/main/java/com/evotech/hd/resource/controller/IDController.java new file mode 100644 index 0000000..638fdd1 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/controller/IDController.java @@ -0,0 +1,33 @@ +package com.evotech.hd.resource.controller; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.utils.SnowflakeUtil; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; + +@Tag(name = "ID生成, 测试用") +@ApiSupport(order = 199) +@RestController +@RequestMapping("/id") +public class IDController { + + + @Operation(description = "获取") + @GetMapping("/list") + public Result> getIds(Integer num) { + List list = new ArrayList<>(); + for (int i = 0; i < (num==null?1:num); i++) { + list.add(SnowflakeUtil.getIdStr()); + } + return new Result>().success(list); + } + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/controller/LogLoginController.java b/resource-server/src/main/java/com/evotech/hd/resource/controller/LogLoginController.java new file mode 100644 index 0000000..201c390 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/controller/LogLoginController.java @@ -0,0 +1,48 @@ +package com.evotech.hd.resource.controller; + +import java.util.List; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.common.core.entity.BasePageRequest; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.LogLogin; +import com.evotech.hd.resource.service.LogLoginService; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Hidden; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; + +@Tag(name = "登录日志") +@ApiSupport(order = 106) +@RestController +@RequestMapping("/loginlog") +public class LogLoginController { + + + @Resource + private LogLoginService logLoginService; + + + @Operation(summary = "增加") + @PostMapping("/add") + @Hidden + public Result add(@Valid @RequestBody LogLogin log) { + return logLoginService.add(log); + } + + + @Operation(summary = "查询") + @GetMapping("/list") + public Result> list(@Valid BasePageRequest bpr) { + return logLoginService.list(bpr); + } + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/controller/LoginInfoController.java b/resource-server/src/main/java/com/evotech/hd/resource/controller/LoginInfoController.java new file mode 100644 index 0000000..a2219ad --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/controller/LoginInfoController.java @@ -0,0 +1,32 @@ +package com.evotech.hd.resource.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.common.core.entity.LoginCacheInfo; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.resource.service.LoginInfoService; + +import io.swagger.v3.oas.annotations.Hidden; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; + +@Tag(name = "登陆所需记录信息") +@RestController +@RequestMapping("/logininfo") +@Hidden +public class LoginInfoController { + + @Resource + private LoginInfoService loginInfoService; + + + @Operation(summary = "获取") + @GetMapping("/get") + public Result getUserInfo(String uid) { + return loginInfoService.getUserInfo(uid); + } + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/controller/MenuController.java b/resource-server/src/main/java/com/evotech/hd/resource/controller/MenuController.java new file mode 100644 index 0000000..3246c8f --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/controller/MenuController.java @@ -0,0 +1,62 @@ +package com.evotech.hd.resource.controller; + +import java.util.List; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.auth.AuthMenu; +import com.evotech.hd.resource.service.MenuService; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + +@Tag(name = "菜单管理") +@ApiSupport(order = 103) +@RestController +@RequestMapping("/menu") +public class MenuController { + + @Resource + private MenuService menuService; + + + @Operation(summary = "增加") + @PostMapping("/add") + @ApiOperationSupport(order = 1) + public Result add(@Valid @ParameterObject AuthMenu menu) { + return menuService.add(menu); + } + + @Operation(summary = "删除") + @PostMapping("/del") + @ApiOperationSupport(order = 2) + public Result delete(@NotNull Integer menuId) { + return menuService.delete(menuId); + } + + @Operation(summary = "修改") + @PostMapping({"/update"}) + @ApiOperationSupport(order = 3) + public Result update(@ParameterObject AuthMenu menu) { + return menuService.update(menu); + } + + @Operation(summary = "账号系统菜单") + @GetMapping("/tree") + @ApiOperationSupport(order = 4) + public Result> treeMenu() { + return menuService.treeMenu(); + } + + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/controller/PermissionController.java b/resource-server/src/main/java/com/evotech/hd/resource/controller/PermissionController.java new file mode 100644 index 0000000..d9dccb8 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/controller/PermissionController.java @@ -0,0 +1,62 @@ +package com.evotech.hd.resource.controller; + +import java.util.List; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.auth.AuthPermission; +import com.evotech.hd.resource.service.PermissionService; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + +@Tag(name = "权限管理") +@ApiSupport(order = 104) +@RestController +@RequestMapping("/permission") +public class PermissionController { + + + @Resource + private PermissionService permissionService; + + + @Operation(summary = "增加") + @PostMapping("/add") + @ApiOperationSupport(order = 1) + public Result add(@Valid @ParameterObject AuthPermission perm) { + return permissionService.add(perm); + } + + @Operation(summary = "删除") + @PostMapping("/del") + @ApiOperationSupport(order = 2) + public Result delete(Integer permissionId) { + return permissionService.delete(permissionId); + } + + @Operation(summary = "修改") + @PostMapping({"/update"}) + @ApiOperationSupport(order = 3) + public Result update(@ParameterObject AuthPermission perm) { + return permissionService.update(perm); + } + + @Operation(summary = "页面权限查询") + @GetMapping("/list") + @ApiOperationSupport(order = 4) + public Result> list(@NotNull Integer menuId) { + return permissionService.list(menuId); + } + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/controller/ProxyOperaterController.java b/resource-server/src/main/java/com/evotech/hd/resource/controller/ProxyOperaterController.java new file mode 100644 index 0000000..10d51ab --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/controller/ProxyOperaterController.java @@ -0,0 +1,62 @@ +package com.evotech.hd.resource.controller; + +import java.util.List; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.ProxyOperater; +import com.evotech.hd.resource.entity.request.PageListProxyOperaterRequest; +import com.evotech.hd.resource.service.ProxyOperaterService; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; + +@Tag(name = "运营商") +@ApiSupport(order = 107) +@RestController +@RequestMapping("/proxyoperater") +public class ProxyOperaterController { + + @Resource + private ProxyOperaterService proxyOperaterService; + + + @Operation(summary = "增加") + @PostMapping("/add") + @ApiOperationSupport(order = 1) + public Result add(@Valid @ParameterObject ProxyOperater po) { + return proxyOperaterService.add(po); + } + + @Operation(summary = "删除") + @PostMapping("/del") + @ApiOperationSupport(order = 2) + public Result delete(Integer id) { + return proxyOperaterService.delete(id); + } + + @Operation(summary = "修改") + @PostMapping({"/update"}) + @ApiOperationSupport(order = 3) + public Result update(@ParameterObject ProxyOperater po) { + return proxyOperaterService.update(po); + } + + @Operation(summary = "查询") + @GetMapping("/list") + @ApiOperationSupport(order = 4) + public Result> list(@ParameterObject PageListProxyOperaterRequest plpor) { + return proxyOperaterService.list(plpor); + } + + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/controller/RoleController.java b/resource-server/src/main/java/com/evotech/hd/resource/controller/RoleController.java new file mode 100644 index 0000000..a3179a7 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/controller/RoleController.java @@ -0,0 +1,92 @@ +package com.evotech.hd.resource.controller; + +import java.util.List; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.auth.AuthRole; +import com.evotech.hd.common.core.entity.resource.auth.AuthRoleResource; +import com.evotech.hd.resource.entity.request.DelAddRoleSourceRequest; +import com.evotech.hd.resource.service.RoleService; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; + +@Tag(name = "角色管理") +@RestController +@RequestMapping("/role") +@ApiSupport(order = 102) +public class RoleController { + + @Resource + private RoleService roleService; + + + @Operation(summary = "增加") + @PostMapping("/add") + @ApiOperationSupport(order = 1) + public Result add(@Valid @ParameterObject AuthRole r) { + return roleService.add(r); + } + + @Operation(summary = "删除") + @PostMapping("/del") + @ApiOperationSupport(order = 2) + public Result delete(Integer rid) { + return roleService.delete(rid); + } + + @Operation(summary = "修改") + @PostMapping({"/update"}) + @ApiOperationSupport(order = 3) + public Result update(@ParameterObject AuthRole r) { + return roleService.update(r); + } + + @Operation(summary = "查询") + @GetMapping("/list") + @ApiOperationSupport(order = 4) + public Result> list(String userId) { + return roleService.list(userId); + } + + @Operation(summary = "角色增量增加资源权限:系统/菜单/按钮") + @PostMapping("/rolesource") + @ApiOperationSupport(order = 5) + public Result addRoleSource(@Valid @RequestBody List list) { + return roleService.addRoleSource(list); + } + + + @Operation(summary = "查询角色资源") + @PostMapping("/listrolesource") + @ApiOperationSupport(order = 7) + public Result> listRoleSource(String rcode, String resourceType) { + return roleService.listRoleSource(rcode, resourceType); + } + + @Operation(summary = "删除角色资源") + @PostMapping("/delrolesource") + @ApiOperationSupport(order = 9) + public Result delRoleSource(String ids) { + return roleService.delRoleSource(ids); + } + + @Operation(summary = "全量新增资源权限") + @PostMapping("/deladdrolesource") + @ApiOperationSupport(order = 10) + public Result delAddRoleSource(@ParameterObject DelAddRoleSourceRequest darsr) { + return roleService.delAddRoleSource(darsr); + } + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/controller/StationTypeController.java b/resource-server/src/main/java/com/evotech/hd/resource/controller/StationTypeController.java new file mode 100644 index 0000000..e047e00 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/controller/StationTypeController.java @@ -0,0 +1,62 @@ +package com.evotech.hd.resource.controller; + +import java.util.List; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.common.core.entity.BasePageRequest; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.resource.entity.StationType; +import com.evotech.hd.resource.service.StationTypeService; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; + +@Tag(name = "换电站型号") +@RestController +@RequestMapping("/stationtype") +@ApiSupport(order = 128) +public class StationTypeController { + + @Resource + private StationTypeService stationTypeService; + + + @Operation(summary = "增加类型") + @PostMapping("/add") + @ApiOperationSupport(order = 1) + public Result add(@Valid @ParameterObject StationType st) { + return stationTypeService.add(st); + } + + @Operation(summary = "删除类型") + @PostMapping("/del") + @ApiOperationSupport(order = 2) + public Result delete(@NotNull Integer id) { + return stationTypeService.delete(id); + } + + @Operation(summary = "修改类型") + @PostMapping({"/update"}) + @ApiOperationSupport(order = 3) + public Result update(@ParameterObject StationType st) { + return stationTypeService.update(st); + } + + @Operation(summary = "查询类型") + @GetMapping("/list") + @ApiOperationSupport(order = 4) + public Result> list(@Valid @ParameterObject BasePageRequest bpr) { + return stationTypeService.list(bpr); + } + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/controller/SystemManagerController.java b/resource-server/src/main/java/com/evotech/hd/resource/controller/SystemManagerController.java new file mode 100644 index 0000000..e585e05 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/controller/SystemManagerController.java @@ -0,0 +1,46 @@ +package com.evotech.hd.resource.controller; + +import java.util.List; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.resource.entity.SystemManager; +import com.evotech.hd.resource.service.SystemManagerService; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.github.xiaoymin.knife4j.annotations.ApiSupport; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; + +@Tag(name = "系统管理方") +@RestController +@RequestMapping("/system/manager") +@ApiSupport(order = 83) +public class SystemManagerController { + + + @Resource + private SystemManagerService systemManagerService; + + @Operation(summary = "查询", description = "查询") + @GetMapping("/list") + @ApiOperationSupport(order = 1) + public Result> listSystemManager() { + return systemManagerService.listSystemManager(); + } + + @Operation(summary = "修改") + @PostMapping("/update") + @ApiOperationSupport(order = 2) + public Result update(@ParameterObject SystemManager sm) { + return systemManagerService.update(sm); + } + + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/dao/BatteryTypeDao.java b/resource-server/src/main/java/com/evotech/hd/resource/dao/BatteryTypeDao.java new file mode 100644 index 0000000..cc714c9 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/dao/BatteryTypeDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.resource.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.resource.entity.BatteryType; + +/** + * @author zrb + * @since 2024-11-09 + */ +public interface BatteryTypeDao extends BaseMapper { + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/dao/CarTypeDao.java b/resource-server/src/main/java/com/evotech/hd/resource/dao/CarTypeDao.java new file mode 100644 index 0000000..7aef5e5 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/dao/CarTypeDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.resource.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.resource.entity.CarType; + +/** + * @author zrb + * @since 2024-11-09 + */ +public interface CarTypeDao extends BaseMapper { + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/dao/CompanyDao.java b/resource-server/src/main/java/com/evotech/hd/resource/dao/CompanyDao.java new file mode 100644 index 0000000..ccb3e73 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/dao/CompanyDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.resource.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.resource.entity.Company; + +/** + * @author zrb + * @since 2024-11-20 + */ +public interface CompanyDao extends BaseMapper { + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/dao/LogLoginDao.java b/resource-server/src/main/java/com/evotech/hd/resource/dao/LogLoginDao.java new file mode 100644 index 0000000..4b218f8 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/dao/LogLoginDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.resource.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.resource.LogLogin; + +/** + * @author zrb + * @date 2024年9月6日08:41:03 + */ +public interface LogLoginDao extends BaseMapper { + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/dao/LogUploadDao.java b/resource-server/src/main/java/com/evotech/hd/resource/dao/LogUploadDao.java new file mode 100644 index 0000000..00de185 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/dao/LogUploadDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.resource.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.resource.LogUpload; + +/** + * @author zrb + * @since 2024-11-01 + */ +public interface LogUploadDao extends BaseMapper { + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/dao/StationTypeDao.java b/resource-server/src/main/java/com/evotech/hd/resource/dao/StationTypeDao.java new file mode 100644 index 0000000..2a59bd5 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/dao/StationTypeDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.resource.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.resource.entity.StationType; + +/** + * @author zrb + * @since 2024-11-09 + */ +public interface StationTypeDao extends BaseMapper { + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/dao/SystemManagerDao.java b/resource-server/src/main/java/com/evotech/hd/resource/dao/SystemManagerDao.java new file mode 100644 index 0000000..73154d7 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/dao/SystemManagerDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.resource.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.resource.entity.SystemManager; + +/** + * @author zrb + * @since 2024-11-12 + */ +public interface SystemManagerDao extends BaseMapper { + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/dao/UploadFileDao.java b/resource-server/src/main/java/com/evotech/hd/resource/dao/UploadFileDao.java new file mode 100644 index 0000000..6ff728a --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/dao/UploadFileDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.resource.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.entity.resource.UploadFile; + +/** + * @author zrb + * @since 2024-11-01 + */ +public interface UploadFileDao extends BaseMapper { + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/entity/BatteryType.java b/resource-server/src/main/java/com/evotech/hd/resource/entity/BatteryType.java new file mode 100644 index 0000000..f05a931 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/entity/BatteryType.java @@ -0,0 +1,82 @@ +package com.evotech.hd.resource.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-11-09 + */ +@Getter +@Setter +@TableName("yt_d_battery_type") +@Schema(name = "电池型号表") +public class BatteryType implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + @Schema(description = "ID", hidden = true) + private Integer pkId; + + @Schema(description = "型号名称", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "型号名称不能为空") + private String typeName; + + @Schema(description = "型号编码", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "型号编码不能为空") + private String typeCode; + + @Schema(description = "电芯厂商") + private String batteryCellManuafactory; + + @Schema(description = "电池包厂商") + private String batteryManuafactory; + + @Schema(description = "电池材料:1-三元铁锂,2-磷酸铁锂") + private Integer material; + + @Schema(description = "连接方式") + private String connectionMode; + + @Schema(description = "标称容量,单位千瓦时kWh") + private Double capacity; + + @Schema(description = "标称电压,单位伏特V") + private Double voltage; + + @Schema(description = "重量,单位克") + private Integer weight; + + @Schema(description = "尺寸,长宽高") + private String size; + + @Schema(description = "创建人", hidden = true) + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/entity/CarType.java b/resource-server/src/main/java/com/evotech/hd/resource/entity/CarType.java new file mode 100644 index 0000000..cf788d4 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/entity/CarType.java @@ -0,0 +1,64 @@ +package com.evotech.hd.resource.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-11-09 + */ +@Getter +@Setter +@TableName("yt_d_car_type") +@Schema(name = "车辆类型") +public class CarType implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + @Schema(description = "ID", hidden = true) + private Integer pkId; + + @Schema(description = "类型名称", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "类型名称不能为空") + private String typeName; + + @Schema(description = "型号编码", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "型号编码不能为空") + private String typeCode; + + @Schema(description = "车辆厂商") + private String manufacturer; + + @Schema(description = "公告号") + private String announceNum; + + @Schema(description = "创建人", hidden = true) + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/entity/Company.java b/resource-server/src/main/java/com/evotech/hd/resource/entity/Company.java new file mode 100644 index 0000000..bcc503b --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/entity/Company.java @@ -0,0 +1,97 @@ +package com.evotech.hd.resource.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-11-20 + */ +@Getter +@Setter +@TableName("yt_t_company") +@Schema(name = "公司客户信息表") +public class Company implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + @Schema(description = "ID", hidden = true) + private Integer pkId; + + @Schema(description = "区划名称", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "区划名称不能为空") + private String division; + + @Schema(description = "区划编码", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "区划编码不能为空") + private String divisionNo; + + @Schema(description = "公司名称", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "公司名称不能为空") + private String cname; + + @Schema(description = "组织机构代码", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "组织机构代码不能为空") + private String ccode; + + @Schema(description = "logo地址") + private String logo; + + @Schema(description = "地址") + private String address; + + @Schema(description = "地址-省") + private String addressProvince; + + @Schema(description = "地址-市") + private String addressCity; + + @Schema(description = "地址-区县") + private String addressArea; + + @Schema(description = "联系人") + private String contacts; + + @Schema(description = "联系电话") + private String phone; + + @Schema(description = "状态:1-启用,0-禁用") + private Integer status; + + @Schema(description = "删除标识:1-已删除,0-未删除") + private Integer delFlag; + + @Schema(description = "账户余额") + private BigDecimal accountBalance; + + @Schema(description = "创建人", hidden = true) + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/entity/DictInfo.java b/resource-server/src/main/java/com/evotech/hd/resource/entity/DictInfo.java new file mode 100644 index 0000000..a41588d --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/entity/DictInfo.java @@ -0,0 +1,28 @@ +package com.evotech.hd.resource.entity; + +import java.io.Serializable; +import java.util.List; + +import com.evotech.hd.common.core.entity.resource.dict.Dict; + +import lombok.Data; +import lombok.EqualsAndHashCode; + + +/** + * @author zrb + * @date 2024年9月5日09:54:33 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class DictInfo implements Serializable { + + private static final long serialVersionUID = 1L; + + private String typeName; + + private String typeCode; + + private List dictList; + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/entity/StationType.java b/resource-server/src/main/java/com/evotech/hd/resource/entity/StationType.java new file mode 100644 index 0000000..6f1946c --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/entity/StationType.java @@ -0,0 +1,69 @@ +package com.evotech.hd.resource.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-11-09 + */ +@Getter +@Setter +@TableName("yt_d_station_type") +@Schema(name = "换电站型号") +public class StationType implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + @Schema(description = "ID", hidden = true) + private Integer pkId; + + @Schema(description = "型号名称", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "型号名称不能为空") + private String name; + + @Schema(description = "仓位数量下限") + private Integer dccNumMin; + + @Schema(description = "仓位数量上限") + private Integer dccNumMax; + + @Schema(description = "服务能力") + private String serviceCapability; + + @Schema(description = "充电机功率") + private String chargerPower; + + @Schema(description = "自动化级别:1-无人值守,2-有人值守") + private Integer autoLevel; + + @Schema(description = "创建人", hidden = true) + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/entity/SystemManager.java b/resource-server/src/main/java/com/evotech/hd/resource/entity/SystemManager.java new file mode 100644 index 0000000..1956cef --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/entity/SystemManager.java @@ -0,0 +1,96 @@ +package com.evotech.hd.resource.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-11-12 + */ +@Getter +@Setter +@TableName("yt_t_system_manager") +@Schema(name = "系统管理方") +public class SystemManager implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + @Schema(description = "ID", hidden = true) + private Integer pkId; + + @Schema(description = "区划名称", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "区划名称不能为空") + private String division; + + @Schema(description = "区划编码", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "区划编码不能为空") + private String divisionNo; + + @Schema(description = "管理方名称", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "管理方名称不能为空") + private String name; + + @Schema(description = "组织机构代码", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "组织机构代码不能为空") + private String code; + + @Schema(description = "logo地址") + private String logo; + + @Schema(description = "地址") + private String address; + + @Schema(description = "地址-省") + private String addressProvince; + + @Schema(description = "地址-市") + private String addressCity; + + @Schema(description = "地址-区县") + private String addressArea; + + @Schema(description = "联系人") + private String contacts; + + @Schema(description = "联系电话") + private String phone; + + @Schema(description = "开户行名称") + private String bankName; + + @Schema(description = "银行账户") + private String bankAccount; + + @Schema(description = "微信支付商户号") + private String wechatPayMchid; + + @Schema(description = "创建人", hidden = true) + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/entity/request/DelAddRoleSourceRequest.java b/resource-server/src/main/java/com/evotech/hd/resource/entity/request/DelAddRoleSourceRequest.java new file mode 100644 index 0000000..e81c429 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/entity/request/DelAddRoleSourceRequest.java @@ -0,0 +1,21 @@ +package com.evotech.hd.resource.entity.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +@Data +public class DelAddRoleSourceRequest { + + @Schema(description = "角色编码", requiredMode = RequiredMode.REQUIRED) + @NotBlank + private String rcode; + + @Schema(description = "类型,不同类型之间用';'隔开") + private String types; + + @Schema(description = "资源ID。同一类型之间用','隔开,不同类型之间用';'隔开,与type对应") + private String sourceIds; + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/entity/request/ListAdmdvsRequest.java b/resource-server/src/main/java/com/evotech/hd/resource/entity/request/ListAdmdvsRequest.java new file mode 100644 index 0000000..a57eaa3 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/entity/request/ListAdmdvsRequest.java @@ -0,0 +1,16 @@ +package com.evotech.hd.resource.entity.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class ListAdmdvsRequest { + + private String admdvsNo; + private String admdvsName; + private Integer level; + + @Schema(description = "是否返回树,1-是,0-否", example = "1") + private Integer isTree = 1; + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/entity/request/ListDictTypeRequest.java b/resource-server/src/main/java/com/evotech/hd/resource/entity/request/ListDictTypeRequest.java new file mode 100644 index 0000000..9db5322 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/entity/request/ListDictTypeRequest.java @@ -0,0 +1,19 @@ +package com.evotech.hd.resource.entity.request; + +import com.evotech.hd.common.core.entity.BasePageRequest; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@Schema(name = "字典类型请求参数") +@EqualsAndHashCode(callSuper=false) +public class ListDictTypeRequest extends BasePageRequest { + + @Schema(description = "类型名称") + private String typeName; + + @Schema(description = "类型编码") + private String typeCode; +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/entity/request/ListFileRequest.java b/resource-server/src/main/java/com/evotech/hd/resource/entity/request/ListFileRequest.java new file mode 100644 index 0000000..bb6d73f --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/entity/request/ListFileRequest.java @@ -0,0 +1,28 @@ +package com.evotech.hd.resource.entity.request; + +import com.evotech.hd.common.core.entity.BasePageRequest; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + + +@Data +@EqualsAndHashCode(callSuper=false) +@Schema(name = "查询文件请求参数") +public class ListFileRequest extends BasePageRequest { + + @Schema(description = "公司编码") + private String ccode; + + @Schema(description = "运营商编码") + private String pocode; + + private String idStringList; + + private String uploadId; + + @Schema(description = "文件原名") + private String fileOriginalName; + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/entity/request/ListUserRequest.java b/resource-server/src/main/java/com/evotech/hd/resource/entity/request/ListUserRequest.java new file mode 100644 index 0000000..9ee9eda --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/entity/request/ListUserRequest.java @@ -0,0 +1,27 @@ +package com.evotech.hd.resource.entity.request; + +import com.evotech.hd.common.core.entity.BasePageRequest; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = false) +public class ListUserRequest extends BasePageRequest { + + private String uid; + + @Schema(description = "账号") + private String uname; + + @Schema(description = "关联方代码") + private String typeRelateCode; + + @Schema(description = "姓名") + private String name; + + @Schema(description = "手机") + private String phone; + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/entity/request/PageListProxyOperaterRequest.java b/resource-server/src/main/java/com/evotech/hd/resource/entity/request/PageListProxyOperaterRequest.java new file mode 100644 index 0000000..6493a13 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/entity/request/PageListProxyOperaterRequest.java @@ -0,0 +1,26 @@ +package com.evotech.hd.resource.entity.request; + +import com.evotech.hd.common.core.entity.BasePageRequest; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@Schema(name = "查询运营商请求参数") +@EqualsAndHashCode(callSuper=false) +public class PageListProxyOperaterRequest extends BasePageRequest { + + @Schema(description = "区划编码") + private String divisionNo; + + @Schema(description = "运营商名称") + private String poname; + + @Schema(description = "运营商组织机构代码") + private String pocode; + + @Schema(description = "状态:1-启用,0-禁用") + private Integer status; + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/AdmdvsInfoService.java b/resource-server/src/main/java/com/evotech/hd/resource/service/AdmdvsInfoService.java new file mode 100644 index 0000000..9186dc7 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/AdmdvsInfoService.java @@ -0,0 +1,13 @@ +package com.evotech.hd.resource.service; + +import java.util.List; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.dict.AdmdvsInfo; +import com.evotech.hd.resource.entity.request.ListAdmdvsRequest; + +public interface AdmdvsInfoService { + + public Result> treeListAdmdvs(ListAdmdvsRequest lar); + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/AuthUserService.java b/resource-server/src/main/java/com/evotech/hd/resource/service/AuthUserService.java new file mode 100644 index 0000000..66614f8 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/AuthUserService.java @@ -0,0 +1,26 @@ +package com.evotech.hd.resource.service; + +import java.util.List; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.auth.AuthUser; +import com.evotech.hd.common.core.entity.resource.auth.AuthUserRole; +import com.evotech.hd.resource.entity.request.ListUserRequest; + +public interface AuthUserService { + + public Result userByName(String uname); + + public Result add(AuthUser u); + + public Result delete(String uid); + + public Result update(AuthUser u); + + public Result> list(ListUserRequest lur); + + public Result addUserRole(AuthUserRole aur); + + public Result deleteUserRole(String uid, String rid); + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/BatteryTypeService.java b/resource-server/src/main/java/com/evotech/hd/resource/service/BatteryTypeService.java new file mode 100644 index 0000000..f7e3dcd --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/BatteryTypeService.java @@ -0,0 +1,19 @@ +package com.evotech.hd.resource.service; + +import java.util.List; + +import com.evotech.hd.common.core.entity.BasePageRequest; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.resource.entity.BatteryType; + +public interface BatteryTypeService { + + public Result add(BatteryType bt); + + public Result delete(Integer id); + + public Result update(BatteryType bt); + + public Result> list(BasePageRequest bpr); + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/CarTypeService.java b/resource-server/src/main/java/com/evotech/hd/resource/service/CarTypeService.java new file mode 100644 index 0000000..284ae93 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/CarTypeService.java @@ -0,0 +1,19 @@ +package com.evotech.hd.resource.service; + +import java.util.List; + +import com.evotech.hd.common.core.entity.BasePageRequest; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.resource.entity.CarType; + +public interface CarTypeService { + + public Result add(CarType ct); + + public Result delete(Integer id); + + public Result update(CarType ct); + + public Result> list(BasePageRequest bpr); + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/CompanyService.java b/resource-server/src/main/java/com/evotech/hd/resource/service/CompanyService.java new file mode 100644 index 0000000..752f34f --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/CompanyService.java @@ -0,0 +1,19 @@ +package com.evotech.hd.resource.service; + +import java.util.List; + +import com.evotech.hd.common.core.entity.BasePageRequest; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.resource.entity.Company; + +public interface CompanyService { + + public Result add(Company company); + + public Result delete(Integer id); + + public Result update(Company company); + + public Result> list(BasePageRequest bpr); + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/DictService.java b/resource-server/src/main/java/com/evotech/hd/resource/service/DictService.java new file mode 100644 index 0000000..3528761 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/DictService.java @@ -0,0 +1,32 @@ +package com.evotech.hd.resource.service; + +import java.util.List; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.request.ListDictRequest; +import com.evotech.hd.common.core.entity.resource.dict.Dict; +import com.evotech.hd.common.core.entity.resource.dict.DictType; +import com.evotech.hd.resource.entity.DictInfo; +import com.evotech.hd.resource.entity.request.ListDictTypeRequest; + +public interface DictService { + + public Result addType(DictType dt); + + public Result deleteType(Integer typeId); + + public Result updateType(DictType dt); + + public Result> listType(ListDictTypeRequest ldtr); + + public Result addDict(Dict d); + + public Result deleteDict(Integer dictId); + + public Result updateDict(Dict d); + + public Result> listDict(ListDictRequest listDictRequest); + + public Result> listDictInfo(String typeCode); + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/FileUpLoadService.java b/resource-server/src/main/java/com/evotech/hd/resource/service/FileUpLoadService.java new file mode 100644 index 0000000..d252eaa --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/FileUpLoadService.java @@ -0,0 +1,23 @@ +package com.evotech.hd.resource.service; + +import java.util.List; + +import org.springframework.web.multipart.MultipartFile; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.LogUpload; +import com.evotech.hd.common.core.entity.resource.UploadFile; +import com.evotech.hd.resource.entity.request.ListFileRequest; + +public interface FileUpLoadService { + + public Result> listFile(ListFileRequest lfr); + + public Result filesUpLoad(MultipartFile[] fileArr, String ccode, String pocode, String type, String user, Boolean isAlterRandomName); + + public Result> list(ListFileRequest lfr); + + public Result delete(String filePath, Integer fileId, String logId); + + public Result fileUpLoad(MultipartFile file, String user, Boolean isAlterRandomName); +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/LogLoginService.java b/resource-server/src/main/java/com/evotech/hd/resource/service/LogLoginService.java new file mode 100644 index 0000000..4358301 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/LogLoginService.java @@ -0,0 +1,15 @@ +package com.evotech.hd.resource.service; + +import java.util.List; + +import com.evotech.hd.common.core.entity.BasePageRequest; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.LogLogin; + +public interface LogLoginService { + + public Result add(LogLogin log); + + public Result> list(BasePageRequest bpr); + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/LoginInfoService.java b/resource-server/src/main/java/com/evotech/hd/resource/service/LoginInfoService.java new file mode 100644 index 0000000..484aaa8 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/LoginInfoService.java @@ -0,0 +1,67 @@ +package com.evotech.hd.resource.service; + +import java.util.List; + +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.evotech.hd.common.core.constant.HDConstant; +import com.evotech.hd.common.core.dao.resource.auth.AuthPermissionDao; +import com.evotech.hd.common.core.dao.resource.auth.AuthRoleResourceDao; +import com.evotech.hd.common.core.dao.resource.auth.AuthUserDao; +import com.evotech.hd.common.core.entity.LoginCacheInfo; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.auth.AuthPermission; +import com.evotech.hd.common.core.entity.resource.auth.AuthRole; +import com.evotech.hd.common.core.entity.resource.auth.AuthRoleResource; +import com.evotech.hd.common.core.entity.resource.auth.AuthUser; +import com.evotech.hd.common.core.enums.CodeMsg; + +import cn.hutool.json.JSONArray; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import jakarta.annotation.Resource; + +@Service +public class LoginInfoService { + + @Resource + private AuthUserDao userDao; + @Resource + private RoleService roleService; + @Resource + private AuthPermissionDao permissionDao; + @Resource + private AuthRoleResourceDao authRoleResourceDao; + + + + public Result getUserInfo(String uid) { + LoginCacheInfo lci = new LoginCacheInfo(); + AuthUser user = userDao.selectOne(new QueryWrapper().eq("uid", uid)); + lci.setUser(user); + + Result> roleRes = roleService.list(uid); + if (!CodeMsg.SUCCESS.getCode().equals(roleRes.getCode())) { + return new Result().error(roleRes.getMsg()); + } + JSONObject jo = JSONUtil.parseObj(roleRes); + JSONArray ja = jo.getJSONArray("data"); + List roleList = JSONUtil.toList(ja, AuthRole.class); + lci.setRoleList(roleList); + + List rcodeList = roleList.stream().map(i -> i.getRcode()).toList(); + if (rcodeList.contains(HDConstant.SYSTEM_MANAGER_ROLE_CODE)) { + + } else { + List roleResourceList = authRoleResourceDao.selectList(new QueryWrapper() + .eq("resource_type", HDConstant.RESOURCE_TYPE_PERM).in("rcode", rcodeList)); + List permIdList = roleResourceList.stream().map(i -> i.getResourceId()).toList(); + List permList = permissionDao.selectList(new QueryWrapper().in("pk_id", permIdList)); + lci.setPermissionList(permList); + } + return new Result().success(lci); + + } + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/MenuService.java b/resource-server/src/main/java/com/evotech/hd/resource/service/MenuService.java new file mode 100644 index 0000000..bb95386 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/MenuService.java @@ -0,0 +1,18 @@ +package com.evotech.hd.resource.service; + +import java.util.List; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.auth.AuthMenu; + +public interface MenuService { + + public Result add(AuthMenu menu); + + public Result delete(Integer menuId); + + public Result update(AuthMenu menu); + + public Result> treeMenu(); + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/PermissionService.java b/resource-server/src/main/java/com/evotech/hd/resource/service/PermissionService.java new file mode 100644 index 0000000..278b1ee --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/PermissionService.java @@ -0,0 +1,18 @@ +package com.evotech.hd.resource.service; + +import java.util.List; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.auth.AuthPermission; + +public interface PermissionService { + + public Result add(AuthPermission perm); + + public Result delete(Integer id); + + public Result update(AuthPermission perm); + + public Result> list(Integer menuId); + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/ProxyOperaterService.java b/resource-server/src/main/java/com/evotech/hd/resource/service/ProxyOperaterService.java new file mode 100644 index 0000000..f2dbdfb --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/ProxyOperaterService.java @@ -0,0 +1,19 @@ +package com.evotech.hd.resource.service; + +import java.util.List; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.ProxyOperater; +import com.evotech.hd.resource.entity.request.PageListProxyOperaterRequest; + +public interface ProxyOperaterService { + + public Result add(ProxyOperater po); + + public Result delete(Integer id); + + public Result update(ProxyOperater po); + + public Result> list(PageListProxyOperaterRequest plpor); + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/RoleService.java b/resource-server/src/main/java/com/evotech/hd/resource/service/RoleService.java new file mode 100644 index 0000000..6ccd232 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/RoleService.java @@ -0,0 +1,28 @@ +package com.evotech.hd.resource.service; + +import java.util.List; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.auth.AuthRole; +import com.evotech.hd.common.core.entity.resource.auth.AuthRoleResource; +import com.evotech.hd.resource.entity.request.DelAddRoleSourceRequest; + +public interface RoleService { + + public Result add(AuthRole r); + + public Result delete(Integer rid); + + public Result update(AuthRole r); + + public Result> list(String userId); + + public Result addRoleSource(List list); + + public Result> listRoleSource(String rcode, String resourceType); + + public Result delRoleSource(String ids); + + public Result delAddRoleSource(DelAddRoleSourceRequest darsr); + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/StationTypeService.java b/resource-server/src/main/java/com/evotech/hd/resource/service/StationTypeService.java new file mode 100644 index 0000000..ae1c4c6 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/StationTypeService.java @@ -0,0 +1,20 @@ +package com.evotech.hd.resource.service; + +import java.util.List; + +import com.evotech.hd.common.core.entity.BasePageRequest; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.resource.entity.StationType; + +public interface StationTypeService { + + public Result add(StationType st); + + public Result delete(Integer id); + + public Result update(StationType st); + + public Result> list(BasePageRequest bpr); + + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/SystemManagerService.java b/resource-server/src/main/java/com/evotech/hd/resource/service/SystemManagerService.java new file mode 100644 index 0000000..bb1433a --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/SystemManagerService.java @@ -0,0 +1,14 @@ +package com.evotech.hd.resource.service; + +import java.util.List; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.resource.entity.SystemManager; + +public interface SystemManagerService { + + public Result> listSystemManager(); + + public Result update(SystemManager sm); + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/impl/AdmdvsInfoServiceImpl.java b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/AdmdvsInfoServiceImpl.java new file mode 100644 index 0000000..a41ed80 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/AdmdvsInfoServiceImpl.java @@ -0,0 +1,54 @@ +package com.evotech.hd.resource.service.impl; + +import java.util.List; + +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.evotech.hd.common.core.dao.resource.dict.AdmdvsInfoDao; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.dict.AdmdvsInfo; +import com.evotech.hd.common.core.enums.CodeMsg; +import com.evotech.hd.resource.entity.request.ListAdmdvsRequest; +import com.evotech.hd.resource.service.AdmdvsInfoService; +import com.evotech.hd.resource.utils.AdmdvsUtil; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import jakarta.annotation.Resource; + +@Service +public class AdmdvsInfoServiceImpl implements AdmdvsInfoService { + + @Resource + private AdmdvsInfoDao admdvsInfoDao; + + @Override + public Result> treeListAdmdvs(ListAdmdvsRequest lar) { + List list = null; + if (lar.getIsTree() == 1) { + list = admdvsInfoDao.selectList(new QueryWrapper()); + if (StrUtil.isNotBlank(lar.getAdmdvsNo())) { + AdmdvsInfo rootAdmdvs = list.stream().filter(i -> lar.getAdmdvsNo().equals(i.getAdmdvsNo())).findFirst().orElse(null); + if (ObjectUtil.isNotEmpty(rootAdmdvs)) { + list = AdmdvsUtil.treeAdmdvsList(list, rootAdmdvs.getAdmdvsNo()); + } else { + new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + rootAdmdvs.setSubAdmdvsInfoList(list); + return new Result>().success(rootAdmdvs); + } + list = AdmdvsUtil.treeAdmdvsList(list, "0"); + return new Result>().success(list); + } + list = admdvsInfoDao.selectList(new QueryWrapper() + .eq(StrUtil.isNotBlank(lar.getAdmdvsNo()), "admdvs_no", lar.getAdmdvsNo()) + .eq(lar.getLevel() != null, "level", lar.getLevel()) + .like(StrUtil.isNotBlank(lar.getAdmdvsName()), "admdvs_name", lar.getAdmdvsName())); + if (list.isEmpty()) { + new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(list); + } + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/impl/AuthUserServiceImpl.java b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/AuthUserServiceImpl.java new file mode 100644 index 0000000..027697f --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/AuthUserServiceImpl.java @@ -0,0 +1,132 @@ +package com.evotech.hd.resource.service.impl; + +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.evotech.hd.common.core.dao.resource.auth.AuthUserDao; +import com.evotech.hd.common.core.dao.resource.auth.AuthUserRoleDao; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.auth.AuthUser; +import com.evotech.hd.common.core.entity.resource.auth.AuthUserRole; +import com.evotech.hd.common.core.enums.CodeMsg; +import com.evotech.hd.common.core.utils.SnowflakeUtil; +import com.evotech.hd.resource.entity.request.ListUserRequest; +import com.evotech.hd.resource.service.AuthUserService; + +import cn.hutool.core.date.DateUtil; +import jakarta.annotation.Resource; + +@Service +public class AuthUserServiceImpl implements AuthUserService { + + @Resource + private AuthUserDao userDao; + @Resource + private AuthUserRoleDao authUserRoleDao; + + + @Override + public Result userByName(String userName) { + AuthUser user = userDao.selectOne(new QueryWrapper().eq("uname", userName)); + if (user == null) { + return new Result().error(CodeMsg.DATABASE_RESULT_NULL); + } + List roleList = authUserRoleDao.selectList(new QueryWrapper().eq("uid", user.getUid())); + String rcodes = roleList.stream().map(i -> i.getRcode()).collect(Collectors.joining(",")); + user.setRcodes(rcodes); + return new Result().success(user); + } + + @Override + public Result add(AuthUser u) { + boolean exists = userDao.exists(new QueryWrapper().eq("uname", u.getUname())); + if (exists) { + return new Result().error("账号已存在!"); + } + u.setUid(SnowflakeUtil.getIdStr()); + // 密码加密 + u.setPassword(new BCryptPasswordEncoder().encode(u.getPassword())); + // 新增账号设置过期时间默认1年 + Date d = new Date(); + u.setCtime(d); + u.setStatus(1); + u.setPasswordExpireTime(DateUtil.offsetMonth(d, 12)); + int n = userDao.insert(u); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加账号出错!"); + } + + @Override + @Transactional + public Result delete(String uid) { + AuthUser u = new AuthUser(); + u.setUid(uid); + int n = userDao.deleteById(u); + if (n == 1) { + // 删除账号关联角色信息 + deleteUserRole(uid, ""); + return new Result().success(n); + } + return new Result().error("删除账号出错!"); + } + + @Override + public Result update(AuthUser u) { + int n = userDao.updateById(u); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("更新账号失败!"); + } + + @Override + public Result> list(ListUserRequest lur) { + Page page = new Page<>(lur.getPageNo(), lur.getPageSize()); + page = userDao.selectPage(page, new QueryWrapper() + .eq(StringUtils.hasText(lur.getUid()), "uid", lur.getUid()) + .eq(StringUtils.hasText(lur.getUname()), "uname", lur.getUname()) + .eq(StringUtils.hasText(lur.getTypeRelateCode()), "typeRelateCode", lur.getTypeRelateCode()) + .eq(StringUtils.hasText(lur.getName()), "name", lur.getName()) + .eq(StringUtils.hasText(lur.getPhone()), "phone", lur.getPhone()) + ); + if (page.getRecords().isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(page); + } + + + @Override + public Result addUserRole(AuthUserRole aur) { + boolean exists = authUserRoleDao.exists(new QueryWrapper() + .eq("uid", aur.getUid()).eq("rcode", aur.getRcode())); + if (exists) { + return new Result().error("该用户已有此角色"); + } + aur.setCtime(new Date()); + int n = authUserRoleDao.insert(aur); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加用户角色失败!"); + } + + @Override + public Result deleteUserRole(String uid, String rid) { + int n = authUserRoleDao.delete(new QueryWrapper() + .eq("uid", uid).eq(StringUtils.hasText(rid), "rid", rid)); + + return new Result().success(n); + } + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/impl/BatteryTypeServiceImpl.java b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/BatteryTypeServiceImpl.java new file mode 100644 index 0000000..5d5c004 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/BatteryTypeServiceImpl.java @@ -0,0 +1,64 @@ +package com.evotech.hd.resource.service.impl; + +import java.util.Date; +import java.util.List; + +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.evotech.hd.common.core.entity.BasePageRequest; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.enums.CodeMsg; +import com.evotech.hd.resource.dao.BatteryTypeDao; +import com.evotech.hd.resource.entity.BatteryType; +import com.evotech.hd.resource.service.BatteryTypeService; + +import jakarta.annotation.Resource; + +@Service +public class BatteryTypeServiceImpl implements BatteryTypeService { + + + @Resource + private BatteryTypeDao batteryTypeDao; + + @Override + public Result add(BatteryType bt) { + bt.setCtime(new Date()); + int n = batteryTypeDao.insert(bt); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加类型出错!"); + } + + @Override + public Result delete(Integer id) { + int n = batteryTypeDao.deleteById(id); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("删除类型出错!"); + } + + @Override + public Result update(BatteryType bt) { + int n = batteryTypeDao.updateById(bt); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("更新类型失败!"); + } + + @Override + public Result> list(BasePageRequest bpr) { + Page page = new Page(bpr.getPageNo(), bpr.getPageSize()); + page = batteryTypeDao.selectPage(page, new QueryWrapper()); + if (page.getRecords().isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(page); + } + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/impl/CarTypeServiceImpl.java b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/CarTypeServiceImpl.java new file mode 100644 index 0000000..421340c --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/CarTypeServiceImpl.java @@ -0,0 +1,66 @@ +package com.evotech.hd.resource.service.impl; + +import java.util.Date; +import java.util.List; + +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.evotech.hd.common.core.entity.BasePageRequest; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.enums.CodeMsg; +import com.evotech.hd.resource.dao.CarTypeDao; +import com.evotech.hd.resource.entity.CarType; +import com.evotech.hd.resource.service.CarTypeService; + +import jakarta.annotation.Resource; + +@Service +public class CarTypeServiceImpl implements CarTypeService { + + @Resource + private CarTypeDao carTypeDao; + + @Override + public Result add(CarType ct) { + ct.setCtime(new Date()); + int n = carTypeDao.insert(ct); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加类型出错!"); + } + + @Override + public Result delete(Integer id) { + int n = carTypeDao.deleteById(id); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("删除类型出错!"); + } + + @Override + public Result update(CarType ct) { + int n = carTypeDao.updateById(ct); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("更新类型失败!"); + } + + @Override + public Result> list(BasePageRequest bpr) { + Page page = new Page(bpr.getPageNo(), bpr.getPageSize()); + page = carTypeDao.selectPage(page, new QueryWrapper()); + if (page.getRecords().isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(page); + } + + + + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/impl/CompanyServiceImpl.java b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/CompanyServiceImpl.java new file mode 100644 index 0000000..d73f0ba --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/CompanyServiceImpl.java @@ -0,0 +1,68 @@ +package com.evotech.hd.resource.service.impl; + +import java.util.Date; +import java.util.List; + +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.evotech.hd.common.core.entity.BasePageRequest; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.enums.CodeMsg; +import com.evotech.hd.resource.dao.CompanyDao; +import com.evotech.hd.resource.entity.Company; +import com.evotech.hd.resource.service.CompanyService; + +import jakarta.annotation.Resource; + + +@Service +public class CompanyServiceImpl implements CompanyService { + + + @Resource + private CompanyDao companyDao; + + @Override + public Result add(Company company) { + company.setCtime(new Date()); + int n = companyDao.insert(company); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加公司出错!"); + } + + @Override + public Result delete(Integer id) { + Company company = new Company(); + company.setPkId(id); + company.setDelFlag(1); + int n = companyDao.updateById(company); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("删除公司出错!"); + } + + @Override + public Result update(Company company) { + int n = companyDao.updateById(company); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("更新公司失败!"); + } + + @Override + public Result> list(BasePageRequest bpr) { + Page page = new Page(bpr.getPageNo(), bpr.getPageSize()); + page = companyDao.selectPage(page, new QueryWrapper().eq("del_flag", 0)); + if (page.getRecords().isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(page); + } + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/impl/DictServiceImpl.java b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/DictServiceImpl.java new file mode 100644 index 0000000..71691ff --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/DictServiceImpl.java @@ -0,0 +1,130 @@ +package com.evotech.hd.resource.service.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.evotech.hd.common.core.dao.resource.dict.DictDao; +import com.evotech.hd.common.core.dao.resource.dict.DictTypeDao; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.request.ListDictRequest; +import com.evotech.hd.common.core.entity.resource.dict.Dict; +import com.evotech.hd.common.core.entity.resource.dict.DictType; +import com.evotech.hd.common.core.enums.CodeMsg; +import com.evotech.hd.resource.entity.DictInfo; +import com.evotech.hd.resource.entity.request.ListDictTypeRequest; +import com.evotech.hd.resource.service.DictService; + +import jakarta.annotation.Resource; + +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; + +@Service +public class DictServiceImpl implements DictService { + + @Resource + private DictTypeDao dictTypeDao; + + @Resource + private DictDao dictDao; + + @Override + public Result addType(DictType dt) { + List list = dictTypeDao.selectList(new QueryWrapper().eq("type_code", dt.getTypeCode())); + if (!list.isEmpty()) { + return new Result().error("类型编码已存在"); + } + dt.setCtime(new Date()); + int n = dictTypeDao.insert(dt); + return new Result().success(n); + } + + @Override + public Result deleteType(Integer typeId) { + DictType dt = new DictType(); + dt.setPkId(typeId); + int n = dictTypeDao.deleteById(dt); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("删除失败"); + } + + @Override + public Result updateType(DictType dt) { + int n = dictTypeDao.updateById(dt); + if (n == 1) { + return new Result().success(n); + } + return new Result().error(""); + } + + @Override + public Result> listType(ListDictTypeRequest ltr) { + Page page = new Page<>(ltr.getPageNo(), ltr.getPageSize()); + page = dictTypeDao.selectPage(page, new QueryWrapper() + .eq(StringUtils.hasText(ltr.getTypeName()), "type_name", ltr.getTypeName()) + .eq(StringUtils.hasText(ltr.getTypeCode()), "type_code", ltr.getTypeCode())); + if (page.getRecords().isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(page); + } + + @Override + public Result addDict(Dict d) { + int n = dictDao.insert(d); + return new Result().success(n); + } + + @Override + public Result deleteDict(Integer dictId) { + Dict d = new Dict(); + d.setPkId(dictId); + int n = dictDao.deleteById(d); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("删除字典出错"); + } + + @Override + public Result> listDict(ListDictRequest ldr) { + List list = dictDao.listDict(ldr); + if (list.isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(list); + } + + @Override + public Result updateDict(Dict d) { + int n = dictDao.updateById(d); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("修改字典出错"); + } + + @Override + public Result> listDictInfo(String typeCode) { + List codeList = Arrays.asList(typeCode.split(",")); + List dictTypeList = dictTypeDao.selectList(new QueryWrapper().in("type_code", codeList)); + List list = new ArrayList<>(); + dictTypeList.forEach(i -> { + DictInfo di = new DictInfo(); + di.setTypeName(i.getTypeName()); + di.setTypeCode(i.getTypeCode()); + List dictList = dictDao.selectList(new QueryWrapper().eq("type_id", i.getPkId()).orderByAsc("sort")); + di.setDictList(dictList); + list.add(di); + }); + return new Result>().success(list); + } + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/impl/FileUpLoadServiceImpl.java b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/FileUpLoadServiceImpl.java new file mode 100644 index 0000000..fd5a789 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/FileUpLoadServiceImpl.java @@ -0,0 +1,194 @@ +package com.evotech.hd.resource.service.impl; + +import java.io.File; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.LogUpload; +import com.evotech.hd.common.core.entity.resource.UploadFile; +import com.evotech.hd.common.core.enums.CodeMsg; +import com.evotech.hd.common.core.utils.SnowflakeUtil; +import com.evotech.hd.resource.dao.LogUploadDao; +import com.evotech.hd.resource.dao.UploadFileDao; +import com.evotech.hd.resource.entity.request.ListFileRequest; +import com.evotech.hd.resource.service.FileUpLoadService; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import jakarta.annotation.Resource; + +@Service +public class FileUpLoadServiceImpl implements FileUpLoadService { + + @Resource + private UploadFileDao uploadFileDao; + @Resource + private LogUploadDao uploadLogDao; + + @Value("${yt.file.file-path}") + private String filePath; + @Value("${yt.file.file-domain}") + private String fileDomain; + + + + + @Override + public Result> listFile(ListFileRequest lfr) { + if (StrUtil.isBlank(lfr.getPocode()) || StrUtil.isBlank(lfr.getCcode())) { + return new Result>().error(CodeMsg.BUSSINESS_ERROR); + } + Page page = new Page(lfr.getPageNo(), lfr.getPageSize()); + QueryWrapper qw = new QueryWrapper(); + if (StrUtil.isNotBlank(lfr.getIdStringList())) { + qw.in("pk_id", Arrays.asList(lfr.getIdStringList().split(","))); + } + qw.like(StrUtil.isNotBlank(lfr.getFileOriginalName()), "file_original_name", lfr.getFileOriginalName()); + qw.eq(StrUtil.isNotBlank(lfr.getPocode()), "pocode", lfr.getPocode()); + qw.eq(StrUtil.isNotBlank(lfr.getCcode()), "ccode", lfr.getCcode()); + qw.eq(StrUtil.isNotBlank(lfr.getUploadId()), "upload_id", lfr.getUploadId()); + qw.orderByDesc("pk_id"); + page = uploadFileDao.selectPage(page, qw); + if (page.getRecords().isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(page); + } + + @Override + public Result filesUpLoad(MultipartFile[] fileArr, String ccode, String pocode, String type, String user, Boolean isAlterRandomName) { + Date d = new Date(); + String id = SnowflakeUtil.getIdStr(); + String path = filePath; + if (StrUtil.isNotBlank(pocode)) { + path += pocode + "/"; + } + if (StrUtil.isNotBlank(ccode)) { + path += ccode + "/"; + } + path += StrUtil.format("{}/", DateUtil.format(d, DatePattern.PURE_DATETIME_MS_PATTERN)); + + if (StrUtil.isNotBlank(type)) { + path += type + "/"; + } else { + path += "hd/"; + } + + for (MultipartFile file : fileArr) { + String pathName = path + file.getOriginalFilename(); + try { + fileUpLoad(file, pathName, id, ccode, pocode, type, user, isAlterRandomName); + } catch (Exception e) { + e.printStackTrace(); + addUploadLog(fileArr.length, ccode, pocode, type, user, d, id, 0, path); + throw new RuntimeException("文件上传出错:" + e.getMessage()); + } + } + + addUploadLog(fileArr.length, ccode, pocode, type, user, d, id, 1, path); + return new Result().success(id, fileArr.length); + } + + private void addUploadLog(Integer size, String ccode, String pocode, String type, String user, Date d, String id, Integer status, String filePath) { + LogUpload ul = new LogUpload(); + ul.setPkId(id); + ul.setAmount(size); + ul.setCtime(d); + ul.setStatus(status); + ul.setUser(user); + ul.setPocode(pocode); + ul.setCcode(ccode); + ul.setType(type); + ul.setFilePath(filePath); + uploadLogDao.insert(ul); + } + + + private String fileUpLoad(MultipartFile file, String pathName, String upload, String ccode, String pocode, String type, String user, Boolean isAlterRandomName) { + String fileOriginalName = file.getOriginalFilename(); + String fileType = FileUtil.extName(fileOriginalName); + String fileFinalName = ""; + if (isAlterRandomName) { + fileFinalName = IdUtil.fastSimpleUUID() + "." + fileType; + } + File newFile = new File(pathName); + if (!newFile.exists()) { + newFile.mkdir(); + } + try { + file.transferTo(newFile.getAbsoluteFile()); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("文件上传出错:" + fileOriginalName + " -- " + e.getMessage()); + } + String fileUrl = pathName.replace(filePath, fileDomain); + UploadFile uf = new UploadFile(); + uf.setCtime(new Date()); + uf.setFileFinalName(StrUtil.isBlank(fileFinalName)?null:fileFinalName); + uf.setFileOriginalName(fileOriginalName); + uf.setType(type); + uf.setFilePath(filePath); + uf.setFileSize(file.getSize()); + uf.setFileType(fileType); + uf.setFileUrl(fileUrl); + uf.setPathName(pathName); + uf.setUploadId(upload); + uf.setCcode(ccode); + uf.setPocode(pocode); + uf.setCreater(fileUrl); + uploadFileDao.insert(uf); + return fileUrl; + } + + @Override + public Result> list(ListFileRequest lfr) { + if (StrUtil.isBlank(lfr.getPocode()) || StrUtil.isBlank(lfr.getCcode())) { + return new Result>().error(CodeMsg.BUSSINESS_ERROR); + } + Page page = new Page(lfr.getPageNo(), lfr.getPageSize()); + page = uploadLogDao.selectPage(page, new QueryWrapper() + .eq(StrUtil.isNotBlank(lfr.getCcode()), "code", lfr.getCcode()) + .eq(StrUtil.isNotBlank(lfr.getPocode()), "pocode", lfr.getPocode()) + .orderByDesc("pk_id")); + if (page.getRecords().isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(page); + } + + @Override + public Result delete(String path, Integer fileId, String logId) { + FileUtil.del(path); + if (fileId != null) { + uploadFileDao.deleteById(fileId); + } + if (StrUtil.isNotBlank(logId)) { + uploadLogDao.deleteById(logId); + uploadFileDao.delete(new QueryWrapper().eq("upload_id", logId)); + } + return new Result().success("OK"); + } + + @Override + public Result fileUpLoad(MultipartFile file, String user, Boolean isAlterRandomName) { + Date d = new Date(); + String id = SnowflakeUtil.getIdStr(); + String path = filePath + "hd/"; + path += StrUtil.format("{}/h", DateUtil.format(d, DatePattern.PURE_DATETIME_MS_PATTERN)); + String pathName = path + file.getOriginalFilename(); + String url = fileUpLoad(file, pathName, id, "anonymous", "anonymous", "hd", user, isAlterRandomName); + return new Result().success(url); + } + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/impl/LogLoginServiceImpl.java b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/LogLoginServiceImpl.java new file mode 100644 index 0000000..cca84e0 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/LogLoginServiceImpl.java @@ -0,0 +1,42 @@ +package com.evotech.hd.resource.service.impl; + +import java.util.List; + +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.evotech.hd.common.core.entity.BasePageRequest; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.LogLogin; +import com.evotech.hd.common.core.enums.CodeMsg; +import com.evotech.hd.resource.dao.LogLoginDao; +import com.evotech.hd.resource.service.LogLoginService; + +import jakarta.annotation.Resource; + +@Service +public class LogLoginServiceImpl implements LogLoginService { + + @Resource + private LogLoginDao logLoginDao; + + @Override + public Result add(LogLogin log) { + int n = logLoginDao.insert(log); + return new Result().success(n); + } + + @Override + public Result> list(BasePageRequest bpr) { + Page page = new Page(bpr.getPageNo(), bpr.getPageSize()); + page = logLoginDao.selectPage(page, new QueryWrapper().orderByDesc("ctime")); + if (page.getRecords().isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(page); + } + + + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/impl/MenuServiceImpl.java b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/MenuServiceImpl.java new file mode 100644 index 0000000..73d3ced --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/MenuServiceImpl.java @@ -0,0 +1,97 @@ +package com.evotech.hd.resource.service.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.evotech.hd.common.core.constant.HDConstant; +import com.evotech.hd.common.core.dao.resource.auth.AuthMenuDao; +import com.evotech.hd.common.core.dao.resource.auth.AuthRoleResourceDao; +import com.evotech.hd.common.core.dao.resource.auth.AuthUserRoleDao; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.auth.AuthMenu; +import com.evotech.hd.common.core.entity.resource.auth.AuthRoleResource; +import com.evotech.hd.common.core.enums.CodeMsg; +import com.evotech.hd.resource.service.MenuService; +import com.evotech.hd.resource.utils.MenuUtil; + +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; + +@Service +public class MenuServiceImpl implements MenuService { + + @Resource + private AuthMenuDao authMenuDao; + @Resource + private AuthUserRoleDao authUserRoleDao; + @Resource + private AuthRoleResourceDao roleResourceDao; + @Resource + private HttpServletRequest request; + + + + + @Override + public Result add(AuthMenu menu) { + menu.setCtime(new Date()); + int n = authMenuDao.insert(menu); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加菜单出错!"); + } + + @Override + public Result delete(Integer menuId) { + int n = authMenuDao.deleteById(menuId); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("删除菜单出错!"); + } + + @Override + public Result update(AuthMenu menu) { + int n = authMenuDao.updateById(menu); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("更新菜单失败!"); + } + + @Override + public Result> treeMenu() { + // 1. 通过token 查看角色,若是系统管理员,返回所有 + String rcodes = request.getHeader("rcodes"); + if (!StringUtils.hasText(rcodes)) { + return new Result>().error("请求头权限验证出错"); + } + List menuList = new ArrayList<>(); + if (rcodes.contains(HDConstant.SYSTEM_MANAGER_ROLE_CODE)) { + menuList = authMenuDao.selectList(new QueryWrapper()); + } else { + List sourceList = roleResourceDao.selectList(new QueryWrapper() + .in("rcode", Arrays.asList(rcodes.split(","))) + .eq("resource_type", "MENU")); + if (sourceList.isEmpty()) { + return new Result>().error("账号角色未分配页面!"); + } + List sourceIdlist = sourceList.stream().map(i -> i.getResourceId()).toList(); + menuList = authMenuDao.selectList(new QueryWrapper().in("pk_id", sourceIdlist)); + } + + if (menuList.isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + menuList = MenuUtil.treeMenuList(menuList, 0); + return new Result>().success(menuList); + } + + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/impl/PermissionServiceImpl.java b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/PermissionServiceImpl.java new file mode 100644 index 0000000..9a2b4bd --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/PermissionServiceImpl.java @@ -0,0 +1,90 @@ +package com.evotech.hd.resource.service.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.evotech.hd.common.core.constant.HDConstant; +import com.evotech.hd.common.core.dao.resource.auth.AuthPermissionDao; +import com.evotech.hd.common.core.dao.resource.auth.AuthRoleResourceDao; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.auth.AuthPermission; +import com.evotech.hd.common.core.entity.resource.auth.AuthRoleResource; +import com.evotech.hd.common.core.enums.CodeMsg; +import com.evotech.hd.resource.service.PermissionService; + +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; + +@Service +public class PermissionServiceImpl implements PermissionService { + + @Resource + private AuthPermissionDao permissionDao; + @Resource + private AuthRoleResourceDao authRoleResourceDao; + @Resource + private HttpServletRequest request; + + @Override + public Result add(AuthPermission perm) { + perm.setCtime(new Date()); + int n = permissionDao.insert(perm); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加权限出错!"); + } + + + @Override + public Result delete(Integer id) { + int n = permissionDao.deleteById(id); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("删除权限出错!", n); + } + + @Override + public Result update(AuthPermission perm) { + int n = permissionDao.updateById(perm); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("更新权限失败!"); + } + + @Override + public Result> list(Integer menuId) { + // 获取角色 + String rcodes = request.getHeader("rcodes"); + if (!StringUtils.hasText(rcodes)) { + return new Result>().error("权限验证出错"); + } + // 根据角色查询数据 + List list = new ArrayList(); + if (rcodes.contains(HDConstant.SYSTEM_MANAGER_ROLE_CODE)) { + list = permissionDao.selectList(new QueryWrapper() + .eq(menuId != null, "menu_id", menuId)); + } else { + List rcodeList = Arrays.asList(rcodes.split(",")); + List roleResourceList = authRoleResourceDao.selectList(new QueryWrapper() + .eq("resource_type", HDConstant.RESOURCE_TYPE_PERM).in("rcode", rcodeList)); + List permIdList = roleResourceList.stream().map(i -> i.getResourceId()).toList(); + list = permissionDao.selectList(new QueryWrapper() + .eq(menuId != null, "menu_id", menuId).in("pk_id", permIdList)); + } + + if (list.isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(list); + } + + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/impl/ProxyOperaterServiceImpl.java b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/ProxyOperaterServiceImpl.java new file mode 100644 index 0000000..2992253 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/ProxyOperaterServiceImpl.java @@ -0,0 +1,74 @@ +package com.evotech.hd.resource.service.impl; + +import java.util.Date; +import java.util.List; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.evotech.hd.common.core.dao.resource.ProxyOperaterDao; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.ProxyOperater; +import com.evotech.hd.common.core.enums.CodeMsg; +import com.evotech.hd.resource.entity.request.PageListProxyOperaterRequest; +import com.evotech.hd.resource.service.ProxyOperaterService; + +import jakarta.annotation.Resource; + +@Service +public class ProxyOperaterServiceImpl implements ProxyOperaterService { + + @Resource + private ProxyOperaterDao proxyOperaterDao; + + @Override + public Result add(ProxyOperater po) { + po.setCtime(new Date()); + int n = proxyOperaterDao.insert(po); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加运营商出错!"); + } + + @Override + @Transactional + public Result delete(Integer id) { + ProxyOperater po = new ProxyOperater(); + po.setPkId(id); + po.setDelFlag(1); + int n = proxyOperaterDao.updateById(po); + if (n == 1) { + return new Result().success(n); + } + throw new RuntimeException("删除运营商出错!"); + } + + @Override + public Result update(ProxyOperater po) { + int n = proxyOperaterDao.updateById(po); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("更新运营商失败!"); + } + + @Override + public Result> list(PageListProxyOperaterRequest plpor) { + Page page = new Page(plpor.getPageNo(), plpor.getPageSize()); + page = proxyOperaterDao.selectPage(page, new QueryWrapper() + .eq(StringUtils.hasText(plpor.getDivisionNo()), "division_no", plpor.getDivisionNo()) + .like(StringUtils.hasText(plpor.getPocode()), "pocode", plpor.getPocode()) + .like(StringUtils.hasText(plpor.getPoname()), "poname", plpor.getPoname()) + .eq(plpor.getStatus() != null, "status", plpor.getStatus()) + .ne("del_flag", 1)); + if (page.getRecords().isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(page); + } + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/impl/RoleServiceImpl.java b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/RoleServiceImpl.java new file mode 100644 index 0000000..1ea68c9 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/RoleServiceImpl.java @@ -0,0 +1,177 @@ +package com.evotech.hd.resource.service.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import org.apache.ibatis.executor.BatchResult; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.evotech.hd.common.core.dao.resource.auth.AuthRoleDao; +import com.evotech.hd.common.core.dao.resource.auth.AuthRoleResourceDao; +import com.evotech.hd.common.core.dao.resource.auth.AuthUserRoleDao; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.entity.resource.auth.AuthRole; +import com.evotech.hd.common.core.entity.resource.auth.AuthRoleResource; +import com.evotech.hd.common.core.entity.resource.auth.AuthUserRole; +import com.evotech.hd.common.core.enums.CodeMsg; +import com.evotech.hd.resource.entity.request.DelAddRoleSourceRequest; +import com.evotech.hd.resource.service.RoleService; + +import cn.hutool.core.util.StrUtil; +import jakarta.annotation.Resource; + +@Service +public class RoleServiceImpl implements RoleService { + + @Resource + private AuthRoleDao authRoleDao; + @Resource + private AuthRoleResourceDao authRoleResourceDao; + @Resource + private AuthUserRoleDao authUserRoleDao; + + + @Override + public Result add(AuthRole r) { + r.setCtime(new Date()); + int n = authRoleDao.insert(r); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加角色出错!"); + } + + @Override + @Transactional + public Result delete(Integer rid) { + int n = authRoleDao.deleteById(rid); + if (n == 1) { + // 删除角色和用户的关系 + authUserRoleDao.delete(new QueryWrapper().eq("rid", rid)); + // 删除角色权限 + authRoleResourceDao.delete(new QueryWrapper().eq("rid", rid)); + return new Result().success(n); + } + return new Result().error("删除角色出错!"); + } + + @Override + public Result update(AuthRole r) { + int n = authRoleDao.updateById(r); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("更新角色失败!"); + } + + @Override + public Result> list(String uid) { + List rcodeList = new ArrayList(); + if (StringUtils.hasText(uid)) { + List userRoleList = authUserRoleDao.selectList(new QueryWrapper().eq("uid", uid)); + if (userRoleList.isEmpty()) { + return new Result>().error("该用户未分配角色!"); + } + rcodeList = userRoleList.stream().map(i -> i.getRcode()).toList(); + } + + List roleList = authRoleDao.selectList(new QueryWrapper().in(!rcodeList.isEmpty(), "rcode", rcodeList)); + if (roleList.isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(roleList); + } + + + @Override + @Transactional + public Result addRoleSource(List list) { + // 先检查 + List resourceIdList = list.stream().map(i -> i.getResourceId()).toList(); + String rcode = list.get(0).getRcode(); + boolean exists = authRoleResourceDao.exists(new QueryWrapper() + .eq("rcode", rcode).in("resource_id", resourceIdList)); + if (exists) { + return new Result().error("权限已存在"); + } + Date d = new Date(); + list.forEach(i -> i.setCtime(d)); + List resList = authRoleResourceDao.insert(list); + int sum = 0; + for (int i = 0; i < resList.size(); i++) { + int[] updateCounts = resList.get(i).getUpdateCounts(); + sum = Arrays.stream(updateCounts).sum(); + } + if (sum == list.size()) { + return new Result().success(sum); + } + + return new Result().error("添加失败"); + } + + + @Override + public Result> listRoleSource(String rcode, String resourceType) { + List list = authRoleResourceDao + .selectList(new QueryWrapper() + .eq("rcode", rcode) + .eq(StrUtil.isNotBlank(resourceType), "resource_type", resourceType)); + if (list.isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(list); + } + + + @Override + @Transactional + public Result delRoleSource(String ids) { + if (StrUtil.isBlank(ids)) { + return new Result().error("参数不能为空!"); + } + List idList = Arrays.asList(ids.split(",")); + int n = authRoleResourceDao.deleteByIds(idList); + if (n == idList.size()) { + return new Result().success(n); + } + throw new RuntimeException("删除权限出错!"); + } + + + + + @Override + @Transactional + public Result delAddRoleSource(DelAddRoleSourceRequest darsr) { + // 1. 解析数据 + String rcode = darsr.getRcode(); + String[] typeArr = darsr.getTypes().split(";"); + String[] sourceArr = darsr.getSourceIds().split(";"); + if (typeArr.length != sourceArr.length) { + return new Result().error("参数格式错误"); + } + // 2. 删除原来的 + authRoleResourceDao.delete(new QueryWrapper().eq("rcode", rcode)); + // 3. 增加新的 + Date d = new Date(); + List list = new ArrayList(); + for (int i = 0; i < typeArr.length; i++) { + String[] sourceIdArr = sourceArr[i].split(","); + for (int j = 0; j < sourceIdArr.length; j++) { + AuthRoleResource arr = new AuthRoleResource(); + arr.setRcode(rcode); + arr.setResourceType(typeArr[i]); + arr.setResourceId(Integer.valueOf(sourceIdArr[j])); + arr.setCtime(d); + list.add(arr); + } + } + return addRoleSource(list); + } + + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/impl/StationTypeServiceImpl.java b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/StationTypeServiceImpl.java new file mode 100644 index 0000000..230d54a --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/StationTypeServiceImpl.java @@ -0,0 +1,65 @@ +package com.evotech.hd.resource.service.impl; + +import java.util.Date; +import java.util.List; + +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.evotech.hd.common.core.entity.BasePageRequest; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.enums.CodeMsg; +import com.evotech.hd.resource.dao.StationTypeDao; +import com.evotech.hd.resource.entity.StationType; +import com.evotech.hd.resource.service.StationTypeService; + +import jakarta.annotation.Resource; + +@Service +public class StationTypeServiceImpl implements StationTypeService { + + @Resource + private StationTypeDao stationTypeDao; + + @Override + public Result add(StationType st) { + st.setCtime(new Date()); + int n = stationTypeDao.insert(st); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("添加类型出错!"); + } + + @Override + public Result delete(Integer id) { + int n = stationTypeDao.deleteById(id); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("删除类型出错!"); + } + + @Override + public Result update(StationType st) { + int n = stationTypeDao.updateById(st); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("更新类型失败!"); + } + + @Override + public Result> list(BasePageRequest bpr) { + Page page = new Page(bpr.getPageNo(), bpr.getPageSize()); + page = stationTypeDao.selectPage(page, new QueryWrapper()); + if (page.getRecords().isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(page); + } + + + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/impl/SystemManagerServiceImpl.java b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/SystemManagerServiceImpl.java new file mode 100644 index 0000000..c7e0f3a --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/SystemManagerServiceImpl.java @@ -0,0 +1,43 @@ +package com.evotech.hd.resource.service.impl; + +import java.util.List; + +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.enums.CodeMsg; +import com.evotech.hd.resource.dao.SystemManagerDao; +import com.evotech.hd.resource.entity.SystemManager; +import com.evotech.hd.resource.service.SystemManagerService; + +import jakarta.annotation.Resource; + +@Service +public class SystemManagerServiceImpl implements SystemManagerService { + + @Resource + private SystemManagerDao systemManagerDao; + + @Override + public Result> listSystemManager() { + List list = systemManagerDao.selectList(new QueryWrapper()); + if (list.isEmpty()) { + return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); + } + return new Result>().success(list); + } + + @Override + public Result update(SystemManager sm) { + int n = systemManagerDao.updateById(sm); + if (n == 1) { + return new Result().success(n); + } + return new Result().error("更新失败!"); + } + + + + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/utils/AdmdvsUtil.java b/resource-server/src/main/java/com/evotech/hd/resource/utils/AdmdvsUtil.java new file mode 100644 index 0000000..e33696a --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/utils/AdmdvsUtil.java @@ -0,0 +1,43 @@ +package com.evotech.hd.resource.utils; + +import java.util.List; +import java.util.stream.Collectors; + +import com.evotech.hd.common.core.entity.resource.dict.AdmdvsInfo; + +/** + * @author zrb + * @date 2024年9月5日09:08:00 + */ +public class AdmdvsUtil { + + public static List treeAdmdvsList(List AdmdvsList, String pno) { + List treeAdmdvsList = AdmdvsList.stream() + .filter(a -> pno.equals(a.getPno())) + .map(a -> { + a.setSubAdmdvsInfoList(getSubAdmdvs(a, AdmdvsList)); + return a; + }) + .sorted((a1, a2) -> a1.getAdmdvsNo().compareTo(a2.getAdmdvsNo())) + .collect(Collectors.toList()); + return treeAdmdvsList; + } + + + public static List getSubAdmdvs(AdmdvsInfo rootAdmdvs, List list) { + List aList = list.stream() + // 获取指定层级 + .filter(a -> rootAdmdvs.getAdmdvsNo().equals(a.getPno())) + // 获取子级 + .map(a -> { + a.setSubAdmdvsInfoList(getSubAdmdvs(a, list)); + return a; + }) + // 排序 + .sorted((a1, a2) -> a1.getAdmdvsNo().compareTo(a2.getAdmdvsNo())) + .collect(Collectors.toList()); + return aList; + } + + +} diff --git a/resource-server/src/main/java/com/evotech/hd/resource/utils/MenuUtil.java b/resource-server/src/main/java/com/evotech/hd/resource/utils/MenuUtil.java new file mode 100644 index 0000000..530a3aa --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/utils/MenuUtil.java @@ -0,0 +1,44 @@ +package com.evotech.hd.resource.utils; + +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +import com.evotech.hd.common.core.entity.resource.auth.AuthMenu; + +/** + * @author zrb + * @date 2024年9月5日09:08:57 + */ +public class MenuUtil { + + public static List treeMenuList(List menuList, Integer menuId) { + List treeMenuList = menuList.stream() + .filter(m -> m.getParentId() == menuId) + .map(m -> { + m.setSubMenuList(getSubMenu(m, menuList)); + return m; + }) + .sorted(Comparator.comparingInt(AuthMenu::getSort)) + .collect(Collectors.toList()); + return treeMenuList; + } + + + static List getSubMenu(AuthMenu rootMenu, List list) { + List mList = list.stream() + // 获取指定层级菜单,Long类型用equals或者longValue()取到值再比较 + .filter(m -> m.getParentId().intValue() == rootMenu.getPkId().intValue()) + // 获取子菜单 + .map(m -> { + m.setSubMenuList(getSubMenu(m, list)); + return m; + }) + // 菜单排序 + .sorted((m1, m2) -> m1.getSort()-m2.getSort()) + .collect(Collectors.toList()); + return mList; + } + + +} diff --git a/resource-server/src/main/resources/application.yml b/resource-server/src/main/resources/application.yml new file mode 100644 index 0000000..fb33eff --- /dev/null +++ b/resource-server/src/main/resources/application.yml @@ -0,0 +1,44 @@ +# 1. server +server: + port: 9102 + servlet: + context-path: /resource +# 2.log +logging: + config: classpath:logback-spring.xml + level: + '[com.evotech.hd.resource.dao]': debug +# 3.spring +spring: + # 服务名称必须带上,不然nacos服务列表中没有,也不会有注册成功的信息 + application: + name: resource-server + config: + import: + - nacos:${spring.application.name}.yaml?refreshEnabled=true + cloud: + nacos: + serverAddr: 192.168.5.213:8848 + username: nacos + password: nacos + discovery: + register-enabled: true + #server-addr: 10.10.1.6:8848 +# ip: 10.10.1.2 + # 因添加了context-path,admin-server要想发现正确路径,需要加这个 + metadata: + management: + context-path: ${server.servlet.context-path}/actuator +# 为springbootadmin开启所有检查 +management: + endpoints: + web: + exposure: + include: "*" + endpoint: + health: + show-details: always + # xml文件中配置的日志文件的名称 + logfile: + external-file: /logs/resource/resource-server.log + \ No newline at end of file diff --git a/resource-server/src/main/resources/logback-spring.xml b/resource-server/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..cf3258a --- /dev/null +++ b/resource-server/src/main/resources/logback-spring.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + ${CONTEXT_NAME} + + + + + + DEBUG + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %replace(%caller{1}){'\t|Caller.{1}0|\r\n', ''} -- %msg%n + + UTF-8 + + + + + + + ${LOG_PATH}/${CONTEXT_NAME}.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{50}.%M\(%line\) -- %msg%n + UTF-8 + + + + + ${LOG_PATH}/${CONTEXT_NAME}-%d{yyyy-MM-dd}-%i.log + + ${MAX_HISTORY} + + + ${MAX_FILE_SIZE} + + + + + + + + 512 + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resource-server/src/main/resources/mapper/AuthMenuMapper.xml b/resource-server/src/main/resources/mapper/AuthMenuMapper.xml new file mode 100644 index 0000000..1c45916 --- /dev/null +++ b/resource-server/src/main/resources/mapper/AuthMenuMapper.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + pk_id, name, mark, component, path, status, sort, icon, type, parent_id, creater, ctime, updater, uptime + + + + + diff --git a/resource-server/src/main/resources/mapper/AuthPermissionMapper.xml b/resource-server/src/main/resources/mapper/AuthPermissionMapper.xml new file mode 100644 index 0000000..76f7af0 --- /dev/null +++ b/resource-server/src/main/resources/mapper/AuthPermissionMapper.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + pk_id, code, name, menu_id, allow, uri, request_type, mark, creater, ctime, updater, uptime + + + + + + diff --git a/resource-server/src/main/resources/mapper/AuthRoleMapper.xml b/resource-server/src/main/resources/mapper/AuthRoleMapper.xml new file mode 100644 index 0000000..903e963 --- /dev/null +++ b/resource-server/src/main/resources/mapper/AuthRoleMapper.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + pk_id, name, rcode, mark, status, type, readonly, creater, ctime, updater, uptime + + + diff --git a/resource-server/src/main/resources/mapper/AuthRoleResourceMapper.xml b/resource-server/src/main/resources/mapper/AuthRoleResourceMapper.xml new file mode 100644 index 0000000..812c62b --- /dev/null +++ b/resource-server/src/main/resources/mapper/AuthRoleResourceMapper.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + pk_id, rid, resource_type, resource_id, ctime, creater + + + diff --git a/resource-server/src/main/resources/mapper/AuthUserMapper.xml b/resource-server/src/main/resources/mapper/AuthUserMapper.xml new file mode 100644 index 0000000..634e361 --- /dev/null +++ b/resource-server/src/main/resources/mapper/AuthUserMapper.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pk_id, uid, uname, type, type_relate_code, name, password, email, phone, sex, status, readonly, del_flag, avatar, password_error_last_time, password_error_num, password_expire_time, last_login_time, creater, ctime, updater, uptime + + + diff --git a/resource-server/src/main/resources/mapper/AuthUserRoleMapper.xml b/resource-server/src/main/resources/mapper/AuthUserRoleMapper.xml new file mode 100644 index 0000000..bfe7e52 --- /dev/null +++ b/resource-server/src/main/resources/mapper/AuthUserRoleMapper.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + pk_id, uid, rcode, creater, ctime, uptime + + + diff --git a/resource-server/src/main/resources/mapper/DictMapper.xml b/resource-server/src/main/resources/mapper/DictMapper.xml new file mode 100644 index 0000000..9615dbe --- /dev/null +++ b/resource-server/src/main/resources/mapper/DictMapper.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + pk_id, dict_name, dict_code, dict_value, sort, type_id, type_code, ctime, uptime + + + + + diff --git a/resource-server/src/test/java/com/evotech/hd/resource/ResourceServerApplicationTests.java b/resource-server/src/test/java/com/evotech/hd/resource/ResourceServerApplicationTests.java new file mode 100644 index 0000000..c444b5f --- /dev/null +++ b/resource-server/src/test/java/com/evotech/hd/resource/ResourceServerApplicationTests.java @@ -0,0 +1,33 @@ +package com.evotech.hd.resource; + +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.evotech.hd.common.core.dao.resource.auth.AuthMenuDao; +import com.evotech.hd.common.core.entity.resource.auth.AuthMenu; +import com.evotech.hd.resource.utils.MenuUtil; + +import cn.hutool.json.JSONUtil; +import jakarta.annotation.Resource; + +@SpringBootTest +class ResourceServerApplicationTests { + + @Resource + private AuthMenuDao authMenuDao; + + @Test + void contextLoads() { + + List menuList = authMenuDao.selectList(new QueryWrapper()); + System.out.println(menuList.size()); + menuList.stream().forEach(i -> System.out.println()); + menuList = MenuUtil.treeMenuList(menuList, 0); + System.out.println("----"); + System.out.println(JSONUtil.toJsonPrettyStr(menuList)); + } + +} diff --git a/wechat-server/.gitignore b/wechat-server/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/wechat-server/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/wechat-server/pom.xml b/wechat-server/pom.xml new file mode 100644 index 0000000..d03dc63 --- /dev/null +++ b/wechat-server/pom.xml @@ -0,0 +1,93 @@ + + + + 4.0.0 + + com.evotech.hd + battery-cloud + 1.0.0-SNAPSHOT + + wechat-server + wechat-server + 微信服务 + + + 17 + + + + + com.evotech.hd + common-web + 1.0.0-SNAPSHOT + + + com.evotech.hd + common-redis + 1.0.0-SNAPSHOT + + + + com.evotech.hd + common-mybatis + 1.0.0-SNAPSHOT + + + + com.github.wechatpay-apiv3 + wechatpay-java + 0.2.14 + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + cn.hutool + hutool-http + + + cn.hutool + hutool-json + + + cn.hutool + hutool-crypto + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + diff --git a/wechat-server/src/main/java/com/evotech/hd/wechat/WechatServerApplication.java b/wechat-server/src/main/java/com/evotech/hd/wechat/WechatServerApplication.java new file mode 100644 index 0000000..f016b63 --- /dev/null +++ b/wechat-server/src/main/java/com/evotech/hd/wechat/WechatServerApplication.java @@ -0,0 +1,19 @@ +package com.evotech.hd.wechat; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication +@EnableDiscoveryClient +@ComponentScan("com.evotech.hd.**") +@MapperScan({"com.evotech.hd.wechat.dao.**", "com.evotech.hd.common.core.dao.**"}) +public class WechatServerApplication { + + public static void main(String[] args) { + SpringApplication.run(WechatServerApplication.class, args); + } + +} diff --git a/wechat-server/src/main/java/com/evotech/hd/wechat/config/WechatConfig.java b/wechat-server/src/main/java/com/evotech/hd/wechat/config/WechatConfig.java new file mode 100644 index 0000000..6c85629 --- /dev/null +++ b/wechat-server/src/main/java/com/evotech/hd/wechat/config/WechatConfig.java @@ -0,0 +1,31 @@ +package com.evotech.hd.wechat.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.wechat.pay.java.core.RSAAutoCertificateConfig; + +@Configuration +public class WechatConfig { + + @Bean + XcxProperties xcxProperties() { + return new XcxProperties(); + } + + + /** + * 支付证书签名配置,系统里面用的SDK里面的方法,这个配置是SDK里面需要的 + */ + @Bean + RSAAutoCertificateConfig rsaAutoCertificateConfig() { + RSAAutoCertificateConfig config = new RSAAutoCertificateConfig.Builder() + .merchantId(xcxProperties().getMchid()) + .privateKeyFromPath(xcxProperties().getPrivateKeyPath()) + .merchantSerialNumber(xcxProperties().getSerialNo()) + .apiV3Key(xcxProperties().getApiV3Key()) + .build(); + return config; + } + +} diff --git a/wechat-server/src/main/java/com/evotech/hd/wechat/config/XcxProperties.java b/wechat-server/src/main/java/com/evotech/hd/wechat/config/XcxProperties.java new file mode 100644 index 0000000..ad17317 --- /dev/null +++ b/wechat-server/src/main/java/com/evotech/hd/wechat/config/XcxProperties.java @@ -0,0 +1,31 @@ +package com.evotech.hd.wechat.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Configuration +@ConfigurationProperties(prefix = "hbyt.xcx", ignoreUnknownFields = true) +@Data +@Schema(description = "小程序信息") +public class XcxProperties { + + private String appid; + + private String appSecret; + + private String mchid; + + private String serialNo; + + private String apiV3Key; + + private String privateKeyPath; + + private String notifyUrl; + + private String refundNotifyUrl; + +} diff --git a/wechat-server/src/main/java/com/evotech/hd/wechat/controller/LoginController.java b/wechat-server/src/main/java/com/evotech/hd/wechat/controller/LoginController.java new file mode 100644 index 0000000..1088889 --- /dev/null +++ b/wechat-server/src/main/java/com/evotech/hd/wechat/controller/LoginController.java @@ -0,0 +1,46 @@ +package com.evotech.hd.wechat.controller; + +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.wechat.service.LoginService; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; + +@Tag(name = "登陆") +@RestController +@RequestMapping("/login") +public class LoginController { + + @Resource + private LoginService loginService; + + + @Operation(summary = "登陆") + @PostMapping("/xcxlogin") + @Parameter(name="js_code", description = "登录时获取的 code,可通过wx.login获取", example = "") + public Result code2Session(String js_code) { + return loginService.code2Session(js_code); + } + + + @Operation(summary = "检验小程序登录态") + @PostMapping("/checksessionkey") + public Result checkSessionKey(String wuid) { + return loginService.checkSessionKey(wuid); + } + + + @Operation(summary = "获取手机号") + @PostMapping("/phone") + public Result phoneNumber(String wuid, String code) { + return loginService.phoneNumber(wuid, code); + } + + +} diff --git a/wechat-server/src/main/java/com/evotech/hd/wechat/controller/WechatPayController.java b/wechat-server/src/main/java/com/evotech/hd/wechat/controller/WechatPayController.java new file mode 100644 index 0000000..791feb7 --- /dev/null +++ b/wechat-server/src/main/java/com/evotech/hd/wechat/controller/WechatPayController.java @@ -0,0 +1,92 @@ +package com.evotech.hd.wechat.controller; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.wechat.service.WechatPayService; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import com.wechat.pay.java.service.payments.jsapi.model.Detail; + +import io.swagger.v3.oas.annotations.Hidden; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.constraints.NotBlank; + +@Tag(name = "微信支付") +@RestController +@RequestMapping("/wechatpay") +public class WechatPayController { + + + @Resource + private WechatPayService wechatPayService; + + + @Operation(summary = "小程序预支付订单") + @PostMapping("/xcx/prepay") + @ApiOperationSupport(order = 1) + public Result xcxPrepay(String wuid, String remarks, Integer money, Detail detail) { + return wechatPayService.xcxPrepay(wuid, remarks, money, detail); + } + + + @Operation(summary = "支付回调地址") + @PostMapping("/prepayback/msg") + @ApiOperationSupport(order = 2) + @Hidden + public ResponseEntity prepayBack(@RequestBody String body, HttpServletRequest request) { + return wechatPayService.PrepayBack(body, request); + } + + + @Operation(summary = "支付订单查询状态") + @GetMapping("/order/query") + @ApiOperationSupport(order = 3) + public Result orderQuery(Integer type, String transactionId, String outTradeNo) { + return wechatPayService.orderQuery(type, transactionId, outTradeNo); + } + + + @Operation(summary = "退款") + @PostMapping("/refunds") + @ApiOperationSupport(order = 4) + public Result refunds(String outTradeNo, String transactionId, String reason, Integer money, Integer total) { + return wechatPayService.refunds(outTradeNo, transactionId, reason, money, total); + } + + + @Operation(summary = "退款回调地址") + @PostMapping("/refundsback/msg") + @ApiOperationSupport(order = 5) + @Hidden + public ResponseEntity refundsBack(@RequestBody String body, HttpServletRequest request) { + return wechatPayService.refundsBack(body, request); + + } + + + @Operation(summary = "单笔退款查询") + @GetMapping("/refunds/query") + @ApiOperationSupport(order = 6) + public Result refundsQuery(String outRefundNo) { + return wechatPayService.refundsQuery(outRefundNo); + } + + + @Operation(summary = "单日交易账单,进3月内") + @PostMapping("/daytradebill") + @ApiOperationSupport(order = 7) + public Result dayTradebill(@RequestParam @NotBlank String day) { + return wechatPayService.dayTradebill(day); + } + + +} diff --git a/wechat-server/src/main/java/com/evotech/hd/wechat/dao/WechatUserDao.java b/wechat-server/src/main/java/com/evotech/hd/wechat/dao/WechatUserDao.java new file mode 100644 index 0000000..5ce0a92 --- /dev/null +++ b/wechat-server/src/main/java/com/evotech/hd/wechat/dao/WechatUserDao.java @@ -0,0 +1,12 @@ +package com.evotech.hd.wechat.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.wechat.entity.WechatUser; + +/** + * @author zrb + * @since 2024-10-12 + */ +public interface WechatUserDao extends BaseMapper { + +} diff --git a/wechat-server/src/main/java/com/evotech/hd/wechat/entity/LoginResponse.java b/wechat-server/src/main/java/com/evotech/hd/wechat/entity/LoginResponse.java new file mode 100644 index 0000000..20bf780 --- /dev/null +++ b/wechat-server/src/main/java/com/evotech/hd/wechat/entity/LoginResponse.java @@ -0,0 +1,23 @@ +package com.evotech.hd.wechat.entity; + +import java.io.Serializable; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +@Schema(name = "小程序登陆返回数据") +public class LoginResponse implements Serializable { + + private static final long serialVersionUID = -3389705805211045576L; + + @Schema(description = "会话密钥") + private String session_key; + + @Schema(description = "会话密钥") + private String unionid; + + @Schema(description = "用户唯一标识") + private String openid; + +} diff --git a/wechat-server/src/main/java/com/evotech/hd/wechat/entity/WechatUser.java b/wechat-server/src/main/java/com/evotech/hd/wechat/entity/WechatUser.java new file mode 100644 index 0000000..4828c2c --- /dev/null +++ b/wechat-server/src/main/java/com/evotech/hd/wechat/entity/WechatUser.java @@ -0,0 +1,68 @@ +package com.evotech.hd.wechat.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +/** + * @author zrb + * @since 2024-10-12 + */ +@Getter +@Setter +@TableName("yt_t_wechat_user") +@Schema(name = "WechatUser", description = "小程序用户信息") +public class WechatUser implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "pk_id", type = IdType.AUTO) + private Integer pkId; + + @Schema(description = "微信用户id") + private String wuid; + + private String appid; + + private String openid; + + private String unionid; + + @Schema(description = "手机号") + private String phoneNumber; + + @Schema(description = "用户昵称") + private String nickName; + + @Schema(description = "用户头像") + private String avatarUrl; + + @Schema(description = "用户性别:1-男;2-女") + private Boolean gender; + + @Schema(description = "创建人", hidden = true) + private String creater; + + @Schema(description = "创建时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date ctime; + + @Schema(description = "更新人", hidden = true) + private String updater; + + @Schema(description = "更新时间", hidden = true) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date uptime; +} diff --git a/wechat-server/src/main/java/com/evotech/hd/wechat/service/AccessTokenService.java b/wechat-server/src/main/java/com/evotech/hd/wechat/service/AccessTokenService.java new file mode 100644 index 0000000..a707fb7 --- /dev/null +++ b/wechat-server/src/main/java/com/evotech/hd/wechat/service/AccessTokenService.java @@ -0,0 +1,38 @@ +package com.evotech.hd.wechat.service; + +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import com.evotech.hd.common.redis.utils.RedisUtil; +import com.evotech.hd.wechat.config.XcxProperties; +import com.evotech.hd.wechat.utils.xcx.AccessTokenUtil; + +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import jakarta.annotation.Resource; + +@Service +public class AccessTokenService { + + @Resource + private XcxProperties xcxProperties; + @Resource + private RedisUtil redisUtil; + + private String accessTokenPrefix = "hd:wechat:accessToken:"; + + public String getAccessToken() { + if (redisUtil.hasKey(accessTokenPrefix + xcxProperties.getAppid())) { + return redisUtil.get(accessTokenPrefix + xcxProperties.getAppid()).toString(); + } + String res = AccessTokenUtil.accessToken(xcxProperties.getAppid(), xcxProperties.getAppSecret()); + JSONObject jo = JSONUtil.parseObj(res); + // {"errcode":40013,"errmsg":"invalid appid rid: 6708ba65-0b425b74-4620599c"} + if (StringUtils.hasText(jo.getStr("errcode"))) { + throw new RuntimeException(res); + } + redisUtil.set(accessTokenPrefix + xcxProperties.getAppid(), jo.getStr("access_token"), 7200L - 15); + return jo.getStr("access_token"); + } + +} diff --git a/wechat-server/src/main/java/com/evotech/hd/wechat/service/LoginService.java b/wechat-server/src/main/java/com/evotech/hd/wechat/service/LoginService.java new file mode 100644 index 0000000..f369f24 --- /dev/null +++ b/wechat-server/src/main/java/com/evotech/hd/wechat/service/LoginService.java @@ -0,0 +1,13 @@ +package com.evotech.hd.wechat.service; + +import com.evotech.hd.common.core.entity.Result; + +public interface LoginService { + + public Result code2Session(String js_code); + + public Result checkSessionKey(String wuid); + + public Result phoneNumber(String wuid, String code); + +} diff --git a/wechat-server/src/main/java/com/evotech/hd/wechat/service/WechatPayService.java b/wechat-server/src/main/java/com/evotech/hd/wechat/service/WechatPayService.java new file mode 100644 index 0000000..8c0b76d --- /dev/null +++ b/wechat-server/src/main/java/com/evotech/hd/wechat/service/WechatPayService.java @@ -0,0 +1,25 @@ +package com.evotech.hd.wechat.service; + +import org.springframework.http.ResponseEntity; +import com.evotech.hd.common.core.entity.Result; +import com.wechat.pay.java.service.payments.jsapi.model.Detail; + +import jakarta.servlet.http.HttpServletRequest; + +public interface WechatPayService { + + public Result xcxPrepay(String wuid, String remarks, Integer money, Detail detail); + + public ResponseEntity PrepayBack(String body, HttpServletRequest request); + + public Result orderQuery(Integer type, String transactionId, String outTradeNo); + + public Result refunds(String outTradeNo, String transactionId, String reason, Integer money, Integer total); + + public ResponseEntity refundsBack(String body, HttpServletRequest request); + + public Result refundsQuery(String outRefundNo); + + public Result dayTradebill(String day); + +} diff --git a/wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/LoginServiceImpl.java b/wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/LoginServiceImpl.java new file mode 100644 index 0000000..88e6015 --- /dev/null +++ b/wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/LoginServiceImpl.java @@ -0,0 +1,115 @@ +package com.evotech.hd.wechat.service.impl; + +import java.util.Date; + +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.common.core.enums.CodeMsg; +import com.evotech.hd.common.redis.utils.RedisUtil; +import com.evotech.hd.wechat.config.XcxProperties; +import com.evotech.hd.wechat.dao.WechatUserDao; +import com.evotech.hd.wechat.entity.WechatUser; +import com.evotech.hd.wechat.service.AccessTokenService; +import com.evotech.hd.wechat.service.LoginService; +import com.evotech.hd.wechat.utils.xcx.LoginUtil; +import com.evotech.hd.wechat.utils.xcx.PhoneNumberUtil; + +import cn.hutool.crypto.digest.DigestUtil; +import cn.hutool.crypto.digest.HMac; +import cn.hutool.crypto.digest.HmacAlgorithm; +import cn.hutool.crypto.digest.MD5; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import jakarta.annotation.Resource; + +@Service +public class LoginServiceImpl implements LoginService { + + public static String openidPrefix = "hd:wechat:login:openid:"; + public static String unionidPrefix = "hd:wechat:login:unionid:"; + public static String sessionKeyPrefix = "hd:wechat:login:sessionKey:"; + + @Resource + private XcxProperties xcxProperties; + @Resource + private RedisUtil redisUtil; + @Resource + private WechatUserDao wechatUserDao; + @Resource + private AccessTokenService accessTokenService; + + @Override + public Result code2Session(String js_code) { + String res = LoginUtil.code2Session(xcxProperties.getAppid(), xcxProperties.getAppSecret(), js_code); + JSONObject jo = JSONUtil.parseObj(res); + if (StringUtils.hasText(jo.getStr("errcode"))) { + return new Result().error(CodeMsg.WECHAT_LOGIN_ERROR, jo); + } + String openid = jo.getStr("openid"); + String unionid = jo.getStr("unionid"); + String sessionKey = jo.getStr("session_key"); + // 是否登陆过 + WechatUser wuser = wechatUserDao.selectOne(new QueryWrapper().eq("openid", openid)); + if (wuser == null) { + String wuid = MD5.create().digestHex(xcxProperties.getAppid() + openid); + wuser = new WechatUser(); + wuser.setAppid(xcxProperties.getAppid()); + wuser.setCtime(new Date()); + wuser.setOpenid(openid); + wuser.setUnionid(unionid); + wuser.setWuid(wuid); + wechatUserDao.insert(wuser); + } + // 缓存数据 + redisUtil.set(openidPrefix + wuser.getWuid(), openid); + redisUtil.set(unionidPrefix + wuser.getWuid(), unionid); + redisUtil.set(sessionKeyPrefix + wuser.getWuid(), sessionKey); + + return new Result().success(wuser.getWuid()); + } + + @Override + public Result checkSessionKey(String wuid) { + if (!redisUtil.hasKey(openidPrefix + wuid) || !redisUtil.hasKey(sessionKeyPrefix + wuid)) { + return new Result().error(CodeMsg.WECHAT_SERRION_ERROR); + } + String openid = redisUtil.get(openidPrefix + wuid).toString(); + String sessionKey = redisUtil.get(sessionKeyPrefix + wuid).toString(); + HMac hmac = DigestUtil.hmac(HmacAlgorithm.HmacSHA256, sessionKey.getBytes()); + String res = LoginUtil.code2Session(xcxProperties.getAppid(), openid, hmac.digestHex("")); + JSONObject jo = JSONUtil.parseObj(res); + if (jo.getInt("errcode") == 0) { + return new Result().success("OK"); + } + return new Result().error(CodeMsg.WECHAT_SERRION_ERROR, jo); + } + + @Override + public Result phoneNumber(String wuid, String code) { + WechatUser wuser = wechatUserDao.selectOne(new QueryWrapper().eq("wuid", wuid)); + if (StringUtils.hasText(wuser.getPhoneNumber())) { + return new Result().success("ok", wuser.getPhoneNumber()); + } + if (!redisUtil.hasKey(openidPrefix + wuid)) { + return new Result().error(CodeMsg.WECHAT_SERRION_ERROR); + } + String openid = redisUtil.get(openidPrefix + wuid).toString(); + String res = PhoneNumberUtil.getPhoneNumber(accessTokenService.getAccessToken(), openid, code); + JSONObject jo = JSONUtil.parseObj(res); + if (jo.getInt("errcode") == 0) { + String phoneNumber = jo.getJSONObject("phone_info").getStr("phoneNumber"); + WechatUser wu = new WechatUser(); + wu.setWuid(wuid); + wechatUserDao.update(wu, new UpdateWrapper().set("phone_number", phoneNumber)); + } + return new Result().error(CodeMsg.WECHAT_API_ERROR, jo); + } + + + + +} diff --git a/wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/WechatPayServiceImpl.java b/wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/WechatPayServiceImpl.java new file mode 100644 index 0000000..ba3bc51 --- /dev/null +++ b/wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/WechatPayServiceImpl.java @@ -0,0 +1,227 @@ +package com.evotech.hd.wechat.service.impl; + +import java.util.Date; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + +import com.evotech.hd.common.core.entity.Result; +import com.evotech.hd.wechat.config.XcxProperties; +import com.evotech.hd.wechat.service.WechatPayService; +import com.evotech.hd.wechat.utils.wechatpay.WechatPayUtil; +import com.wechat.pay.java.core.RSAAutoCertificateConfig; +import com.wechat.pay.java.core.notification.NotificationParser; +import com.wechat.pay.java.core.notification.RequestParam; +import com.wechat.pay.java.service.billdownload.BillDownloadService; +import com.wechat.pay.java.service.billdownload.model.GetTradeBillRequest; +import com.wechat.pay.java.service.billdownload.model.QueryBillEntity; +import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension; +import com.wechat.pay.java.service.payments.jsapi.model.Amount; +import com.wechat.pay.java.service.payments.jsapi.model.Detail; +import com.wechat.pay.java.service.payments.jsapi.model.Payer; +import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest; +import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse; +import com.wechat.pay.java.service.payments.jsapi.model.QueryOrderByIdRequest; +import com.wechat.pay.java.service.payments.jsapi.model.QueryOrderByOutTradeNoRequest; +import com.wechat.pay.java.service.payments.model.Transaction; +import com.wechat.pay.java.service.refund.RefundService; +import com.wechat.pay.java.service.refund.model.AmountReq; +import com.wechat.pay.java.service.refund.model.CreateRequest; +import com.wechat.pay.java.service.refund.model.QueryByOutRefundNoRequest; +import com.wechat.pay.java.service.refund.model.Refund; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.RandomUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; + +@Service +public class WechatPayServiceImpl implements WechatPayService { + + @Resource + private RSAAutoCertificateConfig config; + @Resource + private XcxProperties xcxProperties; + + + @Override + public Result xcxPrepay(String wuid, String remarks, Integer money, Detail detail) { + PrepayRequest request = new PrepayRequest(); + Amount amount = new Amount(); +// amount.setTotal(money); + amount.setTotal(1); + request.setAmount(amount); + request.setAttach(remarks); + request.setAppid(xcxProperties.getAppid()); + request.setMchid(xcxProperties.getMchid()); + request.setDescription("测试商品标题"); + request.setNotifyUrl(xcxProperties.getNotifyUrl()); + request.setOutTradeNo("HD1001" + DateUtil.format(new Date(), DatePattern.PURE_DATETIME_FORMATTER) + RandomUtil.randomInt(10000, 100000)); + Payer payer = new Payer(); + payer.setOpenid("ocEmP7fbW-QD6tbNpi7B665xJu2g"); + request.setPayer(payer); +// request.setDetail(detail); + request.setTimeExpire(DateUtil.format(DateUtil.offsetHour(new Date(), 1), DatePattern.UTC_PATTERN)); + PrepayWithRequestPaymentResponse response = WechatPayUtil.jsapiPrepay(config, request); + System.out.println("\r\n=====>>>>>" + response); + return new Result().success(response); + } + + /** + * 用SDK中封装的NotificationParser解析器进行验签和解密 + */ + @Override + public ResponseEntity PrepayBack(String body, HttpServletRequest request) { + // 1. 初始化解析器 + NotificationParser parser = new NotificationParser(config); + // 2. 构造解析器所需参数 + RequestParam param = new RequestParam.Builder() + // 序列号 + .serialNumber(request.getHeader("Wechatpay-Serial")) + // 随机数 + .nonce(request.getHeader("Wechatpay-Nonce")) + // 签名 + .signature(request.getHeader("Wechatpay-Signature")) + // 时间戳 + .timestamp(request.getHeader("Wechatpay-Timestamp")) + .body(body) + .build(); + + // 3. 验签、解密,parse方法中包含2个方法,一个验签,一个解密 + Transaction transaction; + try { + transaction = parser.parse(param, Transaction.class); + } catch (Exception e) { + e.printStackTrace(); + JSONObject jo = new JSONObject(); + jo.set("code", "FAIL"); + jo.set("message", e.getMessage()); + return new ResponseEntity(jo.toJSONString(0), HttpStatus.FAILED_DEPENDENCY); + } + // 4. 业务处理逻辑 + System.out.println("\r\n=====>>>>>" + JSONUtil.toJsonPrettyStr(transaction)); + if (Transaction.TradeStateEnum.SUCCESS.equals(transaction.getTradeState())) { + + System.out.println(transaction.toString()); + // 支付成功,根据订单编号更新订单状态 + // 查询订单信息 +// Order orderOld = orderService.selectForUpdateByOrderNumber(transaction.getOutTradeNo()); + // 校验金额 +// if (0 == 0) { +// // 金额相等 完成支付 更新订单状态 +//// WechatPayUtil.success(orderOld, transaction); +// } else { +// // 金额异常 执行退款 +//// WechatPayUtil.refunded(new WechatPayRedis(transaction.getOutTradeNo(), transaction.getAmount().getTotal(), null)); +// } + } else { + // 订单支付失败 + System.out.println(transaction.getTradeStateDesc()); + } + + return new ResponseEntity("", HttpStatus.OK); + // 发生异常 + + + + } + + @Override + public Result orderQuery(Integer type, String transactionId, String outTradeNo) { + JsapiServiceExtension jsapiService = new JsapiServiceExtension.Builder().config(config).build(); + Transaction transaction; + if (type == 1) { + QueryOrderByIdRequest request = new QueryOrderByIdRequest(); + request.setTransactionId(transactionId); + request.setMchid(xcxProperties.getMchid()); + transaction = jsapiService.queryOrderById(request); + } else { + QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest(); + request.setMchid(xcxProperties.getMchid()); + request.setOutTradeNo(outTradeNo); + transaction = jsapiService.queryOrderByOutTradeNo(request); + } + return new Result().success(transaction); + } + + @Override + public Result refunds(String outTradeNo, String transactionId, String reason, Integer money, Integer total) { + RefundService refundService = new RefundService.Builder().config(config).build(); + // + CreateRequest request = new CreateRequest(); + request.setOutTradeNo(outTradeNo); + request.setTransactionId(transactionId); + request.setReason(reason); + request.setOutRefundNo("HD1001REFUND" + DateUtil.format(new Date(), DatePattern.PURE_DATETIME_FORMATTER) + RandomUtil.randomInt(1000, 10000)); + request.setNotifyUrl(xcxProperties.getRefundNotifyUrl()); + AmountReq amount = new AmountReq(); + amount.setRefund(Long.valueOf(money)); + amount.setCurrency("CNY"); + amount.setTotal(Long.valueOf(total)); + request.setAmount(amount); + Refund refund = refundService.create(request); + + return new Result().success(refund); + } + + @Override + public ResponseEntity refundsBack(String body, HttpServletRequest request) { + // 1. 初始化解析器 + NotificationParser parser = new NotificationParser(config); + // 2. 构造解析器所需参数 + RequestParam param = new RequestParam.Builder() + // 序列号 + .serialNumber(request.getHeader("Wechatpay-Serial")) + // 随机数 + .nonce(request.getHeader("Wechatpay-Nonce")) + // 签名 + .signature(request.getHeader("Wechatpay-Signature")) + // 时间戳 + .timestamp(request.getHeader("Wechatpay-Timestamp")) + .body(body) + .build(); + + // 3. 验签、解密,parse方法中包含2个方法,一个验签,一个解密 + Refund refund; + try { + refund = parser.parse(param, Refund.class); + } catch (Exception e) { + e.printStackTrace(); + JSONObject jo = new JSONObject(); + jo.set("code", "FAIL"); + jo.set("message", e.getMessage()); + return new ResponseEntity(jo.toJSONString(0), HttpStatus.FAILED_DEPENDENCY); + } + // 4. 业务处理逻辑 + System.out.println("\r\n=====>>>>>" + JSONUtil.toJsonPrettyStr(refund)); + return new ResponseEntity("", HttpStatus.OK); + } + + @Override + public Result refundsQuery(String outRefundNo) { + RefundService refundService = new RefundService.Builder().config(config).build(); + + QueryByOutRefundNoRequest request = new QueryByOutRefundNoRequest(); + request.setOutRefundNo(outRefundNo); + Refund refund = refundService.queryByOutRefundNo(request); + + return new Result().success(refund); + } + + @Override + public Result dayTradebill(String day) { + BillDownloadService billDownloadService = new BillDownloadService.Builder().config(config).build(); + GetTradeBillRequest request = new GetTradeBillRequest(); + request.setBillDate(day); + QueryBillEntity billEntity = billDownloadService.getTradeBill(request); + + return new Result().success(billEntity.getDownloadUrl()); + } + + + +} diff --git a/wechat-server/src/main/java/com/evotech/hd/wechat/utils/wechatpay/WechatPayUtil.java b/wechat-server/src/main/java/com/evotech/hd/wechat/utils/wechatpay/WechatPayUtil.java new file mode 100644 index 0000000..1610554 --- /dev/null +++ b/wechat-server/src/main/java/com/evotech/hd/wechat/utils/wechatpay/WechatPayUtil.java @@ -0,0 +1,28 @@ +package com.evotech.hd.wechat.utils.wechatpay; + +import com.wechat.pay.java.core.RSAAutoCertificateConfig; +import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest; +import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse; +import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension; + +/** + * 微信支付工具类 + */ +public class WechatPayUtil { + + /** + * JSAPI下单 + */ + public static PrepayWithRequestPaymentResponse jsapiPrepay(RSAAutoCertificateConfig config, PrepayRequest request) { + JsapiServiceExtension jsapiService = new JsapiServiceExtension.Builder().config(config).build(); + // 调用下单方法 + PrepayWithRequestPaymentResponse response = jsapiService.prepayWithRequestPayment(request); + return response; + } + + + + + + +} diff --git a/wechat-server/src/main/java/com/evotech/hd/wechat/utils/xcx/AccessTokenUtil.java b/wechat-server/src/main/java/com/evotech/hd/wechat/utils/xcx/AccessTokenUtil.java new file mode 100644 index 0000000..f31541d --- /dev/null +++ b/wechat-server/src/main/java/com/evotech/hd/wechat/utils/xcx/AccessTokenUtil.java @@ -0,0 +1,32 @@ +package com.evotech.hd.wechat.utils.xcx; + +import java.util.HashMap; +import java.util.Map; + +import cn.hutool.http.HttpUtil; + +/** + * 调用凭据 + */ +public class AccessTokenUtil { + + private static String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token"; + + + /** + * 获取接口调用凭据 + * GET https://api.weixin.qq.com/cgi-bin/token + * @param appid + * @param secret + * @return + */ + public static String accessToken(String appid, String secret) { + Map m = new HashMap(); + m.put("appid", appid); + m.put("secret", secret); + m.put("grant_type", "client_credential"); + String res = HttpUtil.get(accessTokenUrl, m); + return res; + } + +} diff --git a/wechat-server/src/main/java/com/evotech/hd/wechat/utils/xcx/LoginUtil.java b/wechat-server/src/main/java/com/evotech/hd/wechat/utils/xcx/LoginUtil.java new file mode 100644 index 0000000..e31770b --- /dev/null +++ b/wechat-server/src/main/java/com/evotech/hd/wechat/utils/xcx/LoginUtil.java @@ -0,0 +1,77 @@ +package com.evotech.hd.wechat.utils.xcx; + +import java.util.HashMap; +import java.util.Map; + +import cn.hutool.http.HttpUtil; + +/** + * 小程序登陆相关 + */ +public class LoginUtil { + + + private static String code2SessionUrl = "https://api.weixin.qq.com/sns/jscode2session"; + + private static String checkSessionKeyUrl = "https://api.weixin.qq.com/wxa/checksession?"; + + private static String resetUserSessionKeyUrl = "https://api.weixin.qq.com/wxa/resetusersessionkey"; + + + /** + * 小程序登陆 + * GET https://api.weixin.qq.com/sns/jscode2session + * @param js_code + * @return + */ + public static String code2Session(String appid, String secret, String js_code) { + Map m = new HashMap(); + m.put("appid", appid); + m.put("secret", secret); + m.put("js_code", js_code); + m.put("grant_type", "authorization_code"); + String res = HttpUtil.get(code2SessionUrl, m); + return res; + } + + + /** + * 检验登录态 + * GET https://api.weixin.qq.com/wxa/checksession?access_token=ACCESS_TOKEN&signature=SIGNATURE&openid=OPENID&sig_method=SIG_METHOD + * @param access_token + * @param openid + * @param signature + * @return + */ + public static String checkSessionKey(String access_token, String openid, String signature) { + Map m = new HashMap(); + m.put("access_token", access_token); + m.put("openid", openid); + m.put("signature", signature); + m.put("sig_method", "hmac_sha256"); + String params = HttpUtil.toParams(m); + String res = HttpUtil.get(checkSessionKeyUrl + params); + return res; + } + + + /** + * 重置登录态 + * GET https://api.weixin.qq.com/wxa/resetusersessionkey?access_token=ACCESS_TOKEN + * @param access_token + * @param openid + * @param signature + * @return + */ + public static String resetUserSessionKey(String access_token, String openid, String signature) { + Map m = new HashMap(); + m.put("access_token", access_token); + m.put("openid", openid); + m.put("signature", signature); + m.put("sig_method", "hmac_sha256"); +// String params = HttpUtil.toParams(m); + String res = HttpUtil.get(resetUserSessionKeyUrl, m); + return res; + } + +} diff --git a/wechat-server/src/main/java/com/evotech/hd/wechat/utils/xcx/PhoneNumberUtil.java b/wechat-server/src/main/java/com/evotech/hd/wechat/utils/xcx/PhoneNumberUtil.java new file mode 100644 index 0000000..4d83cf0 --- /dev/null +++ b/wechat-server/src/main/java/com/evotech/hd/wechat/utils/xcx/PhoneNumberUtil.java @@ -0,0 +1,31 @@ +package com.evotech.hd.wechat.utils.xcx; + +import java.util.HashMap; +import java.util.Map; + +import cn.hutool.http.HttpUtil; + +/** + * 小程序手机号 + */ +public class PhoneNumberUtil { + + +private static String getPhoneNumberUrl = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token="; + + + /** + * 微信手机号 + * POST https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=ACCESS_TOKEN + * @param + * @return + */ + public static String getPhoneNumber(String access_token, String openid, String code) { + Map m = new HashMap(); + m.put("openid", openid); + m.put("code", code); + String res = HttpUtil.post(getPhoneNumberUrl + access_token, m); + return res; + } + +} diff --git a/wechat-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/wechat-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 0000000..188b3d0 --- /dev/null +++ b/wechat-server/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,42 @@ +{"properties": [ + { + "name": "hbyt.xcx.appid", + "type": "java.lang.String", + "description": "A description for 'hbyt.xcx.appid'" + }, + { + "name": "hbyt.xcx.app-secret", + "type": "java.lang.String", + "description": "A description for 'hbyt.xcx.app-secret'" + }, + { + "name": "hbyt.xcx.mchid", + "type": "java.lang.String", + "description": "A description for 'hbyt.xcx.mchid'" + }, + { + "name": "hbyt.xcx.serial_no", + "type": "java.lang.String", + "description": "A description for 'hbyt.xcx.serial_no'" + }, + { + "name": "hbyt.xcx.api_v3_key", + "type": "java.lang.String", + "description": "A description for 'hbyt.xcx.api_v3_key'" + }, + { + "name": "hbyt.xcx.private_key_path", + "type": "java.lang.String", + "description": "A description for 'hbyt.xcx.private_key_path'" + }, + { + "name": "hbyt.xcx.notify_url", + "type": "java.lang.String", + "description": "A description for 'hbyt.xcx.notify_url'" + }, + { + "name": "hbyt.xcx.refund_notify_url", + "type": "java.lang.String", + "description": "A description for 'hbyt.xcx.refund_notify_url'" + } +]} \ No newline at end of file diff --git a/wechat-server/src/main/resources/application.yml b/wechat-server/src/main/resources/application.yml new file mode 100644 index 0000000..3dbf965 --- /dev/null +++ b/wechat-server/src/main/resources/application.yml @@ -0,0 +1,58 @@ +# 1. server +server: + port: 9104 + servlet: + context-path: /wechat +# 2.log +logging: + config: classpath:logback-spring.xml + level: + '[com.evotech.hd.wechat.dao]': debug +# 3.spring +spring: + # 服务名称必须带上,不然nacos服务列表中没有,也不会有注册成功的信息 + application: + name: wechat-server + config: + import: + - nacos:${spring.application.name}.yaml?refreshEnabled=true + cloud: + nacos: + serverAddr: 192.168.5.213:8848 + username: nacos + password: nacos + discovery: + register-enabled: true + #server-addr: 10.10.1.6:8848 +# ip: 10.10.1.2 + # 因添加了context-path,admin-server要想发现正确路径,需要加这个 + metadata: + management: + context-path: ${server.servlet.context-path}/actuator +# 为springbootadmin开启所有检查 +management: + endpoints: + web: + exposure: + include: "*" + endpoint: + health: + show-details: always + # xml文件中配置的日志文件的名称 + logfile: + external-file: /logs/wechat/wechat-server.log + +# 微信 +hbyt: + xcx: + appid: wx2ab384cf1e6f85a1 + app-secret: 6c55a398703529358eac398e2bc89ae2 + mchid: 1695885921 + serial_no: 32B3AF8FD49920B7455E6A38B7A2AFE9004632D0 + api_v3_key: KUSjZPPw96rVR2XvyBXHps3o7MvaAA0x + # 商户 API 证书私钥 + private_key_path: src/main/resources/static/key/apiclient_key.pem + # 支付回调地址 + notify_url: https://api.evo-techina.com/wechat/wechatpay/prepayback/msg + # 退款回调地址 + refund_notify_url: https://api.evo-techina.com/wechat/wechatpay/refundsback/msg \ No newline at end of file diff --git a/wechat-server/src/main/resources/logback-spring.xml b/wechat-server/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..5575e89 --- /dev/null +++ b/wechat-server/src/main/resources/logback-spring.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + ${CONTEXT_NAME} + + + + + + DEBUG + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %replace(%caller{1}){'\t|Caller.{1}0|\r\n', ''} -- %msg%n + + UTF-8 + + + + + + + ${LOG_PATH}/${CONTEXT_NAME}.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{50}.%M\(%line\) -- %msg%n + UTF-8 + + + + + ${LOG_PATH}/${CONTEXT_NAME}-%d{yyyy-MM-dd}-%i.log + + ${MAX_HISTORY} + + + ${MAX_FILE_SIZE} + + + + + + + + 512 + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/wechat-server/src/main/resources/static/key/apiclient_cert.pem b/wechat-server/src/main/resources/static/key/apiclient_cert.pem new file mode 100644 index 0000000..e9fc7c5 --- /dev/null +++ b/wechat-server/src/main/resources/static/key/apiclient_cert.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIELjCCAxagAwIBAgIUMrOvj9SZILdFXmo4t6Kv6QBGMtAwDQYJKoZIhvcNAQEL +BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT +FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg +Q0EwHhcNMjQxMDIxMDIzMzI5WhcNMjkxMDIwMDIzMzI5WjCBhzETMBEGA1UEAwwK +MTY5NTg4NTkyMTEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMTMwMQYDVQQL +DCrmsrPljJfkvIrnibnmnLrmorDorr7lpIfliLbpgKDmnInpmZDlhazlj7gxCzAJ +BgNVBAYTAkNOMREwDwYDVQQHDAhTaGVuWmhlbjCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAMQseTgQ1y3LHZdIVu9vsLL3rBCnfLXEwc+3W9v8lLK4dg/N +WL0Gw5GQZ9q+R461FK/+1ZZ6KpiXGz4kX8VMeBrlXRD4OY4i2YR/F0K+kl83EDLV +0xKrtGmSgDKnOOaFLW4M5ozvPNSpfZmk5WFXUk3H7rirgTZZ+dVEI4GPv9Fl8V86 +o5Z5ZSj3zOJXCyTtPDwNIrj/wwodKy1YJ/BU0pBU/XKt59k3P6+1E0cGi+kmW2e6 +O3ZhsiEsLt9s6zL43hwM3iEqKpzO6S+qduNTuocm6vZsiZrA9T4oEwQQW9USKEOe +IHWHkdJOoHnlpT0HkYQ7dm4WX1/3d0LStploBo8CAwEAAaOBuTCBtjAJBgNVHRME +AjAAMAsGA1UdDwQEAwID+DCBmwYDVR0fBIGTMIGQMIGNoIGKoIGHhoGEaHR0cDov +L2V2Y2EuaXRydXMuY29tLmNuL3B1YmxpYy9pdHJ1c2NybD9DQT0xQkQ0MjIwRTUw +REJDMDRCMDZBRDM5NzU0OTg0NkMwMUMzRThFQkQyJnNnPUhBQ0M0NzFCNjU0MjJF +MTJCMjdBOUQzM0E4N0FEMUNERjU5MjZFMTQwMzcxMA0GCSqGSIb3DQEBCwUAA4IB +AQCx0XwDawo2X2QBLEAhME5dGiDRwAcwu9ayYq0fkSIljNSseOjdG7e1nADShsW+ +vz1yl7rH/x3mnv6jqYuR5nIlMivI7xkjkeUPTckw3XIse7DrBdMDqep67Wti0kcd +hiQDW92+xa7sYTbvKM8j3WMGhK1fBbW+AUf3bcoz1Y0WdQ7YvnypjzGPW2hFWGV2 +3RWp7UrFj0EkCErDPucI/XFPEy4qG1eDNXbT1kFFzljfRtOi1SSLr7kaPAWGWC5A +YWf+tQoT0Qc17SFFbZlS4epdIgWIs1YbDyxyEzFSVdBz3mJkj3TRFzSLI5i1EXhq +o/C3B2tQHvlRAUSt9ASNMuqN +-----END CERTIFICATE----- diff --git a/wechat-server/src/main/resources/static/key/apiclient_key.pem b/wechat-server/src/main/resources/static/key/apiclient_key.pem new file mode 100644 index 0000000..bd45c3d --- /dev/null +++ b/wechat-server/src/main/resources/static/key/apiclient_key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDELHk4ENctyx2X +SFbvb7Cy96wQp3y1xMHPt1vb/JSyuHYPzVi9BsORkGfavkeOtRSv/tWWeiqYlxs+ +JF/FTHga5V0Q+DmOItmEfxdCvpJfNxAy1dMSq7RpkoAypzjmhS1uDOaM7zzUqX2Z +pOVhV1JNx+64q4E2WfnVRCOBj7/RZfFfOqOWeWUo98ziVwsk7Tw8DSK4/8MKHSst +WCfwVNKQVP1yrefZNz+vtRNHBovpJltnujt2YbIhLC7fbOsy+N4cDN4hKiqczukv +qnbjU7qHJur2bImawPU+KBMEEFvVEihDniB1h5HSTqB55aU9B5GEO3ZuFl9f93dC +0raZaAaPAgMBAAECggEAYqwL/MtbsEjuBV35fE2tjxdMkMPt0m+5HIWZyrjtAkgN ++jzLWajBTcJYuoni7EDguvVu8VVZf47hwQwCr/aaosyjVxnDuV6GEkLqrEO20/Wa +TDeJB2ceQ8vQd6ns0OZDx4rtnA3phv4JkvKB/cgyObVKudBqGbCAHWk8grqPPP8s +AAW+2vdsqpceI6CLlWQNiTmaxT67kISPrRY8P7wwrrEog7YYcU0UAyxW2WilisPE +IaXy+tuTxTcsVbXDEi2Yo3VFm9AudgG5+Vtxo3ZtalJOwFNi8MTjeQhK4qgM5PwO +gydqZmox5AZ/kabDG4V1pl//6I5H1Uc7d7JVhBF44QKBgQDr85C+td2OKUN5RhAx +KvVQtEyNVeU1n3NVExszW+j6QSXiN2SdSqOMn/XiYQGoH/HFbKEfZAXfvfaRTEQC +Rs0Vmp26bxXAO0t8gi1x+iZ6XA3MRimzx6QDDRQzH1R0Jr4AaIYqphvxVIcgrHBJ +KRxUokDJqm0UXL3JL58ZJnA87QKBgQDU16kIcLqYoyp1Q0HLTJIpflDAoy1u4ul0 +TLPb1l38sbSQdgobAJoOsuyfSX2VEukbw2o2oBWwhXs/2Onn1fR3k0AJr7xskckh ++bV4ema+YFgkCsvtXr941w4wwwGtvPvQIv4CcGvndKyptP4pFW/HlevW6gIyGkBK +deDpqXZd6wKBgCuuovx7pPHdt80q6HKB1nrDdmywG0grJen5KI8AlAhIqV/RC4KH +P/IX5yiq9uiOSW9YZhfup5u9inlp2illvDAkuNC8IhW9pIL/grRYMGl0w2UvFCdh +bX7XHAc+5J7AUWq37ybUK9Yo5P9qjTsuLj2I8F+lep5LcSNe+qBoWl0dAoGAMN1K +O1vWGxDqwH0ub8QmkkwjsfZEif6iZkbty/zNGySZNclDzKs4s0M0u+UdZcovpmYY +zm22TQ54G1JrcQRX2dP+kbq84ZgeuyQfG4fOasqnsa6g3uAvyUhmQ5+hlQecME64 +TksNGthYg6W/7CK1xPaQbIjQ9Du+otmpRzvWpv0CgYEAp0qkxXS1yoDbWuwQy3B/ +F3BngGf3SlHO37xwhGE2gOiKIOv0nLhp1ylyrAysloIvZzExCQkOj7OyWfz/hM/l +fS+WJSkaCzqiggAS3lT4zsn6URmI3MlWpWPqke6xq/+9HOmkiuDQ6uLhgcenm1T4 +Mp1tXVhA/d8Nd5Omp/UQnzs= +-----END PRIVATE KEY----- diff --git a/wechat-server/src/test/java/com/evotech/hd/wechat/WechatServerApplicationTests.java b/wechat-server/src/test/java/com/evotech/hd/wechat/WechatServerApplicationTests.java new file mode 100644 index 0000000..79582dc --- /dev/null +++ b/wechat-server/src/test/java/com/evotech/hd/wechat/WechatServerApplicationTests.java @@ -0,0 +1,23 @@ +package com.evotech.hd.wechat; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +import com.evotech.hd.wechat.service.AccessTokenService; + +import jakarta.annotation.Resource; + +@SpringBootTest +class WechatServerApplicationTests { + + @Resource + private AccessTokenService accessTokenService; + + + @Test + void contextLoads() { + String res = accessTokenService.getAccessToken(); + System.out.println(res); + } + +} diff --git a/wechat-server/src/test/java/com/evotech/hd/wechat/WechatSignTest.java b/wechat-server/src/test/java/com/evotech/hd/wechat/WechatSignTest.java new file mode 100644 index 0000000..5f935bc --- /dev/null +++ b/wechat-server/src/test/java/com/evotech/hd/wechat/WechatSignTest.java @@ -0,0 +1,23 @@ +package com.evotech.hd.wechat; + +import java.util.Base64; +import cn.hutool.crypto.SecureUtil; +import cn.hutool.crypto.asymmetric.Sign; +import cn.hutool.crypto.asymmetric.SignAlgorithm; + +public class WechatSignTest { + + public static void main(String[] args) { + String privateKey = "MIIEogIBAAKCAQEAptpm+qvIDCh/9wjU26SQCK26ogYkBhDrYxnAaw2JbbBsp1oDbHKk+1r381NeBUG2HEFAuU+Fr72u5ot3yKdzoF/FajAzQNKnm569/D3upKoi8mYBaST15Uig8j8qoUW1U217LL0jEHlSnHV3lcaDTXqDpTRR4Bfz9IqOgJgFZ8/oTfEomSrjrLYef81Eyxr7ZIMQXEKKEK7V4UXKS0+/fDsiG/cXidhzt8UbTL9vqXqxM2+IDImyO+FAc/tkBG55LmzxPto1Nq0WbnZzRM/wTzrd0I/8NlevxtFbphg4evlHjFNI7+GrqR87ViEwuAJJ9Je5QQjct5YJfFRWiZ5CMQIDAQABAoIBAGBi/GhEgezcHIg1ltlHaFlLGuxsRbUnYwM9phVxnXk7GJlYe2/TjpERjPkIqOC6hBwwadZjJORP3FCcMtc8PKRhjuZ377O7vU0915x2nnyLOGL1IE2AJ3iLi0ZFzTea0FPgg+5lWHM00s9FYI6qPcGtS41M+xtMWwZiYE3TBBRibHiY8ugGyaNAhiMKehyW05uApjlIF55wwCGxBkyESJpGRR/6853iHke6Ge+xVcMa9QmQdoH0QqL/8kT28PL568mJJr0Ow/83t4+dPe70YPzKAxgUnaDsHJqO+b8qH69AEs8rTI5h2Mon6pH+bJT66KUoiXhn+Kf+4LSshenRP10CgYEA1QJSfuFOWVRjrg3N/rAIc/Ak84BTZavbyrkqBSuoTs9i/nMI/hOzVxpDntg7Bx2Tctl6sZO3GioTxKdc/YYaTKci1TKBbeginpsqEQVgwkMCy8HpvUmRfyAMqLwZC4h9+j+NiZtuoFJDTCgv+WYbasX+kWYEUM21bnSYuO7yEQsCgYEAyIdPr9uzqPgzN34Tmx+CNTa16VjhBh+zkBtXRLDLhWBeIYxoYNJARD98Pb1XZdvpkZZWSk7MfaKo2/DomzyyyB/MbHWwAdFi3yb4y7uMJfyC1MzdUSNN3Vp579hJxHkJ+nN4Ys76yfcEeVOLnvUT1Z0KKCdIWRdT1Lgi+X1itzMCgYBJUXlPzwGG4fNFj97d0X23Wmt9nSgXkOYgi0eZbAOMzPmIF9R6kBFk49dur4Lx2g5Ms+r1gKC/0sfnIqxxX11iEQ1+UNoYGJUB/uql3TIG68XkmKR50P7RwRhaZBRC0gJ6xrFTMjsL2ATuC88niyvYvrn3FiRaI9RVZrDCxwxvLQKBgEXW4okEAqGBuAzGqztmkOnJoTehDdYdKmOxMgapcGiGdKJIjX3THDDoz3ONQyglnEZpTqpYoV3MTfU0BT8zt6x9bqwDnQY1D7NalmIWcqw0Mri8lQQSQKcsQLWo5aA466G/n5kCL1Qx5OwAjesRvhOyuvvbGpZ0ymyWqQ+tfLkDAoGATcul1L8y5D/wNVP1GXbXMZfBsFP3bbqy8c+Ashm6g8OLm2mGNntd5Z6h1KkID7Yksh+dZ6t7XaPBtGACXX5Eryr537JVvdX8hAVCp5HVtaN/9VBVP8Ka2e4sVS/xeNgOMQ7uzhRPBJ8HiTmdI1nHhDnYQpGiBgQn0Z5RAkSvFMk="; + String str = "GET\n"; + str += "/v3/refund/domestic/refunds/123123123123\n"; + str += "1554208460\n"; + str += "593BEC0C930BF1AFEB40B4A08C8FB242\n"; + str += "\n"; + + Sign sign = SecureUtil.sign(SignAlgorithm.SHA256withRSA, Base64.getDecoder().decode(privateKey), null); + String res = Base64.getEncoder().encodeToString(sign.sign(str)); + System.out.println(res); + } + +}