无关风月
2025-02-13 8236caa8042288fcb9b584c21d6157f713183626
Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/java/mx_charging_pile
53个文件已修改
3个文件已删除
78个文件已添加
7300 ■■■■■ 已修改文件
ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/ChargingGunFallbackFactory.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/ParkingLotFallbackFactory.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/ParkingRecordFallbackFactory.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/SiteFallbackFactory.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/feignClient/ChargingGunClient.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/feignClient/ParkingLotClient.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/feignClient/ParkingRecordClient.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/feignClient/SiteClient.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/factory/TCECClientFallbackFactory.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/factory/TransactionRecordClientFallbackFactory.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/feignClient/BmsDemandAndChargerExportationClient.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/feignClient/TCECClient.java 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/feignClient/TransactionRecordClient.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/vo/StartChargeResult.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-integration/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/factory/ChargingOrderAccountingStrategyFallbackFactory.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/factory/ChargingOrderFallbackFactory.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/ChargingOrderAccountingStrategyClient.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/ChargingOrderClient.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/OrderClient.java 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/AddTripartitePlatformOrder.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/TChargingOrder.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/vo/ChargingOrderListVO.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/vo/GetChargingOrderByLicensePlate.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/Operator.java 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/OperatorFallbackFactory.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/feignClient/OperatorClient.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-other/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/dto/ChargingPercentProvinceDto.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ObsUploadUtil.java 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/obs/OBSUtil.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/AntiShakeProperties.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysMenus.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/TCompanyToUserVo.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserVipDetailController.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/SiteController.java 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TAccountingStrategyController.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TAccountingStrategyDetailController.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TApplyChargingPileController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TChargingGunController.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TChargingPileController.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TParkingLotController.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TParkingRecordController.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/SiteServiceImpl.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/TChargingPileServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/barrierGate/server/ParkingOrderService.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/controller/TransactionRecordController.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/AESUtil.java 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/SignUtil.java 208 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECController.java 1599 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECUtil.java 379 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TokenUtil.java 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/kuaidian/TCECKDUtil.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/kuaidian/model/NotificationChargeCarnum.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/kuaidian/model/NotificationChargeCarnumResult.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/kuaidian/model/NotificationStationChangeResult.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/kuaidian/model/OrderInfo.java 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/kuaidian/model/QueryChargeOrderInfo.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/kuaidian/model/QueryChargeOrderInfoResult.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/kuaidian/model/QueryTerminalCode.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/kuaidian/model/QueryTerminalCodeResult.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/kuaidian/model/StationChange.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/BaseModel.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/BaseRequest.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/BaseResult.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/ChargeDetail.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/ConnectorInfo.java 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/ConnectorStatsInfo.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/ConnectorStatusInfo.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/ConnectorStatusInfo1.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/EquipmentInfo.java 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/EquipmentStatsInfo.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/NotificationChargeOrderInfo.java 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/NotificationChargeOrderInfoResult.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/NotificationEquipChargeStatusResult.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/NotificationStartCharge.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/NotificationStartChargeResult.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/NotificationStationStatusResult.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/NotificationStopCharge.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/NotificationStopChargeResult.java 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/OperatorInfo.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/PlaceHolder.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/PlaceHolderPrice.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/PolicyInfo.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryEquipAuth.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryEquipAuthResult.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryEquipBusinessPolicy.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryEquipBusinessPolicyResult.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryEquipChargeStatus.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryEquipChargeStatusResult.java 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryStartCharge.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryStartChargeResult.java 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryStationStats.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryStationStatsResult.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryStationStatus.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryStationStatusResult.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryStationsInfo.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryStationsInfoResult.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryStopCharge.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryStopChargeResult.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryToken.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryTokenResult.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/StationInfo.java 194 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/StationStatsInfo.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/StationStatusInfo.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/enu/ConnectorTypeEnum.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/enu/ConstructionEnum.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/enu/EquipmentTypeEnum.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/enu/InterfaceUrlEnum.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/enu/StationStatusEnum.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/enu/StationTypeEnum.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/builder/IotBuilder.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/mongodb/service/PingService.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/mongodb/service/PongService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/mongodb/service/impl/PingServiceImpl.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/mongodb/service/impl/PongServiceImpl.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/rocket/listener/UploadRealTimeMonitoringDataMessageListener.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/util/TaskUtil.java 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/resources/bootstrap.yml 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderAccountingStrategyController.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java 153 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TVipOrderController.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/dto/PayOrderInfoDto.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/TChargingOrderService.java 29 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingBillServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java 415 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/resources/bootstrap.yml 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/OperatorController.java 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/OssController.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/mapper/OperatorMapper.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/OperatorService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/OperatorServiceImpl.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TVipServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-other/src/main/resources/bootstrap.yml 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/ChargingGunFallbackFactory.java
@@ -64,7 +64,26 @@
            public R<String> updateChargingGunById(TChargingGun chargingGun) {
                return R.fail("编辑充电枪失败:" + throwable.getMessage());
            }
            @Override
            public R<List<TChargingGun>> getChargingGunByChargingPileId(Integer chargingPileId) {
                return R.fail("根据充电桩id获取枪失败:" + throwable.getMessage());
            }
            @Override
            public R<List<TChargingGun>> getChargingGunByChargingPileIds(List<Integer> chargingPileIds) {
                return R.fail("根据充电桩ids获取枪失败:" + throwable.getMessage());
            }
            @Override
            public R pushChargingGunStatus(Integer id, Integer status) {
                return R.fail("接口状态变化后推送给第三方失败:" + throwable.getMessage());
            }
            @Override
            public R<TChargingGun> getChargingGunByFullNumber(String fullNumber) {
                return R.fail("根据枪唯一码查询信息失败:" + throwable.getMessage());
            }
        };
    }
}
ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/ParkingLotFallbackFactory.java
@@ -34,7 +34,13 @@
            public R<TParkingLot> getLotBySiteId(Integer siteId) {
                return R.fail("通过站点id查询停车场信息调用失败:" + throwable.getMessage());
            }
            @Override
            public R<List<TParkingLot>> getAllParkingLot() {
                return R.fail("获取所有停车场数据失败:" + throwable.getMessage());
            }
            @Override
            public R<TParkingRecord> getRecordById(Long siteId) {
                return R.fail("通过id查询停车场记录:" + throwable.getMessage());
ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/ParkingRecordFallbackFactory.java
@@ -39,7 +39,12 @@
            public R<TParkingRecord> getParkingRecordById(Long id) {
                return R.fail("根据id获取数失败:" + throwable.getMessage());
            }
            @Override
            public R<TParkingRecord> getParkingRecordByChargingOrderId(Long chargingOrderId) {
                return R.fail("根据充电订单id获取数据失败:" + throwable.getMessage());
            }
            @Override
            public void addParkingRecord(TParkingRecord parkingRecord) {
            }
ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/SiteFallbackFactory.java
@@ -6,6 +6,7 @@
import com.ruoyi.chargingPile.api.model.Site;
import com.ruoyi.chargingPile.api.model.TChargingPile;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.web.page.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
@@ -58,6 +59,11 @@
            public R<List<Partner>> getAllPartner() {
                return null;
            }
            @Override
            public PageInfo<Site> getSiteListPaging(Integer PageNo, Integer PageSize) {
                return null;
            }
        };
    }
}
ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/feignClient/ChargingGunClient.java
@@ -9,10 +9,9 @@
import com.ruoyi.common.core.constant.ServiceNameConstants;
import com.ruoyi.common.core.domain.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.List;
@@ -73,5 +72,42 @@
     */
    @PostMapping("/t-charging-gun/updateChargingGunById")
    R<String> updateChargingGunById(@RequestBody TChargingGun chargingGun);
    /**
     * 根据充电桩id获取枪
     * @param chargingPileId
     * @return
     */
    @PostMapping("/t-charging-gun/getChargingGunByChargingPileId")
    R<List<TChargingGun>> getChargingGunByChargingPileId(@RequestParam("chargingPileId") Integer chargingPileId);
    /**
     * 根据充电桩ids获取枪
     * @param chargingPileIds
     * @return
     */
    @PostMapping("/t-charging-gun/getChargingGunByChargingPileIds")
    R<List<TChargingGun>> getChargingGunByChargingPileIds(@RequestParam("chargingPileIds") List<Integer> chargingPileIds);
    /**
     * 接口状态变化后推送给第三方
     * @param id
     * @param status
     * @return
     */
    @PostMapping("/t-charging-gun/pushChargingGunStatus")
    R pushChargingGunStatus(@RequestParam("id") Integer id, @RequestParam("status") Integer status);
    /**
     * 根据枪唯一码查询信息
     * @return
     */
    @PostMapping("/t-charging-gun/getChargingGunByFullNumber")
    R<TChargingGun> getChargingGunByFullNumber(@RequestParam("fullNumber") String fullNumber);
}
ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/feignClient/ParkingLotClient.java
@@ -27,13 +27,21 @@
     * 通过站点id查询停车场信息
     */
    @PostMapping(value = "/t-parking-lot/getLotBySiteId")
    public R<TParkingLot> getLotBySiteId(@RequestParam("siteId") Integer siteId);
    R<TParkingLot> getLotBySiteId(@RequestParam("siteId") Integer siteId);
    /**
     * 获取所有停车场数据
     */
    @PostMapping(value = "/t-parking-lot/getAllParkingLot")
    R<List<TParkingLot>> getAllParkingLot();
    @GetMapping(value = "/t-parking-lot/getRecordById")
    public R<TParkingRecord> getRecordById(@RequestParam("id") Long siteId);
    R<TParkingRecord> getRecordById(@RequestParam("id") Long siteId);
    @PostMapping(value = "/t-parking-lot/getRecordAmount")
    public R<BigDecimal> getRecordAmount(@RequestParam("sixBefore") LocalDate sixBefore);
    R<BigDecimal> getRecordAmount(@RequestParam("sixBefore") LocalDate sixBefore);
    
    
    /**
ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/feignClient/ParkingRecordClient.java
@@ -44,6 +44,15 @@
    R<TParkingRecord> getParkingRecordById(@RequestParam("id") Long id);
    
    
    /**
     * 根据充电订单id获取数据
     * @return
     */
    @PostMapping("/t-parking-record/getParkingRecordByChargingOrderId")
    R<TParkingRecord> getParkingRecordByChargingOrderId(@RequestParam("chargingOrderId") Long chargingOrderId);
    /**
     * 添加数据
     * @param parkingRecord
ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/feignClient/SiteClient.java
@@ -7,6 +7,7 @@
import com.ruoyi.chargingPile.api.model.TChargingPile;
import com.ruoyi.common.core.constant.ServiceNameConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.web.page.PageInfo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
@@ -42,4 +43,14 @@
    R<Partner> getPartnerR(@PathVariable("id") Integer id);
    @GetMapping("/partner/getAllPartner")
    public R<List<Partner>> getAllPartner();
    /**
     * 分页查询站电数据
     * @param PageNo
     * @param PageSize
     * @return
     */
    @PostMapping("/site/getSiteListPaging")
    PageInfo<Site> getSiteListPaging(@RequestParam("PageNo") Integer PageNo, @RequestParam("PageSize") Integer PageSize);
}
ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/factory/TCECClientFallbackFactory.java
New file
@@ -0,0 +1,52 @@
package com.ruoyi.integration.api.factory;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.integration.api.feignClient.TCECClient;
import com.ruoyi.integration.api.vo.StartChargeResult;
import org.springframework.cloud.openfeign.FallbackFactory;
import java.util.List;
/**
 * @author zhibing.pu
 * @Date 2025/1/24 10:33
 */
public class TCECClientFallbackFactory implements FallbackFactory<TCECClient> {
    @Override
    public TCECClient create(Throwable cause) {
        return new TCECClient() {
            @Override
            public R pushChargingGunStatus(Integer id, Integer status) {
                return R.fail("接口状态变化后推送给第三方失败:" + cause.getMessage());
            }
            @Override
            public R notificationStartChargeResult(StartChargeResult result) {
                return R.fail("启动充电结果推送失败:" + cause.getMessage());
            }
            @Override
            public R notificationEquipChargeStatus(String startChargeSeq, Integer operatorId) {
                return R.fail("推送充电状态失败:" + cause.getMessage());
            }
            @Override
            public R notificationStopChargeResult(String startChargeSeq, String connectorID, Integer operatorId) {
                return R.fail("推送停止充电结果失败:" + cause.getMessage());
            }
            @Override
            public R notificationChargeOrderInfo(String startChargeSeq, Integer operatorId) {
                return R.fail("推送订单信息失败:" + cause.getMessage());
            }
            @Override
            public R notificationStationChange(List<Integer> siteIds) {
                return R.fail("站点变更推送通知失败:" + cause.getMessage());
            }
        };
    }
}
ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/factory/TransactionRecordClientFallbackFactory.java
New file
@@ -0,0 +1,26 @@
package com.ruoyi.integration.api.factory;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.integration.api.feignClient.TransactionRecordClient;
import com.ruoyi.integration.api.model.TransactionRecord;
import org.springframework.cloud.openfeign.FallbackFactory;
/**
 * @author zhibing.pu
 * @Date 2025/2/13 14:20
 */
public class TransactionRecordClientFallbackFactory implements FallbackFactory<TransactionRecordClient> {
    @Override
    public TransactionRecordClient create(Throwable cause) {
        return new TransactionRecordClient() {
            @Override
            public R<TransactionRecord> findTransactionRecord(String code) {
                return R.fail("根据订单流水号查询账单数据失败:" + cause.getMessage());
            }
        };
    }
}
ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/feignClient/BmsDemandAndChargerExportationClient.java
@@ -22,6 +22,6 @@
     * @return
     */
    @PostMapping("/bmsDemandAndChargerExportation/getBmsDemandAndChargerExportation")
    R<BmsDemandAndChargerExportation> getBmsDemandAndChargerExportation(@RequestParam("orderCode") String orderCode);
    R<BmsDemandAndChargerExportation> getBmsDemandAndChargerExportation(@RequestParam(value = "orderCode") String orderCode);
}
ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/feignClient/TCECClient.java
New file
@@ -0,0 +1,82 @@
package com.ruoyi.integration.api.feignClient;
import com.ruoyi.common.core.constant.ServiceNameConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.integration.api.factory.TCECClientFallbackFactory;
import com.ruoyi.integration.api.vo.StartChargeResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
/**
 * @author zhibing.pu
 * @Date 2025/1/24 10:32
 */
@FeignClient(contextId = "TCECClient", value = ServiceNameConstants.INTEGRATION_SERVICE, fallbackFactory = TCECClientFallbackFactory.class)
public interface TCECClient {
    /**
     * 接口状态变化后推送给第三方
     * @return
     */
    @PostMapping("/evcs/v1.0/pushChargingGunStatus")
    R pushChargingGunStatus(@RequestParam("id") Integer id, @RequestParam("status") Integer status);
    /**
     * 启动充电结果推送
     * @param result
     * @return
     */
    @PostMapping("/evcs/v1.0/notificationStartChargeResult")
    R notificationStartChargeResult(@RequestBody StartChargeResult result);
    /**
     * 推送充电状态
     * @param startChargeSeq
     * @return
     */
    @PostMapping("/evcs/v1.0/notificationEquipChargeStatus")
    R notificationEquipChargeStatus(@RequestParam("startChargeSeq") String startChargeSeq, @RequestParam("operatorId") Integer operatorId);
    /**
     * 推送停止充电结果
     * @param startChargeSeq    充电订单号
     * @param connectorID       充电设备接口编码
     * @return
     */
    @PostMapping("/evcs/v1.0/notificationStopChargeResult")
    R notificationStopChargeResult(@RequestParam("startChargeSeq") String startChargeSeq, @RequestParam("connectorID") String connectorID,
                                          @RequestParam("operatorId") Integer operatorId);
    /**
     * 推送订单信息
     * @param startChargeSeq
     * @return
     */
    @PostMapping("/evcs/v1.0/notificationChargeOrderInfo")
    R notificationChargeOrderInfo(@RequestParam("startChargeSeq") String startChargeSeq, @RequestParam("operatorId") Integer operatorId);
    /**
     * 站点变更推送通知
     * @param siteIds
     * @return
     */
    @PostMapping("/evcs/v1.0/notificationStationChange")
    R notificationStationChange(@RequestParam("siteIds") List<Integer> siteIds);
}
ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/feignClient/TransactionRecordClient.java
New file
@@ -0,0 +1,26 @@
package com.ruoyi.integration.api.feignClient;
import com.ruoyi.common.core.constant.ServiceNameConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.integration.api.factory.TransactionRecordClientFallbackFactory;
import com.ruoyi.integration.api.model.TransactionRecord;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
 * @author zhibing.pu
 * @Date 2025/2/13 14:20
 */
@FeignClient(contextId = "TransactionRecordClient", value = ServiceNameConstants.INTEGRATION_SERVICE, fallbackFactory = TransactionRecordClientFallbackFactory.class)
public interface TransactionRecordClient {
    /**
     * 根据订单流水号查询账单数据
     * @param code
     * @return
     */
    @PostMapping("/transactionRecord/findTransactionRecord")
    R<TransactionRecord> findTransactionRecord(@RequestParam(value = "code") String code);
}
ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/vo/StartChargeResult.java
New file
@@ -0,0 +1,44 @@
package com.ruoyi.integration.api.vo;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 推送启动充电结果
 * @author zhibing.pu
 * @Date 2025/1/22 18:40
 */
@Data
public class StartChargeResult {
    /**
     * 充电订单号
     */
    @NotNull
    private String StartChargeSeq;
    /**
     * 充电订单状态
     * 1:启动中
     * 2:充电中
     * 3:停止中
     * 4:已结束
     * 5:未知
     */
    @NotNull
    private Integer StartChargeSeqStat;
    /**
     * 充电设别接口编码
     */
    @NotNull
    private String ConnectorID;
    /**
     * 充电启动时间
     * yyyy-MM-dd HH:mm:ss
     */
    @NotNull
    private String StartTime;
    /**
     * 合作商ID
     */
    private String operatorID;
}
ruoyi-api/ruoyi-api-integration/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -7,4 +7,6 @@
com.ruoyi.integration.api.factory.SwitchwayGateFallbackFactory
com.ruoyi.integration.api.factory.IotInterfaceFallbackFactory
com.ruoyi.integration.api.factory.SecurityDetectionFallbackFactory
com.ruoyi.integration.api.factory.BmsDemandAndChargerExportationFallbackFactory
com.ruoyi.integration.api.factory.BmsDemandAndChargerExportationFallbackFactory
com.ruoyi.integration.api.factory.TCECClientFallbackFactory
com.ruoyi.integration.api.factory.TransactionRecordClientFallbackFactory
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/factory/ChargingOrderAccountingStrategyFallbackFactory.java
@@ -4,6 +4,7 @@
import com.ruoyi.order.api.feignClient.ChargingOrderAccountingStrategyClient;
import com.ruoyi.order.api.feignClient.ChargingOrderClient;
import com.ruoyi.order.api.model.TChargingOrder;
import com.ruoyi.order.api.model.TChargingOrderAccountingStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
@@ -38,6 +39,11 @@
            public R<List<Double>> getDailyChargingDegree(Integer days, Set<Integer> siteIds) {
                return R.fail("获取给定天数每天的充电度数失败:" + throwable.getMessage());
            }
            @Override
            public R<List<TChargingOrderAccountingStrategy>> getChargingOrderAccountingStrategyByOrderId(Long chargingOrderId) {
                return R.fail("根据订单id查询充电明细失败:" + throwable.getMessage());
            }
        };
    }
}
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/factory/ChargingOrderFallbackFactory.java
@@ -4,6 +4,7 @@
import com.ruoyi.common.core.dto.ChargingOrderGroup;
import com.ruoyi.common.core.dto.ChargingPercentProvinceDto;
import com.ruoyi.order.api.feignClient.ChargingOrderClient;
import com.ruoyi.order.api.model.AddTripartitePlatformOrder;
import com.ruoyi.order.api.model.ChargingListQuery;
import com.ruoyi.order.api.model.TChargingOrder;
import com.ruoyi.order.api.model.TSettlementConfirm;
@@ -63,7 +64,12 @@
            public R<List<ChargingOrderGroup>> getBySiteIdAndTime(ChargingPercentProvinceDto chargingPercentProvinceDto) {
                return null;
            }
            @Override
            public R<List<TChargingOrder>> getOrderBySiteIdAndTime(ChargingPercentProvinceDto chargingPercentProvinceDto) {
                return R.fail("根据站点id和时间区间查询订单数据失败:" + throwable.getMessage());
            }
            @Override
            public R<Integer> getChargingCount(TChargingCountQuery req) {
                return R.fail("根据会员id和有效期查询有效期内享受充电折扣次数:" + throwable.getMessage());
@@ -174,6 +180,31 @@
            public R<List<TChargingOrder>> getCarChargingOrder(Long carId, String startTime, String endTime) {
                return R.fail("根据车辆id获取指定时间范围内的数据失败:" + throwable.getMessage());
            }
            @Override
            public R<List<TChargingOrder>> getCarChargingOrderByPlateNum(String plateNum, String startTime, String endTime) {
                return R.fail("根据车牌号查询指定时间范围内的数据失败:" + throwable.getMessage());
            }
            @Override
            public R addTripartitePlatformOrder(AddTripartitePlatformOrder query) {
                return R.fail("添加三方平台充电订单数据失败:" + throwable.getMessage());
            }
            @Override
            public R<TChargingOrder> getChargingOrderByStartChargeSeq(String startChargeSeq) {
                return R.fail("根据三方平台订单id获取充电数据失败:" + throwable.getMessage());
            }
            @Override
            public R<List<TChargingOrder>> getChargingOrderByStartChargeSeqs(List<String> startChargeSeqs) {
                return R.fail("根据三方平台订单ids获取充电数据失败" + throwable.getMessage());
            }
            @Override
            public R tripartitePlatformStopCharge(String startChargeSeq) {
                return R.fail("三方平台请求停止充电失败:" + throwable.getMessage());
            }
        };
    }
}
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/ChargingOrderAccountingStrategyClient.java
@@ -4,6 +4,7 @@
import com.ruoyi.common.core.domain.R;
import com.ruoyi.order.api.factory.ChargingOrderAccountingStrategyFallbackFactory;
import com.ruoyi.order.api.factory.ChargingOrderFallbackFactory;
import com.ruoyi.order.api.model.TChargingOrderAccountingStrategy;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@@ -38,4 +39,13 @@
     */
    @PostMapping("/t-charging-order-accounting-strategy/getDailyChargingDegree/{days}")
    R<List<Double>> getDailyChargingDegree(@PathVariable("days") Integer days, @RequestParam("siteIds") Set<Integer> siteIds);
    /**
     * 根据订单id查询充电明细
     * @param chargingOrderId
     * @return
     */
    @PostMapping("/t-charging-order-accounting-strategy/getChargingOrderAccountingStrategyByOrderId")
    R<List<TChargingOrderAccountingStrategy>> getChargingOrderAccountingStrategyByOrderId(@RequestParam("chargingOrderId") Long chargingOrderId);
}
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/ChargingOrderClient.java
@@ -6,6 +6,7 @@
import com.ruoyi.common.core.dto.ChargingPercentProvinceDto;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.order.api.factory.ChargingOrderFallbackFactory;
import com.ruoyi.order.api.model.AddTripartitePlatformOrder;
import com.ruoyi.order.api.model.ChargingListQuery;
import com.ruoyi.order.api.model.TChargingOrder;
import com.ruoyi.order.api.model.TSettlementConfirm;
@@ -42,6 +43,15 @@
    @PostMapping(value = "/t-charging-order/getBySiteIdAndTime")
    R<List<ChargingOrderGroup>> getBySiteIdAndTime(@RequestBody ChargingPercentProvinceDto chargingPercentProvinceDto);
    /**
     * 根据站点id和时间区间查询订单数据
     * @param chargingPercentProvinceDto
     * @return
     */
    @PostMapping(value = "/t-charging-order/getOrderBySiteIdAndTime")
    R<List<TChargingOrder>> getOrderBySiteIdAndTime(@RequestBody ChargingPercentProvinceDto chargingPercentProvinceDto);
@@ -235,5 +245,58 @@
     * @return
     */
    @PostMapping("/t-charging-order/getCarChargingOrder")
    R<List<TChargingOrder>> getCarChargingOrder(@RequestParam("carId") Long carId, @RequestParam("startTime") String startTime, @RequestParam("endTime") String endTime);
    R<List<TChargingOrder>> getCarChargingOrder(@RequestParam("carId") Long carId, @RequestParam("startTime") String startTime,
                                                @RequestParam("endTime") String endTime);
    /**
     * 根据车牌号查询指定时间范围内的数据
     * @param plateNum
     * @param startTime
     * @param endTime
     * @return
     */
    @PostMapping("/t-charging-order/getCarChargingOrderByPlateNum")
    R<List<TChargingOrder>> getCarChargingOrderByPlateNum(@RequestParam("plateNum") String plateNum, @RequestParam("startTime") String startTime,
                                                @RequestParam("endTime") String endTime);
    /**
     * 添加三方平台充电订单数据
     * @return
     */
    @PostMapping("/t-charging-order/addTripartitePlatformOrder")
    R addTripartitePlatformOrder(@RequestBody AddTripartitePlatformOrder query);
    /**
     * 根据三方平台订单id获取充电数据
     * @param startChargeSeq
     * @return
     */
    @PostMapping("/t-charging-order/getChargingOrderByStartChargeSeq")
    R<TChargingOrder> getChargingOrderByStartChargeSeq(@RequestParam("startChargeSeq") String startChargeSeq);
    /**
     * 根据三方平台订单ids获取充电数据
     * @param startChargeSeqs
     * @return
     */
    @PostMapping("/t-charging-order/getChargingOrderByStartChargeSeqs")
    R<List<TChargingOrder>> getChargingOrderByStartChargeSeqs(@RequestParam("startChargeSeqs") List<String> startChargeSeqs);
    /**
     * 三方平台请求停止充电
     * @param startChargeSeq
     * @return
     */
    @PostMapping("/t-charging-order/tripartitePlatformStopCharge")
    R tripartitePlatformStopCharge(@RequestParam("startChargeSeq") String startChargeSeq);
}
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/OrderClient.java
@@ -24,10 +24,16 @@
 */
@FeignClient(contextId = "OrderClient", value = ServiceNameConstants.ORDER_SERVICE, fallbackFactory = OrderFallbackFactory.class)
public interface OrderClient {
    @PostMapping(value = "/t-charging-order/management/give/vip")
    public R managementGiveVip(@RequestBody TGrantVip grantVip);
    R managementGiveVip(@RequestBody TGrantVip grantVip);
    @GetMapping("/t-exchange-order/getSalesCountByGoodsIds/{goodsIds}")
    R<List<Integer>> getSalesCountByGoodsId(@PathVariable("goodsIds") String goodsIds);
    @GetMapping("/t-exchange-order/getCount")
    R<Integer> getSalesCountByGoodsIdgetCount(@RequestParam("goodId") Integer goodId,@RequestParam("goodeType")Integer goodeType,@RequestParam("buyType")Integer buyType);
@@ -37,21 +43,31 @@
     * @return
     */
    @GetMapping("/t-exchange-order/getCodeByOrderId/{goodsIds}")
    public R<List<String>> getCodeByOrderId(@PathVariable("goodsIds")String goodsIds);
    R<List<String>> getCodeByOrderId(@PathVariable("goodsIds")String goodsIds);
    //查询已兑换的订单数
    @PostMapping("/t-exchange-order/getById")
    public R<Long> getExchangeById(@RequestParam("goodId") Integer goodId,@RequestParam("userId")  Long userId,@RequestParam("goodType") Integer goodType);
    R<Long> getExchangeById(@RequestParam("goodId") Integer goodId,@RequestParam("userId")  Long userId,@RequestParam("goodType") Integer goodType);
    @PostMapping("/t-exchange-order/create")
    public R<ExchangeBackDto> exchangeCreate(@RequestBody ExchangeDto exchangeDto);
    R<ExchangeBackDto> exchangeCreate(@RequestBody ExchangeDto exchangeDto);
    @PostMapping("/t-vip-order/addVipOrder1")
    public R<Long> addVipOrder(@RequestBody TVipOrder vipOrder);
    R<Long> addVipOrder(@RequestBody TVipOrder vipOrder);
    @PostMapping("/t-shopping-order/create")
    public R<TShoppingOrder> shopCreate(@RequestBody ExchangeDto exchangeDto);
    R<TShoppingOrder> shopCreate(@RequestBody ExchangeDto exchangeDto);
    @PostMapping("/t-shopping-order/callBack")
    public R callBack(@RequestParam("code")String code,@RequestParam("outTradeNo")String outTradeNo);
    R callBack(@RequestParam("code")String code,@RequestParam("outTradeNo")String outTradeNo);
    @PostMapping("/t-vip-order/callBack")
    public R vipCallBack(@RequestParam("code")String code,@RequestParam("outTradeNo")String outTradeNo);
    R vipCallBack(@RequestParam("code")String code,@RequestParam("outTradeNo")String outTradeNo);
    /**
@@ -61,6 +77,8 @@
     */
    @PostMapping(value = "/t-exchange-order/activityStatistics")
    R<TActivityVO> activityStatistics(@RequestBody TActivityStatisticsQuery dto);
    @PostMapping(value = "/chargingBill/accountBillList")
    @ApiOperation(value = "列表查询", tags = {"管理后台-账户结算账单"})
    R<AccountListVO> accountBillList(@RequestBody ChargingListQuery dto);
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/AddTripartitePlatformOrder.java
New file
@@ -0,0 +1,39 @@
package com.ruoyi.order.api.model;
import lombok.Data;
import javax.validation.constraints.Null;
import java.math.BigDecimal;
/**
 * @author zhibing.pu
 * @Date 2025/1/22 18:20
 */
@Data
public class AddTripartitePlatformOrder {
    /**
     * 三方充电订单号
     */
    private String startChargeSeq;
    /**
     * 充电枪id
     */
    private Integer chargingGunId;
    /**
     * 运营商id
     */
    private String operatorId;
    /**
     * 支付方式(0=未知,1=微信,2=支付宝)
     */
    private Integer rechargePaymentType;
    /**
     * 充电余额
     */
    private BigDecimal paymentAmount;
    /**
     * 充电车牌号
     */
    @Null
    private String PlateNum;
}
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/TChargingOrder.java
@@ -48,9 +48,18 @@
    @ApiModelProperty(value = "订单类型(1=充电订单(小程序),2=充电订单(刷卡))")
    @TableField("order_type")
    private Integer orderType;
    @ApiModelProperty(value = "0平台1其他")
    @ApiModelProperty(value = "订单来源(1=自己平台,2=三方平台)")
    @TableField("order_source")
    private Integer orderSource;
    @ApiModelProperty(value = "运营商id")
    @TableField("operator_id")
    private Integer operatorId;
    @ApiModelProperty(value = "三方平台名称")
    @TableField("tripartite_platform_name")
    private String tripartitePlatformName;
    @ApiModelProperty(value = "三方平台充电订单号")
    @TableField("start_charge_seq")
    private String startChargeSeq;
    @ApiModelProperty(value = "平台或其他第三分名字")
    @TableField("source_name")
@@ -74,6 +83,10 @@
    @TableField("app_user_car_id")
    private Long appUserCarId;
    @ApiModelProperty(value = "充电车辆车牌号")
    @TableField("plate_num")
    private String plateNum;
    @ApiModelProperty(value = "站点 id")
    @TableField("site_id")
    private Integer siteId;
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/vo/ChargingOrderListVO.java
@@ -29,6 +29,8 @@
    private Long appUserId;
    @ApiModelProperty(value = "用户车辆id")
    private Long appUserCarId;
    @ApiModelProperty(value = "车牌号")
    private String plateNum;
    @ApiModelProperty(value = "充电枪id")
    private Integer chargingGunId;
    @ApiModelProperty(value = "订单编号")
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/vo/GetChargingOrderByLicensePlate.java
@@ -18,7 +18,7 @@
    /**
     * 开始时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime startTime;
    
}
ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/Operator.java
New file
@@ -0,0 +1,121 @@
package com.ruoyi.other.api.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
/**
 * 运营商信息
 * @author zhibing.pu
 * @Date 2025/1/22 15:05
 */
@Data
@TableName("t_operator")
public class Operator {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    /**
     * 运营商唯一码
     */
    @TableField("operatorId")
    private String operatorId;
    /**
     * 运营商名称
     */
    @TableField("name")
    private String name;
    /**
     * 运营商秘钥
     */
    @TableField("operatorSecret")
    private String operatorSecret;
    /**
     * 数据加密秘钥
     */
    @TableField("dataSecret")
    private String dataSecret;
    /**
     * 初始化向量
     */
    @TableField("dataSecretIv")
    private String dataSecretIv;
    /**
     * 签名秘钥
     */
    @TableField("sigSecret")
    private String sigSecret;
    /**
     * 测试接口地址
     */
    @TableField("test_url")
    private String testUrl;
    /**
     * 接口地址
     */
    @TableField("url")
    private String url;
    /**
     * 各平台登录token
     */
    @TableField("accessToken")
    private String accessToken;
    /**
     * token过期时间(秒)
     */
    @TableField("tokenAvailableTime")
    private Long tokenAvailableTime;
    /**
     * 我方运营商唯一码
     */
    @TableField("ourOperatorId")
    private String ourOperatorId;
    /**
     * 我方运营商名称
     */
    @TableField("ourName")
    private String ourName;
    /**
     * 我方运营商秘钥
     */
    @TableField("ourOperatorSecret")
    private String ourOperatorSecret;
    /**
     * 我方数据加密秘钥
     */
    @TableField("ourDataSecret")
    private String ourDataSecret;
    /**
     * 我方初始化向量
     */
    @TableField("ourDataSecretIv")
    private String ourDataSecretIv;
    /**
     * 我方签名秘钥
     */
    @TableField("ourSigSecret")
    private String ourSigSecret;
    /**
     * token
     */
    @TableField(exist = false)
    private String token;
    /**
     * 登录时间
     */
    @TableField(exist = false)
    private Long loginTime;
    /**
     * 过期时间
     */
    @TableField(exist = false)
    private Long expireTime;
}
ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/OperatorFallbackFactory.java
New file
@@ -0,0 +1,47 @@
package com.ruoyi.other.api.factory;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.other.api.domain.Operator;
import com.ruoyi.other.api.feignClient.OperatorClient;
import org.springframework.cloud.openfeign.FallbackFactory;
import java.util.List;
/**
 * @author zhibing.pu
 * @Date 2025/1/22 15:16
 */
public class OperatorFallbackFactory implements FallbackFactory<OperatorClient> {
    @Override
    public OperatorClient create(Throwable cause) {
        return new OperatorClient() {
            @Override
            public R<Operator> getOperatorById(Integer id) {
                return R.fail("获取运营商数据失败:" + cause.getMessage());
            }
            @Override
            public R<Operator> getOperatorByName(String name) {
                return R.fail("获取运营商数据失败:" + cause.getMessage());
            }
            @Override
            public R<Operator> getOperator(String operatorId) {
                return R.fail("获取运营商数据失败:" + cause.getMessage());
            }
            @Override
            public R<List<Operator>> getAllOperator() {
                return R.fail("获取所有运营商失败:" + cause.getMessage());
            }
            @Override
            public R editOperator(Operator operator) {
                return R.fail("更新运营商数据失败:" + cause.getMessage());
            }
        };
    }
}
ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/feignClient/OperatorClient.java
New file
@@ -0,0 +1,63 @@
package com.ruoyi.other.api.feignClient;
import com.ruoyi.common.core.constant.ServiceNameConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.other.api.domain.Operator;
import com.ruoyi.other.api.factory.OperatorFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
/**
 * @author zhibing.pu
 * @Date 2025/1/22 15:15
 */
@FeignClient(contextId = "OperatorClient", value = ServiceNameConstants.OTHER_SERVICE, fallbackFactory = OperatorFallbackFactory.class)
public interface OperatorClient {
    /**
     * 获取运营商数据
     * @param id
     * @return
     */
    @PostMapping("/operator/getOperatorById")
    R<Operator> getOperatorById(@RequestParam("id") Integer id);
    /**
     * 获取运营商数据
     * @param name
     * @return
     */
    @PostMapping("/operator/getOperatorByName")
    R<Operator> getOperatorByName(@RequestParam("name") String name);
    /**
     * 获取运营商数据
     * @param operatorId
     * @return
     */
    @PostMapping("/operator/getOperator")
    R<Operator> getOperator(@RequestParam("operatorId") String operatorId);
    /**
     * 获取所有运营商
     * @return
     */
    @PostMapping("/operator/getAllOperator")
    R<List<Operator>> getAllOperator();
    /**
     * 更新运营商数据
     * @return
     */
    @PostMapping("/operator/editOperator")
    R editOperator(@RequestBody Operator operator);
}
ruoyi-api/ruoyi-api-other/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -8,4 +8,5 @@
com.ruoyi.other.api.factory.CouponFallbackFactory
com.ruoyi.other.api.factory.InvoiceTypeFallbackFactory
com.ruoyi.other.api.factory.WebSocketFallbackFactory
com.ruoyi.other.api.factory.UserTagFallbackFactory
com.ruoyi.other.api.factory.UserTagFallbackFactory
com.ruoyi.other.api.factory.OperatorFallbackFactory
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/dto/ChargingPercentProvinceDto.java
@@ -9,8 +9,9 @@
@Data
public class ChargingPercentProvinceDto {
    String provinceCode;
    LocalDate date1;
    LocalDate date2;
    Set<Integer> siteIds;
    private String provinceCode;
    private LocalDate date1;
    private LocalDate date2;
    private Set<Integer> siteIds;
    private String tripartitePlatformName;
}
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ObsUploadUtil.java
File was deleted
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/obs/OBSUtil.java
File was deleted
ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/AntiShakeProperties.java
@@ -4,6 +4,9 @@
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
/**
 * @author ruoyi
 */
@@ -15,6 +18,10 @@
    private Boolean enable;
    
    private Long interval;
    /**
     * 放行白名单配置,网关不校验此处的白名单
     */
    private List<String> whites = new ArrayList<>();
    
    public Boolean getEnable() {
        return enable;
@@ -31,4 +38,12 @@
    public void setInterval(Long interval) {
        this.interval = interval;
    }
    public List<String> getWhites() {
        return whites;
    }
    public void setWhites(List<String> whites) {
        this.whites = whites;
    }
}
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysMenus.java
@@ -81,7 +81,7 @@
    @TableField("create_by")
    private String createBy;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @TableField("create_time")
    private Date createTime;
@@ -92,7 +92,7 @@
    private String updateBy;
    /** 更新时间 */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @TableField("update_time")
    private Date updateTime;
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/TCompanyToUserVo.java
@@ -19,9 +19,9 @@
    private String status;
    private List<String> shopName;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date createTime;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date loginDate;
    private String userName;
ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserVipDetailController.java
@@ -49,11 +49,7 @@
                .last(" and now() between start_time and end_time"));
        return R.ok(one);
    }
    @Resource
    private VipClient vipClient;
    @Resource
    private OtherClient otherClient;
    @GetMapping("/getVipUseDetail")
    @ApiOperation(value = "生效会员列表", tags = {"小程序-个人中心"})
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/SiteController.java
@@ -332,8 +332,7 @@
        return R.ok(divide);
    }
    @Resource
    private SiteClient siteClient;
    
@@ -611,4 +610,18 @@
        List<Site> list = siteService.list(new LambdaQueryWrapper<Site>().eq(Site::getDelFlag, 0));
        return R.ok(list);
    }
    /**
     * 分页查询站电数据
     * @param PageNo
     * @param PageSize
     * @return
     */
    @PostMapping("/getSiteListPaging")
    public PageInfo<Site> getSiteListPaging(@RequestParam("PageNo") Integer PageNo, @RequestParam("PageSize") Integer PageSize){
        PageInfo<Site> pageInfo = new PageInfo<>(PageNo, PageSize);
        PageInfo<Site> page = siteService.lambdaQuery().eq(Site::getStatus, 1).page(pageInfo);
        return page;
    }
}
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TAccountingStrategyController.java
@@ -28,6 +28,7 @@
import com.ruoyi.common.security.service.TokenService;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.integration.api.feignClient.IntegrationClient;
import com.ruoyi.integration.api.feignClient.TCECClient;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.feignClient.SysUserClient;
import io.swagger.annotations.ApiOperation;
@@ -44,6 +45,7 @@
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import static com.ruoyi.common.core.context.SecurityContextHolder.getUserId;
@@ -66,11 +68,14 @@
    private TChargingPileService chargingPileService;
    @Autowired
    private ISiteService siteService;
    @Autowired
    @Resource
    private SysUserClient sysUserClient;
    
    @Resource
    private IntegrationClient integrationClient;
    @Resource
    private TCECClient tcecClient;
    @Autowired
@@ -386,12 +391,12 @@
                        site.setAccountingStrategyId(byId.getId());
                    }
                    siteService.updateBatchById(list);
                    //
                    //
                    accountingStrategyService.removeById(one.getId());
                    //推送三方平台
                    List<Integer> siteIds = list.stream().map(Site::getId).collect(Collectors.toList());
                    tcecClient.notificationStationChange(siteIds);
                }
                //硬件
    
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TAccountingStrategyDetailController.java
@@ -187,7 +187,8 @@
     */
    @GetMapping("/getListByAccountingStrategyId")
    public R<List<TAccountingStrategyDetail>> getListByAccountingStrategyId(@RequestParam("id") Integer id){
        List<TAccountingStrategyDetail> list = accountingStrategyDetailService.list(new LambdaQueryWrapper<TAccountingStrategyDetail>().eq(TAccountingStrategyDetail::getAccountingStrategyId, id));
        List<TAccountingStrategyDetail> list = accountingStrategyDetailService.list(new LambdaQueryWrapper<TAccountingStrategyDetail>()
                .eq(TAccountingStrategyDetail::getAccountingStrategyId, id).orderByAsc(TAccountingStrategyDetail::getStartTime));
        return R.ok(list);
    }
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TApplyChargingPileController.java
@@ -455,6 +455,8 @@
                        settlementExportVO.setVehicleBrand(data5.get(0).getVehicleBrand());
                    }
                }else{
                    settlementExportVO.setLicensePlate(chargingOrder.getPlateNum());
                }
                settlementExportVO.setSiteCode(data3.get(0).getCode());
                settlementExportVO.setSiteName(data3.get(0).getName());
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TChargingGunController.java
@@ -310,5 +310,43 @@
        chargingGunService.updateById(chargingGun);
        return R.ok();
    }
    /**
     * 根据充电桩id获取枪
     * @param chargingPileId
     * @return
     */
    @PostMapping("/getChargingGunByChargingPileId")
    public R<List<TChargingGun>> getChargingGunByChargingPileId(@RequestParam("chargingPileId") Integer chargingPileId){
        List<TChargingGun> list = chargingGunService.list(new LambdaQueryWrapper<TChargingGun>().eq(TChargingGun::getChargingPileId, chargingPileId)
                .eq(TChargingGun::getDelFlag, 0));
        return R.ok(list);
    }
    /**
     * 根据充电桩ids获取枪
     * @param chargingPileIds
     * @return
     */
    @PostMapping("/getChargingGunByChargingPileIds")
    public R<List<TChargingGun>> getChargingGunByChargingPileIds(@RequestParam("chargingPileIds") List<Integer> chargingPileIds){
        List<TChargingGun> list = chargingGunService.list(new LambdaQueryWrapper<TChargingGun>().in(TChargingGun::getChargingPileId, chargingPileIds)
                .eq(TChargingGun::getDelFlag, 0));
        return R.ok(list);
    }
    /**
     * 根据枪唯一码查询信息
     * @return
     */
    @PostMapping("/getChargingGunByFullNumber")
    public R<TChargingGun> getChargingGunByFullNumber(@RequestParam("fullNumber") String fullNumber){
        TChargingGun chargingGun = chargingGunService.getOne(new LambdaQueryWrapper<TChargingGun>().eq(TChargingGun::getDelFlag, 0).eq(TChargingGun::getFullNumber, fullNumber));
        return R.ok(chargingGun);
    }
}
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TChargingPileController.java
@@ -30,6 +30,7 @@
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.common.security.annotation.Logical;
import com.ruoyi.common.security.annotation.RequiresPermissions;
import com.ruoyi.integration.api.feignClient.TCECClient;
import com.ruoyi.order.api.feignClient.ChargingOrderClient;
import com.ruoyi.order.api.model.TChargingOrder;
import com.ruoyi.order.api.vo.TChargingOrderVo;
@@ -74,6 +75,9 @@
    
    @Resource
    private ChargingOrderClient chargingOrderClient;
    @Resource
    private TCECClient tcecClient;
    @Autowired
@@ -259,6 +263,9 @@
                tChargingGun1.setId(tChargingGun.getId());
                tChargingGun1.setStatus(2);
                chargingGunService.updateById(tChargingGun1);
                //推送状态给三方平台
                tcecClient.pushChargingGunStatus(tChargingGun.getId(), tChargingGun1.getStatus());
                if(chargingPile.getStatus() != 1){
                    TChargingPile chargingPile1 = new TChargingPile();
                    chargingPile1.setId(chargingPile.getId());
@@ -279,6 +286,8 @@
                tChargingGun1.setId(tChargingGun.getId());
                tChargingGun1.setStatus(7);
                chargingGunService.updateById(tChargingGun1);
                //推送状态给三方平台
                tcecClient.pushChargingGunStatus(tChargingGun.getId(), tChargingGun1.getStatus());
                
                //桩处于正常,桩所属的枪都处于非正常,修改桩状态为异常
                List<TChargingGun> list = chargingGunService.list(new LambdaQueryWrapper<TChargingGun>().eq(TChargingGun::getChargingPileId, chargingPile.getId()).eq(TChargingGun::getDelFlag, 0));
@@ -321,11 +330,16 @@
                    }
                    tChargingGun1.setId(tChargingGun.getId());
                    chargingGunService.updateById(tChargingGun1);
                    //推送状态给三方平台
                    tcecClient.pushChargingGunStatus(tChargingGun.getId(), tChargingGun1.getStatus());
                }else{
                    TChargingGun tChargingGun1 = new TChargingGun();
                    tChargingGun1.setId(tChargingGun.getId());
                    tChargingGun1.setStatus(3);
                    chargingGunService.updateById(tChargingGun1);
                    //推送状态给三方平台
                    tcecClient.pushChargingGunStatus(tChargingGun.getId(), tChargingGun1.getStatus());
                }
                
                List<TFaultMessage> list = faultMessageService.list(new LambdaQueryWrapper<TFaultMessage>().eq(TFaultMessage::getChargingGunId, tChargingGun.getId())
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TParkingLotController.java
@@ -158,6 +158,19 @@
    }
    
    
    /**
     * 获取所有停车场数据
     */
    @PostMapping(value = "/getAllParkingLot")
    public R<List<TParkingLot>> getAllParkingLot(){
        List<TParkingLot> list = parkingLotService.list(new LambdaQueryWrapper<TParkingLot>()
                .eq(TParkingLot::getDelFlag, 0));
        return R.fail(list);
    }
    @RequiresPermissions(value = {"/paymentOrder/order"}, logical = Logical.OR)
    @GetMapping(value = "/getRecordById")
    public R<TParkingRecord> getRecordById(@RequestParam("id") Long id){
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TParkingRecordController.java
@@ -264,6 +264,20 @@
    }
    
    
    /**
     * 根据充电订单id获取数据
     * @return
     */
    @PostMapping("/getParkingRecordByChargingOrderId")
    public R<TParkingRecord> getParkingRecordByChargingOrderId(@RequestParam("chargingOrderId") Long chargingOrderId){
        TParkingRecord parkingRecord = parkingRecordService.getOne(new LambdaQueryWrapper<TParkingRecord>()
                .eq(TParkingRecord::getChargingOrderId, chargingOrderId));
        return R.ok(parkingRecord);
    }
    /**
     * 添加数据
     * @param parkingRecord
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/SiteServiceImpl.java
@@ -25,6 +25,7 @@
import com.ruoyi.common.security.service.TokenService;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.integration.api.feignClient.IntegrationClient;
import com.ruoyi.integration.api.feignClient.TCECClient;
import com.ruoyi.other.api.domain.TVip;
import com.ruoyi.other.api.feignClient.RoleSiteClient;
import com.ruoyi.other.api.feignClient.UserSiteClient;
@@ -72,8 +73,6 @@
    @Resource
    private AppUserClient appUserClient;
    @Resource
    private VipClient vipClient;
    @Resource
    private SysUserRoleClient sysUserRoleClient;
    @Resource
    private TParkingLotService parkingLotService;
@@ -88,6 +87,9 @@
    
    @Resource
    private TPartnerSiteService partnerSiteService;
    @Resource
    private TCECClient tcecClient;
    
    
    /**
@@ -462,5 +464,8 @@
        for (TChargingPile tChargingPile : list1) {
            integrationClient.setupBillingModel1(tChargingPile.getCode(), JSON.toJSONString(accountingStrategyDetails));
        }
        //推送三方平台
        tcecClient.notificationStationChange(Arrays.asList(id));
    }
}
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/TChargingPileServiceImpl.java
@@ -26,10 +26,7 @@
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.common.security.service.TokenService;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.integration.api.feignClient.IntegrationClient;
import com.ruoyi.integration.api.feignClient.IotInterfaceClient;
import com.ruoyi.integration.api.feignClient.SendMessageClient;
import com.ruoyi.integration.api.feignClient.UploadRealTimeMonitoringDataClient;
import com.ruoyi.integration.api.feignClient.*;
import com.ruoyi.integration.api.model.QrCodeDelivery;
import com.ruoyi.integration.api.model.UploadRealTimeMonitoringData;
import com.ruoyi.integration.api.vo.AddDevice;
@@ -69,6 +66,9 @@
    
    @Resource
    private TChargingGunService chargingGunService;
    @Resource
    private TCECClient tcecClient;
    
    @Resource
    private SysUserClient sysUserClient;
@@ -615,6 +615,8 @@
                    if(null != appUserCarId){
                        TAppUserCar tAppUserCar = appUserCarClient.getCarByIds(Arrays.asList(appUserCarId)).getData().get(0);
                        gunMonitoring.setLicensePlate(tAppUserCar.getLicensePlate());
                    }else{
                        gunMonitoring.setLicensePlate(chargingOrder.getPlateNum());
                    }
                    UploadRealTimeMonitoringData data = uploadRealTimeMonitoringDataClient.chargingOrderInfo(chargingOrder.getCode()).getData();
@@ -696,6 +698,8 @@
                chargingGun1.setId(chargingGun.getId());
                chargingGun1.setStatus(1);
                chargingGunService.updateById(chargingGun1);
                //推送状态给三方平台
                tcecClient.pushChargingGunStatus(chargingGun1.getId(), chargingGun1.getStatus());
                
                //桩处于正常,桩所属的枪都处于非正常,修改桩状态为异常
                TChargingPile chargingPile = this.getById(chargingGun.getChargingPileId());
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/barrierGate/server/ParkingOrderService.java
@@ -9,6 +9,7 @@
import com.ruoyi.chargingPile.api.model.TParkingLot;
import com.ruoyi.chargingPile.api.model.TParkingRecord;
import com.ruoyi.chargingPile.api.vo.GetParkingRecord;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.integration.barrierGate.model.CloudParkingOrder;
import com.ruoyi.integration.barrierGate.model.CloudParkingSpace;
import com.ruoyi.integration.barrierGate.model.OfflineParkingOrder;
@@ -98,24 +99,33 @@
        parkingRecord.setOutParkingType(BigDecimal.ZERO.compareTo(payment) == 0 ? 2 : 1);
        parkingRecord.setTitle("【停车缴费】" + payment + "元");
        TAppUserCar appUserCar = appUserCarClient.getAppUserCarByLicensePlate(parkingRecord.getLicensePlate()).getData();
        TChargingOrder chargingOrder = null;
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        if(null != appUserCar){
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            List<TChargingOrder> data = chargingOrderClient.getCarChargingOrder(appUserCar.getId(), parkingRecord.getInParkingTime().format(formatter), LocalDateTime.now().format(formatter)).getData();
            if(null != data && data.size() > 0){
                TChargingOrder chargingOrder = data.get(0);
                parkingRecord.setAppUserId(chargingOrder.getAppUserId());
                parkingRecord.setChargingOrderId(chargingOrder.getId());
                TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData();
                parkingRecord.setPhone(appUser.getPhone());
                parkingRecord.setFreeDuration(parkingLot.getChargeFreeDuration());
                long m = parkingRecord.getParkingDuration() - parkingRecord.getFreeDuration();
                parkingRecord.setTimeoutAmount(m > parkingLot.getChargeFreeDuration() ? new BigDecimal(m - parkingLot.getChargeFreeDuration()).multiply(parkingLot.getChargeRate()) : BigDecimal.ZERO);
            }else{
                parkingRecord.setFreeDuration(parkingLot.getNonChargeFreeDuration());
                long m = parkingRecord.getParkingDuration() - parkingRecord.getFreeDuration();
                parkingRecord.setTimeoutAmount(m > parkingLot.getNonChargeFreeDuration() ? new BigDecimal(m - parkingLot.getNonChargeFreeDuration()).multiply(parkingLot.getChargeRate()) : BigDecimal.ZERO);
                chargingOrder = data.get(0);
            }
        }else if(StringUtils.isNotEmpty(parkingRecord.getLicensePlate())){
            List<TChargingOrder> data = chargingOrderClient.getCarChargingOrderByPlateNum(parkingRecord.getLicensePlate(), parkingRecord.getInParkingTime().format(formatter), LocalDateTime.now().format(formatter)).getData();
            if(null != data && data.size() > 0){
                chargingOrder = data.get(0);
            }
        }
        if(null != chargingOrder){
            parkingRecord.setAppUserId(chargingOrder.getAppUserId());
            parkingRecord.setChargingOrderId(chargingOrder.getId());
            TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData();
            parkingRecord.setPhone(appUser.getPhone());
            parkingRecord.setFreeDuration(parkingLot.getChargeFreeDuration());
            long m = parkingRecord.getParkingDuration() - parkingRecord.getFreeDuration();
            parkingRecord.setTimeoutAmount(m > parkingLot.getChargeFreeDuration() ? new BigDecimal(m - parkingLot.getChargeFreeDuration()).multiply(parkingLot.getChargeRate()) : BigDecimal.ZERO);
        }else{
            parkingRecord.setFreeDuration(parkingLot.getNonChargeFreeDuration());
            long m = parkingRecord.getParkingDuration() - parkingRecord.getFreeDuration();
            parkingRecord.setTimeoutAmount(m > parkingLot.getNonChargeFreeDuration() ? new BigDecimal(m - parkingLot.getNonChargeFreeDuration()).multiply(parkingLot.getChargeRate()) : BigDecimal.ZERO);
        }
        parkingRecord.setFreeAmount(parkingRecord.getOrderAmount().subtract(parkingRecord.getPayment()));
        parkingRecordClient.updateParkingRecord(parkingRecord);
@@ -174,25 +184,35 @@
        parkingRecord.setOutParkingType(BigDecimal.ZERO.compareTo(payment) == 0 ? 2 : 1);
        parkingRecord.setTitle("【停车缴费】" + payment + "元");
        TAppUserCar appUserCar = appUserCarClient.getAppUserCarByLicensePlate(parkingRecord.getLicensePlate()).getData();
        TChargingOrder chargingOrder = null;
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        if(null != appUserCar){
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            List<TChargingOrder> data = chargingOrderClient.getCarChargingOrder(appUserCar.getId(), parkingRecord.getInParkingTime().format(formatter), LocalDateTime.now().format(formatter)).getData();
            if(null != data && data.size() > 0){
                TChargingOrder chargingOrder = data.get(0);
                parkingRecord.setAppUserId(chargingOrder.getAppUserId());
                parkingRecord.setChargingOrderId(chargingOrder.getId());
                TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData();
                parkingRecord.setPhone(appUser.getPhone());
                parkingRecord.setFreeDuration(parkingLot.getChargeFreeDuration());
                long m = parkingRecord.getParkingDuration() - parkingRecord.getFreeDuration();
                parkingRecord.setTimeoutAmount(m > parkingLot.getChargeFreeDuration() ? new BigDecimal(m - parkingLot.getChargeFreeDuration()).multiply(parkingLot.getChargeRate()) : BigDecimal.ZERO);
            }else{
                parkingRecord.setFreeDuration(parkingLot.getNonChargeFreeDuration());
                long m = parkingRecord.getParkingDuration() - parkingRecord.getFreeDuration();
                parkingRecord.setTimeoutAmount(m > parkingLot.getNonChargeFreeDuration() ? new BigDecimal(m - parkingLot.getNonChargeFreeDuration()).multiply(parkingLot.getChargeRate()) : BigDecimal.ZERO);
                chargingOrder = data.get(0);
            }
        }else if(StringUtils.isNotEmpty(parkingRecord.getLicensePlate())){
            List<TChargingOrder> data = chargingOrderClient.getCarChargingOrderByPlateNum(parkingRecord.getLicensePlate(), parkingRecord.getInParkingTime().format(formatter), LocalDateTime.now().format(formatter)).getData();
            if(null != data && data.size() > 0){
                chargingOrder = data.get(0);
            }
        }
        if(null != chargingOrder){
            parkingRecord.setAppUserId(chargingOrder.getAppUserId());
            parkingRecord.setChargingOrderId(chargingOrder.getId());
            TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData();
            parkingRecord.setPhone(appUser.getPhone());
            parkingRecord.setFreeDuration(parkingLot.getChargeFreeDuration());
            long m = parkingRecord.getParkingDuration() - parkingRecord.getFreeDuration();
            parkingRecord.setTimeoutAmount(m > parkingLot.getChargeFreeDuration() ? new BigDecimal(m - parkingLot.getChargeFreeDuration()).multiply(parkingLot.getChargeRate()) : BigDecimal.ZERO);
        }else{
            parkingRecord.setFreeDuration(parkingLot.getNonChargeFreeDuration());
            long m = parkingRecord.getParkingDuration() - parkingRecord.getFreeDuration();
            parkingRecord.setTimeoutAmount(m > parkingLot.getNonChargeFreeDuration() ? new BigDecimal(m - parkingLot.getNonChargeFreeDuration()).multiply(parkingLot.getChargeRate()) : BigDecimal.ZERO);
        }
        parkingRecord.setFreeAmount(parkingRecord.getOrderAmount().subtract(parkingRecord.getPayment()));
        parkingRecordClient.updateParkingRecord(parkingRecord);
    }
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/controller/TransactionRecordController.java
New file
@@ -0,0 +1,35 @@
package com.ruoyi.integration.controller;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.integration.api.model.TransactionRecord;
import com.ruoyi.integration.mongodb.service.TransactionRecordService;
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 javax.annotation.Resource;
/**
 * @author zhibing.pu
 * @Date 2025/2/13 14:17
 */
@RestController
@RequestMapping("/transactionRecord")
public class TransactionRecordController {
    @Resource
    private TransactionRecordService transactionRecordService;
    /**
     * 根据订单流水号查询账单数据
     * @param code
     * @return
     */
    @PostMapping("/findTransactionRecord")
    public R<TransactionRecord> findTransactionRecord(@RequestParam(value = "code") String code){
        TransactionRecord transactionRecord = transactionRecordService.findOne(code);
        return R.ok(transactionRecord);
    }
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/AESUtil.java
New file
@@ -0,0 +1,107 @@
package com.ruoyi.integration.drainage;
import com.ruoyi.common.core.utils.StringUtils;
import org.springframework.util.Base64Utils;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
 * 定义AES加密解密工具类
 */
public class AESUtil {
    private static final String KEY_ALGORITHM = "AES";//加密方式
    private static final String DEFAULT_CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";//默认的加密算法
    private static final String KEY = "1234567890abcdef";//密码
    private static final String IV_PARAMETER = "1234567890abcdef";//偏移量
    private static final String CHARSET = "UTF-8";//编码
    /**
     * 加密操作
     * @param content  待加密内容
     * @return
     * @throws Exception
     */
    public static String encrypt(String content) {
        return encrypt(content, KEY, IV_PARAMETER);
    }
    /**
     * 加密操作
     * @param content  待加密内容
     * @return
     * @throws Exception
     */
    public static String encrypt(String content, String key, String iv_parameter) {
        try {
            if(StringUtils.isEmpty(content)){
                return content;
            }
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
            byte[] raw = key.getBytes(CHARSET);
            SecretKeySpec skeySpec = new SecretKeySpec(raw, KEY_ALGORITHM);
            IvParameterSpec iv = new IvParameterSpec(iv_parameter.getBytes());
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
            byte[] encrypted = cipher.doFinal(content.getBytes(CHARSET));
            return Base64Utils.encodeToString(encrypted);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
    public static String decrypt(String content) {
        return decrypt(content, KEY, IV_PARAMETER);
    }
    /**
     *解密操作
     * @param content 待解密内容
     * @return
     * @throws Exception
     */
    public static String decrypt(String content, String key, String iv_parameter) {
        try {
            if(StringUtils.isEmpty(content)){
                return content;
            }
            byte[] raw = key.getBytes(CHARSET);
            SecretKeySpec skeySpec = new SecretKeySpec(raw, KEY_ALGORITHM);
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
            IvParameterSpec iv = new IvParameterSpec(iv_parameter.getBytes());
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
            byte[] encrypted1 = Base64Utils.decodeFromString(content);
            byte[] original = cipher.doFinal(encrypted1);
            String originalString = new String(original, CHARSET);
            return originalString;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }
    public static void main(String[] ages){
//        String encrypt = AESUtil.encrypt("{\"OperatorSecret\":\"cn51EeFQDTSMsn11R1ZNsYSEYBxDYcKK\",\"OperatorID\":\"MA25CNM38\"}", "YPFVz1OvAS4nSwLW", "5tLoP60aR9QUB5Mx");
//        System.err.println(encrypt);
        String travel = AESUtil.decrypt("9gVnNqAh9O7IuqqbyD8G1ukK86O3g0bUBLzM1LJL060bNjPJCtW0wWRjr756abxIm+nOuKkjMy7/DYScMcnl2KSYJJJb6Xc4Aza8L24Mp/UKQyW6Fe9m+ThDVUfMwvn7U2OxHDXniBUdmpNi2Ex9uHa/R18H2ka0DCv/bKCm/F4KTfz48Et/1L64JTTmj7l4the0Wr7KGiVewPIEE03LF5lF+h9j0W8czC6Gx5UJOMU=", "YPFVz1OvAS4nSwLW", "5tLoP60aR9QUB5Mx");
        System.err.println(travel);
    }
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/SignUtil.java
New file
@@ -0,0 +1,208 @@
package com.ruoyi.integration.drainage;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
/**
 * 签名工具
 * @author zhibing.pu
 * @Date 2025/1/23 11:30
 */
public class SignUtil {
    /*************************************快电******************************************/
    /**
     * 签名算法
     *
     * @param aValue 加密的原文,即源数据
     * @param aKey   密钥 这是针对一条字符串进行加密的方法
     */
    public static String hmacSign (String aValue, String aKey) {
        byte k_ipad[] = new byte[64];
        byte k_opad[] = new byte[64];
        byte keyb[];
        byte value[];
        try {
            keyb = aKey.getBytes("UTF-8");
            value = aValue.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            keyb = aKey.getBytes();
            value = aValue.getBytes();
        }
        Arrays.fill(k_ipad, keyb.length, 64, (byte) 54);
        Arrays.fill(k_opad, keyb.length, 64, (byte) 92);
        for (int i = 0; i < keyb.length; i++) {
            k_ipad[i] = (byte) (keyb[i] ^ 0x36);
            k_opad[i] = (byte) (keyb[i] ^ 0x5c);
        }
        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            return null;
        }
        md.update(k_ipad);
        md.update(value);
        byte dg[] = md.digest();
        md.reset();
        md.update(k_opad);
        md.update(dg, 0, 16);
        dg = md.digest();
        return toHex(dg);
    }
    public static String toHex (byte input[]) {
        if (input == null) {
            return null;
        }
        StringBuffer output = new StringBuffer(input.length * 2);
        for (int i = 0; i < input.length; i++) {
            int current = input[i] & 0xff;
            if (current < 16) {
                output.append("0");
            }
            output.append(Integer.toString(current, 16));
        }
        return output.toString().toUpperCase();
    }
    /*************************************新电途******************************************/
    /**
     * HmacMd5的计算公式为:HMAC(K,M) = H(K⊕opad∣H(K⊕ipad∣M))
     * 其中:K是密钥(byte[] key),长度可为64字节(后面涉及描述都是以字节byte进行),若小于该长度,在密钥后面用0(即0x00)补齐。
     * M是消息内容(byte[] m);
     * H是散列函数(此处采用MD5);
     * opad和ipad分别是由若干个0x5c和0x36组成的字符串;
     * ⊕表示异或运算;
     * ∣表示连接操作。
     **/
    public static byte[] getHMacMD5Bytes(byte[] key, byte[] m) {
        try {
            //定义长度
            int length = 64;
            //定义opad和ipad
            byte[] opad = new byte[length];
            byte[] ipad = new byte[length];
            for (int i = 0; i < length; i++) {
                opad[i] = 0x5C;
                ipad[i] = 0x36;
            }
            byte[] actualKey = key;
            byte[] keyArr = new byte[length];
            //如果密钥长度,大于64字节,就使用MD5算法计算其散列值,作为密钥
            if (key.length > length) {
                actualKey = md5(key);
            }
            for (int i = 0; i < actualKey.length; i++) {
                keyArr[i] = actualKey[i];
            }
            //如果密钥长度不足64字节,就使用0x00补齐到64字节
            if (actualKey.length < length) {
                for (int i = key.length; i < length; i++) {
                    keyArr[i] = 0x00;
                }
            }
            //使用密钥和ipad进行异或运算【K⊕ipad】
            byte[] kIpadXorResult = new byte[length];
            for (int i = 0; i < length; i++) {
                kIpadXorResult[i] = (byte) (keyArr[i] ^ ipad[i]);
            }
            //将待加密数据M追加到kIpadXorResult后面【K⊕ipad∣M】
            byte[] firstAppendResult = new byte[kIpadXorResult.length + m.length];
            for (int i = 0; i < kIpadXorResult.length; i++) {
                firstAppendResult[i] = kIpadXorResult[i];
            }
            for (int i = 0; i < m.length; i++) {
                firstAppendResult[i + keyArr.length] = m[i];
            }
            //做MD5运算【H(K⊕ipad∣M)】
            byte[] firstHashResult = md5(firstAppendResult);
            //使用密钥和opad进行异或运算【K⊕opad】
            byte[] kOpadXorResult = new byte[length];
            for (int i = 0; i < length; i++) {
                kOpadXorResult[i] = (byte) (keyArr[i] ^ opad[i]);
            }
            //将firstHashResult追加到kOpadXorResult后面【K⊕opad∣H(K⊕ipad∣M)】
            byte[] secondAppendResult = new byte[kOpadXorResult.length + firstHashResult.length];
            for (int i = 0; i < kOpadXorResult.length; i++) {
                secondAppendResult[i] = kOpadXorResult[i];
            }
            for (int i = 0; i < firstHashResult.length; i++) {
                secondAppendResult[kOpadXorResult.length + i] = firstHashResult[i];
            }
            //做MD5运算【H(K⊕opad∣H(K⊕ipad∣M))】
            return md5(secondAppendResult);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * MD5(产生出一个128位(16字节)的散列值)
     **/
    private static byte[] md5(byte[] str) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(str);
        return md.digest();
    }
    /**
     * HEX转化为字符串
     **/
    public static String bytesToHexString(byte[] m) {
        StringBuilder stringBuilder = new StringBuilder();
        if (m == null || m.length <= 0) {
            return null;
        }
        for (int i = 0; i < m.length; i++) {
            int v = m[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        //最后得到的签名,统一转化为大写
        return stringBuilder.toString().toUpperCase();
    }
    public static void main(String[] args) {
//        String encrypt = AESUtil.encrypt("{\"total\":1,\"stationStatusInfo\":{\"operationID\":\"123456789\",\"stationID\":\"111111111111111\",\"connectorStatusInfos\":{\"connectorID\":1,\"equipmentID\":\"10000000000000000000001\",\"status\":4,\"currentA\":0,\"currentB\":0,\"currentC\":0,\"voltageA\":0,\"voltageB\":0,\"voltageC\":0,\"soc\":10,}}}");
//        String s = hmacSign(encrypt, "123456789abcdef");
//        System.err.println(s);
        //签名秘钥SigSecret
        String key = "1234567890abcdef";
        //运营商标识OperatorId
        String operatorId = "123456789";
        //参数信息Data
        String data = "il7B0BSEjFdzpyKzfOFpvg/Se1CP802RItKYFPfSLRxJ3jf0bVl9hvYOEktPAYW2nd7S8MBcyHYyacHKbISq5iTmDzG+ivnR+SZJv3USNTYVMz9rCQVSxd0cLlqsJauko79NnwQJbzDTyLooYoIwz75qBOH2/xOMirpeEqRJrF/EQjWekJmGk9RtboXePu2rka+Xm51syBPhiXJAq0GfbfaFu9tNqs/e2Vjja/ltE1M0lqvxfXQ6da6HrThsm5id4ClZFIi0acRfrsPLRixS/IQYtksxghvJwbqOsbIsITail9Ayy4tKcogeEZiOO+4Ed264NSKmk7l3wKwJLAFjCFogBx8GE3OBz4pqcAn/ydA=";
        //时间戳TimeStamp(格式:年月日时分秒)
        String timeStamp = "20160729142400";
        //自增序列Seq
        String seq = "0001";
        //进行字符串拼接、计算
        String m = new StringBuilder(operatorId).append(data).append(timeStamp).append(seq).toString();
        byte[] hmacMd5 = getHMacMD5Bytes(key.getBytes(), m.getBytes());
        // 打印计算得到的签名Sig
        System.out.println(bytesToHexString(hmacMd5));
    }
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECController.java
New file
@@ -0,0 +1,1599 @@
package com.ruoyi.integration.drainage;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.ruoyi.chargingPile.api.feignClient.*;
import com.ruoyi.chargingPile.api.model.*;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.dto.ChargingPercentProvinceDto;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.web.page.PageInfo;
import com.ruoyi.integration.drainage.kuaidian.TCECKDUtil;
import com.ruoyi.integration.drainage.kuaidian.model.*;
import com.ruoyi.integration.drainage.model.*;
import com.ruoyi.integration.drainage.model.enu.*;
import com.ruoyi.order.api.feignClient.ChargingOrderAccountingStrategyClient;
import com.ruoyi.order.api.feignClient.ChargingOrderClient;
import com.ruoyi.order.api.model.AddTripartitePlatformOrder;
import com.ruoyi.integration.api.vo.StartChargeResult;
import com.ruoyi.order.api.model.TChargingOrder;
import com.ruoyi.order.api.model.TChargingOrderAccountingStrategy;
import com.ruoyi.other.api.domain.Operator;
import com.ruoyi.other.api.feignClient.OperatorClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;
/**
 * @author zhibing.pu
 * @Date 2025/1/21 17:52
 */
@Slf4j
@RestController
@RequestMapping("/evcs/v1.0")
public class TCECController {
    @Resource
    private SiteClient siteClient;
    @Resource
    private ChargingPileClient chargingPileClient;
    @Resource
    private ChargingGunClient chargingGunClient;
    @Resource
    private ChargingOrderClient chargingOrderClient;
    @Resource
    private OperatorClient operatorClient;
    @Resource
    private AccountingStrategyDetailClient accountingStrategyDetailClient;
    @Resource
    private ChargingOrderAccountingStrategyClient chargingOrderAccountingStrategyClient;
    @Resource
    private TokenUtil tokenUtil;
    @Resource
    private ParkingLotClient parkingLotClient;
    @Resource
    private ParkingRecordClient parkingRecordClient;
    /**
     * 请求校验
     * @param baseRequest
     * @param request
     * @return
     */
    public BaseResult requestCheck(Boolean tokenCheck, BaseRequest baseRequest, HttpServletRequest request){
        BaseResult baseResult = new BaseResult();
        baseResult.setRet(0);
        baseResult.setMsg("成功");
        baseResult.setOperatorID(baseRequest.getOperatorID());
        Long mapKey = Long.valueOf(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
        baseResult.setTimeStamp(mapKey);
        baseResult.setSeq("0001");
        //校验token和签名
        String operatorID = baseRequest.getOperatorID();
        String sig = baseRequest.getSig();
        Long timeStamp = baseRequest.getTimeStamp();
        String data = baseRequest.getData();
        String seq = baseRequest.getSeq();
        if(StringUtils.isEmpty(operatorID) || StringUtils.isEmpty(sig) || StringUtils.isEmpty(data) || StringUtils.isEmpty(seq) || null == timeStamp){
            baseResult.setRet(4003);
            baseResult.setMsg("参数异常");
            return baseResult;
        }
        R<Operator> r = operatorClient.getOperator(operatorID);
        if(200 != r.getCode()){
            baseResult.setRet(500);
            baseResult.setMsg("系统异常");
            return baseResult;
        }
        //校验token
        if(tokenCheck){
            Operator loginUser = tokenUtil.getLoginUser(request);
            if(null == loginUser){
                baseResult.setRet(4002);
                baseResult.setMsg("身份校验失败,无效的token");
                return baseResult;
            }
        }
        Operator operator = r.getData();
        baseResult.setOperator(operator);
        baseRequest.setOperator(operator);
        //校验签名
        String sign = TCECUtil.ourBuildSign(baseRequest);
        if(!sign.equals(sig)){
            baseResult.setRet(4001);
            baseResult.setMsg("签名校验失败");
            return baseResult;
        }
        return baseResult;
    }
    /**
     * 获取token
     * @return
     */
    @PostMapping("/query_token")
    public BaseResult queryToken(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("三方平台获取token请求参数:" + JacksonUtils.toJson(baseRequest));
        BaseResult baseResult = requestCheck(false, baseRequest, request);
        if(0 != baseResult.getRet()){
            log.info("三方平台获取token响应Data:");
            baseResult.setData("");
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台获取token响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        QueryTokenResult queryTokenResult = new QueryTokenResult();
        Operator operator = baseResult.getOperator();
        if(null == operator){
            queryTokenResult.setSuccStat(1);
            queryTokenResult.setFailReason(1);
            //参数加密
            String jsonString = JacksonUtils.toJson(queryTokenResult);
            log.info("三方平台获取token响应Data:" + jsonString);
            String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
            baseResult.setData(encrypt);
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台获取token响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getOurDataSecret(), operator.getOurDataSecretIv());
        log.info("三方平台获取token请求Data:" + decrypt);
        QueryToken queryToken = JSON.parseObject(decrypt, QueryToken.class);
        if(!queryToken.getOperatorSecret().equals(operator.getOurOperatorSecret())){
            queryTokenResult.setSuccStat(1);
            queryTokenResult.setFailReason(2);
            //参数加密
            String jsonString = JacksonUtils.toJson(queryTokenResult);
            log.info("三方平台获取token响应Data:" + jsonString);
            String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
            baseResult.setData(encrypt);
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台获取token响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        //生成token
        Map<String, Object> token = tokenUtil.createToken(operator);
        String access_token = token.get("access_token").toString();
        Long expires_in = Long.valueOf(token.get("expires_in").toString());
        queryTokenResult.setOperatorID("906171535");
        queryTokenResult.setSuccStat(0);
        queryTokenResult.setFailReason(0);
        queryTokenResult.setAccessToken(access_token);
        queryTokenResult.setTokenAvailableTime(expires_in * 60);
        //参数加密
        String jsonString = JacksonUtils.toJson(queryTokenResult);
        log.info("三方平台获取token响应Data:" + jsonString);
        String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
        baseResult.setData(encrypt);
        baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
        log.info("三方平台获取token响应参数:" + JacksonUtils.toJson(baseResult));
        return baseResult;
    }
    /**
     * 查询充电站信息
     * @return
     */
    @PostMapping("/query_stations_info")
    public BaseResult queryStationsInfo(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("三方平台查询充电站信息请求参数:" + JacksonUtils.toJson(baseRequest));
        //校验token和签名
        BaseResult baseResult = requestCheck(true, baseRequest, request);
        if(0 != baseResult.getRet()){
            log.info("三方平台查询充电站信息响应Data:");
            baseResult.setData("");
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台查询充电站信息响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        Operator operator = baseResult.getOperator();
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getOurDataSecret(), operator.getOurDataSecretIv());
        log.info("三方平台查询充电站信息请求Data:" + decrypt);
        QueryStationsInfo queryStationsInfo = JSON.parseObject(decrypt, QueryStationsInfo.class);
        Integer pageNo = queryStationsInfo.getPageNo();
        Integer pageSize = queryStationsInfo.getPageSize();
        if(null == pageNo){
            pageNo = 1;
        }
        if(null == pageSize){
            pageSize = 10;
        }
        PageInfo<Site> siteListPaging = siteClient.getSiteListPaging(pageNo, pageSize);
        List<TParkingLot> parkingLots = parkingLotClient.getAllParkingLot().getData();
        QueryStationsInfoResult queryStationsInfoResult = new QueryStationsInfoResult();
        queryStationsInfoResult.setPageNo(pageNo);
        queryStationsInfoResult.setPageCount((0 == (siteListPaging.getTotal() % pageSize) ? 0 : 1) + Double.valueOf(siteListPaging.getTotal() / pageSize).intValue());
        queryStationsInfoResult.setItemSize(Long.valueOf(siteListPaging.getTotal()).intValue());
        queryStationsInfoResult.setStationInfos(buildSite(parkingLots, siteListPaging.getRecords()));
        //参数加密
        String jsonString = JacksonUtils.toJson(queryStationsInfoResult);
        log.info("三方平台查询充电站信息响应Data:" + jsonString);
        String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
        baseResult.setData(encrypt);
        baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
        log.info("三方平台查询充电站信息响应参数:" + JacksonUtils.toJson(baseResult));
        return baseResult;
    }
    /**
     * 构建站点数据
     * @param sites
     * @return
     */
    public List<StationInfo> buildSite(List<TParkingLot> parkingLots, List<Site> sites){
        List<Integer> siteIds = sites.stream().map(Site::getId).collect(Collectors.toList());
        List<TChargingPile> tChargingPiles = chargingPileClient.getChargingPileBySiteIds(siteIds).getData();
        List<Integer> collect1 = tChargingPiles.stream().map(TChargingPile::getId).collect(Collectors.toList());
        List<TChargingGun> chargingGunList = chargingGunClient.getChargingGunByChargingPileIds(collect1).getData();
        List<StationInfo> StationInfos = new ArrayList<>();
        for (Site datum : sites) {
            StationInfo stationInfo = new StationInfo();
            stationInfo.setStationID(datum.getId().toString());
            stationInfo.setOperatorID("906171535");
            stationInfo.setEquipmentOwnerID("906171535");
            stationInfo.setStationName(datum.getName());
            stationInfo.setCountryCode(StringUtils.isNotEmpty(datum.getCountryCode()) ? datum.getCountryCode() : "CN");
            stationInfo.setAreaCode(datum.getDistrictsCode());
            stationInfo.setAddress(datum.getAddress());
            stationInfo.setStationTel(datum.getPhone());
            stationInfo.setServiceTel(datum.getServicePhone());
            switch (datum.getSiteType()){
                case 0:
                    stationInfo.setStationType(StationTypeEnum.OTHER.getType());
                    break;
                case 1:
                    stationInfo.setStationType(StationTypeEnum.PUBLIC.getType());
                    break;
                case 2:
                    stationInfo.setStationType(StationTypeEnum.PERSONAGE.getType());
                    break;
                case 3:
                    stationInfo.setStationType(StationTypeEnum.BUS_SPECIFIC.getType());
                    break;
                case 4:
                    stationInfo.setStationType(StationTypeEnum.SANITATION_SPECIFIC.getType());
                    break;
                case 5:
                    stationInfo.setStationType(StationTypeEnum.LOGISTICS_SPECIFIC.getType());
                    break;
                case 6:
                    stationInfo.setStationType(StationTypeEnum.TEXT_SPECIFIC.getType());
                    break;
            }
            if(datum.getStatus() == 1){
                stationInfo.setStationStatus(StationStatusEnum.NORMAL_USE.getStatus());
            }
            if(datum.getStatus() == 2){
                stationInfo.setStationStatus(StationStatusEnum.MAINTAIN.getStatus());
            }
            if(datum.getStatus() == 3){
                stationInfo.setStationStatus(StationStatusEnum.OFF_LINE.getStatus());
            }
            stationInfo.setParkNums(datum.getParkingSpace());
            stationInfo.setStationLat(new BigDecimal(datum.getLat()).setScale(6, RoundingMode.DOWN));
            stationInfo.setStationLng(new BigDecimal(datum.getLon()).setScale(6, RoundingMode.DOWN));
            stationInfo.setConstruction(datum.getConstructionSite() == 0 ? ConstructionEnum.OTHER.getType() : datum.getConstructionSite());
            stationInfo.setPictures(StringUtils.isNotEmpty(datum.getImgUrl()) ? Arrays.asList(datum.getImgUrl().split(",")) : new ArrayList<>());
            stationInfo.setSiteGuide(datum.getGuide());
            stationInfo.setMatchCars(datum.getVehicleDescription());
            stationInfo.setBusineHours(datum.getStartServiceTime() + "-" + datum.getEndServiceTime());
            stationInfo.setElectricityFee(datum.getRateDescription());
            //添加停车费信息
            Optional<TParkingLot> first = parkingLots.stream().filter(s -> s.getSiteId().equals(datum.getId())).findFirst();
            if(first.isPresent()){
                TParkingLot tParkingLot = first.get();
                buildPlaceHolder(tParkingLot, stationInfo);
            }
            //构建充电设备信息数据
            stationInfo.setEquipmentInfos(buildEquipmentInfo(datum.getId(), tChargingPiles, chargingGunList));
            StationInfos.add(stationInfo);
        }
        return StationInfos;
    }
    /**
     * 构建停车费信息
     * @param tParkingLot
     * @param stationInfo
     */
    public void buildPlaceHolder(TParkingLot tParkingLot, StationInfo stationInfo){
        stationInfo.setOvertimeFee(tParkingLot.getName() + "停车费");
        PlaceHolder placeHolder = new PlaceHolder();
        placeHolder.setFreeTime(tParkingLot.getChargeFreeDuration());
        placeHolder.setMaxFee(tParkingLot.getChargeCapping());
        List<PlaceHolderPrice> PlaceHolderPrices = new ArrayList<>();
        PlaceHolderPrice placeHolderPrice = new PlaceHolderPrice();
        placeHolderPrice.setStartTime("00:00");
        placeHolderPrice.setEndTime("23:59");
        placeHolderPrice.setPrice(tParkingLot.getChargeRate());
        PlaceHolderPrices.add(placeHolderPrice);
        placeHolder.setPlaceHolderPrices(PlaceHolderPrices);
        stationInfo.setPlaceHolder(placeHolder);
    }
    /**
     * 构建桩数据
     * @param tChargingPiles
     * @return
     */
    public List<EquipmentInfo> buildEquipmentInfo(Integer siteId, List<TChargingPile> tChargingPiles, List<TChargingGun> chargingGunList){
        List<EquipmentInfo> equipmentInfos = new ArrayList<>();
        List<TChargingPile> collect = tChargingPiles.stream().filter(s -> s.getSiteId().equals(siteId)).collect(Collectors.toList());
        for (TChargingPile tChargingPile : collect) {
            EquipmentInfo equipmentInfo = new EquipmentInfo();
            equipmentInfo.setEquipmentID(tChargingPile.getId().toString());
            equipmentInfo.setManufacturerID(tChargingPile.getManufacturerCode());
            equipmentInfo.setManufacturerName(tChargingPile.getManufacturer());
            equipmentInfo.setEquipmentModel(tChargingPile.getEquipmentType());
            if(null != tChargingPile.getProductionDate()){
                equipmentInfo.setProductionDate(tChargingPile.getProductionDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            }
            switch (tChargingPile.getType()){
                case 0:
                    equipmentInfo.setEquipmentType(EquipmentTypeEnum.OTHER.getType());
                    break;
                case 1:
                    equipmentInfo.setEquipmentType(EquipmentTypeEnum.DIRECT_CURRENT.getType());
                    break;
                case 2:
                    equipmentInfo.setEquipmentType(EquipmentTypeEnum.ALTERNATING_CURRENT.getType());
                    break;
                case 3:
                    equipmentInfo.setEquipmentType(EquipmentTypeEnum.ALTERNATING_DIRECT.getType());
                    break;
                case 4:
                    equipmentInfo.setEquipmentType(EquipmentTypeEnum.WIRELESS_DEVICE.getType());
                    break;
            }
            //构建设备接口信息
            equipmentInfo.setConnectorInfos(buildConnectorInfos(tChargingPile.getId(), tChargingPile.getCode(), chargingGunList));
            equipmentInfo.setPower(tChargingPile.getRatedPower());
            equipmentInfos.add(equipmentInfo);
        }
        return equipmentInfos;
    }
    /**
     * 构建接口数据
     * @param chargingGunList
     * @return
     */
    public List<ConnectorInfo> buildConnectorInfos(Integer chargingPileId, String code, List<TChargingGun> chargingGunList){
        List<ConnectorInfo> connectorInfos = new ArrayList<>();
        List<TChargingGun> collect = chargingGunList.stream().filter(s -> s.getChargingPileId().equals(chargingPileId)).collect(Collectors.toList());
        for (TChargingGun chargingGun : collect) {
            ConnectorInfo connectorInfo = new ConnectorInfo();
            connectorInfo.setConnectorID(chargingGun.getId().toString());
            connectorInfo.setConnectorName(chargingGun.getName());
            switch (chargingGun.getType()){
                case 0:
                    connectorInfo.setConnectorType(ConnectorTypeEnum.OTHER.getType());
                    break;
                case 1:
                    connectorInfo.setConnectorType(ConnectorTypeEnum.HOUSEHOLD_SOCKET.getType());
                    break;
                case 2:
                    connectorInfo.setConnectorType(ConnectorTypeEnum.AC_SOCKET.getType());
                    break;
                case 3:
                    connectorInfo.setConnectorType(ConnectorTypeEnum.AC_INTERFACE_PLUG.getType());
                    break;
                case 4:
                    connectorInfo.setConnectorType(ConnectorTypeEnum.DC_INTERFACE_GUN_HEAD.getType());
                    break;
                case 5:
                    connectorInfo.setConnectorType(ConnectorTypeEnum.WIRELESS_CHARGING_STAND.getType());
                    break;
            }
            connectorInfo.setVoltageUpperLimits(chargingGun.getUpperRatedVoltage().intValue());
            connectorInfo.setVoltageLowerLimits(chargingGun.getLowerLimitOfRatedVoltage().intValue());
            connectorInfo.setCurrent(chargingGun.getRatedCurrent().intValue());
            connectorInfo.setPower(chargingGun.getRatedPower());
            connectorInfo.setParkNo(chargingGun.getParkingNumber());
            connectorInfo.setNationalStandard(Integer.valueOf(chargingGun.getNationalStandard()));
            connectorInfo.setQRCode("https://mxcd.zhinenganguan.com?No=" + code + chargingGun.getCode());
            connectorInfos.add(connectorInfo);
        }
        return connectorInfos;
    }
    /**
     * 接口状态变化后推送给第三方
     * @return
     */
    @PostMapping("/pushChargingGunStatus")
    public R pushChargingGunStatus(@RequestParam("id") Integer id, @RequestParam("status") Integer status){
        ConnectorStatusInfo connectorStatusInfo = new ConnectorStatusInfo();
        connectorStatusInfo.setConnectorID(id.toString());
        switch (status){
            case 1:
                connectorStatusInfo.setStatus(0);
                break;
            case 2:
                connectorStatusInfo.setStatus(1);
                break;
            case 3:
                connectorStatusInfo.setStatus(2);
                break;
            case 4:
                connectorStatusInfo.setStatus(3);
                break;
            case 5:
                connectorStatusInfo.setStatus(3);
                break;
            case 6:
                connectorStatusInfo.setStatus(4);
                break;
            case 7:
                connectorStatusInfo.setStatus(255);
                break;
        }
        ConnectorStatusInfo connectorStatusInfo1 = new ConnectorStatusInfo();
        BeanUtils.copyProperties(connectorStatusInfo, connectorStatusInfo1);
        connectorStatusInfo.setConnectorStatusInfo(connectorStatusInfo1);
        List<Operator> operators = operatorClient.getAllOperator().getData();
        for (Operator operator : operators) {
            TCECUtil.notificationStationStatus(operator, connectorStatusInfo);
        }
        return R.ok();
    }
    /**
     * 设备接口状态查询
     * @return
     */
    @PostMapping("/query_station_status")
    public BaseResult queryStationStatus(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("三方平台获取设备接口状态请求参数:" + JacksonUtils.toJson(baseRequest));
        BaseResult baseResult = requestCheck(true, baseRequest, request);
        if(0 != baseResult.getRet()){
            log.info("三方平台获取设备接口状态响应Data:");
            baseResult.setData("");
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台获取设备接口状态响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        Operator operator = baseResult.getOperator();
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getOurDataSecret(), operator.getOurDataSecretIv());
        log.info("三方平台获取设备接口状态请求Data:" + decrypt);
        QueryStationStatus queryStationsInfo = JSON.parseObject(decrypt, QueryStationStatus.class);
        List<Integer> collect = queryStationsInfo.getStationIDs().stream().map(Integer::valueOf).collect(Collectors.toList());
        List<Site> data = siteClient.getSiteByIds(collect).getData();
        List<Integer> siteIds = data.stream().map(Site::getId).collect(Collectors.toList());
        List<TChargingPile> tChargingPiles = chargingPileClient.getChargingPileBySiteIds(siteIds).getData();
        List<Integer> collect1 = tChargingPiles.stream().map(TChargingPile::getId).collect(Collectors.toList());
        List<TChargingGun> chargingGunList = chargingGunClient.getChargingGunByChargingPileIds(collect1).getData();
        QueryStationStatusResult result = new QueryStationStatusResult();
        result.setTotal(data.size());
        List<StationStatusInfo> StationStatusInfos = new ArrayList<>();
        for (Site datum : data) {
            StationStatusInfo stationStatusInfo = new StationStatusInfo();
            stationStatusInfo.setStationID(datum.getId().toString());
            //构建接口状态
            List<ConnectorStatusInfo> ConnectorStatusInfos = new ArrayList<>();
            List<TChargingGun> collect2 = chargingGunList.stream().filter(s -> s.getSiteId().equals(datum.getId())).collect(Collectors.toList());
            for (TChargingGun chargingGun : collect2) {
                ConnectorStatusInfo info = new ConnectorStatusInfo();
                info.setConnectorID(chargingGun.getId().toString());
                switch (chargingGun.getStatus()){
                    case 1:
                        info.setStatus(0);
                        break;
                    case 2:
                        info.setStatus(1);
                        break;
                    case 3:
                        info.setStatus(2);
                        break;
                    case 4:
                        info.setStatus(3);
                        break;
                    case 5:
                        info.setStatus(3);
                        break;
                    case 6:
                        info.setStatus(4);
                        break;
                    case 7:
                        info.setStatus(255);
                        break;
                }
                ConnectorStatusInfos.add(info);
            }
            stationStatusInfo.setConnectorStatusInfos(ConnectorStatusInfos);
            StationStatusInfos.add(stationStatusInfo);
        }
        result.setStationStatusInfos(StationStatusInfos);
        //参数加密
        String jsonString = JacksonUtils.toJson(result);
        log.info("三方平台获取设备接口状态响应Data:" + jsonString);
        String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
        baseResult.setData(encrypt);
        baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
        log.info("三方平台获取设备接口状态响应参数:" + JacksonUtils.toJson(baseResult));
        return baseResult;
    }
    /**
     * 查询统计信息
     * @return
     */
    @PostMapping("/query_station_stats")
    public BaseResult queryStationStats(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("三方平台获取统计信息请求参数:" + JacksonUtils.toJson(baseRequest));
        //校验token和签名
        BaseResult baseResult = requestCheck(true, baseRequest, request);
        if(0 != baseResult.getRet()){
            log.info("三方平台获取统计信息响应Data:");
            baseResult.setData("");
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台获取统计信息响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        Operator operator = baseResult.getOperator();
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getOurDataSecret(), operator.getOurDataSecretIv());
        log.info("三方平台获取统计信息请求Data:" + decrypt);
        QueryStationStats queryStationStats = JSON.parseObject(decrypt, QueryStationStats.class);
        QueryStationStatsResult result = new QueryStationStatsResult();
        ChargingPercentProvinceDto dto = new ChargingPercentProvinceDto();
        dto.setDate1(LocalDate.parse(queryStationStats.getStartTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        dto.setDate2(LocalDate.parse(queryStationStats.getEndTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        dto.setSiteIds(new HashSet<>(Integer.valueOf(queryStationStats.getStationID())));
        dto.setTripartitePlatformName(operator.getName());
        List<TChargingOrder> chargingOrders = chargingOrderClient.getOrderBySiteIdAndTime(dto).getData();
        BigDecimal reduce = chargingOrders.stream().map(TChargingOrder::getChargingCapacity).reduce(BigDecimal.ZERO, BigDecimal::add);
        StationStatsInfo stationStats = new StationStatsInfo();
        stationStats.setStationID(chargingOrders.get(0).getSiteId().toString());
        stationStats.setStartTime(queryStationStats.getStartTime());
        stationStats.setEndTime(queryStationStats.getEndTime());
        stationStats.setStationElectricity(reduce);
        //构建设备统计数据
        List<EquipmentStatsInfo> EquipmentStatsInfos = new ArrayList<>();
        Map<Integer, List<TChargingOrder>> collect = chargingOrders.stream().collect(Collectors.groupingBy(TChargingOrder::getChargingPileId));
        for (Integer integer : collect.keySet()) {
            List<TChargingOrder> tChargingOrders = collect.get(integer);
            BigDecimal reduce1 = tChargingOrders.stream().map(TChargingOrder::getChargingCapacity).reduce(BigDecimal.ZERO, BigDecimal::add);
            EquipmentStatsInfo equipmentStatsInfo = new EquipmentStatsInfo();
            equipmentStatsInfo.setEquipmentID(integer.toString());
            equipmentStatsInfo.setEquipmentElectricity(reduce1);
            //构建设备接口统计数据
            Map<Integer, List<TChargingOrder>> collect2 = tChargingOrders.stream().collect(Collectors.groupingBy(TChargingOrder::getChargingGunId));
            List<ConnectorStatsInfo> ConnectorStatsInfos = new ArrayList<>();
            for (Integer integer1 : collect2.keySet()) {
                List<TChargingOrder> tChargingOrders1 = collect2.get(integer1);
                BigDecimal reduce2 = tChargingOrders1.stream().map(TChargingOrder::getChargingCapacity).reduce(BigDecimal.ZERO, BigDecimal::add);
                ConnectorStatsInfo connectorStatsInfo = new ConnectorStatsInfo();
                connectorStatsInfo.setConnectorID(integer1.toString());
                connectorStatsInfo.setConnectorElectricity(reduce2);
                ConnectorStatsInfos.add(connectorStatsInfo);
            }
            equipmentStatsInfo.setConnectorStatsInfos(ConnectorStatsInfos);
            EquipmentStatsInfos.add(equipmentStatsInfo);
        }
        stationStats.setEquipmentStatsInfos(EquipmentStatsInfos);
        result.setStationStats(stationStats);
        //参数加密
        String jsonString = JacksonUtils.toJson(result);
        log.info("三方平台获取统计信息响应Data:" + jsonString);
        String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
        baseResult.setData(encrypt);
        baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
        log.info("三方平台获取统计信息响应参数:" + JacksonUtils.toJson(baseResult));
        return baseResult;
    }
    /**
     * 请求设备认证
     * @return
     */
    @PostMapping("/query_equip_auth")
    public BaseResult queryEquipAuth(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("三方平台设备认证请求参数:" + JacksonUtils.toJson(baseRequest));
        //校验token和签名
        BaseResult baseResult = requestCheck(true, baseRequest, request);
        if(0 != baseResult.getRet()){
            log.info("三方平台设备认证响应Data:");
            baseResult.setData("");
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台设备认证响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        Operator operator = baseResult.getOperator();
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getOurDataSecret(), operator.getOurDataSecretIv());
        log.info("三方平台设备认证请求Data:" + decrypt);
        QueryEquipAuth queryEquipAuth = JSON.parseObject(decrypt, QueryEquipAuth.class);
        String connectorID = queryEquipAuth.getConnectorID();
        TChargingGun tChargingGun = chargingGunClient.getChargingGunById(Integer.valueOf(connectorID)).getData();
        if(null == tChargingGun){
            baseResult.setRet(4004);
            baseResult.setMsg("connectorID 参数无效");
            log.info("三方平台设备认证响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        QueryEquipAuthResult queryEquipAuthResult = new QueryEquipAuthResult();
        queryEquipAuthResult.setEquipAuthSeq(queryEquipAuth.getEquipAuthSeq());
        queryEquipAuthResult.setConnectorID(connectorID);
        //1=离线,2=空闲,3=占用(未充电),4=占用(充电中),5=占用(已充满),6=占用(预约锁定),7=故障
        switch (tChargingGun.getStatus()){
            case 1:
                queryEquipAuthResult.setSuccStat(1);
                queryEquipAuthResult.setFailReason(2);
                break;
            case 2:
                queryEquipAuthResult.setSuccStat(0);
                queryEquipAuthResult.setFailReason(0);
                break;
            case 3:
                queryEquipAuthResult.setSuccStat(0);
                queryEquipAuthResult.setFailReason(1);
                break;
            case 4:
                queryEquipAuthResult.setSuccStat(1);
                queryEquipAuthResult.setFailReason(4);
                break;
            case 5:
                queryEquipAuthResult.setSuccStat(1);
                queryEquipAuthResult.setFailReason(5);
                break;
            case 6:
                queryEquipAuthResult.setSuccStat(1);
                queryEquipAuthResult.setFailReason(6);
                break;
            case 7:
                queryEquipAuthResult.setSuccStat(1);
                queryEquipAuthResult.setFailReason(2);
                break;
        }
        //参数加密
        String jsonString = JacksonUtils.toJson(queryEquipAuthResult);
        log.info("三方平台设备认证响应Data:" + jsonString);
        String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
        baseResult.setData(encrypt);
        baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
        log.info("三方平台设备认证响应参数:" + JacksonUtils.toJson(baseResult));
        return baseResult;
    }
    /**
     * 查询业务策略信息
     * @return
     */
    @PostMapping("/query_equip_business_policy")
    public BaseResult queryEquipBusinessPolicy(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("三方平台查询业务策略信息请求参数:" + JacksonUtils.toJson(baseRequest));
        //校验token和签名
        BaseResult baseResult = requestCheck(true, baseRequest, request);
        if(0 != baseResult.getRet()){
            log.info("三方平台查询业务策略信息响应Data:");
            baseResult.setData("");
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台查询业务策略信息响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        Operator operator = baseResult.getOperator();
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getOurDataSecret(), operator.getOurDataSecretIv());
        log.info("三方平台查询业务策略信息请求Data:" + decrypt);
        QueryEquipBusinessPolicy queryEquipBusinessPolicy = JSON.parseObject(decrypt, QueryEquipBusinessPolicy.class);
        //构建返回结果
        QueryEquipBusinessPolicyResult queryEquipBusinessPolicyResult = new QueryEquipBusinessPolicyResult();
        queryEquipBusinessPolicyResult.setEquipBizSeq(queryEquipBusinessPolicy.getEquipBizSeq());
        queryEquipBusinessPolicyResult.setConnectorID(queryEquipBusinessPolicy.getConnectorID());
        queryEquipBusinessPolicyResult.setSuccStat(0);
        queryEquipBusinessPolicyResult.setFailReason(0);
        String connectorID = queryEquipBusinessPolicy.getConnectorID();
        TChargingGun tChargingGun = chargingGunClient.getChargingGunById(Integer.valueOf(connectorID)).getData();
        if(null == tChargingGun){
            baseResult.setRet(4004);
            baseResult.setMsg("connectorID 参数无效");
            //参数加密
            String jsonString = JacksonUtils.toJson(queryEquipBusinessPolicyResult);
            log.info("三方平台查询业务策略信息响应Data:" + jsonString);
            String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
            baseResult.setData(encrypt);
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台查询业务策略信息响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        Integer accountingStrategyId = tChargingGun.getAccountingStrategyId();
        if(null == accountingStrategyId){
            List<Site> data = siteClient.getSiteByIds(Arrays.asList(tChargingGun.getSiteId())).getData();
            accountingStrategyId = data.get(0).getAccountingStrategyId();
        }
        List<TAccountingStrategyDetail> accountingStrategyDetails = accountingStrategyDetailClient.getListByAccountingStrategyId(accountingStrategyId).getData();
        if(accountingStrategyDetails.size() == 0){
            queryEquipBusinessPolicyResult.setSuccStat(1);
            queryEquipBusinessPolicyResult.setFailReason(1);
            queryEquipBusinessPolicyResult.setSumPeriod(0);
            //参数加密
            String jsonString = JacksonUtils.toJson(queryEquipBusinessPolicyResult);
            log.info("三方平台查询业务策略信息响应Data:" + jsonString);
            String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
            baseResult.setData(encrypt);
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台查询业务策略信息响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        List<PolicyInfo> PolicyInfos = new ArrayList<>();
        for (TAccountingStrategyDetail accountingStrategyDetail : accountingStrategyDetails) {
            PolicyInfo policyInfo = new PolicyInfo();
            policyInfo.setStartTime(accountingStrategyDetail.getStartTime().replaceAll(":", "") + "00");
            policyInfo.setElecPrice(accountingStrategyDetail.getElectrovalence());
            policyInfo.setSevicePrice(accountingStrategyDetail.getServiceCharge());
            PolicyInfos.add(policyInfo);
        }
        queryEquipBusinessPolicyResult.setSumPeriod(PolicyInfos.size());
        queryEquipBusinessPolicyResult.setPolicyInfos(PolicyInfos);
        //参数加密
        String jsonString = JacksonUtils.toJson(queryEquipBusinessPolicyResult);
        log.info("三方平台查询业务策略信息响应Data:" + jsonString);
        String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
        baseResult.setData(encrypt);
        baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
        log.info("三方平台查询业务策略信息响应参数:" + JacksonUtils.toJson(baseResult));
        return baseResult;
    }
    /**
     * 站点变更推送通知(快电)
     * @param siteIds
     * @return
     */
    @PostMapping("/notificationStationChange")
    public R notificationStationChange(@RequestParam("siteIds") List<Integer> siteIds){
        Operator operator = operatorClient.getOperatorByName("KuaiDian").getData();
        NotificationStationChangeResult notificationStationChange = TCECKDUtil.notificationStationChange(operator, 3, siteIds);
        //启动重试推送机制
        if(null == notificationStationChange || 1 == notificationStationChange.getSuccStat()){
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
            threadPoolExecutor.execute(new Runnable() {
                //计数器
                Integer size = 0;
                @Override
                public void run() {
                    NotificationStationChangeResult notificationStationChange1 = TCECKDUtil.notificationStationChange(operator, 3, siteIds);
                    //启动重试推送机制
                    if(null != notificationStationChange1 && 0 == notificationStationChange1.getSuccStat()){
                        threadPoolExecutor.shutdown();
                        return;
                    }
                    size++;
                    if(size >= 5){
                        threadPoolExecutor.shutdown();
                        return;
                    }
                    //间隔一分钟重试一次
                    try {
                        Thread.sleep(60000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        }
        return R.ok();
    }
    /**
     * 请求开始充电
     * @return
     */
    @PostMapping("/query_start_charge")
    public BaseResult queryStartCharge(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("三方平台请求开始充电请求参数:" + JacksonUtils.toJson(baseRequest));
        //校验token和签名
        BaseResult baseResult = requestCheck(true, baseRequest, request);
        if(0 != baseResult.getRet()){
            log.info("三方平台请求开始充电响应Data:");
            baseResult.setData("");
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台请求开始充电响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        Operator operator = baseResult.getOperator();
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getOurDataSecret(), operator.getOurDataSecretIv());
        log.info("三方平台请求开始充电请求Data:" + decrypt);
        QueryStartCharge queryStartCharge = JSON.parseObject(decrypt, QueryStartCharge.class);
        //构建返回结果
        QueryStartChargeResult result = new QueryStartChargeResult();
        result.setStartChargeSeq(queryStartCharge.getStartChargeSeq());
        result.setConnectorID(queryStartCharge.getConnectorID());
        String connectorID = queryStartCharge.getConnectorID();
        TChargingGun tChargingGun = chargingGunClient.getChargingGunById(Integer.valueOf(connectorID)).getData();
        //设备不存在
        if(null == tChargingGun){
            baseResult.setRet(4004);
            baseResult.setMsg("connectorID 参数无效");
            result.setSuccStat(1);
            result.setFailReason(1);
            result.setStartChargeSeqStat(5);
            //参数加密
            String jsonString = JacksonUtils.toJson(result);
            log.info("三方平台请求开始充电响应Data:" + jsonString);
            String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
            baseResult.setData(encrypt);
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台请求开始充电响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        //设备离线
        if(tChargingGun.getStatus() == 1){
            result.setSuccStat(1);
            result.setFailReason(2);
            result.setStartChargeSeqStat(5);
            //参数加密
            String jsonString = JacksonUtils.toJson(result);
            log.info("三方平台请求开始充电响应Data:" + jsonString);
            String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
            baseResult.setData(encrypt);
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台请求开始充电响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        //调用充电接口
        AddTripartitePlatformOrder addTripartitePlatformOrder = new AddTripartitePlatformOrder();
        addTripartitePlatformOrder.setStartChargeSeq(queryStartCharge.getStartChargeSeq());
        addTripartitePlatformOrder.setChargingGunId(tChargingGun.getId());
        addTripartitePlatformOrder.setOperatorId(operator.getOperatorId());
        addTripartitePlatformOrder.setPaymentAmount(null == queryStartCharge.getChargingAmt() ? new BigDecimal(9999) : queryStartCharge.getChargingAmt());
        addTripartitePlatformOrder.setRechargePaymentType(0);
        addTripartitePlatformOrder.setPlateNum(queryStartCharge.getPlateNum());
        R order = chargingOrderClient.addTripartitePlatformOrder(addTripartitePlatformOrder);
        //启动失败
        if(200 != order.getCode()){
            result.setSuccStat(1);
            result.setFailReason(1);
            result.setStartChargeSeqStat(2);
            //参数加密
            String jsonString = JacksonUtils.toJson(result);
            log.info("三方平台请求开始充电响应Data:" + jsonString);
            String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
            baseResult.setData(encrypt);
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台请求开始充电响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        result.setStartChargeSeqStat(1);
        result.setSuccStat(0);
        result.setFailReason(0);
        //参数加密
        String jsonString = JacksonUtils.toJson(result);
        log.info("三方平台请求开始充电响应Data:" + jsonString);
        String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
        baseResult.setData(encrypt);
        baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
        log.info("三方平台请求开始充电响应参数:" + JacksonUtils.toJson(baseResult));
        return baseResult;
    }
    /**
     * 启动充电结果推送
     * @param result
     * @return
     */
    @PostMapping("/notificationStartChargeResult")
    public R notificationStartChargeResult(@RequestBody StartChargeResult result){
        NotificationStartCharge notificationStartCharge = new NotificationStartCharge();
        BeanUtils.copyProperties(result, notificationStartCharge);
        Operator operator = operatorClient.getOperator(result.getOperatorID()).getData();
        com.ruoyi.integration.drainage.model.NotificationStartChargeResult notificationStartChargeResult = TCECUtil.notificationStartChargeResult(operator, notificationStartCharge);
        //启动重试推送机制
        if(null == notificationStartChargeResult || 1 == notificationStartChargeResult.getSuccStat()){
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
            threadPoolExecutor.execute(new Runnable() {
                //计数器
                Integer size = 0;
                @Override
                public void run() {
                    NotificationStartChargeResult notificationStartChargeResult1 = TCECUtil.notificationStartChargeResult(operator, notificationStartCharge);
                    //启动重试推送机制
                    if(null != notificationStartChargeResult1 && 0 == notificationStartChargeResult1.getSuccStat()){
                        threadPoolExecutor.shutdown();
                        return;
                    }
                    size++;
                    if(size >= 5){
                        threadPoolExecutor.shutdown();
                        return;
                    }
                    //间隔一分钟重试一次
                    try {
                        Thread.sleep(60000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        }
        //定义定时任务推送订单状态
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
        Runnable task = new Runnable() {
            @Override
            public void run() {
                TChargingOrder chargingOrder = chargingOrderClient.getChargingOrderByStartChargeSeq(result.getStartChargeSeq()).getData();
                if(null == chargingOrder || chargingOrder.getStatus() != 3){
                    scheduler.shutdown();
                    return;
                }
                notificationEquipChargeStatus(result.getStartChargeSeq(), operator.getId());
            }
        };
        //一分钟执行一次
        scheduler.scheduleAtFixedRate(task, 1, 1, TimeUnit.MINUTES);
        return R.ok();
    }
    /**
     * 查询充电状态
     * @return
     */
    @PostMapping("/query_equip_charge_status")
    public BaseResult queryEquipChargeStatus(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("三方平台查询充电状态请求参数:" + JacksonUtils.toJson(baseRequest));
        //校验token和签名
        BaseResult baseResult = requestCheck(true, baseRequest, request);
        if(0 != baseResult.getRet()){
            log.info("三方平台查询充电状态响应Data:");
            baseResult.setData("");
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台查询充电状态响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        Operator operator = baseResult.getOperator();
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getOurDataSecret(), operator.getOurDataSecretIv());
        log.info("三方平台查询充电状态请求Data:" + decrypt);
        QueryEquipChargeStatus queryEquipChargeStatus = JSON.parseObject(decrypt, QueryEquipChargeStatus.class);
        //校验token和签名
        QueryEquipChargeStatusResult queryEquipChargeStatusResult = buildQueryEquipChargeStatusResult(queryEquipChargeStatus.getStartChargeSeq());
        //参数加密
        String jsonString = JacksonUtils.toJson(queryEquipChargeStatusResult);
        log.info("三方平台查询充电状态响应Data:" + jsonString);
        String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
        baseResult.setData(encrypt);
        baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
        log.info("三方平台查询充电状态响应参数:" + JacksonUtils.toJson(baseResult));
        return baseResult;
    }
    /**
     * 构建充电状态结果
     * @param startChargeSeq
     * @return
     */
    public QueryEquipChargeStatusResult buildQueryEquipChargeStatusResult(String startChargeSeq){
        //构建返回结果
        QueryEquipChargeStatusResult queryEquipChargeStatusResult = new QueryEquipChargeStatusResult();
        queryEquipChargeStatusResult.setStartChargeSeq(startChargeSeq);
        TChargingOrder chargingOrder = chargingOrderClient.getChargingOrderByStartChargeSeq(startChargeSeq).getData();
        if(null == chargingOrder){
            return null;
        }
        //0=未知,1=等待中/已插枪,2=启动中,3=充电中,4=停止中,5=已结束
        switch (chargingOrder.getStatus()){
            case 0:
                queryEquipChargeStatusResult.setStartChargeSeqStat(5);
                break;
            case 1:
                queryEquipChargeStatusResult.setStartChargeSeqStat(0);
                break;
            case 2:
                queryEquipChargeStatusResult.setStartChargeSeqStat(1);
                break;
            case 3:
                queryEquipChargeStatusResult.setStartChargeSeqStat(2);
                break;
            case 4:
                queryEquipChargeStatusResult.setStartChargeSeqStat(3);
                break;
            case 5:
                queryEquipChargeStatusResult.setStartChargeSeqStat(4);
                break;
        }
        queryEquipChargeStatusResult.setConnectorID(chargingOrder.getChargingGunId().toString());
        TChargingGun chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
        //1=离线,2=空闲,3=占用(未充电),4=占用(充电中),5=占用(已充满),6=占用(预约锁定),7=故障
        switch (chargingGun.getStatus()){
            case 1:
                queryEquipChargeStatusResult.setConnectorStatus(0);
                break;
            case 2:
                queryEquipChargeStatusResult.setConnectorStatus(1);
                break;
            case 3:
                queryEquipChargeStatusResult.setConnectorStatus(2);
                break;
            case 4:
                queryEquipChargeStatusResult.setConnectorStatus(3);
                break;
            case 5:
                queryEquipChargeStatusResult.setConnectorStatus(1);
                break;
            case 6:
                queryEquipChargeStatusResult.setConnectorStatus(4);
                break;
            case 7:
                queryEquipChargeStatusResult.setConnectorStatus(255);
                break;
        }
        queryEquipChargeStatusResult.setCurrentA(chargingOrder.getCurrent());
        queryEquipChargeStatusResult.setVoltageA(chargingOrder.getVoltage());
        queryEquipChargeStatusResult.setSoc(chargingOrder.getTotalElectricity());
        queryEquipChargeStatusResult.setStartTime((null == chargingOrder.getStartTime() ? chargingOrder.getCreateTime() : chargingOrder.getStartTime()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        queryEquipChargeStatusResult.setEndTime((null == chargingOrder.getEndTime() ? LocalDateTime.now() : chargingOrder.getEndTime()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        queryEquipChargeStatusResult.setTotalPower(chargingOrder.getElectricity());
        queryEquipChargeStatusResult.setElecMoney(chargingOrder.getTotalElectricity());
        queryEquipChargeStatusResult.setSeviceMoney(chargingOrder.getServiceCharge());
        queryEquipChargeStatusResult.setTotalMoney(chargingOrder.getTotalElectricity().add(chargingOrder.getServiceCharge()));
        //构建充电明细
        List<ChargeDetail> chargeDetails = new ArrayList<>();
        List<TChargingOrderAccountingStrategy> data = chargingOrderAccountingStrategyClient.getChargingOrderAccountingStrategyByOrderId(chargingOrder.getId()).getData();
        LocalDateTime startTime = chargingOrder.getStartTime();
        LocalDateTime endTime = null == chargingOrder.getEndTime() ? LocalDateTime.now() : chargingOrder.getEndTime();
        String s_format = startTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        String e_format = endTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        for (TChargingOrderAccountingStrategy datum : data) {
            ChargeDetail chargeDetail = new ChargeDetail();
            if(s_format.equals(e_format)){
                chargeDetail.setDetailStartTime(s_format + " " + datum.getStartTime() + ":00");
                chargeDetail.setDetailEndTime(s_format + " " + datum.getEndTime() + ":59");
            }else{
                String substring = datum.getEndTime().substring(0, datum.getEndTime().indexOf(":"));
                if(Integer.valueOf(substring) > 12){
                    chargeDetail.setDetailStartTime(s_format + " " + datum.getStartTime() + ":00");
                    chargeDetail.setDetailEndTime(s_format + " " + datum.getEndTime() + ":59");
                }else{
                    chargeDetail.setDetailStartTime(e_format + " " + datum.getStartTime() + ":00");
                    chargeDetail.setDetailEndTime(e_format + " " + datum.getEndTime() + ":59");
                }
            }
            chargeDetail.setElecPrice(datum.getElectrovalence());
            chargeDetail.setSevicePrice(datum.getServiceCharge());
            chargeDetail.setDetailPower(datum.getChargingCapacity());
            chargeDetail.setDetailElecMoney(datum.getPeriodElectricPrice());
            chargeDetail.setDetailSeviceMoney(datum.getPeriodServicePrice());
            chargeDetails.add(chargeDetail);
        }
        queryEquipChargeStatusResult.setChargeDetails(chargeDetails);
        return queryEquipChargeStatusResult;
    }
    /**
     * 推送充电状态
     * @param startChargeSeq
     * @return
     */
    @PostMapping("/notificationEquipChargeStatus")
    public R notificationEquipChargeStatus(@RequestParam(value = "startChargeSeq") String startChargeSeq, @RequestParam(value = "operatorId") Integer operatorId){
        QueryEquipChargeStatusResult queryEquipChargeStatusResult = buildQueryEquipChargeStatusResult(startChargeSeq);
        Operator operator = operatorClient.getOperatorById(operatorId).getData();
        NotificationEquipChargeStatusResult notificationEquipChargeStatusResult = TCECUtil.notificationEquipChargeStatus(operator, queryEquipChargeStatusResult);
        //启动重试推送机制
        if(null == notificationEquipChargeStatusResult || 1 == notificationEquipChargeStatusResult.getSuccStat()){
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
            threadPoolExecutor.execute(new Runnable() {
                //计数器
                Integer size = 0;
                @Override
                public void run() {
                    NotificationEquipChargeStatusResult notificationEquipChargeStatusResult1 = TCECUtil.notificationEquipChargeStatus(operator, queryEquipChargeStatusResult);
                    //启动重试推送机制
                    if(null != notificationEquipChargeStatusResult1 && 0 == notificationEquipChargeStatusResult1.getSuccStat()){
                        threadPoolExecutor.shutdown();
                        return;
                    }
                    size++;
                    if(size >= 5){
                        threadPoolExecutor.shutdown();
                        return;
                    }
                    //间隔一分钟重试一次
                    try {
                        Thread.sleep(60000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        }
        return R.ok();
    }
    /**
     * 请求停止充电
     * @return
     */
    @PostMapping("/query_stop_charge")
    public BaseResult queryStopCharge(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("三方平台请求停止充电请求参数:" + JacksonUtils.toJson(baseRequest));
        //校验token和签名
        BaseResult baseResult = requestCheck(true, baseRequest, request);
        if(0 != baseResult.getRet()){
            log.info("三方平台请求停止充电响应Data:");
            baseResult.setData("");
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台请求停止充电响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        Operator operator = baseResult.getOperator();
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getOurDataSecret(), operator.getOurDataSecretIv());
        log.info("三方平台请求停止充电请求Data:" + decrypt);
        QueryStopCharge queryStopCharge = JSON.parseObject(decrypt, QueryStopCharge.class);
        QueryStopChargeResult queryStopChargeResult = new QueryStopChargeResult();
        queryStopChargeResult.setStartChargeSeq(queryStopCharge.getStartChargeSeq());
        queryStopChargeResult.setStartChargeSeqStat(3);
        queryStopChargeResult.setSuccStat(0);
        queryStopChargeResult.setFailReason(0);
        //执行停机操作
        R r = chargingOrderClient.tripartitePlatformStopCharge(queryStopCharge.getStartChargeSeq());
        if(200 != r.getCode()){
            queryStopChargeResult.setStartChargeSeqStat(5);
            queryStopChargeResult.setSuccStat(1);
            queryStopChargeResult.setFailReason(3);
            //参数加密
            String jsonString = JacksonUtils.toJson(queryStopChargeResult);
            log.info("三方平台请求停止充电响应Data:" + jsonString);
            String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
            baseResult.setData(encrypt);
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台请求停止充电响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        //参数加密
        String jsonString = JacksonUtils.toJson(queryStopChargeResult);
        log.info("三方平台请求停止充电响应Data:" + jsonString);
        String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
        baseResult.setData(encrypt);
        baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
        log.info("三方平台请求停止充电响应参数:" + JacksonUtils.toJson(baseResult));
        return baseResult;
    }
    /**
     * 推送停止充电结果
     * @param startChargeSeq    充电订单号
     * @param connectorID       充电设备接口编码
     * @return
     */
    @PostMapping("/notificationStopChargeResult")
    public R notificationStopChargeResult(@RequestParam("startChargeSeq") String startChargeSeq, @RequestParam("connectorID") String connectorID,
                                          @RequestParam("operatorId") Integer operatorId){
        Operator operator = operatorClient.getOperatorById(operatorId).getData();
        NotificationStopChargeResult info = new NotificationStopChargeResult();
        info.setStartChargeSeq(startChargeSeq);
        info.setStartChargeSeqStat(4);
        info.setConnectorID(connectorID);
        info.setSuccStat(0);
        info.setFailReason(0);
        NotificationStopCharge notificationStopCharge = TCECUtil.notificationStopChargeResult(operator, info);
        //启动重试推送机制
        if(null == notificationStopCharge || 1 == notificationStopCharge.getSuccStat()){
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
            threadPoolExecutor.execute(new Runnable() {
                //计数器
                Integer size = 0;
                @Override
                public void run() {
                    NotificationStopCharge notificationStopCharge1 = TCECUtil.notificationStopChargeResult(operator, info);
                    //启动重试推送机制
                    if(null != notificationStopCharge1 && 0 == notificationStopCharge1.getSuccStat()){
                        threadPoolExecutor.shutdown();
                        return;
                    }
                    size++;
                    if(size >= 5){
                        threadPoolExecutor.shutdown();
                        return;
                    }
                    //间隔一分钟重试一次
                    try {
                        Thread.sleep(60000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        }
        return R.ok();
    }
    /**
     * 推送订单信息
     * @param startChargeSeq
     * @return
     */
    @PostMapping("/notificationChargeOrderInfo")
    public R notificationChargeOrderInfo(@RequestParam("startChargeSeq") String startChargeSeq, @RequestParam("operatorId") Integer operatorId){
        NotificationChargeOrderInfo info = buildNotificationChargeOrderInfo(startChargeSeq);
        Operator operator = operatorClient.getOperatorById(operatorId).getData();
        NotificationChargeOrderInfoResult notificationChargeOrderInfoResult = TCECUtil.notificationChargeOrderInfo(operator, info);
        //启动重试推送机制
        if(null == notificationChargeOrderInfoResult || 1 == notificationChargeOrderInfoResult.getConfirmResult()){
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
            threadPoolExecutor.execute(new Runnable() {
                //计数器
                Integer size = 0;
                @Override
                public void run() {
                    NotificationChargeOrderInfoResult notificationChargeOrderInfoResult1 = TCECUtil.notificationChargeOrderInfo(operator, info);
                    //启动重试推送机制
                    if(null != notificationChargeOrderInfoResult1 && 0 == notificationChargeOrderInfoResult1.getConfirmResult()){
                        threadPoolExecutor.shutdown();
                        return;
                    }
                    size++;
                    if(size >= 5){
                        threadPoolExecutor.shutdown();
                        return;
                    }
                    //间隔一分钟重试一次
                    try {
                        Thread.sleep(60000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        }
        return R.ok();
    }
    /**
     * 构建推送订单信息
     * @param startChargeSeq
     * @return
     */
    public NotificationChargeOrderInfo buildNotificationChargeOrderInfo(String startChargeSeq){
        //构建返回结果
        NotificationChargeOrderInfo notificationChargeOrderInfo = new NotificationChargeOrderInfo();
        notificationChargeOrderInfo.setStartChargeSeq(startChargeSeq);
        TChargingOrder chargingOrder = chargingOrderClient.getChargingOrderByStartChargeSeq(startChargeSeq).getData();
        if(null == chargingOrder){
            return null;
        }
        notificationChargeOrderInfo.setConnectorID(chargingOrder.getChargingGunId().toString());
        notificationChargeOrderInfo.setStartTime((null == chargingOrder.getStartTime() ? chargingOrder.getCreateTime() : chargingOrder.getStartTime()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        notificationChargeOrderInfo.setEndTime((null == chargingOrder.getEndTime() ? LocalDateTime.now() : chargingOrder.getEndTime()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        notificationChargeOrderInfo.setTotalPower(chargingOrder.getElectricity());
        notificationChargeOrderInfo.setTotalElecMoney(chargingOrder.getTotalElectricity());
        notificationChargeOrderInfo.setTotalSeviceMoney(chargingOrder.getServiceCharge());
        notificationChargeOrderInfo.setTotalMoney(chargingOrder.getTotalElectricity().add(chargingOrder.getServiceCharge()));
        notificationChargeOrderInfo.setTotalDelayMoney(BigDecimal.ZERO);
        TParkingRecord parkingRecord = parkingRecordClient.getParkingRecordByChargingOrderId(chargingOrder.getId()).getData();
        if(null != parkingRecord && parkingRecord.getStatus() == 3){
            notificationChargeOrderInfo.setTotalDelayMoney(parkingRecord.getPayment());
        }
        //结束方式(0=异常终止,1=主动终止,2=满电终止,3=费用不足终止)
        switch (chargingOrder.getEndMode()){
            case 0:
                notificationChargeOrderInfo.setStopReason(3);
                break;
            case 1:
                notificationChargeOrderInfo.setStopReason(0);
                break;
            case 2:
                notificationChargeOrderInfo.setStopReason(2);
                break;
            case 3:
                notificationChargeOrderInfo.setStopReason(5);
                break;
        }
        //构建充电明细
        List<ChargeDetail> chargeDetails = new ArrayList<>();
        List<TChargingOrderAccountingStrategy> data = chargingOrderAccountingStrategyClient.getChargingOrderAccountingStrategyByOrderId(chargingOrder.getId()).getData();
        LocalDateTime startTime = chargingOrder.getStartTime();
        LocalDateTime endTime = null == chargingOrder.getEndTime() ? LocalDateTime.now() : chargingOrder.getEndTime();
        String s_format = startTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        String e_format = endTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        for (TChargingOrderAccountingStrategy datum : data) {
            ChargeDetail chargeDetail = new ChargeDetail();
            if(s_format.equals(e_format)){
                chargeDetail.setDetailStartTime(s_format + " " + datum.getStartTime() + ":00");
                chargeDetail.setDetailEndTime(s_format + " " + datum.getEndTime() + ":59");
            }else{
                String substring = datum.getEndTime().substring(0, datum.getEndTime().indexOf(":"));
                if(Integer.valueOf(substring) > 12){
                    chargeDetail.setDetailStartTime(s_format + " " + datum.getStartTime() + ":00");
                    chargeDetail.setDetailEndTime(s_format + " " + datum.getEndTime() + ":59");
                }else{
                    chargeDetail.setDetailStartTime(e_format + " " + datum.getStartTime() + ":00");
                    chargeDetail.setDetailEndTime(e_format + " " + datum.getEndTime() + ":59");
                }
            }
            chargeDetail.setElecPrice(datum.getElectrovalence());
            chargeDetail.setSevicePrice(datum.getServiceCharge());
            chargeDetail.setDetailPower(datum.getChargingCapacity());
            chargeDetail.setDetailElecMoney(datum.getPeriodElectricPrice());
            chargeDetail.setDetailSeviceMoney(datum.getPeriodServicePrice());
            chargeDetails.add(chargeDetail);
        }
        notificationChargeOrderInfo.setChargeDetails(chargeDetails);
        return notificationChargeOrderInfo;
    }
    /**
     * 二维码查询枪号(快电)
     * @param baseRequest
     * @param request
     * @return
     */
    @PostMapping("/query_terminal_code")
    public BaseResult queryTerminalCode(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("三方平台二维码查询枪号请求参数:" + JacksonUtils.toJson(baseRequest));
        //校验token和签名
        BaseResult baseResult = requestCheck(true, baseRequest, request);
        if(0 != baseResult.getRet()){
            log.info("三方平台二维码查询枪号响应Data:");
            baseResult.setData("");
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台二维码查询枪号响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        Operator operator = baseResult.getOperator();
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getOurDataSecret(), operator.getOurDataSecretIv());
        log.info("三方平台二维码查询枪号请求Data:" + decrypt);
        QueryTerminalCode queryTerminalCode = JSON.parseObject(decrypt, QueryTerminalCode.class);
        String qrCode = queryTerminalCode.getQRCode();
        String substring = qrCode.substring(qrCode.indexOf("=") + 1);
        TChargingGun chargingGun = chargingGunClient.getChargingGunByFullNumber(substring).getData();
        QueryTerminalCodeResult queryTerminalCodeResult = new QueryTerminalCodeResult();
        if(null != chargingGun){
            queryTerminalCodeResult.setTerminalCode(chargingGun.getId().toString());
        }
        //参数加密
        String jsonString = JacksonUtils.toJson(queryTerminalCodeResult);
        log.info("三方平台二维码查询枪号响应Data:" + jsonString);
        String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
        baseResult.setData(encrypt);
        baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
        log.info("三方平台二维码查询枪号响应参数:" + JacksonUtils.toJson(baseResult));
        return baseResult;
    }
    /**
     * 推送充电车牌号
     * 客户归属运营商向设备运营商推送充电用户车牌号减免停车费,多次推送以最后一次车牌号为准
     * @param baseRequest
     * @param request
     * @return
     */
    @PostMapping("/notification_charge_carnum")
    public BaseResult notificationChargeCarnum(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        //校验token和签名
        BaseResult baseResult = requestCheck(true, baseRequest, request);
        if(0 != baseResult.getRet()){
            baseResult.setData("");
            baseResult.setSig(TCECUtil.buildSign(baseResult));
            return baseResult;
        }
        Operator operator = baseResult.getOperator();
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getDataSecret(), operator.getDataSecretIv());
        NotificationChargeCarnum notificationChargeCarnum = JSON.parseObject(decrypt, NotificationChargeCarnum.class);
        NotificationChargeCarnumResult notificationChargeCarnumResult = new NotificationChargeCarnumResult();
        notificationChargeCarnumResult.setStartChargeSeqs(notificationChargeCarnum.getStartChargeSeqs());
        notificationChargeCarnumResult.setSuccStat(0);
        notificationChargeCarnumResult.setFailReason(0);
        TChargingOrder chargingOrder = chargingOrderClient.getChargingOrderByStartChargeSeq(notificationChargeCarnum.getStartChargeSeqs()).getData();
        if(null == chargingOrder){
            notificationChargeCarnumResult.setSuccStat(1);
            notificationChargeCarnumResult.setFailReason(1);
        }else{
            //待处理相关业务逻辑
        }
        //参数加密
        String jsonString = JacksonUtils.toJson(notificationChargeCarnumResult);
        String encrypt = AESUtil.encrypt(jsonString, operator.getDataSecret(), operator.getDataSecretIv());
        baseResult.setData(encrypt);
        baseResult.setSig(TCECUtil.buildSign(baseResult));
        return baseResult;
    }
    /**
     * 账单拉取(快电)
     * @param baseRequest
     * @param request
     * @return
     */
    @PostMapping("/query_charge_order_info")
    public BaseResult queryChargeOrderInfo(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("三方平台账单拉取请求参数:" + JacksonUtils.toJson(baseRequest));
        //校验token和签名
        BaseResult baseResult = requestCheck(true, baseRequest, request);
        if(0 != baseResult.getRet()){
            log.info("三方平台账单拉取响应Data:");
            baseResult.setData("");
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台账单拉取响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        Operator operator = baseResult.getOperator();
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getOurDataSecret(), operator.getOurDataSecretIv());
        log.info("三方平台账单拉取请求Data:" + decrypt);
        QueryChargeOrderInfo queryChargeOrderInfo = JSON.parseObject(decrypt, QueryChargeOrderInfo.class);
        //构建返回结果
        QueryChargeOrderInfoResult result = buildQueryChargeOrderInfoResult(queryChargeOrderInfo);
        //参数加密
        String jsonString = JacksonUtils.toJson(result);
        log.info("三方平台账单拉取响应Data:" + jsonString);
        String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
        baseResult.setData(encrypt);
        baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
        log.info("三方平台账单拉取响应参数:" + JacksonUtils.toJson(baseResult));
        return baseResult;
    }
    /**
     * 构建充电账单拉取实体
     * @param queryChargeOrderInfo
     * @return
     */
    public QueryChargeOrderInfoResult buildQueryChargeOrderInfoResult(QueryChargeOrderInfo queryChargeOrderInfo){
        //构建返回结果
        QueryChargeOrderInfoResult queryChargeOrderInfoResult = new QueryChargeOrderInfoResult();
        List<OrderInfo> orderInfos = new ArrayList<>();
        List<String> startChargeSeqs = queryChargeOrderInfo.getStartChargeSeqs();
        List<TChargingOrder> chargingOrders = chargingOrderClient.getChargingOrderByStartChargeSeqs(startChargeSeqs).getData();
        for (TChargingOrder chargingOrder : chargingOrders) {
            if(null == chargingOrder){
                return null;
            }
            OrderInfo orderInfo = new OrderInfo();
            orderInfo.setStartChargeSeq(chargingOrder.getStartChargeSeq());
            orderInfo.setConnectorID(chargingOrder.getChargingGunId().toString());
            orderInfo.setStartTime((null == chargingOrder.getStartTime() ? chargingOrder.getCreateTime() : chargingOrder.getStartTime()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            orderInfo.setEndTime((null == chargingOrder.getEndTime() ? LocalDateTime.now() : chargingOrder.getEndTime()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            orderInfo.setTotalPower(chargingOrder.getTotalElectricity());
            orderInfo.setTotalElecMoney(chargingOrder.getElectrovalence());
            orderInfo.setTotalSeviceMoney(chargingOrder.getServiceCharge());
            orderInfo.setTotalMoney(chargingOrder.getTotalElectricity().add(chargingOrder.getServiceCharge()));
            //结束方式(0=异常终止,1=主动终止,2=满电终止,3=费用不足终止)
            switch (chargingOrder.getEndMode()){
                case 0:
                    orderInfo.setStopReason(3);
                    break;
                case 1:
                    orderInfo.setStopReason(0);
                    break;
                case 2:
                    orderInfo.setStopReason(2);
                    break;
                case 3:
                    orderInfo.setStopReason(4);
                    break;
            }
            //构建充电明细
            List<ChargeDetail> chargeDetails = new ArrayList<>();
            List<TChargingOrderAccountingStrategy> data = chargingOrderAccountingStrategyClient.getChargingOrderAccountingStrategyByOrderId(chargingOrder.getId()).getData();
            LocalDateTime startTime = chargingOrder.getStartTime();
            LocalDateTime endTime = null == chargingOrder.getEndTime() ? LocalDateTime.now() : chargingOrder.getEndTime();
            String s_format = startTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            String e_format = endTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            for (TChargingOrderAccountingStrategy datum : data) {
                ChargeDetail chargeDetail = new ChargeDetail();
                if(s_format.equals(e_format)){
                    chargeDetail.setDetailStartTime(s_format + " " + datum.getStartTime() + ":00");
                    chargeDetail.setDetailEndTime(s_format + " " + datum.getEndTime() + ":59");
                }else{
                    String substring = datum.getEndTime().substring(0, datum.getEndTime().indexOf(":"));
                    if(Integer.valueOf(substring) > 12){
                        chargeDetail.setDetailStartTime(s_format + " " + datum.getStartTime() + ":00");
                        chargeDetail.setDetailEndTime(s_format + " " + datum.getEndTime() + ":59");
                    }else{
                        chargeDetail.setDetailStartTime(e_format + " " + datum.getStartTime() + ":00");
                        chargeDetail.setDetailEndTime(e_format + " " + datum.getEndTime() + ":59");
                    }
                }
                chargeDetail.setElecPrice(datum.getElectrovalence());
                chargeDetail.setSevicePrice(datum.getServiceCharge());
                chargeDetail.setDetailPower(datum.getChargingCapacity());
                chargeDetail.setDetailElecMoney(datum.getPeriodElectricPrice());
                chargeDetail.setDetailSeviceMoney(datum.getPeriodServicePrice());
                chargeDetails.add(chargeDetail);
            }
            orderInfo.setChargeDetails(chargeDetails);
            orderInfos.add(orderInfo);
        }
        queryChargeOrderInfoResult.setOrderInfos(orderInfos);
        return queryChargeOrderInfoResult;
    }
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECUtil.java
New file
@@ -0,0 +1,379 @@
package com.ruoyi.integration.drainage;
import cn.hutool.http.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.ruoyi.common.core.utils.SpringUtils;
import com.ruoyi.integration.drainage.kuaidian.model.NotificationStationChangeResult;
import com.ruoyi.integration.drainage.kuaidian.model.StationChange;
import com.ruoyi.integration.drainage.model.*;
import com.ruoyi.integration.drainage.model.enu.InterfaceUrlEnum;
import com.ruoyi.other.api.domain.Operator;
import com.ruoyi.other.api.feignClient.OperatorClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
 * 中电联TCEC标准
 * @author zhibing.pu
 * @Date 2025/1/21 11:48
 */
@Slf4j
public class TCECUtil {
    private static OperatorClient operatorClient = SpringUtils.getBean(OperatorClient.class);
    /**
     * 获取token
     */
    public static String queryToken(Operator operator){
        HttpRequest post = HttpUtil.createPost(operator.getUrl() + InterfaceUrlEnum.QUERY_TOKEN.getUrl());
        JSONObject info = new JSONObject();
        info.put("OperatorID", operator.getOurOperatorId());
        info.put("OperatorSecret", operator.getOperatorSecret());
        Long timeStamp = Long.valueOf(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
        post.contentType("application/json;charset=utf-8");
        BaseRequest baseRequest = new BaseRequest();
        baseRequest.setOperatorID(operator.getOurOperatorId());
        baseRequest.setTimeStamp(timeStamp);
        baseRequest.setSeq("0001");
        String jsonString = JacksonUtils.toJson(info);
        String encrypt = AESUtil.encrypt(jsonString, operator.getDataSecret(), operator.getDataSecretIv());
        baseRequest.setData(encrypt);
        baseRequest.setOperator(operator);
        baseRequest.setSig(buildSign(baseRequest));
        String request_json = JacksonUtils.toJson(baseRequest);
        log.info("获取三方平台授权token请求地址:" + post.getUrl());
        log.info("获取三方平台授权token请求参数:" + request_json);
        log.info("获取三方平台授权token请求Data:" + jsonString);
        post.body(request_json);
        HttpResponse execute = post.execute();
        if(200 != execute.getStatus()){
            log.error("获取三方平台授权token失败:" + execute.body());
            return null;
        }
        log.info("获取三方平台授权token响应参数:" + execute.body());
        BaseResult baseResult = JSON.parseObject(execute.body(), BaseResult.class);
        Integer Ret = baseResult.getRet();
        if(0 != Ret){
            log.error("获取三方平台授权token失败:" + baseResult.getMsg());
            return null;
        }
        //解密参数
        String decrypt = AESUtil.decrypt(baseResult.getData(), operator.getDataSecret(), operator.getDataSecretIv());
        log.info("获取三方平台授权token响应Data:" + decrypt);
        QueryTokenResult queryTokenResult = JSON.parseObject(decrypt, QueryTokenResult.class);
        String token = queryTokenResult.getAccessToken();
        Long tokenAvailableTime = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC) + queryTokenResult.getTokenAvailableTime();
        operator.setAccessToken(token);
        operator.setTokenAvailableTime(tokenAvailableTime);
        operatorClient.editOperator(operator);
        return token;
    }
    /**
     * 获取token
     * @return
     */
    public static String getToken(Operator operator){
        if(null != operator.getTokenAvailableTime() && operator.getTokenAvailableTime() > LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)){
            return operator.getAccessToken();
        }else{
            return queryToken(operator);
        }
    }
    /**
     * 设备状态变化推送
     * @param info
     */
    public static NotificationStationStatusResult notificationStationStatus(Operator operator, ConnectorStatusInfo info) {
        HttpRequest post = HttpUtil.createPost(operator.getUrl() + InterfaceUrlEnum.NOTIFICATION_STATION_STATUS.getUrl());
        buildBody(post, info, operator);
        HttpResponse execute = post.execute();
        if(200 != execute.getStatus()){
            log.error("推送三方平台设备状态失败:" + execute.body());
            return null;
        }
        log.info("推送三方平台设备状态响应:" + execute.body());
        BaseResult baseResult = JSON.parseObject(execute.body(), BaseResult.class);
        Integer Ret = baseResult.getRet();
        if(0 != Ret){
            log.error("推送三方平台设备状态失败:" + baseResult.getMsg());
            return null;
        }
        //解密参数
        String decrypt = AESUtil.decrypt(baseResult.getData(), operator.getDataSecret(), operator.getDataSecretIv());
        log.info("推送三方平台设备状态Data:" + decrypt);
        NotificationStationStatusResult notificationStationStatusResult = JSON.parseObject(decrypt, NotificationStationStatusResult.class);
        return notificationStationStatusResult;
    }
    /**
     * 推送启动充电结果
     * @param info
     * @return
     */
    public static NotificationStartChargeResult notificationStartChargeResult(Operator operator, NotificationStartCharge info){
        HttpRequest post = HttpUtil.createPost(operator.getUrl() + InterfaceUrlEnum.NOTIFICATION_START_CHARGE_RESULT.getUrl());
        buildBody(post, info, operator);
        HttpResponse execute = post.execute();
        if(200 != execute.getStatus()){
            log.error("推送三方平台启动充电结果失败:" + execute.body());
            return null;
        }
        log.info("推送三方平台启动充电结果响应:" + execute.body());
        BaseResult baseResult = JSON.parseObject(execute.body(), BaseResult.class);
        Integer Ret = baseResult.getRet();
        if(0 != Ret){
            log.error("推送三方平台启动充电结果失败:" + baseResult.getMsg());
            return null;
        }
        //解密参数
        String decrypt = AESUtil.decrypt(baseResult.getData(), operator.getDataSecret(), operator.getDataSecretIv());
        log.info("推送三方平台启动充电结果Data:" + decrypt);
        NotificationStartChargeResult notificationStartChargeResult = JSON.parseObject(decrypt, NotificationStartChargeResult.class);
        return notificationStartChargeResult;
    }
    /**
     * 推动充电状态
     * @param info
     * @return
     */
    public static NotificationEquipChargeStatusResult notificationEquipChargeStatus(Operator operator, QueryEquipChargeStatusResult info){
        HttpRequest post = HttpUtil.createPost(operator.getUrl() + InterfaceUrlEnum.NOTIFICATION_EQUIP_CHARGE_STATUS.getUrl());
        buildBody(post, info, operator);
        HttpResponse execute = post.execute();
        if(200 != execute.getStatus()){
            log.error("推送三方平台充电状态失败:" + execute.body());
            return null;
        }
        log.info("推送三方平台充电状态响应:" + execute.body());
        BaseResult baseResult = JSON.parseObject(execute.body(), BaseResult.class);
        Integer Ret = baseResult.getRet();
        if(0 != Ret){
            log.error("推送三方平台充电状态失败:" + baseResult.getMsg());
            return null;
        }
        //解密参数
        String decrypt = AESUtil.decrypt(baseResult.getData(), operator.getDataSecret(), operator.getDataSecretIv());
        log.info("推送三方平台充电状态Data:" + decrypt);
        NotificationEquipChargeStatusResult notificationEquipChargeStatusResult = JSON.parseObject(decrypt, NotificationEquipChargeStatusResult.class);
        return notificationEquipChargeStatusResult;
    }
    /**
     * 推送停止充电结果
     * @param info
     * @return
     */
    public static NotificationStopCharge notificationStopChargeResult(Operator operator, NotificationStopChargeResult info){
        HttpRequest post = HttpUtil.createPost(operator.getUrl() + InterfaceUrlEnum.NOTIFICATION_STOP_CHARGE_RESULT.getUrl());
        buildBody(post, info, operator);
        HttpResponse execute = post.execute();
        if(200 != execute.getStatus()){
            log.error("推送三方平台停止充电结果失败:" + execute.body());
            return null;
        }
        log.info("推送三方平台停止充电结果响应:" + execute.body());
        BaseResult baseResult = JSON.parseObject(execute.body(), BaseResult.class);
        Integer Ret = baseResult.getRet();
        if(0 != Ret){
            log.error("推送三方平台停止充电结果失败:" + baseResult.getMsg());
            return null;
        }
        //解密参数
        String decrypt = AESUtil.decrypt(baseResult.getData(), operator.getDataSecret(), operator.getDataSecretIv());
        log.info("推送三方平台停止充电结果Data:" + decrypt);
        NotificationStopCharge notificationStopCharge = JSON.parseObject(decrypt, NotificationStopCharge.class);
        return notificationStopCharge;
    }
    /**
     * 推送充电订单信息
     * @param info
     * @return
     */
    public static NotificationChargeOrderInfoResult notificationChargeOrderInfo(Operator operator, NotificationChargeOrderInfo info){
        HttpRequest post = HttpUtil.createPost(operator.getUrl() + InterfaceUrlEnum.NOTIFICATION_CHARGE_ORDER_INFO.getUrl());
        buildBody(post, info, operator);
        HttpResponse execute = post.execute();
        if(200 != execute.getStatus()){
            log.error("推送三方平台充电订单信息失败:" + execute.body());
            return null;
        }
        log.info("推送三方平台充电订单信息响应:" + execute.body());
        BaseResult baseResult = JSON.parseObject(execute.body(), BaseResult.class);
        Integer Ret = baseResult.getRet();
        if(0 != Ret){
            log.error("推送三方平台充电订单信息失败:" + baseResult.getMsg());
            return null;
        }
        //解密参数
        String decrypt = AESUtil.decrypt(baseResult.getData(), operator.getDataSecret(), operator.getDataSecretIv());
        log.info("推送三方平台充电订单信息Data:" + decrypt);
        NotificationChargeOrderInfoResult notificationChargeOrderInfoResult = JSON.parseObject(decrypt, NotificationChargeOrderInfoResult.class);
        return notificationChargeOrderInfoResult;
    }
    /**
     * 构建请求参数和消息头
     * @param post
     * @param o
     */
    public static void buildBody(HttpRequest post, Object o, Operator operator){
        Long timeStamp = Long.valueOf(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
        post.contentType("application/json;charset=utf-8");
        post.header("Authorization", "Bearer " + getToken(operator));
        BaseRequest baseRequest = new BaseRequest();
        baseRequest.setOperatorID(operator.getOurOperatorId());
        baseRequest.setTimeStamp(timeStamp);
        baseRequest.setSeq("0001");
        String jsonString = JacksonUtils.toJson(o);
        String encrypt = AESUtil.encrypt(jsonString, operator.getDataSecret(), operator.getDataSecretIv());
        baseRequest.setData(encrypt);
        baseRequest.setOperator(operator);
        baseRequest.setSig(buildSign(baseRequest));
        String request_json = JacksonUtils.toJson(baseRequest);
        post.body(request_json);
        log.info("推送三方平台请求地址:" + post.getUrl());
        log.info("推送三方平台请求参数:" + request_json);
        log.info("推送三方平台请求Data:" + jsonString);
    }
    /**
     * 构建签名字符串
     * @param model
     * @return
     */
    public static String buildSign(BaseModel model){
        Operator operator = model.getOperator();
        if(null == operator){
            return "";
        }
        //签名秘钥SigSecret
        String key = operator.getSigSecret();
        String sign = "";
        switch (operator.getName()){
            case "XinDianTu":
                //进行字符串拼接、计算
                String m = new StringBuilder(model.getOperatorID()).append(model.getData()).append(model.getTimeStamp()).append(model.getSeq()).toString();
                byte[] hmacMd5 = SignUtil.getHMacMD5Bytes(key.getBytes(), m.getBytes());
                // 打印计算得到的签名Sig
                sign = SignUtil.bytesToHexString(hmacMd5);
                break;
            case "KuaiDian":
                //进行字符串拼接、计算
                String m1 = new StringBuilder(model.getOperatorID()).append(model.getData()).append(model.getTimeStamp()).append(model.getSeq()).toString();
                // 打印计算得到的签名Sig
                sign = SignUtil.hmacSign(m1, key);
                break;
        }
        return sign;
    }
    /**
     * 构建签名字符串
     * @param model
     * @return
     */
    public static String ourBuildSign(BaseModel model){
        Operator operator = model.getOperator();
        if(null == operator){
            return "";
        }
        //签名秘钥SigSecret
        String key = operator.getOurSigSecret();
        String sign = "";
        switch (operator.getName()){
            case "XinDianTu":
                //进行字符串拼接、计算
                String m = new StringBuilder(model.getOperatorID()).append(model.getData()).append(model.getTimeStamp()).append(model.getSeq()).toString();
                byte[] hmacMd5 = SignUtil.getHMacMD5Bytes(key.getBytes(), m.getBytes());
                // 打印计算得到的签名Sig
                sign = SignUtil.bytesToHexString(hmacMd5);
                break;
            case "KuaiDian":
                //进行字符串拼接、计算
                String m1 = new StringBuilder(model.getOperatorID()).append(model.getData()).append(model.getTimeStamp()).append(model.getSeq()).toString();
                sign = SignUtil.hmacSign(m1, key);
                break;
        }
        return sign;
    }
    public static void main(String[] args) {
        BaseModel model = new BaseModel();
        model.setOperatorID("MA25CNM38");
        model.setData("AoArdDDcmHcmOMkCLHodTpY1xLtt9yhLqxvKPyfdlmEOBj1LJnQM+Z4JOZllt3Pj9rubfgxJ51zMAfzquQegJzHGAT9Y7JrKFzFe6jGtXo0=");
        model.setTimeStamp(20250205120800L);
        model.setSeq("0001");
        Operator operator = new Operator();
        operator.setName("XinDianTu");
        operator.setSigSecret("S94xUpTpOIlLJBk8");
        model.setOperator(operator);
        String key = operator.getSigSecret();
        String m = new StringBuilder(model.getOperatorID()).append(model.getData()).append(model.getTimeStamp()).append(model.getSeq()).toString();
        byte[] hmacMd5 = SignUtil.getHMacMD5Bytes(key.getBytes(), m.getBytes());
        // 打印计算得到的签名Sig
        String s = SignUtil.bytesToHexString(hmacMd5);
        System.err.println(s);
//        BaseModel model = new BaseModel();
//        model.setOperatorID("MA25CNM38");
//        model.setData("xQYYEPiwoc4JENnQsF50qP6Tmnj7uU/AshWn3QbIgrMIk8zvFpy6fWLIiLzQHcLPFCihqH1uzoNhGVNcS8Wvf5gIx9+cWJvYtjwtsjAGMEwNQ6y+rF1jjKnqCNcQbHbhqJ2l76sD54QCFKyenKxymrXri19bDV8hizn3nBw+jcHBtqKHWzjdSHwPDWPIw4rXnrbWLya2PXVgYtVg93WPtliw+0xsqW0BxJamE70/Ilbg4wB5fOAOvXmbLFI+v9jRjpcA7ImhprqPMYkXYAfa2QlICrJEBK7DfpJvRMzKzeT90kOAITqIqFvbfV0ti+greRqToLP6ni4o6w3ID42UmKasIpLTnx+qtR4bVTBTRuDzXvNXDA92RqHaJO21xbSen1eHN/yGfrchBIM0gmav7EpaYAerfU4ubnmJ6xujR6okYepJwBD5DiSIrObfS+GWVPRekvnjvm7BC02NXTrGKA==");
//        model.setTimeStamp(20250205161426L);
//        model.setSeq("0001");
//        Operator operator = new Operator();
//        operator.setOurOperatorId("2921700136");
//        operator.setOurSigSecret("KBm5J2fbGzyhX023");
//        model.setOperator(operator);
//        String key = operator.getOurSigSecret();
//
//        String m = new StringBuilder(operator.getOurOperatorId()).append(model.getData()).append(model.getTimeStamp()).append(model.getSeq()).toString();
//        byte[] hmacMd5 = SignUtil.getHMacMD5Bytes(key.getBytes(), m.getBytes());
//        // 打印计算得到的签名Sig
//        String s = SignUtil.bytesToHexString(hmacMd5);
//        System.err.println(s);
    }
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TokenUtil.java
New file
@@ -0,0 +1,159 @@
package com.ruoyi.integration.drainage;
import com.ruoyi.common.core.constant.CacheConstants;
import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.exception.auth.NotLoginException;
import com.ruoyi.common.core.utils.JwtUtils;
import com.ruoyi.common.core.utils.ServletUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.ip.IpUtils;
import com.ruoyi.common.core.utils.uuid.IdUtils;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.other.api.domain.Operator;
import com.ruoyi.system.api.model.LoginUser;
import com.ruoyi.system.api.model.LoginUserApplet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
 * token验证处理
 *
 * @author ruoyi
 */
@Component
public class TokenUtil {
    @Autowired
    private RedisService redisService;
    protected static final long MILLIS_SECOND = 1000;
    protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
    private final static long expireTime = CacheConstants.EXPIRATION;
    private final static long expireAppletTime = CacheConstants.EXPIRATION_APPLET;
    private final static String ACCESS_TOKEN = CacheConstants.LOGIN_TOKEN_KEY;
    private final static Long MILLIS_MINUTE_TEN = CacheConstants.REFRESH_TIME * MILLIS_MINUTE;
    /**
     * 创建令牌
     */
    public Map<String, Object> createToken(Operator operator) {
        String token = IdUtils.fastUUID();
        operator.setToken(token);
        refreshToken(operator);
        // Jwt存储信息
        Map<String, Object> claimsMap = new HashMap<String, Object>();
        claimsMap.put(SecurityConstants.USER_KEY, token);
        claimsMap.put(SecurityConstants.DETAILS_USER_ID, operator.getOperatorId());
        claimsMap.put(SecurityConstants.USER_TYPE, "system");
        claimsMap.put(SecurityConstants.DETAILS_USERNAME, operator.getName());
        // 接口返回信息
        Map<String, Object> rspMap = new HashMap<String, Object>();
        rspMap.put("access_token", JwtUtils.createToken(claimsMap));
        rspMap.put("expires_in", expireTime);
        return rspMap;
    }
    /**
     * 获取用户身份信息
     *
     * @return 用户信息
     */
    public Operator getLoginUser() {
        Operator loginUser = getLoginUser(ServletUtils.getRequest());
        if (loginUser == null) {
            throw new NotLoginException("令牌已过期,请重新登录!");
        }
        return loginUser;
    }
    /**
     * 获取用户身份信息
     *
     * @return 用户信息
     */
    public Operator getLoginUser(HttpServletRequest request) {
        // 获取请求携带的令牌
        String token = SecurityUtils.getToken(request);
        return getLoginUser(token);
    }
    /**
     * 获取用户身份信息
     *
     * @return 用户信息
     */
    public Operator getLoginUser(String token) {
        Operator user = null;
        try {
            if (StringUtils.isNotEmpty(token)) {
                String userkey = JwtUtils.getUserKey(token);
                user = redisService.getCacheObject(getTokenKey(userkey));
                return user;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return user;
    }
    /**
     * 设置用户身份信息
     */
    public void setLoginUser(Operator operator) {
        if (StringUtils.isNotNull(operator) && StringUtils.isNotEmpty(operator.getToken())) {
            refreshToken(operator);
        }
    }
    /**
     * 删除用户缓存信息
     */
    public void delLoginUser(String token) {
        if (StringUtils.isNotEmpty(token)) {
            String userkey = JwtUtils.getUserKey(token);
            redisService.deleteObject(getTokenKey(userkey));
        }
    }
    /**
     * 验证令牌有效期,相差不足120分钟,自动刷新缓存
     *
     * @param operator
     */
    public void verifyToken(Operator operator) {
        long expireTime = operator.getExpireTime();
        long currentTime = System.currentTimeMillis();
        if (expireTime - currentTime <= MILLIS_MINUTE_TEN) {
            refreshToken(operator);
        }
    }
    /**
     * 刷新令牌有效期
     *
     * @param operator 登录信息
     */
    public void refreshToken(Operator operator) {
        operator.setLoginTime(System.currentTimeMillis());
        operator.setExpireTime(operator.getLoginTime() + expireTime * MILLIS_MINUTE);
        // 根据uuid将loginUser缓存
        String userKey = getTokenKey(operator.getToken());
        redisService.setCacheObject(userKey, operator, expireTime, TimeUnit.MINUTES);
    }
    private String getTokenKey(String token) {
        return ACCESS_TOKEN + token;
    }
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/kuaidian/TCECKDUtil.java
New file
@@ -0,0 +1,77 @@
package com.ruoyi.integration.drainage.kuaidian;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.utils.SpringUtils;
import com.ruoyi.integration.drainage.AESUtil;
import com.ruoyi.integration.drainage.SignUtil;
import com.ruoyi.integration.drainage.TCECUtil;
import com.ruoyi.integration.drainage.kuaidian.model.NotificationStationChangeResult;
import com.ruoyi.integration.drainage.kuaidian.model.StationChange;
import com.ruoyi.integration.drainage.model.*;
import com.ruoyi.integration.drainage.model.enu.InterfaceUrlEnum;
import com.ruoyi.other.api.domain.Operator;
import com.ruoyi.other.api.feignClient.OperatorClient;
import lombok.extern.slf4j.Slf4j;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
 * 中电联TCEC标准(快电)
 * @author zhibing.pu
 * @Date 2025/1/21 11:48
 */
@Slf4j
public class TCECKDUtil extends TCECUtil {
    /**
     * 站点变更通知
     * @param operator
     * @param type
     * @param siteIds
     * @return
     */
    public static NotificationStationChangeResult notificationStationChange(Operator operator, Integer type, List<Integer> siteIds) {
        StationChange stationChange = new StationChange();
        stationChange.setOperatorId(operator.getOurOperatorId());
        stationChange.setType(type);
        List<String> collect = siteIds.stream().map(String::valueOf).collect(Collectors.toList());
        stationChange.setStationIds(collect);
        HttpRequest post = HttpUtil.createPost(operator.getUrl() + InterfaceUrlEnum.NOTIFICATION_STATION_CHANGE.getUrl());
        buildBody(post, stationChange, operator);
        HttpResponse execute = post.execute();
        if(200 != execute.getStatus()){
            log.error("推送三方平台站点变更通知失败:" + execute.body());
            return null;
        }
        log.info("推送三方平台站点变更通知响应:" + execute.body());
        BaseResult baseResult = JSON.parseObject(execute.body(), BaseResult.class);
        Integer Ret = baseResult.getRet();
        if(0 != Ret){
            log.error("推送三方平台站点变更通知失败:" + baseResult.getMsg());
            return null;
        }
        //解密参数
        String decrypt = AESUtil.decrypt(baseResult.getData(), operator.getDataSecret(), operator.getDataSecretIv());
        log.info("推送三方平台站点变更通知Data:" + decrypt);
        NotificationStationChangeResult notificationStationChangeResult = JSON.parseObject(decrypt, NotificationStationChangeResult.class);
        return notificationStationChangeResult;
    }
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/kuaidian/model/NotificationChargeCarnum.java
New file
@@ -0,0 +1,24 @@
package com.ruoyi.integration.drainage.kuaidian.model;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 推送充电车牌号
 * @author zhibing.pu
 * @Date 2025/1/26 14:38
 */
@Data
public class NotificationChargeCarnum {
    /**
     * 充电订单号
     */
    @NotNull
    private String StartChargeSeqs;
    /**
     * 充电车牌号
     */
    @NotNull
    private String Carnum;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/kuaidian/model/NotificationChargeCarnumResult.java
New file
@@ -0,0 +1,34 @@
package com.ruoyi.integration.drainage.kuaidian.model;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 推送充电车牌号返回结果
 * @author zhibing.pu
 * @Date 2025/1/26 14:43
 */
@Data
public class NotificationChargeCarnumResult {
    /**
     * 充电订单号
     */
    @NotNull
    private String StartChargeSeqs;
    /**
     * 成功状态
     * 0:成功
     * 1:失败
     */
    @NotNull
    private Integer SuccStat;
    /**
     * 失败原因
     * 0:无
     * 1:无此订单
     * 2`9自定义
     */
    @NotNull
    private Integer FailReason;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/kuaidian/model/NotificationStationChangeResult.java
New file
@@ -0,0 +1,40 @@
package com.ruoyi.integration.drainage.kuaidian.model;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
 * 站点变更通知返回结果
 * @author zhibing.pu
 * @Date 2025/1/26 10:45
 */
@Data
public class NotificationStationChangeResult {
    /**
     * 运营商ID
     */
    @NotNull
    private String OperatorId;
    /**
     * 站点ID
     */
    @NotNull
    private List<String> StationIds;
    /**
     * 成功状态
     * 0:成功
     * 1:失败
     */
    @NotNull
    private Integer SuccStat;
    /**
     * 失败原因
     * 0:无
     * 1:无效站点
     * 2`9:自定义
     */
    @NotNull
    private Integer FailReason;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/kuaidian/model/OrderInfo.java
New file
@@ -0,0 +1,99 @@
package com.ruoyi.integration.drainage.kuaidian.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.ruoyi.integration.drainage.model.ChargeDetail;
import lombok.Data;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
import java.math.BigDecimal;
import java.util.List;
/**
 * 账单实体
 * @author zhibing.pu
 * @Date 2025/1/26 15:29
 */
@Data
public class OrderInfo {
    /**
     * 充电订单号
     */
    @NotNull
    @JsonProperty("StartChargeSeq")
    private String startChargeSeq;
    /**
     * 充电设备接口编码
     */
    @NotNull
    @JsonProperty("ConnectorID")
    private String connectorID;
    /**
     * 开始充电时间
     * yyyy-MM-dd HH:mm:ss
     */
    @NotNull
    @JsonProperty("StartTime")
    private String startTime;
    /**
     * 结束充电时间
     * yyyy-MM-dd HH:mm:ss
     */
    @NotNull
    @JsonProperty("EndTime")
    private String endTime;
    /**
     * 累计充电电量
     */
    @NotNull
    @JsonProperty("TotalPower")
    private BigDecimal totalPower;
    /**
     * 总电费
     */
    @NotNull
    @JsonProperty("TotalElecMoney")
    private BigDecimal totalElecMoney;
    /**
     * 总服务费
     */
    @NotNull
    @JsonProperty("TotalSeviceMoney")
    private BigDecimal totalSeviceMoney;
    /**
     * 累计总金额
     */
    @NotNull
    @JsonProperty("TotalMoney")
    private BigDecimal totalMoney;
    /**
     * 车辆识别码
     */
    @Null
    @JsonProperty("VIN")
    private String VIN;
    /**
     * 充电结束原因
     * 0:用户手动停止充电
     * 1:客户归属地运营商平台停止充电
     * 2:BMS停止充电
     * 3:充电机设备故障
     * 4:连接器断开
     * 5`99:自定义
     */
    @NotNull
    @JsonProperty("StopReason")
    private Integer stopReason;
    /**
     * 时段数N
     * 范围0`23
     */
    @Null
    @JsonProperty("SumPeriod")
    private Integer sumPeriod;
    /**
     * 充电明细信息
     */
    @JsonProperty("ChargeDetails")
    private List<ChargeDetail> chargeDetails;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/kuaidian/model/QueryChargeOrderInfo.java
New file
@@ -0,0 +1,18 @@
package com.ruoyi.integration.drainage.kuaidian.model;
import lombok.Data;
import java.util.List;
/**
 * 账单拉取
 * @author zhibing.pu
 * @Date 2025/1/26 15:26
 */
@Data
public class QueryChargeOrderInfo {
    /**
     * 充电订单号集合
     */
    private List<String> StartChargeSeqs;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/kuaidian/model/QueryChargeOrderInfoResult.java
New file
@@ -0,0 +1,20 @@
package com.ruoyi.integration.drainage.kuaidian.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;
/**
 * 账单拉取
 * @author zhibing.pu
 * @Date 2025/1/26 15:28
 */
@Data
public class QueryChargeOrderInfoResult {
    /**
     * 充电订单账单集合
     */
    @JsonProperty("Orderlnfos")
    private List<OrderInfo> orderInfos;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/kuaidian/model/QueryTerminalCode.java
New file
@@ -0,0 +1,19 @@
package com.ruoyi.integration.drainage.kuaidian.model;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 二维码查询抢号
 * @author zhibing.pu
 * @Date 2025/1/26 11:12
 */
@Data
public class QueryTerminalCode {
    /**
     * 二维码信息
     */
    @NotNull
    private String QRCode;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/kuaidian/model/QueryTerminalCodeResult.java
New file
@@ -0,0 +1,21 @@
package com.ruoyi.integration.drainage.kuaidian.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 二维码查询抢号结果
 * @author zhibing.pu
 * @Date 2025/1/26 11:18
 */
@Data
public class QueryTerminalCodeResult {
    /**
     * 枪号
     */
    @NotNull
    @JsonProperty("TerminalCode")
    private String TerminalCode;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/kuaidian/model/StationChange.java
New file
@@ -0,0 +1,31 @@
package com.ruoyi.integration.drainage.kuaidian.model;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
 * 站点变更通知
 * @author zhibing.pu
 * @Date 2025/1/26 10:34
 */
@Data
public class StationChange {
    /**
     * 运营商ID
     */
    @NotNull
    private String operatorId;
    /**
     * 变更类型
     * 3:站点计费策略变更
     */
    @NotNull
    private Integer type;
    /**
     * 站点ID
     */
    @NotNull
    private List<String> stationIds;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/BaseModel.java
New file
@@ -0,0 +1,48 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.ruoyi.other.api.domain.Operator;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * @author zhibing.pu
 * @Date 2025/1/23 18:33
 */
@Data
public class BaseModel {
    /**
     * 运营商标识
     */
    @NotNull
    @JsonProperty("OperatorID")
    private String operatorID;
    /**
     * 参数内容
     */
    @NotNull
    @JsonProperty("Data")
    private String data;
    /**
     * 时间戳
     * yyyyMMddHHmmss
     */
    @NotNull
    @JsonProperty("TimeStamp")
    private Long timeStamp;
    /**
     * 自增序列
     * 4位自增序列取自时间戳,同一秒内按序列自增长,新秒重计。如 0001
     */
    @NotNull
    @JsonProperty("Seq")
    private String seq;
    /**
     * 运营商对象
     */
    @JsonIgnore
    private Operator operator;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/BaseRequest.java
New file
@@ -0,0 +1,21 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 公共请求
 * @author zhibing.pu
 * @Date 2025/1/21 17:08
 */
@Data
public class BaseRequest extends BaseModel {
    /**
     * 数字签名
     */
    @NotNull
    @JsonProperty("Sig")
    private String sig;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/BaseResult.java
New file
@@ -0,0 +1,46 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.ruoyi.other.api.domain.Operator;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 公共返回结果
 * @author zhibing.pu
 * @Date 2025/1/21 15:54
 */
@Data
public class BaseResult extends BaseModel {
    /**
     * 参数编码
     * -1:系统繁忙,此时请求方稍后重试
     * 0:请求成功
     * 4001:签名错误
     * 4002:Token错误
     * 4003:POST参数不合法,缺少必需的
     * 4004:请求的业务参数不合法
     * 500:系统错误
     */
    @NotNull
    @JsonProperty("Ret")
    private Integer ret;
    /**
     * 错误信息描述
     */
    @NotNull
    @JsonProperty("Msg")
    private String msg;
    /**
     * 签名
     */
    @NotNull
    @JsonProperty("Sig")
    private String sig;
    /**
     * 运营商对象
     */
    private Operator operator;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/ChargeDetail.java
New file
@@ -0,0 +1,61 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
import java.math.BigDecimal;
/**
 * 充电明细信息
 * @author zhibing.pu
 * @Date 2025/1/21 16:40
 */
@Data
public class ChargeDetail {
    /**
     * 开始时间
     * yyyy-MM-dd HH:mm:ss
     */
    @NotNull
    @JsonProperty("DetailStartTime")
    private String detailStartTime;
    /**
     * 结束时间
     * yyyy-MM-dd HH:mm:ss
     */
    @NotNull
    @JsonProperty("DetailEndTime")
    private String detailEndTime;
    /**
     * 时段电价
     */
    @Null
    @JsonProperty("ElecPrice")
    private BigDecimal elecPrice;
    /**
     * 时段服务费价格
     */
    @Null
    @JsonProperty("SevicePrice")
    private BigDecimal sevicePrice;
    /**
     * 时段充电量
     */
    @Null
    @JsonProperty("DetailPower")
    private BigDecimal detailPower;
    /**
     * 时段电费
     */
    @Null
    @JsonProperty("DetailElecMoney")
    private BigDecimal detailElecMoney;
    /**
     * 时段服务费
     */
    @Null
    @JsonProperty("DetailSeviceMoney")
    private BigDecimal detailSeviceMoney;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/ConnectorInfo.java
New file
@@ -0,0 +1,79 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
import java.math.BigDecimal;
/**
 * 充电设备接口
 * @author zhibing.pu
 * @Date 2025/1/21 14:03
 */
@Data
public class ConnectorInfo {
    /**
     * 充电设备接口编码
     */
    @NotNull
    @JsonProperty("ConnectorID")
    private String connectorID;
    /**
     * 充电设备接口名称
     */
    @Null
    @JsonProperty("ConnectorName")
    private String connectorName;
    /**
     * 充电设备接口类型
     */
    @NotNull
    @JsonProperty("ConnectorType")
    private Integer connectorType;
    /**
     * 额定电压上限
     */
    @NotNull
    @JsonProperty("VoltageUpperLimits")
    private Integer voltageUpperLimits;
    /**
     * 额定电压下限
     */
    @NotNull
    @JsonProperty("VoltageLowerLimits")
    private Integer voltageLowerLimits;
    /**
     * 额定电流
     */
    @NotNull
    @JsonProperty("Current")
    private Integer current;
    /**
     * 额定功率
     */
    @NotNull
    @JsonProperty("Power")
    private BigDecimal power;
    /**
     * 车位号
     */
    @Null
    @JsonProperty("ParkNo")
    private String parkNo;
    /**
     * 国家标准
     * 1:2011
     * 2:2015
     */
    @NotNull
    @JsonProperty("NationalStandard")
    private Integer nationalStandard;
    /**
     * 枪二维码
     */
    @Null
    @JsonProperty("QRCode")
    private String QRCode;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/ConnectorStatsInfo.java
New file
@@ -0,0 +1,28 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
/**
 * 充电设备接口统计信息
 * @author zhibing.pu
 * @Date 2025/1/21 15:24
 */
@Data
public class ConnectorStatsInfo {
    /**
     * 充电设备接口编码
     */
    @NotNull
    @JsonProperty("ConnectorID")
    private String connectorID;
    /**
     * 充电设备接口累计电量
     */
    @NotNull
    @JsonProperty("ConnectorElectricity")
    private BigDecimal connectorElectricity;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/ConnectorStatusInfo.java
New file
@@ -0,0 +1,55 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
/**
 * 充电设备接口状态
 * @author zhibing.pu
 * @Date 2025/1/21 14:53
 */
@Data
public class ConnectorStatusInfo {
    /**
     * 充电设备接口编码
     */
    @NotNull
    @JsonProperty("ConnectorID")
    private String connectorID;
    /**
     * 充电设备接口状态
     * 0:离网
     * 1:空闲
     * 2:占用(未充电)
     * 3:占用(充电中)
     * 4:占用(预约锁定)
     * 255:故障
     */
    @NotNull
    @JsonProperty("Status")
    private Integer status;
    /**
     * 车位状态
     * 0:未知
     * 10:空闲
     * 50:占用
     */
    @Null
    @JsonProperty("ParkStatus")
    private Integer parkStatus;
    /**
     * 地锁状态
     * 0:未知
     * 10:已解锁
     * 50:已上锁
     */
    @Null
    @JsonProperty("LookStatus")
    private Integer lookStatus;
    @JsonProperty("ConnectorStatusInfo")
    private ConnectorStatusInfo connectorStatusInfo;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/ConnectorStatusInfo1.java
New file
@@ -0,0 +1,54 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
/**
 * 充电设备接口状态
 * @author zhibing.pu
 * @Date 2025/1/21 14:53
 */
@Data
public class ConnectorStatusInfo1 {
    /**
     * 充电设备接口编码
     */
    @NotNull
    @JsonProperty("ConnectorID")
    private String connectorID;
    /**
     * 充电设备接口状态
     * 0:离网
     * 1:空闲
     * 2:占用(未充电)
     * 3:占用(充电中)
     * 4:占用(预约锁定)
     * 255:故障
     */
    @NotNull
    @JsonProperty("Status")
    private Integer status;
    /**
     * 车位状态
     * 0:未知
     * 10:空闲
     * 50:占用
     */
    @Null
    @JsonProperty("ParkStatus")
    private Integer parkStatus;
    /**
     * 地锁状态
     * 0:未知
     * 10:已解锁
     * 50:已上锁
     */
    @Null
    @JsonProperty("LookStatus")
    private Integer lookStatus;
    private ConnectorStatusInfo1 ConnectorStatusInfo;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/EquipmentInfo.java
New file
@@ -0,0 +1,85 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
import java.math.BigDecimal;
import java.util.List;
/**
 * 充电设备信息
 * @author zhibing.pu
 * @Date 2025/1/21 13:51
 */
@Data
public class EquipmentInfo {
    /**
     * 设备编号
     */
    @NotNull
    @JsonProperty("EquipmentID")
    private String equipmentID;
    /**
     * 设备生产商组织机构代码
     */
    @Null
    @JsonProperty("ManufacturerID")
    private String manufacturerID;
    /**
     * 设备生产商名称
     */
    @Null
    @JsonProperty("ManufacturerName")
    private String manufacturerName;
    /**
     * 设备型号
     */
    @Null
    @JsonProperty("EquipmentModel")
    private String equipmentModel;
    /**
     * 设备生产日期
     * YYYY-MM-DD
     */
    @Null
    @JsonProperty("ProductionDate")
    private String productionDate;
    /**
     * 设备类型
     */
    @NotNull
    @JsonProperty("EquipmentType")
    private Integer equipmentType;
    /**
     * 充电设备接口信息列表
     */
    @NotNull
    @JsonProperty("ConnectorInfos")
    private List<ConnectorInfo> connectorInfos;
    /**
     * 充电设备经度
     */
    @Null
    @JsonProperty("EquipmentLng")
    private BigDecimal equipmentLng;
    /**
     * 充电设备纬度
     */
    @Null
    @JsonProperty("EquipmentLat")
    private BigDecimal equipmentLat;
    /**
     * 充电设备总功率
     */
    @NotNull
    @JsonProperty("Power")
    private BigDecimal power;
    /**
     * 充电设备名称
     */
    @Null
    @JsonProperty("EquipmentName")
    private String equipmentName;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/EquipmentStatsInfo.java
New file
@@ -0,0 +1,35 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.List;
/**
 * 充电设备统计信息
 * @author zhibing.pu
 * @Date 2025/1/21 15:22
 */
@Data
public class EquipmentStatsInfo {
    /**
     * 设备编码
     */
    @NotNull
    @JsonProperty("EquipmentID")
    private String equipmentID;
    /**
     * 充电设备接口累计电量
     */
    @NotNull
    @JsonProperty("EquipmentElectricity")
    private BigDecimal equipmentElectricity;
    /**
     * 充电设备接口统计信息列表
     */
    @NotNull
    @JsonProperty("ConnectorStatsInfos")
    private List<ConnectorStatsInfo> connectorStatsInfos;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/NotificationChargeOrderInfo.java
New file
@@ -0,0 +1,106 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
import java.math.BigDecimal;
import java.util.List;
/**
 * 推送充电订单信息
 * @author zhibing.pu
 * @Date 2025/1/21 15:39
 */
@Data
public class NotificationChargeOrderInfo {
    /**
     * 充电订单号
     */
    @NotNull
    @JsonProperty("StartChargeSeq")
    private String startChargeSeq;
    /**
     * 充电设备接口编码
     */
    @NotNull
    @JsonProperty("ConnectorID")
    private String connectorID;
    /**
     * 开始充电时间
     * yyyy-MM-dd HH:mm:ss
     */
    @NotNull
    @JsonProperty("StartTime")
    private String startTime;
    /**
     * 结束充电时间
     * yyyy-MM-dd HH:mm:ss
     */
    @NotNull
    @JsonProperty("EndTime")
    private String endTime;
    /**
     * 累计充电量
     */
    @NotNull
    @JsonProperty("TotalPower")
    private BigDecimal totalPower;
    /**
     * 总电费
     */
    @NotNull
    @JsonProperty("TotalElecMoney")
    private BigDecimal totalElecMoney;
    /**
     * 总服务费
     */
    @NotNull
    @JsonProperty("TotalSeviceMoney")
    private BigDecimal totalSeviceMoney;
    /**
     * 累计总金额
     */
    @NotNull
    @JsonProperty("TotalMoney")
    private BigDecimal totalMoney;
    /**
     * 充电结束原因
     * 0:用户手动停止充电
     * 1:客户归属地运营商平台停止充电
     * 2:BMS停止充电
     * 3:充电机设备故障
     * 4:连接器断开
     * 5·99:自定义
     */
    @NotNull
    @JsonProperty("StopReason")
    private Integer stopReason;
    /**
     * 时段数 N
     * 0·32
     */
    @Null
    @JsonProperty("SumPeriod")
    private Integer sumPeriod;
    /**
     * 充电明细信息
     */
    @Null
    @JsonProperty("ChargeDetails")
    private List<ChargeDetail> chargeDetails;
    /**
     * 占位费
     */
    @Null
    @JsonProperty("TotalDelayMoney")
    private BigDecimal totalDelayMoney;
    /**
     * 车辆识别码
     */
    @Null
    @JsonProperty("VIN")
    private String VIN;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/NotificationChargeOrderInfoResult.java
New file
@@ -0,0 +1,35 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 推送充电订单信息返回记过
 * @author zhibing.pu
 * @Date 2025/1/21 15:49
 */
@Data
public class NotificationChargeOrderInfoResult {
    /**
     * 充电订单号
     */
    @NotNull
    @JsonProperty("StartChargeSeq")
    private String startChargeSeq;
    /**
     * 充电设备接口编码
     */
    @NotNull
    @JsonProperty("ConnectorID")
    private String connectorID;
    /**
     * 确认结果
     * 0;成功
     * 1:争议交易
     * 2·99:自定义
     */
    @JsonProperty("ConfirmResult")
    private Integer confirmResult;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/NotificationEquipChargeStatusResult.java
New file
@@ -0,0 +1,29 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 推送充电状态结果
 * @author zhibing.pu
 * @Date 2025/1/21 16:48
 */
@Data
public class NotificationEquipChargeStatusResult {
    /**
     * 充电订单号
     */
    @NotNull
    @JsonProperty("StartChargeSeq")
    private String startChargeSeq;
    /**
     * 操作结果
     * 0:成功
     * 1:失败
     */
    @NotNull
    @JsonProperty("SuccStat")
    private Integer succStat;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/NotificationStartCharge.java
New file
@@ -0,0 +1,44 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 推送启动充电结果
 * @author zhibing.pu
 * @Date 2025/1/22 18:40
 */
@Data
public class NotificationStartCharge {
    /**
     * 充电订单号
     */
    @NotNull
    @JsonProperty("StartChargeSeq")
    private String startChargeSeq;
    /**
     * 充电订单状态
     * 1:启动中
     * 2:充电中
     * 3:停止中
     * 4:已结束
     * 5:未知
     */
    @NotNull
    @JsonProperty("StartChargeSeqStat")
    private Integer startChargeSeqStat;
    /**
     * 充电设别接口编码
     */
    @NotNull
    @JsonProperty("ConnectorID")
    private String connectorID;
    /**
     * 充电启动时间
     */
    @NotNull
    @JsonProperty("StartTime")
    private String startTime;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/NotificationStartChargeResult.java
New file
@@ -0,0 +1,37 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 推送启动充电结果返回值
 * @author zhibing.pu
 * @Date 2025/1/22 18:47
 */
@Data
public class NotificationStartChargeResult {
    /**
     * 充电订单号
     */
    @NotNull
    @JsonProperty("StartChargeSeq")
    private String startChargeSeq;
    /**
     * 操作结果
     * 0:成功
     * 1:失败
     */
    @NotNull
    @JsonProperty("SuccStat")
    private Integer succStat;
    /**
     * 失败原因
     * 0:无
     * 1:接收失败
     */
    @NotNull
    @JsonProperty("FailReason")
    private Integer failReason;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/NotificationStationStatusResult.java
New file
@@ -0,0 +1,23 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 设备状态变化推动返回结果
 * @author zhibing.pu
 * @Date 2025/1/21 14:58
 */
@Data
public class NotificationStationStatusResult {
    /**
     * 状态
     * 0:接收
     * 1:丢弃/忽略,不需要重试
     */
    @NotNull
    @JsonProperty("Status")
    private Integer status;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/NotificationStopCharge.java
New file
@@ -0,0 +1,37 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 推送停止充电结果应答
 * @author zhibing.pu
 * @Date 2025/1/23 9:17
 */
@Data
public class NotificationStopCharge {
    /**
     * 充电订单号
     */
    @NotNull
    @JsonProperty("StartChargeSeq")
    private String startChargeSeq;
    /**
     * 操作结果
     * 0:成功
     * 1:失败
     */
    @NotNull
    @JsonProperty("SuccStat")
    private Integer succStat;
    /**
     * 失败原因
     * 0:无
     * 1:接收失败
     */
    @NotNull
    @JsonProperty("FailReason")
    private Integer failReason;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/NotificationStopChargeResult.java
New file
@@ -0,0 +1,57 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 推送停止充电结果
 * @author zhibing.pu
 * @Date 2025/1/23 9:13
 */
@Data
public class NotificationStopChargeResult {
    /**
     * 充电订单号
     */
    @NotNull
    @JsonProperty("StartChargeSeq")
    private String startChargeSeq;
    /**
     * 充电订单状态
     * 1:启动中
     * 2:充电中
     * 3:停止中
     * 4:已结束
     * 5:未知
     */
    @NotNull
    @JsonProperty("StartChargeSeqStat")
    private Integer startChargeSeqStat;
    /**
     * 充电设备接口编码
     */
    @NotNull
    @JsonProperty("ConnectorID")
    private String connectorID;
    /**
     * 操作结果
     * 0:成功
     * 1:失败
     */
    @NotNull
    @JsonProperty("SuccStat")
    private Integer succStat;
    /**
     * 失败原因
     * 0:无
     * 1:此设备不存在
     * 2:此设备离线
     * 3:此设备已停止充电
     * 4`9:自定义
     */
    @NotNull
    @JsonProperty("FailReason")
    private Integer failReason;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/OperatorInfo.java
New file
@@ -0,0 +1,52 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
/**
 * 基础设施运营商信息
 * @author zhibing.pu
 * @Date 2025/1/21 11:49
 */
@Data
public class OperatorInfo {
    /**
     * 运营商ID
     */
    @NotNull
    @JsonProperty("OperatorID")
    private String operatorID;
    /**
     * 运营商名称
     */
    @NotNull
    @JsonProperty("OperatorName")
    private String operatorName;
    /**
     * 运营商电话1
     */
    @NotNull
    @JsonProperty("OperatorTel1")
    private String operatorTel1;
    /**
     * 运营商电话2
     */
    @Null
    @JsonProperty("OperatorTel2")
    private String operatorTel2;
    /**
     * 运营商注册地址
     */
    @Null
    @JsonProperty("OperatorRegAddress")
    private String operatorRegAddress;
    /**
     * 备注
     */
    @Null
    @JsonProperty("OperatorNote")
    private String operatorNote;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/PlaceHolder.java
New file
@@ -0,0 +1,48 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.List;
/**
 * 占位费信息
 * @author zhibing.pu
 * @Date 2025/1/26 9:29
 */
@Data
public class PlaceHolder {
    /**
     * 免费时长
     */
    @NotNull
    @JsonProperty("FreeTime")
    private Integer freeTime;
    /**
     * 嘴阀占位费
     */
    @NotNull
    @JsonProperty("MaxFee")
    private BigDecimal maxFee;
    /**
     * 生效开始时间
     * yyyy-MM-dd HH:mm:ss
     */
    @NotNull
    @JsonProperty("EffectStartTime")
    private String effectStartTime;
    /**
     * 生效结束时间
     */
    @NotNull
    @JsonProperty("EffectEndTime")
    private String effectEndTime;
    /**
     * 占位费价格
     */
    @NotNull
    @JsonProperty("PlaceHolderPrices")
    private List<PlaceHolderPrice> placeHolderPrices;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/PlaceHolderPrice.java
New file
@@ -0,0 +1,36 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
/**
 * 占位费价格
 * @author zhibing.pu
 * @Date 2025/1/26 9:33
 */
@Data
public class PlaceHolderPrice {
    /**
     * 开始时段
     * HH:mm
     */
    @NotNull
    @JsonProperty("StartTime")
    private String startTime;
    /**
     * 结束时段
     * HH:mm
     */
    @NotNull
    @JsonProperty("EndTime")
    private String endTime;
    /**
     * 单价
     */
    @NotNull
    @JsonProperty("Price")
    private BigDecimal price;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/PolicyInfo.java
New file
@@ -0,0 +1,35 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
/**
 * 计费信息
 * @author zhibing.pu
 * @Date 2025/1/21 16:10
 */
@Data
public class PolicyInfo {
    /**
     * 时段起始时间点
     * HHmmss
     */
    @NotNull
    @JsonProperty("StartTime")
    private String startTime;
    /**
     * 时段电费
     */
    @NotNull
    @JsonProperty("ElecPrice")
    private BigDecimal elecPrice;
    /**
     * 时段服务费
     */
    @NotNull
    @JsonProperty("SevicePrice")
    private BigDecimal sevicePrice;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryEquipAuth.java
New file
@@ -0,0 +1,27 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 请求设备认证
 * @author zhibing.pu
 * @Date 2025/1/22 16:15
 */
@Data
public class QueryEquipAuth {
    /**
     * 设备认证流水
     */
    @NotNull
    @JsonProperty("EquipAuthSeq")
    private String equipAuthSeq;
    /**
     * 充电设备接口编码
     */
    @NotNull
    @JsonProperty("ConnectorID")
    private String connectorID;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryEquipAuthResult.java
New file
@@ -0,0 +1,45 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 请求设备认证返回结果
 * @author zhibing.pu
 * @Date 2025/1/22 16:16
 */
@Data
public class QueryEquipAuthResult {
    /**
     * 设备认证流水号
     */
    @NotNull
    @JsonProperty("EquipAuthSeq")
    private String equipAuthSeq;
    /**
     * 充电设备接口编码
     */
    @NotNull
    @JsonProperty("ConnectorID")
    private String connectorID;
    /**
     * 操作结果
     * 0:成功
     * 1:失败
     */
    @NotNull
    @JsonProperty("SuccStat")
    private Integer succStat;
    /**
     * 失败原因
     * 0:无
     * 1:此设备尚未插枪
     * 2:设备检测失败
     * 3·99:自定义
     */
    @NotNull
    @JsonProperty("FailReason")
    private Integer failReason;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryEquipBusinessPolicy.java
New file
@@ -0,0 +1,28 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 查询业务策略信息
 * @author zhibing.pu
 * @Date 2025/1/21 16:03
 */
@Data
public class QueryEquipBusinessPolicy {
    /**
     * 业务策略查询流水号
     * 格式”运营商ID+唯一编号“。27字符
     */
    @NotNull
    @JsonProperty("EquipBizSeq")
    private String equipBizSeq;
    /**
     * 充电设备接口编码
     */
    @NotNull
    @JsonProperty("ConnectorID")
    private String connectorID;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryEquipBusinessPolicyResult.java
New file
@@ -0,0 +1,58 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
 * 查询业务策略信息结果
 * @author zhibing.pu
 * @Date 2025/1/21 16:05
 */
@Data
public class QueryEquipBusinessPolicyResult {
    /**
     * 业务策略查询流水号
     */
    @NotNull
    @JsonProperty("EquipBizSeq")
    private String equipBizSeq;
    /**
     * 充电设备接口编码
     */
    @NotNull
    @JsonProperty("ConnectorID")
    private String connectorID;
    /**
     * 操作结果
     * 0:成功
     * 1:失败
     */
    @NotNull
    @JsonProperty("SuccStat")
    private Integer succStat;
    /**
     * 失败原因
     * 0:无
     * 1:此充电桩业务策略不存在
     */
    @NotNull
    @JsonProperty("FailReason")
    private Integer failReason;
    /**
     * 时段数N
     * 0`32
     */
    @NotNull
    @JsonProperty("SumPeriod")
    private Integer sumPeriod;
    /**
     * 计策信息
     */
    @NotNull
    @JsonProperty("PolicyInfos")
    private List<PolicyInfo> policyInfos;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryEquipChargeStatus.java
New file
@@ -0,0 +1,34 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
/**
 * 查询充电状态
 * @author zhibing.pu
 * @Date 2025/1/21 16:17
 */
@Data
public class QueryEquipChargeStatus {
    /**
     * 充电订单号
     */
    @NotNull
    @JsonProperty("StartChargeSeq")
    private String startChargeSeq;
    /**
     * 抢号
     */
    @NotNull
    @JsonProperty("ConnectorID")
    private String connectorID;
    /**
     * 车辆识别码
     */
    @Null
    @JsonProperty("VIN")
    private String VIN;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryEquipChargeStatusResult.java
New file
@@ -0,0 +1,150 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
import java.math.BigDecimal;
import java.util.List;
/**
 * 查询充电状态结果
 * @author zhibing.pu
 * @Date 2025/1/21 15:58
 */
@Data
public class QueryEquipChargeStatusResult {
    /**
     * 充电订单号
     */
    @NotNull
    @JsonProperty("StartChargeSeq")
    private String startChargeSeq;
    /**
     * 充电订单状态
     * 1:启动中
     * 2:充电中
     * 3:停止中
     * 4:已结束
     * 5:未知
     */
    @NotNull
    @JsonProperty("StartChargeSeqStat")
    private Integer startChargeSeqStat;
    /**
     * 充电设备接口编号
     */
    @NotNull
    @JsonProperty("ConnectorID")
    private String connectorID;
    /**
     * 充电设备接口状态
     * 1:空闲
     * 2:占用(未充电)
     * 3:占用(充电中)
     * 4:占用(预约锁定)
     * 255:故障
     */
    @NotNull
    @JsonProperty("ConnectorStatus")
    private Integer connectorStatus;
    /**
     * A相电流
     */
    @NotNull
    @JsonProperty("CurrentA")
    private BigDecimal currentA;
    /**
     * B相电流
     */
    @Null
    @JsonProperty("CurrentB")
    private BigDecimal currentB;
    /**
     * C相电流
     */
    @Null
    @JsonProperty("CurrentC")
    private BigDecimal currentC;
    /**
     * A相电压
     */
    @NotNull
    @JsonProperty("VoltageA")
    private BigDecimal voltageA;
    /**
     * B相电压
     */
    @Null
    @JsonProperty("VoltageB")
    private BigDecimal voltageB;
    /**
     * C相电压
     */
    @Null
    @JsonProperty("VoltageC")
    private BigDecimal voltageC;
    /**
     * 电池剩余电量
     */
    @NotNull
    @JsonProperty("Soc")
    private BigDecimal soc;
    /**
     * 开始充电时间
     */
    @NotNull
    @JsonProperty("StartTime")
    private String startTime;
    /**
     * 本次采样时间
     */
    @NotNull
    @JsonProperty("EndTime")
    private String endTime;
    /**
     * 累计充电量
     */
    @NotNull
    @JsonProperty("TotalPower")
    private BigDecimal totalPower;
    /**
     * 累计电费
     */
    @Null
    @JsonProperty("ElecMoney")
    private BigDecimal elecMoney;
    /**
     * 累计服务费
     */
    @Null
    @JsonProperty("SeviceMoney")
    private BigDecimal seviceMoney;
    /**
     * 累计总金额
     */
    @Null
    @JsonProperty("TotalMoney")
    private BigDecimal totalMoney;
    /**
     * 时段数N
     * 0`32
     */
    @Null
    @JsonProperty("SumPeriod")
    private Integer sumPeriod;
    /**
     * 充电明细信息
     */
    @Null
    @JsonProperty("ChargeDetails")
    private List<ChargeDetail> chargeDetails;
    /**
     * 车辆识别码
     */
    @Null
    @JsonProperty("VIN")
    private String VIN;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryStartCharge.java
New file
@@ -0,0 +1,47 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
import java.math.BigDecimal;
/**
 * 请求启动充电
 * @author zhibing.pu
 * @Date 2025/1/22 16:59
 */
@Data
public class QueryStartCharge {
    /**
     * 充电订单号
     */
    @NotNull
    @JsonProperty("StartChargeSeq")
    private String startChargeSeq;
    /**
     * 充电设备接口编码
     */
    @NotNull
    @JsonProperty("ConnectorID")
    private String connectorID;
    /**
     * 二维码其他信息
     */
    @NotNull
    @JsonProperty("QRCode")
    private String QRCode;
    /**
     * 充电余额
     */
    @NotNull
    @JsonProperty("ChargingAmt")
    private BigDecimal chargingAmt;
    /**
     * 充电车牌号
     */
    @Null
    @JsonProperty("PlateNum")
    private String plateNum;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryStartChargeResult.java
New file
@@ -0,0 +1,57 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
/**
 * 请求启动充电返回结果
 * @author zhibing.pu
 * @Date 2025/1/22 17:02
 */
@Data
public class QueryStartChargeResult {
    /**
     * 充电订单号
     */
    @NotNull
    @JsonProperty("StartChargeSeq")
    private String startChargeSeq;
    /**
     * 充电订单状态
     * 1:启动中
     * 2:充电中
     * 3:停止中
     * 4:已结束
     * 5:未知
     */
    @NotNull
    @JsonProperty("StartChargeSeqStat")
    private Integer startChargeSeqStat;
    /**
     * 充电设别接口编码
     */
    @NotNull
    @JsonProperty("ConnectorID")
    private String connectorID;
    /**
     * 操作结果
     * 0:成功
     * 1:失败
     */
    @NotNull
    @JsonProperty("SuccStat")
    private Integer succStat;
    /**
     * 失败原因
     * 0:无
     * 1:此设备不存在
     * 2:此设备离线
     * 3`9:自定义
     */
    @NotNull
    @JsonProperty("FailReason")
    private Integer failReason;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryStationStats.java
New file
@@ -0,0 +1,35 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 查询统计信息
 * @author zhibing.pu
 * @Date 2025/1/21 15:11
 */
@Data
public class QueryStationStats {
    /**
     * 充电站ID
     */
    @NotNull
    @JsonProperty("StationID")
    private String stationID;
    /**
     * 统计开始时间
     * yyyy-MM-dd
     */
    @NotNull
    @JsonProperty("StartTime")
    private String startTime;
    /**
     * 统计结束时间
     * yyyy-MM-dd
     */
    @NotNull
    @JsonProperty("EndTime")
    private String endTime;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryStationStatsResult.java
New file
@@ -0,0 +1,21 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 查询统计信息结果
 * @author zhibing.pu
 * @Date 2025/1/21 15:16
 */
@Data
public class QueryStationStatsResult {
    /**
     * 充电站统计信息
     */
    @NotNull
    @JsonProperty("StationStats")
    private StationStatsInfo stationStats;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryStationStatus.java
New file
@@ -0,0 +1,23 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
 * 设备接口状态查询
 * @author zhibing.pu
 * @Date 2025/1/21 15:01
 */
@Data
public class QueryStationStatus {
    /**
     * 充电站ID列表
     * 数组长度不超过50
     */
    @NotNull
    @JsonProperty("StationIDs")
    private List<String> stationIDs;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryStationStatusResult.java
New file
@@ -0,0 +1,25 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;
/**
 * 设备接口状态查询返回结果
 * @author zhibing.pu
 * @Date 2025/1/21 15:04
 */
@Data
public class QueryStationStatusResult {
    /**
     * 结果总数
     */
    @JsonProperty("Total")
    private Integer total;
    /**
     * 设备接口状态列表
     */
    @JsonProperty("StationStatusInfos")
    private List<StationStatusInfo> stationStatusInfos;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryStationsInfo.java
New file
@@ -0,0 +1,35 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.Null;
/**
 * @author zhibing.pu
 * @Date 2025/1/21 14:41
 */
@Data
public class QueryStationsInfo {
    /**
     * 上次查询时间
     * yyyy-MM-dd HH:mm:ss
     */
    @Null
    @JsonProperty("LastQueryTime")
    private String lastQueryTime;
    /**
     * 查询页码
     * 默认1
     */
    @Null
    @JsonProperty("PageNo")
    private Integer pageNo;
    /**
     * 每页数量
     * 默认10
     */
    @Null
    @JsonProperty("PageSize")
    private Integer pageSize;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryStationsInfoResult.java
New file
@@ -0,0 +1,41 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
import java.util.List;
/**
 * 公共返回结果
 * @author zhibing.pu
 * @Date 2025/1/21 14:44
 */
@Data
public class QueryStationsInfoResult {
    /**
     * 当前页数
     */
    @NotNull
    @JsonProperty("PageNo")
    private Integer pageNo;
    /**
     * 页码总数
     */
    @NotNull
    @JsonProperty("PageCount")
    private Integer pageCount;
    /**
     * 总记录条数
     */
    @NotNull
    @JsonProperty("ItemSize")
    private Integer itemSize;
    /**
     * 充电站信息列表
     */
    @NotNull
    @JsonProperty("StationInfos")
    private List<StationInfo> stationInfos;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryStopCharge.java
New file
@@ -0,0 +1,27 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 请求停止充电
 * @author zhibing.pu
 * @Date 2025/1/22 19:56
 */
@Data
public class QueryStopCharge {
    /**
     * 充电订单号
     */
    @NotNull
    @JsonProperty("StartChargeSeq")
    private String startChargeSeq;
    /**
     * 充电设备接口编码
     */
    @NotNull
    @JsonProperty("ConnectorID")
    private String connectorID;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryStopChargeResult.java
New file
@@ -0,0 +1,52 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 请求停止充电返回结果
 * @author zhibing.pu
 * @Date 2025/1/22 19:58
 */
@Data
public class QueryStopChargeResult {
    /**
     * 充电订单号
     */
    @NotNull
    @JsonProperty("StartChargeSeq")
    private String startChargeSeq;
    /**
     * 充电订单状态
     * 1:启动中
     * 2:充电中
     * 3:停止中
     * 4:已结束
     * 5:未知
     */
    @NotNull
    @JsonProperty("StartChargeSeqStat")
    private Integer startChargeSeqStat;
    /**
     * 操作结果
     * 0:成功
     * 1:失败
     */
    @NotNull
    @JsonProperty("SuccStat")
    private Integer succStat;
    /**
     * 失败原因
     * 0:无
     * 1:此设备不存在
     * 2:此设备离线
     * 3:此设备已停止充电
     * 4`9:自定义
     */
    @NotNull
    @JsonProperty("FailReason")
    private Integer failReason;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryToken.java
New file
@@ -0,0 +1,27 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 获取token
 * @author zhibing.pu
 * @Date 2025/1/23 17:13
 */
@Data
public class QueryToken {
    /**
     * 运营商标识
     */
    @NotNull
    @JsonProperty("OperatorID")
    private String operatorID;
    /**
     * 运营商秘钥
     */
    @NotNull
    @JsonProperty("OperatorSecret")
    private String operatorSecret;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryTokenResult.java
New file
@@ -0,0 +1,51 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 获取token返回结果
 * @author zhibing.pu
 * @Date 2025/1/23 17:15
 */
@Data
public class QueryTokenResult {
    /**
     * 运营商标识
     */
    @NotNull
    @JsonProperty("OperatorID")
    private String operatorID;
    /**
     * 成功状态
     * 0:成功
     * 1:失败
     */
    @NotNull
    @JsonProperty("SuccStat")
    private Integer succStat;
    /**
     * 获取的凭证
     */
    @NotNull
    @JsonProperty("AccessToken")
    private String accessToken;
    /**
     * 凭证有效期,秒
     */
    @NotNull
    @JsonProperty("TokenAvailableTime")
    private Long tokenAvailableTime;
    /**
     * 失败原因
     * 0:无
     * 1:无此运营商
     * 2:秘钥错误
     * 3`9自定义
     */
    @NotNull
    @JsonProperty("FailReason")
    private Integer failReason;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/StationInfo.java
New file
@@ -0,0 +1,194 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
import java.math.BigDecimal;
import java.util.List;
/**
 * 充电站信息
 * @author zhibing.pu
 * @Date 2025/1/21 11:54
 */
@Data
public class StationInfo {
    /**
     * 充电站ID
     */
    @NotNull
    @JsonProperty("StationID")
    private String stationID;
    /**
     * 运营商ID
     */
    @NotNull
    @JsonProperty("OperatorID")
    private String operatorID;
    /**
     * 设备所属方ID
     * 设备所属运营平台组织机构代码
     */
    @NotNull
    @JsonProperty("EquipmentOwnerID")
    private String equipmentOwnerID;
    /**
     * 充电站名称
     */
    @NotNull
    @JsonProperty("StationName")
    private String stationName;
    /**
     * 充电站国家代码
     */
    @NotNull
    @JsonProperty("CountryCode")
    private String countryCode;
    /**
     * 充电站省市辖区编码
     */
    @NotNull
    @JsonProperty("AreaCode")
    private String areaCode;
    /**
     * 详细地址
     */
    @NotNull
    @JsonProperty("Address")
    private String address;
    /**
     * 站点电话
     */
    @Null
    @JsonProperty("StationTel")
    private String stationTel;
    /**
     * 站点电话
     */
    @NotNull
    @JsonProperty("ServiceTel")
    private String serviceTel;
    /**
     * 站点类型
     */
    @NotNull
    @JsonProperty("StationType")
    private Integer stationType;
    /**
     * 站点状态
     */
    @NotNull
    @JsonProperty("StationStatus")
    private Integer stationStatus;
    /**
     * 车位数量,0:未知
     */
    @NotNull
    @JsonProperty("ParkNums")
    private Integer parkNums;
    /**
     * 经度(保留6位小数)
     */
    @NotNull
    @JsonProperty("StationLng")
    private BigDecimal stationLng;
    /**
     * 纬度(保留6位小数)
     */
    @NotNull
    @JsonProperty("StationLat")
    private BigDecimal stationLat;
    /**
     * 站点引导
     */
    @Null
    @JsonProperty("SiteGuide")
    private String siteGuide;
    /**
     * 建设场所
     */
    @NotNull
    @JsonProperty("Construction")
    private Integer construction;
    /**
     * 站点照片
     * 字符串数组
     */
    @Null
    @JsonProperty("Pictures")
    private List<String> pictures;
    /**
     * 使用车型描述
     */
    @Null
    @JsonProperty("MatchCars")
    private String matchCars;
    /**
     * 车位楼层及数量描述
     */
    @Null
    @JsonProperty("ParkInfo")
    private String parkInfo;
    /**
     * 营业时间
     */
    @Null
    @JsonProperty("BusineHours")
    private String busineHours;
    /**
     * 充电电费率描述
     */
    @Null
    @JsonProperty("ElectricityFee")
    private String electricityFee;
    /**
     * 服务费率描述
     */
    @Null
    @JsonProperty("ServiceFee")
    private String serviceFee;
    /**
     * 停车费率描述
     */
    @Null
    @JsonProperty("ParkFee")
    private String parkFee;
    /**
     * 支付方式:刷卡、线上、现金
     */
    @Null
    @JsonProperty("Payment")
    private String payment;
    /**
     * 是否支持预约
     */
    @Null
    @JsonProperty("SupportOrder")
    private Integer supportOrder;
    /**
     * 备注
     */
    @Null
    @JsonProperty("Remark")
    private String remark;
    /**
     * 充电设备信息列表
     */
    @NotNull
    @JsonProperty("EquipmentInfos")
    private List<EquipmentInfo> equipmentInfos;
    /**
     * 占位费描述
     */
    @Null
    @JsonProperty("OvertimeFee")
    private String overtimeFee;
    /**
     * 占位费信息
     */
    @Null
    @JsonProperty("PlaceHolder")
    private PlaceHolder placeHolder;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/StationStatsInfo.java
New file
@@ -0,0 +1,49 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.List;
/**
 * 充电站统计信息
 * @author zhibing.pu
 * @Date 2025/1/21 15:17
 */
@Data
public class StationStatsInfo {
    /**
     * 充电站ID
     */
    @NotNull
    @JsonProperty("StationID")
    private String stationID;
    /**
     * 统计的开始时间
     * yyyy-MM-dd
     */
    @NotNull
    @JsonProperty("StartTime")
    private String startTime;
    /**
     * 统计的结束时间
     * yyyy-MM-dd
     */
    @NotNull
    @JsonProperty("EndTime")
    private String endTime;
    /**
     * 充电站累计电量 kw/h
     */
    @NotNull
    @JsonProperty("StationElectricity")
    private BigDecimal stationElectricity;
    /**
     * 充电设备统计信息列表
     */
    @NotNull
    @JsonProperty("EquipmentStatsInfos")
    private List<EquipmentStatsInfo> equipmentStatsInfos;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/StationStatusInfo.java
New file
@@ -0,0 +1,27 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
 * 充电站状态信息
 * @author zhibing.pu
 * @Date 2025/1/21 15:07
 */
@Data
public class StationStatusInfo {
    /**
     * 充电站ID
     */
    @NotNull
    @JsonProperty("StationID")
    private String stationID;
    /**
     * 充电设备接口状态列表
     */
    @JsonProperty("ConnectorStatusInfos")
    private List<ConnectorStatusInfo> connectorStatusInfos;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/enu/ConnectorTypeEnum.java
New file
@@ -0,0 +1,39 @@
package com.ruoyi.integration.drainage.model.enu;
/**
 * 充电设备接口类型
 * @author zhibing.pu
 * @Date 2025/1/21 14:14
 */
public enum ConnectorTypeEnum {
    HOUSEHOLD_SOCKET(1, "家用插座"),
    AC_SOCKET(2, "交流接口插座"),
    AC_INTERFACE_PLUG(3, "交流接口插头"),
    DC_INTERFACE_GUN_HEAD(4, "直流接口枪头"),
    WIRELESS_CHARGING_STAND(5, "无线充电座"),
    OTHER(6, "其他")
    ;
    private Integer type;
    private String note;
    ConnectorTypeEnum(Integer type, String note) {
        this.type = type;
        this.note = note;
    }
    public Integer getType() {
        return type;
    }
    public void setType(Integer type) {
        this.type = type;
    }
    public String getNote() {
        return note;
    }
    public void setNote(String note) {
        this.note = note;
    }
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/enu/ConstructionEnum.java
New file
@@ -0,0 +1,45 @@
package com.ruoyi.integration.drainage.model.enu;
/**
 * 建设场所
 * @author zhibing.pu
 * @Date 2025/1/21 13:25
 */
public enum ConstructionEnum {
    RESIDENTIAL_AREA(1, "居民区"),
    PUBLIC_INSTITUTION(2, "公共机构"),
    ENTERPRISE(3, "企事业单位"),
    OFFICE_BUILDING(4, "写字楼"),
    INDUSTRIAL_PARK(5, "工业园区"),
    TRANSPORTATION_JUNCTION(6, "交通枢纽"),
    CULTURE_AND_SPORTS(7, "大型文体设施"),
    URBAN_GREEN_SPACE(8, "城市绿地"),
    ANCILLARY_PARKING_LOT(9, "大型建筑配建停车场"),
    OFF_STREET_PARKING_SPACE(10, "路边停车位"),
    HIGH_SPEED_SERVICE_AREA(11, "城际高速服务区"),
    OTHER(255, "其他");
    private Integer type;
    private String note;
    ConstructionEnum(Integer type, String note) {
        this.type = type;
        this.note = note;
    }
    public Integer getType() {
        return type;
    }
    public void setType(Integer type) {
        this.type = type;
    }
    public String getNote() {
        return note;
    }
    public void setNote(String note) {
        this.note = note;
    }
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/enu/EquipmentTypeEnum.java
New file
@@ -0,0 +1,40 @@
package com.ruoyi.integration.drainage.model.enu;
/**
 * 设备类型
 * @author zhibing.pu
 * @Date 2025/1/21 13:59
 */
public enum EquipmentTypeEnum {
    DIRECT_CURRENT(1, "直流设备"),
    ALTERNATING_CURRENT(2, "交流设备"),
    ALTERNATING_DIRECT(3, "交直流一体设备"),
    WIRELESS_DEVICE(4, "无线设备"),
    OTHER(5, "其他")
    ;
    private Integer type;
    private String note;
    EquipmentTypeEnum(Integer type, String note) {
        this.type = type;
        this.note = note;
    }
    public Integer getType() {
        return type;
    }
    public void setType(Integer type) {
        this.type = type;
    }
    public String getNote() {
        return note;
    }
    public void setNote(String note) {
        this.note = note;
    }
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/enu/InterfaceUrlEnum.java
New file
@@ -0,0 +1,43 @@
package com.ruoyi.integration.drainage.model.enu;
/**
 * 接口地址枚举
 * @author zhibing.pu
 * @Date 2025/1/21 14:38
 */
public enum InterfaceUrlEnum {
    QUERY_TOKEN("/query_token", "获取权限token"),
    NOTIFICATION_STATION_STATUS("/notification_stationStatus", "设备状态变化推送"),
    NOTIFICATION_STATION_CHANGE("/notification_station_change", "站点计费策略变更推送"),
    NOTIFICATION_START_CHARGE_RESULT("/notification_start_charge_result", "推送启动充电结果"),
    NOTIFICATION_EQUIP_CHARGE_STATUS("/notification_equip_charge_status", "推送充电状态"),
    NOTIFICATION_STOP_CHARGE_RESULT("/notification_stop_charge_result", "推送停止充电结果"),
    NOTIFICATION_CHARGE_ORDER_INFO("/notification_charge_order_info", "推送充电订单信息"),
    CHECK_CHARGE_ORDERS("/check_charge_orders", "推送订单对账结果信息"),
    ;
    private String url;
    private String note;
    InterfaceUrlEnum(String url, String note) {
        this.url = url;
        this.note = note;
    }
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public String getNote() {
        return note;
    }
    public void setNote(String note) {
        this.note = note;
    }
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/enu/StationStatusEnum.java
New file
@@ -0,0 +1,38 @@
package com.ruoyi.integration.drainage.model.enu;
/**
 * 站点状态
 * @author zhibing.pu
 * @Date 2025/1/21 12:10
 */
public enum StationStatusEnum {
    UNKNOWN(0, "未知"),
    UNDER_CONSTRUCTION(1, "建设中"),
    OFF_LINE(5, "关闭下线"),
    MAINTAIN(6, "维护中"),
    NORMAL_USE(50, "正常使用")
    ;
    private Integer status;
    private String note;
    StationStatusEnum(Integer status, String note) {
        this.status = status;
        this.note = note;
    }
    public Integer getStatus() {
        return status;
    }
    public void setStatus(Integer status) {
        this.status = status;
    }
    public String getNote() {
        return note;
    }
    public void setNote(String note) {
        this.note = note;
    }
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/enu/StationTypeEnum.java
New file
@@ -0,0 +1,41 @@
package com.ruoyi.integration.drainage.model.enu;
/**
 * 站点类型
 * @author zhibing.pu
 * @Date 2025/1/21 12:00
 */
public enum StationTypeEnum {
    PUBLIC(1, "公共"),
    PERSONAGE(50, "个人"),
    BUS_SPECIFIC(100, "公交(专用)"),
    SANITATION_SPECIFIC(101, "环卫(专用)"),
    LOGISTICS_SPECIFIC(102, "物流(专用)"),
    TEXT_SPECIFIC(103, "出租车(专用)"),
    OTHER(255, "其他")
    ;
    private Integer type;
    private String note;
    StationTypeEnum(Integer type, String note) {
        this.type = type;
        this.note = note;
    }
    public Integer getType() {
        return type;
    }
    public void setType(Integer type) {
        this.type = type;
    }
    public String getNote() {
        return note;
    }
    public void setNote(String note) {
        this.note = note;
    }
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/builder/IotBuilder.java
@@ -30,7 +30,8 @@
                // 标准版/企业版需要使用衍生算法,基础版请删除配置"withDerivedPredicate";
                .withDerivedPredicate(AbstractCredentials.DEFAULT_DERIVED_PREDICATE) // Used in derivative ak/sk authentication scenarios
                .withAk(config.getAk())
                .withSk(config.getSk());
                .withSk(config.getSk())
                .withProjectId(config.getProjectId());
        return IoTDAClient.newBuilder()
                .withCredential(auth)
                // 标准版/企业版:需自行创建Region对象,基础版:请使用IoTDARegion的region对象,如"withRegion(IoTDARegion.CN_NORTH_4)"
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/mongodb/service/PingService.java
@@ -4,4 +4,9 @@
import com.ruoyi.integration.mongodb.base.BaseService;
public interface PingService extends BaseService<Ping> {
    /**
     * 定时删除数据
     */
    void delPing();
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/mongodb/service/PongService.java
@@ -7,5 +7,7 @@
 * 心跳包应答接口
 */
public interface PongService extends BaseService<Pong> {
    void delPong();
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/mongodb/service/impl/PingServiceImpl.java
@@ -1,12 +1,17 @@
package com.ruoyi.integration.mongodb.service.impl;
import com.mongodb.client.result.DeleteResult;
import com.ruoyi.integration.iotda.constant.IotConstant;
import com.ruoyi.integration.api.model.Ping;
import com.ruoyi.integration.mongodb.service.PingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
@Service
@@ -29,4 +34,9 @@
    public List<Ping> findAll() {
        return mongoTemplate.findAll(Ping.class);
    }
    @Override
    public void delPing() {
        mongoTemplate.remove(new Query().addCriteria(Criteria.where("create_time").lt(LocalDateTime.now().minusDays(1))));
    }
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/mongodb/service/impl/PongServiceImpl.java
@@ -1,5 +1,6 @@
package com.ruoyi.integration.mongodb.service.impl;
import com.mongodb.client.result.DeleteResult;
import com.ruoyi.integration.iotda.constant.IotConstant;
import com.ruoyi.integration.api.model.Online;
import com.ruoyi.integration.api.model.Pong;
@@ -7,8 +8,12 @@
import com.ruoyi.integration.mongodb.service.PongService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
@@ -35,4 +40,10 @@
    public List<Pong> findAll() {
        return mongoTemplate.findAll(Pong.class);
    }
    @Override
    public void delPong() {
        mongoTemplate.remove(new Query().addCriteria(Criteria.where("create_time").lt(LocalDateTime.now().minusDays(1))));
    }
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/rocket/listener/UploadRealTimeMonitoringDataMessageListener.java
@@ -7,6 +7,7 @@
import com.ruoyi.chargingPile.api.model.TChargingGun;
import com.ruoyi.chargingPile.api.model.TFaultMessage;
import com.ruoyi.chargingPile.api.vo.GetChargingGunByCode;
import com.ruoyi.integration.api.feignClient.TCECClient;
import com.ruoyi.integration.api.model.Online;
import com.ruoyi.integration.api.model.UploadRealTimeMonitoringData;
import com.ruoyi.integration.mongodb.service.UploadRealTimeMonitoringDataService;
@@ -51,6 +52,9 @@
    private ChargingGunClient chargingGunClient;
    @Resource
    private FaultMessageClient faultMessageClient;
    @Resource
    private TCECClient tcecClient;
    @Override
@@ -124,6 +128,8 @@
                }
            }
            chargingGunClient.updateChargingGunById(chargingGun);
            //推送状态给三方平台
            tcecClient.pushChargingGunStatus(chargingGun.getId(), chargingGun.getStatus());
        }
    }
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/util/TaskUtil.java
@@ -1,5 +1,7 @@
package com.ruoyi.integration.util;
import com.ruoyi.integration.mongodb.service.PingService;
import com.ruoyi.integration.mongodb.service.PongService;
import com.ruoyi.integration.rocket.produce.ChargingMessageListener;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@@ -17,6 +19,12 @@
    @Resource
    private ChargingMessageListener chargingMessageListener;
    
    @Resource
    private PingService pingService;
    @Resource
    private PongService pongService;
    
    /**
     * 5分钟执行的定时任务
@@ -25,6 +33,12 @@
    public void taskMonth() {
        chargingMessageListener.transactionRecord();
    }
    @Scheduled(cron = "0 0 0 * * ?")
    public void task2() {
        pingService.delPing();
        pongService.delPong();
    }
}
ruoyi-service/ruoyi-integration/src/main/resources/bootstrap.yml
@@ -24,7 +24,7 @@
    nacos:
      discovery:
        # 服务注册地址
        server-addr: 127.0.0.1:8848
        server-addr: 192.168.110.169:8848
        service: ${spring.application.name}
        group: DEFAULT_GROUP
        namespace: b5290bc2-e3aa-4988-8a7d-9c07e4e073cb
@@ -32,7 +32,7 @@
        password: nacos
      config:
        # 配置中心地址
        server-addr: 127.0.0.1:8848
        server-addr: 192.168.110.169:8848
        namespace: b5290bc2-e3aa-4988-8a7d-9c07e4e073cb
        group: DEFAULT_GROUP
        name: ${spring.application.name}
@@ -57,7 +57,7 @@
    type: nacos
    nacos:
      # 开发环境
#      server-addr: 127.0.0.1:8848
#      server-addr: 192.168.110.169:8848
#      namespace: b5290bc2-e3aa-4988-8a7d-9c07e4e073cb
#      group: DEFAULT_GROUP
#      data-id: seata-server.properties
@@ -75,7 +75,7 @@
    nacos:
      application: seata-server
      # 开发环境
#      server-addr: 127.0.0.1:8848
#      server-addr: 192.168.110.169:8848
#      namespace: b5290bc2-e3aa-4988-8a7d-9c07e4e073cb
#      group: DEFAULT_GROUP
#      username: nacos
@@ -90,7 +90,7 @@
    nacos:
      discovery:
        # 开发环境
#        server-addr: 127.0.0.1:8848 # nacos注册中心地址
#        server-addr: 192.168.110.169:8848 # nacos注册中心地址
#        namespace: b5290bc2-e3aa-4988-8a7d-9c07e4e073cb # 命名空间
#        group: DEFAULT_GROUP
#        application: seata-server #Nacos 中 Seata 名称
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderAccountingStrategyController.java
@@ -1,7 +1,9 @@
package com.ruoyi.order.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.order.api.model.TChargingOrderAccountingStrategy;
import com.ruoyi.order.service.TChargingOrderAccountingStrategyService;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.*;
@@ -52,5 +54,18 @@
        List<Double> list = chargingOrderAccountingStrategyService.getDailyChargingDegree(days, siteIds);
        return R.ok(list);
    }
    /**
     * 根据订单id查询充电明细
     * @param chargingOrderId
     * @return
     */
    @PostMapping("/getChargingOrderAccountingStrategyByOrderId")
    public R<List<TChargingOrderAccountingStrategy>> getChargingOrderAccountingStrategyByOrderId(@RequestParam("chargingOrderId") Long chargingOrderId){
        List<TChargingOrderAccountingStrategy> list = chargingOrderAccountingStrategyService.list(new LambdaQueryWrapper<TChargingOrderAccountingStrategy>().eq(TChargingOrderAccountingStrategy::getChargingOrderId, chargingOrderId));
        return R.ok(list);
    }
}
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java
@@ -21,6 +21,7 @@
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.dto.ChargingOrderGroup;
import com.ruoyi.common.core.dto.ChargingPercentProvinceDto;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.web.domain.BasePojo;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.common.security.annotation.Logical;
@@ -235,9 +236,9 @@
        data.setRecords(res1);
        return R.ok(data);
    }
    public static List<PayOrderDto> testing5(long total, long current, long size, List<PayOrderDto> str){
    List<PayOrderDto> result = new ArrayList<>();
    //获取初始化分页结构
@@ -332,10 +333,10 @@
        return R.ok();
    }
    @ResponseBody
    @GetMapping(value = "/pay/order/refund/detail")
    @ApiOperation(value = "退款信息", tags = {"管理后台-支付订单-订单信息"})
@@ -371,6 +372,8 @@
        if (byId.getAppUserCarId()!=null) {
            List<TAppUserCar> data3 = appUserCarClient.getCarByIds(Collections.singletonList(byId.getAppUserCarId())).getData();
            payOrderChargingInfo.setCarNum(data3.get(0).getLicensePlate());
        }else{
            payOrderChargingInfo.setCarNum(byId.getPlateNum());
        }
        payOrderChargingInfo.setTChargingOrder(byId);
@@ -381,6 +384,8 @@
            carid.add(byId.getAppUserCarId());
            R<List<TAppUserCar>> carByIds = appUserCarClient.getCarByIds(carid);
            payOrderChargingInfo.setCarNum(carByIds.getData().get(0).getLicensePlate());
        }else{
            payOrderChargingInfo.setCarNum(byId.getPlateNum());
        }
        payOrderChargingInfo.setStartTime(byId.getStartTime());
        payOrderChargingInfo.setEndTime(byId.getEndTime());
@@ -481,10 +486,10 @@
        }
        return result;
    }
    @ResponseBody
    @PostMapping(value = "/pay/order/refund/list1")
    @ApiOperation(value = "列表1", tags = {"管理后台-支付订单-退款订单"})
@@ -529,6 +534,8 @@
                chargingOrderInfoVO.setVehicleModel(data.getVehicleModel());
                chargingOrderInfoVO.setVehicleUse(data.getVehicleUse());
            }
        }else{
            chargingOrderInfoVO.setLicensePlate(byId.getPlateNum());
        }
        // 时段总服务费
        List<TChargingOrderAccountingStrategy> list = chargingOrderAccountingStrategyService.lambdaQuery().eq(TChargingOrderAccountingStrategy::getChargingOrderId, strategyId).orderByDesc(TChargingOrderAccountingStrategy::getStartTime).list();
@@ -593,8 +600,8 @@
                .between(TChargingOrder::getStartTime, req.getStartTime(), req.getEndTime())).size();
        return R.ok(size);
    }
    //用户订单数量
    @PostMapping(value = "/useOrderCount")
    public R<Long> useOrderCount(@RequestParam("userId") Long userId) {
@@ -603,16 +610,16 @@
        return R.ok(count);
    }
    //订单详情
    @PostMapping(value = "/detail")
    public R<TChargingOrder> detail(@RequestParam("orderId") Long orderId) {
        return R.ok(chargingOrderService.getById(orderId));
    }
    @PostMapping(value = "/getList")
    public R<List<TChargingOrder>> getList(@RequestParam("siteId") Integer siteId) {
@@ -620,14 +627,35 @@
        return R.ok(list);
    }
    @PostMapping(value = "/getBySiteIdAndTime")
    public R<List<ChargingOrderGroup>> getBySiteIdAndTime(@RequestBody ChargingPercentProvinceDto chargingPercentProvinceDto) {
        List<ChargingOrderGroup> groups = chargingOrderService.chargingOrderGroup(chargingPercentProvinceDto);
        return R.ok(groups);
    }
    /**
     * 根据站点id和时间区间查询订单数据
     * @param chargingPercentProvinceDto
     * @return
     */
    @PostMapping(value = "/getOrderBySiteIdAndTime")
    public R<List<TChargingOrder>> getOrderBySiteIdAndTime(@RequestBody ChargingPercentProvinceDto chargingPercentProvinceDto){
        LocalDate date1 = chargingPercentProvinceDto.getDate1();
        LocalDate date2 = chargingPercentProvinceDto.getDate2();
        String tripartitePlatformName = chargingPercentProvinceDto.getTripartitePlatformName();
        List<TChargingOrder> list = chargingOrderService.list(new LambdaQueryWrapper<TChargingOrder>().in(TChargingOrder::getSiteId, chargingPercentProvinceDto.getSiteIds())
                .between(null != date1 && null != date2, TChargingOrder::getPayTime, date1.atTime(0, 0, 0), date2.atTime(23, 59, 59))
                .eq(TChargingOrder::getDelFlag, 0).eq(TChargingOrder::getStatus, 5)
                .eq(StringUtils.isNotEmpty(tripartitePlatformName), TChargingOrder::getOrderSource, 2)
                .eq(StringUtils.isNotEmpty(tripartitePlatformName), TChargingOrder::getTripartitePlatformName, tripartitePlatformName));
        return R.ok(list);
    }
    /**
     * 根据充电枪id获取正在进行中的订单
@@ -805,7 +833,7 @@
        log.info("-------------------停止充电返回账单后计算费用及修改业务状态-------------------:" + vo);
        return chargingOrderService.endChargeBillingCharge(vo);
    }
    
    
    
@@ -2018,8 +2046,8 @@
        chargingOrderService.endCharge(code, 2);
    }
    /**
     * 硬件异常结束充电后的处理逻辑
     * @param code
@@ -2041,8 +2069,8 @@
        TChargingOrder chargingOrder = chargingOrderService.getChargingOrderByLicensePlate(query);
        return R.ok(chargingOrder);
    }
    /**
     * 修改充电订单
     * @param chargingOrder
@@ -2093,4 +2121,81 @@
        return R.ok(list);
    }
    
    /**
     * 根据车牌号查询指定时间范围内的数据
     * @param plateNum
     * @param startTime
     * @param endTime
     * @return
     */
    @PostMapping("/getCarChargingOrderByPlateNum")
    public R<List<TChargingOrder>> getCarChargingOrderByPlateNum(@RequestParam("plateNum") String plateNum, @RequestParam("startTime") String startTime,
                                                          @RequestParam("endTime") String endTime){
        List<TChargingOrder> list = chargingOrderService.list(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getPlateNum, plateNum).eq(TChargingOrder::getDelFlag, 0)
                .in(TChargingOrder::getStatus, Arrays.asList(4, 5)).between(TChargingOrder::getStartTime, startTime, endTime));
        return R.ok(list);
    }
    /**
     * 添加三方平台充电订单数据
     * @return
     */
    @PostMapping("/addTripartitePlatformOrder")
    public R addTripartitePlatformOrder(@RequestBody AddTripartitePlatformOrder query){
        return chargingOrderService.addTripartitePlatformOrder(query);
    }
    /**
     * 根据三方平台订单id获取充电数据
     * @param startChargeSeq
     * @return
     */
    @PostMapping("/getChargingOrderByStartChargeSeq")
    public R<TChargingOrder> getChargingOrderByStartChargeSeq(@RequestParam("startChargeSeq") String startChargeSeq){
        TChargingOrder chargingOrder = chargingOrderService.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getStartChargeSeq, startChargeSeq));
        return R.ok(chargingOrder);
    }
    /**
     * 根据三方平台订单ids获取充电数据
     * @param startChargeSeqs
     * @return
     */
    @PostMapping("/getChargingOrderByStartChargeSeqs")
    public R<List<TChargingOrder>> getChargingOrderByStartChargeSeqs(@RequestParam("startChargeSeqs") List<String> startChargeSeqs){
        List<TChargingOrder> list = chargingOrderService.list(new LambdaQueryWrapper<TChargingOrder>().in(TChargingOrder::getStartChargeSeq, startChargeSeqs));
        return R.ok(list);
    }
    /**
     * 三方平台请求停止充电
     * @param startChargeSeq
     * @return
     */
    @PostMapping("/tripartitePlatformStopCharge")
    public R tripartitePlatformStopCharge(@RequestParam("startChargeSeq") String startChargeSeq){
        return chargingOrderService.tripartitePlatformStopCharge(startChargeSeq);
    }
    /**
     * 临时接口
     * 获取充电后没有扣除费用的数据
     * @return
     */
    @GetMapping("/getNotPaymentChargingOrder")
    public R getNotPaymentChargingOrder(){
        return chargingOrderService.getNotPaymentChargingOrder();
    }
}
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TVipOrderController.java
@@ -3,6 +3,8 @@
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.ruoyi.account.api.dto.GiveVipDto;
import com.ruoyi.account.api.feignClient.AppUserClient;
import com.ruoyi.common.core.domain.R;
@@ -114,7 +116,8 @@
    @GetMapping("/deleteVipOrder")
    @ApiOperation(value = "批量删除会员订单", tags = {"管理后台-会员订单"})
    public AjaxResult deleteVipOrder(String id) {
        vipOrderService.removeBatchByIds(Arrays.asList(id.split(",")));
        vipOrderService.update(new LambdaUpdateWrapper<TVipOrder>().in(TVipOrder::getId, Arrays.asList(id.split(",")))
                .set(TVipOrder::getDelFlag, 1));
        return AjaxResult.success();
    }
    
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/dto/PayOrderInfoDto.java
@@ -21,7 +21,7 @@
    @ApiModelProperty("支付金额")
    private BigDecimal payAmount;
    @ApiModelProperty("支付时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime payTime;
    @ApiModelProperty("退款金额")
    private BigDecimal refundAmount;
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/TChargingOrderService.java
@@ -7,10 +7,7 @@
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.page.PageInfo;
import com.ruoyi.order.api.dto.SettlementConfirmAdd;
import com.ruoyi.order.api.model.ChargingListQuery;
import com.ruoyi.order.api.model.TChargingOrder;
import com.ruoyi.order.api.model.TChargingOrderRefund;
import com.ruoyi.order.api.model.TSettlementConfirm;
import com.ruoyi.order.api.model.*;
import com.ruoyi.order.api.query.ChargingOrderQuery;
import com.ruoyi.order.api.query.SettlementListQuery;
import com.ruoyi.order.api.query.UploadRealTimeMonitoringDataQuery;
@@ -19,7 +16,9 @@
import com.ruoyi.order.vo.ChargingOrderListInfoVO;
import com.ruoyi.order.vo.EndOfChargePageInfo;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
@@ -280,4 +279,26 @@
    List<TChargingOrder> getChargingOrder(TChargingOrderVo order);
    Long countCar(List<String> brands);
    /**
     * 添加三方平台充电订单数据
     * @param query
     */
    R addTripartitePlatformOrder(AddTripartitePlatformOrder query);
    /**
     * 三方平台停止充电操作
     * @param startChargeSeq
     * @return
     */
    R tripartitePlatformStopCharge(@RequestParam("startChargeSeq") String startChargeSeq);
    /**
     * 获取充电后没有扣除费用的数据
     * @return
     */
    R getNotPaymentChargingOrder();
}
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingBillServiceImpl.java
@@ -325,6 +325,8 @@
                        tChargingOrder.setLicensePlate(data4.getLicensePlate());
                        tChargingOrder.setVehicleModel(data4.getVehicleModel());
                    }
                }else{
                    tChargingOrder.setLicensePlate(tChargingOrder.getPlateNum());
                }
                if (data3!=null)tChargingOrder.setUserName(data3.getName());
                // 累加实收金额 支付结算金额
@@ -754,6 +756,8 @@
                        tChargingOrder.setLicensePlate(tAppUserCar.getLicensePlate());
                        tChargingOrder.setVehicleModel(tAppUserCar.getVehicleModel());
                    }
                }else{
                    tChargingOrder.setLicensePlate(tChargingOrder.getPlateNum());
                }
                if (data3!=null)tChargingOrder.setUserName(data3.getName());
                if ( tChargingOrder.getPaymentAmount()!=null){
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
@@ -32,6 +32,7 @@
import com.ruoyi.integration.api.feignClient.*;
import com.ruoyi.integration.api.model.*;
import com.ruoyi.integration.api.vo.GetPlatformStopChargingReply;
import com.ruoyi.integration.api.vo.StartChargeResult;
import com.ruoyi.order.api.dto.SettlementConfirmAdd;
import com.ruoyi.order.api.feignClient.AccountingStrategyDetailOrderClient;
import com.ruoyi.order.api.feignClient.AccountingStrategyOrderClient;
@@ -142,7 +143,7 @@
    private UploadRealTimeMonitoringDataClient uploadRealTimeMonitoringDataClient;
    
    @Resource
    private ChargingHandshakeClient chargingHandshakeClient;
    private TCECClient tcecClient;
    @Resource
    private SendMessageClient sendMessageClient;
@@ -203,6 +204,12 @@
    
    //计数器
    private Map<String, Integer> boot_failed_map = new HashMap<>();
    @Resource
    private OperatorClient operatorClient;
    @Resource
    private TransactionRecordClient transactionRecordClient;
@@ -273,6 +280,8 @@
            }else{
                myChargingOrderInfo.setLicensePlate("无");
            }
        }else{
            myChargingOrderInfo.setLicensePlate(chargingOrder.getPlateNum());
        }
        myChargingOrderInfo.setStartTime(chargingOrder.getStartTime().atZone(ZoneId.systemDefault()).toInstant().getEpochSecond() * 1000);
        myChargingOrderInfo.setEndTime(chargingOrder.getEndTime().atZone(ZoneId.systemDefault()).toInstant().getEpochSecond() * 1000);
@@ -456,6 +465,12 @@
        chargingOrder.setOrderClassification(1);
        chargingOrder.setAppUserId(userId);
        chargingOrder.setAppUserCarId(addChargingOrder.getAppUserCarId());
        if(null != addChargingOrder.getAppUserCarId()){
            TAppUserCar userCar = appUserCarClient.getCarById(addChargingOrder.getAppUserCarId().toString()).getData();
            if(null != userCar){
                chargingOrder.setPlateNum(userCar.getLicensePlate());
            }
        }
        TChargingGun tChargingGun = chargingGunClient.getChargingGunById(addChargingOrder.getId()).getData();
        TChargingPile chargingPile = chargingPileClient.getChargingPileById(tChargingGun.getChargingPileId()).getData();
        chargingOrder.setSiteId(tChargingGun.getSiteId());
@@ -466,7 +481,7 @@
        chargingOrder.setRechargeAmount(addChargingOrder.getPaymentAmount());
        chargingOrder.setAppCouponId(addChargingOrder.getAppUserCouponId());
        chargingOrder.setVipDiscountAmount(BigDecimal.ZERO);
        chargingOrder.setOrderSource(0);
        chargingOrder.setOrderSource(1);
        chargingOrder.setTitle("【充电桩充电】" + chargingPile.getNumber() + "号桩/" + tChargingGun.getCode() + "号枪");
        
        Site site = siteClient.getSiteByIds(Arrays.asList(tChargingGun.getSiteId())).getData().get(0);
@@ -746,6 +761,10 @@
            }
            this.updateById(order);
            redisService.setCacheObject(key, preChargeCheck1, 24L, TimeUnit.HOURS);
            //推送三方平台订单状态
            if(2 == chargingOrder.getOrderSource()){
                tcecClient.notificationEquipChargeStatus(chargingOrder.getStartChargeSeq(), chargingOrder.getOperatorId());
            }
            return true;
        }else{
            Integer counter = boot_failed_map.get(code);
@@ -776,6 +795,10 @@
            order.setEndMode(0);
            this.updateById(order);
            redisService.setCacheObject(key, preChargeCheck1, 24L, TimeUnit.HOURS);
            //推送三方平台订单状态
            if(2 == chargingOrder.getOrderSource()){
                tcecClient.notificationEquipChargeStatus(chargingOrder.getStartChargeSeq(), chargingOrder.getOperatorId());
            }
            return true;
        }
    }
@@ -835,9 +858,24 @@
            TChargingGun chargingGun = chargingGunClient.getChargingGunById(order.getChargingGunId()).getData();
            chargingGun.setStatus(4);
            chargingGunClient.updateChargingGunById(chargingGun);
            //推送状态给三方平台
            tcecClient.pushChargingGunStatus(chargingGun.getId(), chargingGun.getStatus());
        }
        redisService.setCacheObject("AQJC_" + order.getChargingGunId(), preChargeCheck1, 24L, TimeUnit.HOURS);
        this.updateById(order);
        //推送三方平台启动充电结果
        if(2 == order.getOrderSource()){
            StartChargeResult result = new StartChargeResult();
            result.setStartChargeSeq(order.getStartChargeSeq());
            result.setStartChargeSeqStat(3 == order.getStatus() ? 2 : 4);
            result.setConnectorID(order.getChargingGunId().toString());
            result.setStartTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            Operator operator = operatorClient.getOperatorById(order.getOperatorId()).getData();
            result.setOperatorID(operator.getOperatorId());
            tcecClient.notificationStartChargeResult(result);
            tcecClient.notificationEquipChargeStatus(order.getStartChargeSeq(), order.getOperatorId());
        }
    }
    
    /**
@@ -847,7 +885,7 @@
    public void refund(String code){
        log.info(code + ":-------------------充电启动失败,执行退款-------------------");
        TChargingOrder chargingOrder = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, code));
        if(chargingOrder.getStatus() == 2){
        if(chargingOrder.getOrderSource() == 1 && chargingOrder.getStatus() == 2){
            Integer rechargePaymentType = chargingOrder.getRechargePaymentType();
            BigDecimal rechargeAmount = chargingOrder.getRechargeAmount();
            //构建退款明细
@@ -1005,7 +1043,6 @@
        chargingOrder.setStatus(4);
        chargingOrder.setEndMode(1);
        this.updateById(chargingOrder);
        String code1 = order.getCode();
        TChargingGun chargingGun = chargingGunClient.getChargingGunById(order.getChargingGunId()).getData();
        //异步线程处理停机
@@ -1020,6 +1057,11 @@
            log.info(code1 + ":-------------------远程停止充电请求-------------------");
            log.info(platformStopCharging.toString());
        });
        //推送三方平台
        if(2 == order.getOrderSource()){
            tcecClient.notificationEquipChargeStatus(order.getStartChargeSeq(), order.getOperatorId());
        }
        return AjaxResult.success();
    }
    
@@ -1320,6 +1362,8 @@
                    if (tAppUserCar!=null){
                        chargingOrderVO.setLicensePlate(tAppUserCar.getLicensePlate());
                    }
                }else{
                    chargingOrderVO.setLicensePlate(chargingOrderVO.getPlateNum());
                }
            }
@@ -1589,6 +1633,8 @@
                                chargingOrderListVO.setLicensePlate(data4.get(0).getLicensePlate());
                            }
                        }
                    }else{
                        chargingOrderListVO.setLicensePlate(chargingOrderListVO.getPlateNum());
                    }
                    chargingOrderListVO.setPhone(data3.getPhone());
                }
@@ -1866,7 +1912,11 @@
        if (chargingOrder.getAppUserCarId()!=null){
            List<TAppUserCar> data3 = appUserCarClient.getCarByIds(Collections.singletonList(chargingOrder.getAppUserCarId())).getData();
            if (data3!=null && !data3.isEmpty())chargingOrderListInfoVO.setLicensePlate(data3.get(0).getLicensePlate());
            if (data3!=null && !data3.isEmpty()) {
                chargingOrderListInfoVO.setLicensePlate(data3.get(0).getLicensePlate());
            }
        }else{
            chargingOrderListInfoVO.setLicensePlate(chargingOrder.getPlateNum());
        }
        chargingOrderListInfoVO.setStartTime(chargingOrder.getStartTime());
        chargingOrderListInfoVO.setEndTime(chargingOrder.getEndTime());
@@ -1915,7 +1965,7 @@
            chargingOrder.setChargingCapacity(query.getCharging_degree());
            chargingOrder.setElectricity(query.getCharging_degree());
            chargingOrder.setTotalElectricity(new BigDecimal(100 - query.getSoc()));
            BmsDemandAndChargerExportation data = bmsDemandAndChargerExportationClient.getBmsDemandAndChargerExportation(chargingOrder.getCode()).getData();
            BmsDemandAndChargerExportation data = bmsDemandAndChargerExportationClient.getBmsDemandAndChargerExportation(chargingOrder1.getCode()).getData();
            if(null != data){
                chargingOrder.setNeedElec(data.getBms_current_requirements());
            }
@@ -2277,6 +2327,14 @@
        this.updateById(order);
        chargingOrder = this.getById(order.getId());
        
        //推送三方平台
        if(2 == chargingOrder.getOrderSource()){
            tcecClient.notificationEquipChargeStatus(chargingOrder.getStartChargeSeq(), chargingOrder.getOperatorId());
            tcecClient.notificationStopChargeResult(chargingOrder.getStartChargeSeq(), chargingOrder.getChargingGunId().toString(),
                    chargingOrder.getOperatorId());
            tcecClient.notificationChargeOrderInfo(chargingOrder.getStartChargeSeq(), chargingOrder.getOperatorId());
        }
        //开始将优惠券优惠的金额添加到明细中
        BigDecimal couponDiscountAmount = order.getCouponDiscountAmount();
        if(null != couponDiscountAmount && couponDiscountAmount.compareTo(BigDecimal.ZERO) > 0){
@@ -2298,91 +2356,97 @@
        chargingGun.setStatus(2);
        chargingGun.setChargingPower(BigDecimal.ZERO);
        chargingGunClient.updateChargingGunById(chargingGun);
        //推送状态给三方平台
        if(2 == chargingOrder.getOrderSource()){
            tcecClient.pushChargingGunStatus(chargingGun.getId(), chargingGun.getStatus());
        }
        
        //添加积分
        TIntegralRule integralRule = integralRuleClient.getSet().getData();
        if(null != integralRule){
            TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData();
            Integer num1 = JSON.parseObject(integralRule.getChargeCredit()).getInteger("num1");
            Integer integral = chargingOrder.getServiceCharge().intValue() * num1;
            if(null != appUser.getVipId()){
                TVip vip = vipClient.getInfo1(appUser.getVipId()).getData();
                Integer doubleIntegration = vip.getDoubleIntegration();
                //双倍积分
                if(1 == doubleIntegration){
                    integral *= 2;
        if(1 == chargingOrder.getOrderSource()){
            TIntegralRule integralRule = integralRuleClient.getSet().getData();
            if(null != integralRule){
                TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData();
                Integer num1 = JSON.parseObject(integralRule.getChargeCredit()).getInteger("num1");
                Integer integral = chargingOrder.getServiceCharge().intValue() * num1;
                if(null != appUser.getVipId()){
                    TVip vip = vipClient.getInfo1(appUser.getVipId()).getData();
                    Integer doubleIntegration = vip.getDoubleIntegration();
                    //双倍积分
                    if(1 == doubleIntegration){
                        integral *= 2;
                    }
                }
                if(integral > 0){
                    TAppUserIntegralChange appUserIntegralChange = new TAppUserIntegralChange();
                    appUserIntegralChange.setAppUserId(appUser.getId());
                    appUserIntegralChange.setChangeType(2);
                    appUserIntegralChange.setHistoricalIntegral(appUser.getPoints());
                    appUser.setPoints(appUser.getPoints() + integral);
                    appUserIntegralChange.setCurrentIntegral(appUser.getPoints());
                    appUserIntegralChange.setCreateTime(LocalDateTime.now());
                    appUserIntegralChange.setOrderCode(chargingOrder.getCode());
                    appUserIntegralChange.setExtension(chargingOrder.getId().toString());
                    appUserClient.updateAppUser(appUser);
                    appUserIntegralChangeClient.addAppUserIntegralChange(appUserIntegralChange);
                }
            }
            
            if(integral > 0){
                TAppUserIntegralChange appUserIntegralChange = new TAppUserIntegralChange();
                appUserIntegralChange.setAppUserId(appUser.getId());
                appUserIntegralChange.setChangeType(2);
                appUserIntegralChange.setHistoricalIntegral(appUser.getPoints());
                appUser.setPoints(appUser.getPoints() + integral);
                appUserIntegralChange.setCurrentIntegral(appUser.getPoints());
                appUserIntegralChange.setCreateTime(LocalDateTime.now());
                appUserIntegralChange.setOrderCode(chargingOrder.getCode());
                appUserIntegralChange.setExtension(chargingOrder.getId().toString());
                appUserClient.updateAppUser(appUser);
                appUserIntegralChangeClient.addAppUserIntegralChange(appUserIntegralChange);
            }
        }
        //计算用户标签
        editUserTag(chargingOrder);
        //用户推荐奖励
        referralReward(chargingOrder);
        //开始构建退款费用
        refundAmount = refundAmount.setScale(2, RoundingMode.HALF_EVEN);
        if(refundAmount.compareTo(BigDecimal.ZERO) > 0){
            Integer rechargePaymentType = chargingOrder.getRechargePaymentType();
            //构建退款明细
            TChargingOrderRefund chargingOrderRefund = new TChargingOrderRefund();
            chargingOrderRefund.setChargingOrderId(chargingOrder.getId());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
            chargingOrderRefund.setRefundCode("CDF" + sdf.format(new Date()) + (Double.valueOf(Math.random() * 1000).intValue()));
            chargingOrderRefund.setRefundAmount(refundAmount);
            chargingOrderRefund.setRefundStatus(1);
            chargingOrderRefund.setPayType(rechargePaymentType);
            chargingOrderRefund.setRefundStatus(1);
            chargingOrderRefund.setCode(chargingOrder.getCode());
            chargingOrderRefund.setRefundTitle("充电完成退款");
            chargingOrderRefund.setRefundContent("充电完成退款");
            chargingOrderRefund.setRefundReason("充电完成退款");
            chargingOrderRefund.setRefundRemark("实际充电消费金额:" + chargingOrder.getPaymentAmount());
            chargingOrderRefund.setRefundTotalAmount(refundAmount);
            chargingOrderRefund.setPayAmount(rechargeAmount);
            if(1 == rechargePaymentType){
                WxPaymentRefundModel model = new WxPaymentRefundModel();
                model.setOut_trade_no(chargingOrder.getCode());
                model.setOut_refund_no(chargingOrderRefund.getRefundCode());
                model.setReason("充电完成退款");
                model.setNotify_url("/payment/wx/refund/notify");
                WxPaymentRefundModel.RefundAmount amount = new WxPaymentRefundModel.RefundAmount();
                amount.setRefund(refundAmount.multiply(new BigDecimal(100)).intValue());
                amount.setTotal(rechargeAmount.multiply(new BigDecimal(100)).intValue());
                amount.setCurrency("CNY");
                model.setAmount(amount);
                R<String> orderR = wxPaymentClient.refundOrderR(model);
                if(200 == orderR.getCode()){
                    chargingOrderRefundService.save(chargingOrderRefund);
                }
            }
            if(2 == rechargePaymentType){
                RefundReq dto = new RefundReq();
                dto.setOutTradeNo(chargingOrder.getCode());
                dto.setOutRequestNo(chargingOrderRefund.getRefundCode());
                dto.setRefundAmount(refundAmount.toString());
                dto.setRefundReason("充电完成退款");
                RefundResp resp = aliPaymentClient.refund(dto).getData();
                if(null != resp){
                    chargingOrderRefundService.save(chargingOrderRefund);
                    this.chargingOrderStartupFailureWxRefund(chargingOrderRefund.getRefundCode(), resp.getTradeNo(), "SUCCESS", null);
                }
            }
            //计算用户标签
            editUserTag(chargingOrder);
            //用户推荐奖励
            referralReward(chargingOrder);
            
            //开始构建退款费用
            refundAmount = refundAmount.setScale(2, RoundingMode.HALF_EVEN);
            if(refundAmount.compareTo(BigDecimal.ZERO) > 0){
                Integer rechargePaymentType = chargingOrder.getRechargePaymentType();
                //构建退款明细
                TChargingOrderRefund chargingOrderRefund = new TChargingOrderRefund();
                chargingOrderRefund.setChargingOrderId(chargingOrder.getId());
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
                chargingOrderRefund.setRefundCode("CDF" + sdf.format(new Date()) + (Double.valueOf(Math.random() * 1000).intValue()));
                chargingOrderRefund.setRefundAmount(refundAmount);
                chargingOrderRefund.setRefundStatus(1);
                chargingOrderRefund.setPayType(rechargePaymentType);
                chargingOrderRefund.setRefundStatus(1);
                chargingOrderRefund.setCode(chargingOrder.getCode());
                chargingOrderRefund.setRefundTitle("充电完成退款");
                chargingOrderRefund.setRefundContent("充电完成退款");
                chargingOrderRefund.setRefundReason("充电完成退款");
                chargingOrderRefund.setRefundRemark("实际充电消费金额:" + chargingOrder.getPaymentAmount());
                chargingOrderRefund.setRefundTotalAmount(refundAmount);
                chargingOrderRefund.setPayAmount(rechargeAmount);
                if(1 == rechargePaymentType){
                    WxPaymentRefundModel model = new WxPaymentRefundModel();
                    model.setOut_trade_no(chargingOrder.getCode());
                    model.setOut_refund_no(chargingOrderRefund.getRefundCode());
                    model.setReason("充电完成退款");
                    model.setNotify_url("/payment/wx/refund/notify");
                    WxPaymentRefundModel.RefundAmount amount = new WxPaymentRefundModel.RefundAmount();
                    amount.setRefund(refundAmount.multiply(new BigDecimal(100)).intValue());
                    amount.setTotal(rechargeAmount.multiply(new BigDecimal(100)).intValue());
                    amount.setCurrency("CNY");
                    model.setAmount(amount);
                    R<String> orderR = wxPaymentClient.refundOrderR(model);
                    if(200 == orderR.getCode()){
                        chargingOrderRefundService.save(chargingOrderRefund);
                    }
                }
                if(2 == rechargePaymentType){
                    RefundReq dto = new RefundReq();
                    dto.setOutTradeNo(chargingOrder.getCode());
                    dto.setOutRequestNo(chargingOrderRefund.getRefundCode());
                    dto.setRefundAmount(refundAmount.toString());
                    dto.setRefundReason("充电完成退款");
                    RefundResp resp = aliPaymentClient.refund(dto).getData();
                    if(null != resp){
                        chargingOrderRefundService.save(chargingOrderRefund);
                        this.chargingOrderStartupFailureWxRefund(chargingOrderRefund.getRefundCode(), resp.getTradeNo(), "SUCCESS", null);
                    }
                }
            }
        }
        return R.ok();
    }
@@ -2678,11 +2742,7 @@
     */
    @Override
    public TChargingOrder getChargingOrderByLicensePlate(GetChargingOrderByLicensePlate query) {
        TAppUserCar appUserCar = appUserCarClient.getAppUserCarByLicensePlate(query.getLicensePlate()).getData();
        if(null == appUserCar){
            return null;
        }
        TChargingOrder one = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getAppUserCarId, appUserCar.getId())
        TChargingOrder one = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getPlateNum, query.getLicensePlate())
                .eq(TChargingOrder::getDelFlag, 0).between(TChargingOrder::getStartTime, query.getStartTime(), LocalDateTime.now())
                .eq(TChargingOrder::getRechargePaymentStatus, 2).in(TChargingOrder::getStatus, Arrays.asList(4, 5)));
        return one;
@@ -3541,4 +3601,179 @@
    public Long countCar(List<String> brands) {
        return this.baseMapper.countCar(brands);
    }
    /**
     * 添加三方平台充电订单数据
     * @param query
     */
    @Override
    public R addTripartitePlatformOrder(AddTripartitePlatformOrder query) {
        //检查当前枪是否是正在使用中
        TChargingOrder one = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getChargingGunId, query.getChargingGunId())
                .in(TChargingOrder::getStatus, Arrays.asList(1, 2, 3)).eq(TChargingOrder::getDelFlag, 0));
        if(null != one){
            return R.fail("充电枪正在充电中,启动失败");
        }
        //构建订单数据
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        TChargingOrder chargingOrder = new TChargingOrder();
        String code = "CD" + Double.valueOf(Math.random() * 1000).intValue() + sdf.format(new Date());
        chargingOrder.setCode(code);
        chargingOrder.setOrderType(1);
        chargingOrder.setOrderClassification(1);
        TChargingGun tChargingGun = chargingGunClient.getChargingGunById(query.getChargingGunId()).getData();
        TChargingPile chargingPile = chargingPileClient.getChargingPileById(tChargingGun.getChargingPileId()).getData();
        chargingOrder.setSiteId(tChargingGun.getSiteId());
        chargingOrder.setChargingPileId(tChargingGun.getChargingPileId());
        chargingOrder.setChargingGunId(query.getChargingGunId());
        chargingOrder.setRechargePaymentType(query.getRechargePaymentType());
        chargingOrder.setRechargePaymentStatus(2);
        chargingOrder.setRechargeAmount(query.getPaymentAmount());
        chargingOrder.setVipDiscountAmount(BigDecimal.ZERO);
        chargingOrder.setOrderSource(2);
        Operator operator = operatorClient.getOperator(query.getOperatorId()).getData();
        chargingOrder.setOperatorId(operator.getId());
        chargingOrder.setAppUserId(operator.getId().longValue());
        chargingOrder.setTripartitePlatformName(operator.getName());
        chargingOrder.setStartChargeSeq(query.getStartChargeSeq());
        //车辆信息
        if(StringUtils.hasLength(query.getPlateNum())){
            TAppUserCar appUserCar = appUserCarClient.getAppUserCarByLicensePlate(query.getPlateNum()).getData();
            if(null != appUserCar){
                chargingOrder.setAppUserCarId(appUserCar.getId());
            }
            chargingOrder.setPlateNum(query.getPlateNum());
        }
        chargingOrder.setTitle("【充电桩充电】" + chargingPile.getNumber() + "号桩/" + tChargingGun.getCode() + "号枪");
        chargingOrder.setStatus(2);
        chargingOrder.setPayTime(LocalDateTime.now());
        chargingOrder.setChargeAmount(chargingOrder.getRechargeAmount());
        chargingOrder.setVipDiscountAmount(BigDecimal.ZERO);
        this.save(chargingOrder);
        Integer accountingStrategyId = tChargingGun.getAccountingStrategyId();
        if(null == accountingStrategyId){
            Site site = siteClient.getSiteByIds(Arrays.asList(tChargingGun.getSiteId())).getData().get(0);
            //查询站点上面的计费策略
            accountingStrategyId = site.getAccountingStrategyId();
        }
        TAccountingStrategy accountingStrategy = accountingStrategyClient.getAccountingStrategyById(accountingStrategyId).getData();
        //添加订单的计费策略
        List<TAccountingStrategyDetail> strategyDetailList = accountingStrategyDetailClient.getListByAccountingStrategyId(accountingStrategyId).getData();
        AccountingStrategyOrder accountingStrategyOrder = new AccountingStrategyOrder();
        BeanUtils.copyProperties(accountingStrategy, accountingStrategyOrder);
        accountingStrategyOrder.setChargingOrderId(chargingOrder.getId());
        accountingStrategyOrderService.save(accountingStrategyOrder);
        List<AccountingStrategyDetailOrder> list1 = new ArrayList<>();
        for (TAccountingStrategyDetail tAccountingStrategyDetail : strategyDetailList) {
            AccountingStrategyDetailOrder accountingStrategyDetailOrder = new AccountingStrategyDetailOrder();
            BeanUtils.copyProperties(tAccountingStrategyDetail, accountingStrategyDetailOrder);
            accountingStrategyDetailOrder.setChargingOrderId(chargingOrder.getId());
            list1.add(accountingStrategyDetailOrder);
        }
        accountingStrategyDetailOrderService.saveBatch(list1);
        //添加安全检测数据到缓存中,每步安全检测完成后需要更新缓存数据
        PreChargeCheck preChargeCheck = new PreChargeCheck();
        preChargeCheck.setElectronicLockLock(false);
        preChargeCheck.setInsulationTesting(false);
        preChargeCheck.setSecureConnectionDetection(false);
        preChargeCheck.setStartupSuccess(1);
        String key = "AQJC_" + chargingOrder.getChargingGunId();
        redisService.setCacheObject(key, preChargeCheck, 24L, TimeUnit.HOURS);
        BigDecimal rechargeAmount = chargingOrder.getRechargeAmount();
        //调用远程启动充电消息
        PlatformStartCharging platformStartCharging = new PlatformStartCharging();
        platformStartCharging.setTransaction_serial_number(chargingOrder.getCode());
        platformStartCharging.setCharging_pile_code(chargingPile.getCode());
        platformStartCharging.setCharging_gun_code(tChargingGun.getCode());
        //使用订单id作为逻辑卡号
        platformStartCharging.setCard_number(chargingOrder.getId().toString());
        platformStartCharging.setAccount_balance(rechargeAmount);
        log.info(chargingOrder.getCode() + ":-------------------远程调起开始充电请求-------------------" + platformStartCharging.toString());
        sendMessageClient.platformStartCharging(platformStartCharging);
        //异步线程检测远程启动的应答结果。如果失败,则需要全额退款
        Long id = chargingOrder.getId();
        //执行5分钟的定时任务检测
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
        scheduler.scheduleAtFixedRate(()->{
            if(timingDetection(id)){
                scheduler.shutdown();
            }
        }, 5, 1, TimeUnit.SECONDS);
        //推送三方平台订单状态
        tcecClient.notificationEquipChargeStatus(chargingOrder.getStartChargeSeq(), chargingOrder.getOperatorId());
        return R.ok();
    }
    /**
     * 三方平台停止充电操作
     * @param startChargeSeq
     * @return
     */
    @Override
    public R tripartitePlatformStopCharge(String startChargeSeq) {
        TChargingOrder order = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getStartChargeSeq, startChargeSeq));
        Integer status = order.getStatus();
        if(status != 3){
            return R.fail("还未开始充电");
        }
        if(status == 4 || status == 5){
            return R.fail("不能重复操作");
        }
        TChargingOrder chargingOrder = new TChargingOrder();
        chargingOrder.setId(order.getId());
        chargingOrder.setAppUserId(order.getOperatorId().longValue());
        chargingOrder.setEndTime(LocalDateTime.now());
        chargingOrder.setStatus(4);
        chargingOrder.setEndMode(1);
        this.updateById(chargingOrder);
        tcecClient.notificationEquipChargeStatus(order.getStartChargeSeq(), order.getOperatorId());
        String code1 = order.getCode();
        TChargingGun chargingGun = chargingGunClient.getChargingGunById(order.getChargingGunId()).getData();
        //异步线程处理停机
        ExecutorService cachedThreadPool = Executors.newFixedThreadPool(1);
        cachedThreadPool.execute(()->{
            //调用硬件停止充电,停止成功后开始计算费用退款
            TChargingPile chargingPile = chargingPileClient.getChargingPileById(order.getChargingPileId()).getData();
            PlatformStopCharging platformStopCharging = new PlatformStopCharging();
            platformStopCharging.setCharging_pile_code(chargingPile.getCode());
            platformStopCharging.setCharging_gun_code(chargingGun.getCode());
            sendMessageClient.platformStopCharging(platformStopCharging);
            log.info(code1 + ":-------------------远程停止充电请求-------------------");
            log.info(platformStopCharging.toString());
        });
        return R.ok();
    }
    /**
     * 获取充电后没有扣除费用的数据
     * @return
     */
    @Override
    public R getNotPaymentChargingOrder() {
        List<TChargingOrder> list = this.list(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getPaymentAmount, 0)
                .ne(TChargingOrder::getElectricity, 0).in(TChargingOrder::getStatus, Arrays.asList(4, 5)));
        List<Map<String, Object>> mapList = new ArrayList<>();
        for (TChargingOrder order : list) {
            TransactionRecord transactionRecord = transactionRecordClient.findTransactionRecord(order.getCode()).getData();
            Map<String, Object> map = new HashMap<>();
            map.put("order", order);
            map.put("transactionRecord", transactionRecord);
            mapList.add(map);
        }
        return R.ok(mapList);
    }
}
ruoyi-service/ruoyi-order/src/main/resources/bootstrap.yml
@@ -23,7 +23,7 @@
    nacos:
      discovery:
        # 服务注册地址
        server-addr: 127.0.0.1:8848
        server-addr: 192.168.110.169:8848
        service: ${spring.application.name}
        group: DEFAULT_GROUP
        namespace: b5290bc2-e3aa-4988-8a7d-9c07e4e073cb
@@ -31,7 +31,7 @@
        password: nacos
      config:
        # 配置中心地址
        server-addr: 127.0.0.1:8848
        server-addr: 192.168.110.169:8848
        namespace: b5290bc2-e3aa-4988-8a7d-9c07e4e073cb
        group: DEFAULT_GROUP
        name: ${spring.application.name}
@@ -56,7 +56,7 @@
    type: nacos
    nacos:
      # 开发环境
#      server-addr: 127.0.0.1:8848
#      server-addr: 192.168.110.169:8848
#      namespace: b5290bc2-e3aa-4988-8a7d-9c07e4e073cb
#      group: DEFAULT_GROUP
#      data-id: seata-server.properties
@@ -74,7 +74,7 @@
    nacos:
      application: seata-server
      # 开发环境
#      server-addr: 127.0.0.1:8848
#      server-addr: 192.168.110.169:8848
#      namespace: b5290bc2-e3aa-4988-8a7d-9c07e4e073cb
#      group: DEFAULT_GROUP
#      username: nacos
@@ -89,7 +89,7 @@
    nacos:
      discovery:
        # 开发环境
#        server-addr: 127.0.0.1:8848
#        server-addr: 192.168.110.169:8848
#        namespace: b5290bc2-e3aa-4988-8a7d-9c07e4e073cb # 命名空间
#        group: DEFAULT_GROUP
#        application: seata-server #Nacos 中 Seata 名称
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/OperatorController.java
New file
@@ -0,0 +1,86 @@
package com.ruoyi.other.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.other.api.domain.Operator;
import com.ruoyi.other.service.OperatorService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
 * @author zhibing.pu
 * @Date 2025/1/22 15:12
 */
@RestController
@RequestMapping("/operator")
public class OperatorController {
    @Resource
    private OperatorService operatorService;
    /**
     * 获取运营商数据
     * @param id
     * @return
     */
    @PostMapping("/getOperatorById")
    public R<Operator> getOperatorById(@RequestParam("id") Integer id){
        Operator operator = operatorService.getById(id);
        return R.ok(operator);
    }
    /**
     * 获取运营商数据
     * @param name
     * @return
     */
    @PostMapping("/getOperatorByName")
    public R<Operator> getOperatorByName(@RequestParam("name") String name){
        Operator operator = operatorService.getOne(new LambdaQueryWrapper<Operator>().eq(Operator::getName, name));
        return R.ok(operator);
    }
    /**
     * 获取运营商数据
     * @param operatorId
     * @return
     */
    @PostMapping("/getOperator")
    public R<Operator> getOperator(@RequestParam("operatorId") String operatorId){
        Operator operator = operatorService.getOne(new LambdaQueryWrapper<Operator>().eq(Operator::getOperatorId, operatorId));
        return R.ok(operator);
    }
    /**
     * 获取所有运营商
     * @return
     */
    @PostMapping("/getAllOperator")
    public R<List<Operator>> getAllOperator(){
        List<Operator> list = operatorService.list();
        return R.ok(list);
    }
    /**
     * 更新运营商数据
     * @return
     */
    @PostMapping("/editOperator")
    public R editOperator(@RequestBody Operator operator){
        operatorService.updateById(operator);
        return R.ok();
    }
}
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/OssController.java
File was deleted
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/mapper/OperatorMapper.java
New file
@@ -0,0 +1,11 @@
package com.ruoyi.other.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.other.api.domain.Operator;
/**
 * @author zhibing.pu
 * @Date 2025/1/22 15:08
 */
public interface OperatorMapper extends BaseMapper<Operator> {
}
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/OperatorService.java
New file
@@ -0,0 +1,11 @@
package com.ruoyi.other.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.other.api.domain.Operator;
/**
 * @author zhibing.pu
 * @Date 2025/1/22 15:09
 */
public interface OperatorService extends IService<Operator> {
}
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/OperatorServiceImpl.java
New file
@@ -0,0 +1,15 @@
package com.ruoyi.other.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.other.api.domain.Operator;
import com.ruoyi.other.mapper.OperatorMapper;
import com.ruoyi.other.service.OperatorService;
import org.springframework.stereotype.Service;
/**
 * @author zhibing.pu
 * @Date 2025/1/22 15:09
 */
@Service
public class OperatorServiceImpl extends ServiceImpl<OperatorMapper, Operator> implements OperatorService {
}
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TVipServiceImpl.java
@@ -111,6 +111,7 @@
        shopOrder.setPaymentStatus(1);
        shopOrder.setPaymentType(payType);
        shopOrder.setPayTime(LocalDateTime.now());
        shopOrder.setDelFlag(false);
        R<Long> longR = orderClient.addVipOrder(shopOrder);
        if(200 != longR.getCode()){
            return AjaxResult.error(longR.getMsg());
ruoyi-service/ruoyi-other/src/main/resources/bootstrap.yml
@@ -23,7 +23,7 @@
    nacos:
      discovery:
        # 服务注册地址
        server-addr: 127.0.0.1:8848
        server-addr: 192.168.110.169:8848
        service: ${spring.application.name}
        group: DEFAULT_GROUP
        namespace: b5290bc2-e3aa-4988-8a7d-9c07e4e073cb
@@ -31,7 +31,7 @@
        password: nacos
      config:
        # 配置中心地址
        server-addr: 127.0.0.1:8848
        server-addr: 192.168.110.169:8848
        namespace: b5290bc2-e3aa-4988-8a7d-9c07e4e073cb
        group: DEFAULT_GROUP
        name: ${spring.application.name}
@@ -56,7 +56,7 @@
    type: nacos
    nacos:
      # 开发环境
#      server-addr: 127.0.0.1:8848
#      server-addr: 192.168.110.169:8848
#      namespace: b5290bc2-e3aa-4988-8a7d-9c07e4e073cb
#      group: DEFAULT_GROUP
#      data-id: seata-server.properties
@@ -74,7 +74,7 @@
    nacos:
      application: seata-server
      # 开发环境
#      server-addr: 127.0.0.1:8848
#      server-addr: 192.168.110.169:8848
#      namespace: b5290bc2-e3aa-4988-8a7d-9c07e4e073cb
#      group: DEFAULT_GROUP
#      username: nacos
@@ -89,7 +89,7 @@
    nacos:
      discovery:
        # 开发环境
#        server-addr: 127.0.0.1:8848
#        server-addr: 192.168.110.169:8848
#        namespace: b5290bc2-e3aa-4988-8a7d-9c07e4e073cb # 命名空间
#        group: DEFAULT_GROUP
#        application: seata-server #Nacos 中 Seata 名称