From 376e14adeb4e53a42f8ad23b861b7526a4e13446 Mon Sep 17 00:00:00 2001 From: Guoqs Date: Wed, 8 May 2024 18:40:45 +0800 Subject: [PATCH] =?UTF-8?q?update=20=E5=AF=B9=E6=8E=A5lianlian=E5=B9=B3?= =?UTF-8?q?=E5=8F=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../thirdparty/ThirdPartyBaseController.java | 116 +++++++++++++++++- .../lianlian/LianLianController.java | 38 +++--- .../thirdparty/ThirdPartyReturnCodeEnum.java | 3 +- .../service/LianLianPlatformServiceImpl.java | 87 ++++++++++++- 4 files changed, 222 insertions(+), 22 deletions(-) diff --git a/jsowell-admin/src/main/java/com/jsowell/web/controller/thirdparty/ThirdPartyBaseController.java b/jsowell-admin/src/main/java/com/jsowell/web/controller/thirdparty/ThirdPartyBaseController.java index 24732b3ce..94efb39b5 100644 --- a/jsowell-admin/src/main/java/com/jsowell/web/controller/thirdparty/ThirdPartyBaseController.java +++ b/jsowell-admin/src/main/java/com/jsowell/web/controller/thirdparty/ThirdPartyBaseController.java @@ -2,6 +2,7 @@ package com.jsowell.web.controller.thirdparty; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; +import com.fasterxml.jackson.annotation.JsonProperty; import com.google.common.collect.Maps; import com.jsowell.common.annotation.Anonymous; import com.jsowell.common.core.controller.BaseController; @@ -20,6 +21,9 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.Map; /** @@ -61,7 +65,7 @@ public class ThirdPartyBaseController extends BaseController { * @return * @param */ - protected T parseParamsDTO(CommonParamsDTO dto, Class targetClass) { + protected T parseParamsDTO(CommonParamsDTO dto, Class targetClass) throws NoSuchFieldException, IllegalAccessException { // 解密 String operatorId = StringUtils.isNotBlank(dto.getOperatorID()) ? dto.getOperatorID() : dto.getPlatformID(); // 通过operatorId 查出 operatorSecret @@ -76,7 +80,115 @@ public class ThirdPartyBaseController extends BaseController { // 解密data 获取参数中的OperatorSecret String decrypt = Cryptos.decrypt(dto.getData(), dataSecret, dataSecretIv); - return JSONObject.parseObject(decrypt, targetClass); + T t = JSONObject.parseObject(decrypt, targetClass); + + // 校验是否有operatorId, 没有就set + verifyOperatorId(dto, t); + + return t; + } + + /** + * 获取OperatorId的值 verify + * @param t + * @return + * @throws NoSuchFieldException + * @throws IllegalAccessException + */ + private void verifyOperatorId(CommonParamsDTO dto, T t) throws NoSuchFieldException, IllegalAccessException { + String targetFieldName = "operatorId"; + String operatorId = (String) getFieldValueByObject(t, targetFieldName); + if (StringUtils.isBlank(operatorId)) { + setFieldValueByFieldName(t, targetFieldName, dto.getOperatorID()); + } + } + + private void setFieldValueByFieldName(T t, String targetFieldName, Object value) { + // 获取该对象的class + Class tClass = t.getClass(); + // 获取所有的属性数组 + Field[] fields = tClass.getDeclaredFields(); + + for (Field field : fields) { + // 属性名称 + String currentFieldName = ""; + try { + boolean has_JsonProperty = field.isAnnotationPresent(JsonProperty.class); + if (has_JsonProperty) { + currentFieldName = field.getAnnotation(JsonProperty.class).value(); + } else { + currentFieldName = field.getName(); + } + // 忽略大小写对比 + if (currentFieldName.equalsIgnoreCase(targetFieldName)) { + // 取消语言访问检查 + field.setAccessible(true); + // 给变量赋值 + field.set(t, value); + return; + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + + /** + * 使用反射获取字段值 + */ + private Object getFieldValueByObject(T t, String targetFieldName) throws NoSuchFieldException, IllegalAccessException { + // 获取该对象的class + Class tClass = t.getClass(); + // 获取所有的属性数组 + Field[] fields = tClass.getDeclaredFields(); + /** + * 这里只需要 id 这个属性,所以直接取 fields[0] 这 + * 一个,如果id不是排在第一位,自己取相应的位置, + * 如果有需要,可以写成for循环,遍历全部属性 + */ + + for (Field field : fields) { + // 属性名称 + String currentFieldName = ""; + // 获取属性上面的注解 import com.fasterxml.jackson.annotation.JsonProperty; + /** + * 举例: @JsonProperty("roleIds") + * private String roleIds; + */ + + try { + boolean has_JsonProperty = field.isAnnotationPresent(JsonProperty.class); + + if (has_JsonProperty) { + currentFieldName = field.getAnnotation(JsonProperty.class).value(); + } else { + currentFieldName = field.getName(); + } + + // 忽略大小写对比 + if (currentFieldName.equalsIgnoreCase(targetFieldName)) { + field.setAccessible(true); + currentFieldName = currentFieldName.replaceFirst(currentFieldName.substring(0, 1), currentFieldName.substring(0, 1).toUpperCase()); + //整合出 getId() 属性这个方法 + Method m = tClass.getMethod("get" + currentFieldName); + return m.invoke(t); + } + + } catch (SecurityException e) { + // 安全性异常 + e.printStackTrace(); + } catch (IllegalArgumentException e) { + // 非法参数 + e.printStackTrace(); + } catch (IllegalAccessException | NoSuchMethodException e) { + // 无访问权限 + e.printStackTrace(); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } + + return null; } /** diff --git a/jsowell-admin/src/main/java/com/jsowell/web/controller/thirdparty/lianlian/LianLianController.java b/jsowell-admin/src/main/java/com/jsowell/web/controller/thirdparty/lianlian/LianLianController.java index b897d7d13..601608267 100644 --- a/jsowell-admin/src/main/java/com/jsowell/web/controller/thirdparty/lianlian/LianLianController.java +++ b/jsowell-admin/src/main/java/com/jsowell/web/controller/thirdparty/lianlian/LianLianController.java @@ -3,7 +3,6 @@ package com.jsowell.web.controller.thirdparty.lianlian; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.jsowell.common.annotation.Anonymous; -import com.jsowell.common.core.controller.BaseController; import com.jsowell.common.enums.thirdparty.ThirdPlatformTypeEnum; import com.jsowell.common.enums.ykc.ReturnCodeEnum; import com.jsowell.common.exception.BusinessException; @@ -18,6 +17,7 @@ import com.jsowell.thirdparty.lianlian.common.CommonResult; import com.jsowell.thirdparty.platform.ThirdPartyPlatformService; import com.jsowell.thirdparty.platform.util.Cryptos; import com.jsowell.thirdparty.platform.util.Encodes; +import com.jsowell.web.controller.thirdparty.ThirdPartyBaseController; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.web.bind.annotation.*; @@ -35,7 +35,7 @@ import java.util.Map; @Anonymous @RestController @RequestMapping("/LianLian") -public class LianLianController extends BaseController { +public class LianLianController extends ThirdPartyBaseController { // @Autowired // private LianLianService lianLianService; @@ -106,6 +106,9 @@ public class LianLianController extends BaseController { QueryStationInfoDTO queryStationInfoDTO = JSONObject.parseObject(dataStr, QueryStationInfoDTO.class); queryStationInfoDTO.setOperatorId(dto.getOperatorID()); // Map map = lianLianService.query_stations_info(queryStationInfoDTO); + + QueryOperatorInfoDTO paramDTO = parseParamsDTO(dto, QueryOperatorInfoDTO.class); + Map map = lianLianService.queryStationsInfo(queryStationInfoDTO); return CommonResult.success(0, "查询充电站信息成功!", map.get("Data"), map.get("Sig")); @@ -415,10 +418,11 @@ public class LianLianController extends BaseController { try { // 校验令牌 String token = request.getHeader("Authorization"); - if (!JWTUtils.checkThirdPartyToken(token)) { - // 校验失败 - return CommonResult.failed("令牌校验错误"); - } + // if (!JWTUtils.checkThirdPartyToken(token)) { + // // 校验失败 + // return CommonResult.failed("令牌校验错误"); + // } + // 校验签名 // Map resultMap = lianLianService.checkoutSign(dto); // if (resultMap == null) { @@ -431,19 +435,23 @@ public class LianLianController extends BaseController { // String dataSecretIV = resultMap.get("DataSecretIV"); // 查询配置信息 - ThirdPartyPlatformConfig platformConfig = thirdPartyPlatformConfigService.getInfoByOperatorId(dto.getOperatorID()); - String operatorSecret = platformConfig.getOperatorSecret(); - String dataString = dto.getData(); - String dataSecret = platformConfig.getDataSecret(); - String dataSecretIV = platformConfig.getDataSecretIv(); + // ThirdPartyPlatformConfig platformConfig = thirdPartyPlatformConfigService.getInfoByOperatorId(dto.getOperatorID()); + // String operatorSecret = platformConfig.getOperatorSecret(); + // String dataString = dto.getData(); + // String dataSecret = platformConfig.getDataSecret(); + // String dataSecretIV = platformConfig.getDataSecretIv(); // 解密data - byte[] plainText = Cryptos.aesDecrypt(Encodes.decodeBase64(dataString), dataSecret.getBytes(), dataSecretIV.getBytes()); - String dataStr = new String(plainText, StandardCharsets.UTF_8); + // byte[] plainText = Cryptos.aesDecrypt(Encodes.decodeBase64(dataString), dataSecret.getBytes(), dataSecretIV.getBytes()); + // String dataStr = new String(plainText, StandardCharsets.UTF_8); // 转换成相应对象 - QueryStartChargeDTO queryStartChargeDTO = JSONObject.parseObject(dataStr, QueryStartChargeDTO.class); - queryStartChargeDTO.setOperatorId(dto.getOperatorID()); + // QueryStartChargeDTO queryStartChargeDTO = JSONObject.parseObject(dataStr, QueryStartChargeDTO.class); + // queryStartChargeDTO.setOperatorId(dto.getOperatorID()); // Map map = lianLianService.query_start_charge(queryStartChargeDTO); + + QueryStartChargeDTO queryStartChargeDTO = parseParamsDTO(dto, QueryStartChargeDTO.class); + + queryStartChargeDTO.setOperatorId(dto.getOperatorID()); Map map = lianLianService.queryStartCharge(queryStartChargeDTO); return CommonResult.success(0, "请求启动充电成功!", map.get("Data"), map.get("Sig")); diff --git a/jsowell-common/src/main/java/com/jsowell/common/enums/thirdparty/ThirdPartyReturnCodeEnum.java b/jsowell-common/src/main/java/com/jsowell/common/enums/thirdparty/ThirdPartyReturnCodeEnum.java index 5b5c62867..862c43360 100644 --- a/jsowell-common/src/main/java/com/jsowell/common/enums/thirdparty/ThirdPartyReturnCodeEnum.java +++ b/jsowell-common/src/main/java/com/jsowell/common/enums/thirdparty/ThirdPartyReturnCodeEnum.java @@ -21,8 +21,9 @@ public enum ThirdPartyReturnCodeEnum { QUERY_IS_NULL_ERROR("1001", "根据消息体中的组织机构代码,获取不到商户"), ENCRYPTION_OR_DECRYPTION_ERROR("1002", "加解密异常"), FIELD_FORMAT_ERROR("1003", "字段格式错误"), - // ↓ ↓ ↓ ↓ ↓ 内蒙古平台定义 end ↓ ↓ ↓ ↓ ↓ + // ↑ ↑ ↑ ↑ ↑ 内蒙古平台定义 end ↑ ↑ ↑ ↑ ↑ + QUERY_DATA_IS_NULL_ERROR("1004", "查询不到数据"), ; private String ret; diff --git a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/lianlian/service/LianLianPlatformServiceImpl.java b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/lianlian/service/LianLianPlatformServiceImpl.java index 9dfd87f67..19371fd60 100644 --- a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/lianlian/service/LianLianPlatformServiceImpl.java +++ b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/lianlian/service/LianLianPlatformServiceImpl.java @@ -11,6 +11,7 @@ import com.jsowell.common.core.domain.ykc.RealTimeMonitorData; import com.jsowell.common.enums.lianlian.PayChannelEnum; import com.jsowell.common.enums.lianlian.StationPaymentEnum; import com.jsowell.common.enums.thirdparty.BusinessInformationExchangeEnum; +import com.jsowell.common.enums.thirdparty.ThirdPartyOperatorIdEnum; import com.jsowell.common.enums.thirdparty.ThirdPlatformTypeEnum; import com.jsowell.common.enums.ykc.OrderPayModeEnum; import com.jsowell.common.enums.ykc.PileConnectorDataBaseStatusEnum; @@ -20,10 +21,8 @@ import com.jsowell.common.util.JWTUtils; import com.jsowell.common.util.PageUtils; import com.jsowell.common.util.StringUtils; import com.jsowell.pile.domain.*; -import com.jsowell.pile.dto.PushOrderSettlementDTO; -import com.jsowell.pile.dto.PushRealTimeInfoDTO; -import com.jsowell.pile.dto.QueryEquipmentDTO; -import com.jsowell.pile.dto.QueryStationInfoDTO; +import com.jsowell.pile.domain.ykcCommond.StartChargingCommand; +import com.jsowell.pile.dto.*; import com.jsowell.pile.service.*; import com.jsowell.pile.thirdparty.CommonParamsDTO; import com.jsowell.pile.thirdparty.EquipmentInfo; @@ -38,6 +37,7 @@ import com.jsowell.pile.vo.web.PileStationVO; import com.jsowell.thirdparty.lianlian.domain.*; import com.jsowell.thirdparty.lianlian.vo.AccessTokenVO; import com.jsowell.thirdparty.lianlian.vo.EquipmentAuthVO; +import com.jsowell.thirdparty.lianlian.vo.QueryStartChargeVO; import com.jsowell.thirdparty.platform.ThirdPartyPlatformService; import com.jsowell.thirdparty.platform.common.ChargeDetail; import com.jsowell.thirdparty.platform.common.OrderInfo; @@ -63,6 +63,9 @@ public class LianLianPlatformServiceImpl implements ThirdPartyPlatformService { @Autowired private PileMerchantInfoService pileMerchantInfoService; + @Autowired + private YKCPushCommandService ykcPushCommandService; + @Autowired private PileStationInfoService pileStationInfoService; @@ -1200,5 +1203,81 @@ public class LianLianPlatformServiceImpl implements ThirdPartyPlatformService { return resultMap; } + /** + * 请求启动充电 + * + * @param dto + */ + public Map queryStartCharge(QueryStartChargeDTO dto) { + // 通过传过来的订单号和枪口号生成订单 + String pileConnectorCode = dto.getConnectorID(); + OrderBasicInfo orderInfo = orderBasicInfoService.getOrderInfoByOrderCode(dto.getStartChargeSeq()); + if (orderInfo != null) { + // 平台已存在订单 + return null; + } + + ThirdPartySecretInfoVO thirdPartySecretInfoVO = thirdpartySecretInfoService.queryByOperatorId(dto.getOperatorId()); + if (thirdPartySecretInfoVO == null) { + return null; + } + + // 生成订单 + Map map = orderBasicInfoService.generateOrderForThirdParty(dto); + String orderCode = (String) map.get("orderCode"); + String transactionCode = (String) map.get("transactionCode"); + OrderBasicInfo orderBasicInfo = (OrderBasicInfo) map.get("orderBasicInfo"); + + // 发送启机指令 + StartChargingCommand command = StartChargingCommand.builder() + .pileSn(orderBasicInfo.getPileSn()) + .connectorCode(orderBasicInfo.getConnectorCode()) + .transactionCode(transactionCode) + .chargeAmount(orderBasicInfo.getPayAmount()) + .logicCardNum(null) + .physicsCardNum(null) + .build(); + ykcPushCommandService.pushStartChargingCommand(command); + + // 拼装对应的数据并返回 + QueryStartChargeVO vo = QueryStartChargeVO.builder() + .startChargeSeq(orderCode) + .startChargeSeqStat(2) // 1、启动中 ;2、充电中;3、停止中;4、已结束;5、未知 + .connectorID(pileConnectorCode) + .succStat(0) + .failReason(0) + + .build(); + String type = ThirdPartyOperatorIdEnum.getTypeByOperatorId(dto.getOperatorId()); + if (StringUtils.equals(ThirdPlatformTypeEnum.XIN_DIAN_TU.getTypeCode(), type)) { + // 如果是新电途平台,则将 startChargeSeqStat 改为 1-启动中 + vo.setStartChargeSeqStat(1); + } + // 异步推送启动充电结果 2024.01.25改为在0x33帧类型中统一回复 + // CompletableFuture.runAsync(() -> { + // try { + // Thread.sleep(200); + // } catch (InterruptedException e) { + // e.printStackTrace(); + // } + // pushStartChargeResult(orderCode); + // }); + + // 加密 + // Map resultMap = Maps.newLinkedHashMap(); + // 加密数据 + // byte[] encryptText = Cryptos.aesEncrypt(JSON.toJSONString(vo).getBytes(), + // configInfo.getDataSecret().getBytes(), configInfo.getDataSecretIv().getBytes()); + // String encryptData = Encodes.encodeBase64(encryptText); + // + // resultMap.put("Data", encryptData); + // 生成sig + // String resultSign = GBSignUtils.sign(resultMap, configInfo.getSignSecret()); + // resultMap.put("Sig", resultSign); + + Map resultMap = ThirdPartyPlatformUtils.generateResultMap(vo, thirdPartySecretInfoVO); + return resultMap; + + } }