|
|
@@ -16,6 +16,7 @@ import com.zsElectric.boot.business.model.vo.applet.AppletConnectorDetailVO;
|
|
|
import com.zsElectric.boot.charging.mapper.ThirdPartyConnectorInfoMapper;
|
|
|
import com.zsElectric.boot.business.mapper.UserAccountMapper;
|
|
|
import com.zsElectric.boot.business.mapper.UserOrderInfoMapper;
|
|
|
+import com.zsElectric.boot.business.model.entity.ChargeOrderInfo;
|
|
|
import com.zsElectric.boot.business.model.entity.RechargeLevel;
|
|
|
import com.zsElectric.boot.business.model.entity.ThirdPartyInfo;
|
|
|
import com.zsElectric.boot.business.model.entity.UserAccount;
|
|
|
@@ -50,6 +51,7 @@ import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
+import java.time.Duration;
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.time.LocalTime;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
@@ -99,6 +101,12 @@ public class ThirdPartyTokenServiceImpl implements ThirdPartyTokenService {
|
|
|
*/
|
|
|
private static final int DEFAULT_TOKEN_EXPIRE_SECONDS = 7200;
|
|
|
|
|
|
+ private static final long REQUEST_TIMESTAMP_WINDOW_SECONDS = 300;
|
|
|
+
|
|
|
+ private static final String REPLAY_KEY_PREFIX = "third_party_access:replay:";
|
|
|
+
|
|
|
+ private static final DateTimeFormatter REQUEST_TIMESTAMP_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
|
|
|
+
|
|
|
@Override
|
|
|
public ThirdPartyResponse queryToken(ThirdPartyRequest request) {
|
|
|
try {
|
|
|
@@ -120,6 +128,10 @@ public class ThirdPartyTokenServiceImpl implements ThirdPartyTokenService {
|
|
|
log.warn("签名验证失败, operatorId: {}", request.getOperatorId());
|
|
|
return buildErrorResponse(4001, "签名错误", thirdPartyInfo);
|
|
|
}
|
|
|
+ ThirdPartyResponse replayValidationResponse = validateTimestampAndReplay(request, thirdPartyInfo);
|
|
|
+ if (replayValidationResponse != null) {
|
|
|
+ return replayValidationResponse;
|
|
|
+ }
|
|
|
|
|
|
// 4. 解密并解析业务参数
|
|
|
String decryptedData = AESCryptoUtils.decrypt(
|
|
|
@@ -187,13 +199,9 @@ public class ThirdPartyTokenServiceImpl implements ThirdPartyTokenService {
|
|
|
|
|
|
// 4. 从Header中解析并验证Token
|
|
|
String accessToken = parseAccessToken(authorization);
|
|
|
- if (StrUtil.isBlank(accessToken)) {
|
|
|
- log.warn("Token为空或格式错误, operatorId: {}", request.getOperatorId());
|
|
|
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
|
|
|
- }
|
|
|
- if (!validateAccessToken(accessToken, request.getOperatorId())) {
|
|
|
- log.warn("Token验证失败, operatorId: {}", request.getOperatorId());
|
|
|
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
|
|
|
+ ThirdPartyResponse accessTokenValidationResponse = validateAccessTokenAndReplay(accessToken, request, thirdPartyInfo);
|
|
|
+ if (accessTokenValidationResponse != null) {
|
|
|
+ return accessTokenValidationResponse;
|
|
|
}
|
|
|
|
|
|
// 5. 解密并解析业务参数
|
|
|
@@ -258,13 +266,9 @@ public class ThirdPartyTokenServiceImpl implements ThirdPartyTokenService {
|
|
|
|
|
|
// 4. 从Header中解析并验证Token
|
|
|
String accessToken = parseAccessToken(authorization);
|
|
|
- if (StrUtil.isBlank(accessToken)) {
|
|
|
- log.warn("Token为空或格式错误, operatorId: {}", request.getOperatorId());
|
|
|
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
|
|
|
- }
|
|
|
- if (!validateAccessToken(accessToken, request.getOperatorId())) {
|
|
|
- log.warn("Token验证失败, operatorId: {}", request.getOperatorId());
|
|
|
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
|
|
|
+ ThirdPartyResponse accessTokenValidationResponse = validateAccessTokenAndReplay(accessToken, request, thirdPartyInfo);
|
|
|
+ if (accessTokenValidationResponse != null) {
|
|
|
+ return accessTokenValidationResponse;
|
|
|
}
|
|
|
|
|
|
// 5. 解密并解析业务参数
|
|
|
@@ -364,13 +368,9 @@ public class ThirdPartyTokenServiceImpl implements ThirdPartyTokenService {
|
|
|
|
|
|
// 4. 从Header中解析并验证Token
|
|
|
String accessToken = parseAccessToken(authorization);
|
|
|
- if (StrUtil.isBlank(accessToken)) {
|
|
|
- log.warn("Token为空或格式错误, operatorId: {}", request.getOperatorId());
|
|
|
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
|
|
|
- }
|
|
|
- if (!validateAccessToken(accessToken, request.getOperatorId())) {
|
|
|
- log.warn("Token验证失败, operatorId: {}", request.getOperatorId());
|
|
|
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
|
|
|
+ ThirdPartyResponse accessTokenValidationResponse = validateAccessTokenAndReplay(accessToken, request, thirdPartyInfo);
|
|
|
+ if (accessTokenValidationResponse != null) {
|
|
|
+ return accessTokenValidationResponse;
|
|
|
}
|
|
|
|
|
|
// 5. 解密并解析业务参数
|
|
|
@@ -519,6 +519,57 @@ public class ThirdPartyTokenServiceImpl implements ThirdPartyTokenService {
|
|
|
return operatorId.equals(storedOperatorId);
|
|
|
}
|
|
|
|
|
|
+ private ThirdPartyResponse validateAccessTokenAndReplay(String accessToken, ThirdPartyRequest request, ThirdPartyInfo thirdPartyInfo) {
|
|
|
+ if (StrUtil.isBlank(accessToken)) {
|
|
|
+ log.warn("Token为空或格式错误, operatorId: {}", request.getOperatorId());
|
|
|
+ return buildErrorResponse(4002, "token错误", thirdPartyInfo);
|
|
|
+ }
|
|
|
+ if (!validateAccessToken(accessToken, request.getOperatorId())) {
|
|
|
+ log.warn("Token验证失败, operatorId: {}", request.getOperatorId());
|
|
|
+ return buildErrorResponse(4002, "token错误", thirdPartyInfo);
|
|
|
+ }
|
|
|
+ return validateTimestampAndReplay(request, thirdPartyInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ private ThirdPartyResponse validateTimestampAndReplay(ThirdPartyRequest request, ThirdPartyInfo thirdPartyInfo) {
|
|
|
+ LocalDateTime requestTime;
|
|
|
+ try {
|
|
|
+ requestTime = LocalDateTime.parse(request.getTimeStamp(), REQUEST_TIMESTAMP_FORMATTER);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("timeStamp格式错误, operatorId: {}, timeStamp: {}", request.getOperatorId(), request.getTimeStamp());
|
|
|
+ return buildErrorResponse(4003, "timeStamp格式错误", thirdPartyInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ long diffSeconds = Math.abs(Duration.between(requestTime, LocalDateTime.now()).getSeconds());
|
|
|
+ if (diffSeconds > REQUEST_TIMESTAMP_WINDOW_SECONDS) {
|
|
|
+ log.warn("timeStamp已过期, operatorId: {}, timeStamp: {}, diffSeconds: {}",
|
|
|
+ request.getOperatorId(), request.getTimeStamp(), diffSeconds);
|
|
|
+ return buildErrorResponse(4003, "timeStamp已过期", thirdPartyInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ String replayKey = REPLAY_KEY_PREFIX + request.getOperatorId() + ":" + request.getTimeStamp() + ":" + request.getSeq();
|
|
|
+ Boolean acquired = redisTemplate.opsForValue()
|
|
|
+ .setIfAbsent(replayKey, "1", REQUEST_TIMESTAMP_WINDOW_SECONDS * 2, TimeUnit.SECONDS);
|
|
|
+ if (!Boolean.TRUE.equals(acquired)) {
|
|
|
+ log.warn("重复请求, operatorId: {}, timeStamp: {}, seq: {}",
|
|
|
+ request.getOperatorId(), request.getTimeStamp(), request.getSeq());
|
|
|
+ return buildErrorResponse(4003, "重复请求", thirdPartyInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private ChargeOrderInfo getCurrentOperatorChargeOrder(String chargeOrderNo, String operatorId) {
|
|
|
+ return chargeOrderInfoService.getOne(
|
|
|
+ Wrappers.<ChargeOrderInfo>lambdaQuery()
|
|
|
+ .eq(ChargeOrderInfo::getChargeOrderNo, chargeOrderNo)
|
|
|
+ .eq(ChargeOrderInfo::getOrderType, SystemConstants.CHARGE_ORDER_TYPE_CHANNEL)
|
|
|
+ .eq(ChargeOrderInfo::getOperatorId, operatorId)
|
|
|
+ .eq(ChargeOrderInfo::getIsDeleted, 0)
|
|
|
+ .last("LIMIT 1")
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 从数据库查询充值档位分页数据
|
|
|
*/
|
|
|
@@ -674,13 +725,9 @@ public class ThirdPartyTokenServiceImpl implements ThirdPartyTokenService {
|
|
|
|
|
|
// 4. 从Header中解析并验证Token
|
|
|
String accessToken = parseAccessToken(authorization);
|
|
|
- if (StrUtil.isBlank(accessToken)) {
|
|
|
- log.warn("Token为空或格式错误, operatorId: {}", request.getOperatorId());
|
|
|
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
|
|
|
- }
|
|
|
- if (!validateAccessToken(accessToken, request.getOperatorId())) {
|
|
|
- log.warn("Token验证失败, operatorId: {}", request.getOperatorId());
|
|
|
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
|
|
|
+ ThirdPartyResponse accessTokenValidationResponse = validateAccessTokenAndReplay(accessToken, request, thirdPartyInfo);
|
|
|
+ if (accessTokenValidationResponse != null) {
|
|
|
+ return accessTokenValidationResponse;
|
|
|
}
|
|
|
|
|
|
// 5. 解密并解析业务参数
|
|
|
@@ -755,13 +802,9 @@ public class ThirdPartyTokenServiceImpl implements ThirdPartyTokenService {
|
|
|
|
|
|
// 4. 从Header中解析并验证Token
|
|
|
String accessToken = parseAccessToken(authorization);
|
|
|
- if (StrUtil.isBlank(accessToken)) {
|
|
|
- log.warn("Token为空或格式错误, operatorId: {}", request.getOperatorId());
|
|
|
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
|
|
|
- }
|
|
|
- if (!validateAccessToken(accessToken, request.getOperatorId())) {
|
|
|
- log.warn("Token验证失败, operatorId: {}", request.getOperatorId());
|
|
|
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
|
|
|
+ ThirdPartyResponse accessTokenValidationResponse = validateAccessTokenAndReplay(accessToken, request, thirdPartyInfo);
|
|
|
+ if (accessTokenValidationResponse != null) {
|
|
|
+ return accessTokenValidationResponse;
|
|
|
}
|
|
|
|
|
|
// 5. 解密并解析业务参数
|
|
|
@@ -942,13 +985,9 @@ public class ThirdPartyTokenServiceImpl implements ThirdPartyTokenService {
|
|
|
|
|
|
// 4. 从Header中解析并验证Token
|
|
|
String accessToken = parseAccessToken(authorization);
|
|
|
- if (StrUtil.isBlank(accessToken)) {
|
|
|
- log.warn("Token为空或格式错误, operatorId: {}", request.getOperatorId());
|
|
|
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
|
|
|
- }
|
|
|
- if (!validateAccessToken(accessToken, request.getOperatorId())) {
|
|
|
- log.warn("Token验证失败, operatorId: {}", request.getOperatorId());
|
|
|
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
|
|
|
+ ThirdPartyResponse accessTokenValidationResponse = validateAccessTokenAndReplay(accessToken, request, thirdPartyInfo);
|
|
|
+ if (accessTokenValidationResponse != null) {
|
|
|
+ return accessTokenValidationResponse;
|
|
|
}
|
|
|
|
|
|
// 5. 解密并解析业务参数
|
|
|
@@ -1044,6 +1083,8 @@ public class ThirdPartyTokenServiceImpl implements ThirdPartyTokenService {
|
|
|
item.setStationName(stationInfoVO.getStationName());
|
|
|
item.setTips(stationInfoVO.getTips());
|
|
|
item.setDistance(stationInfoVO.getDistance());
|
|
|
+ item.setLongitude(stationInfoVO.getLongitude());
|
|
|
+ item.setLatitude(stationInfoVO.getLatitude());
|
|
|
item.setFastCharging(stationInfoVO.getFastCharging());
|
|
|
item.setSlowCharging(stationInfoVO.getSlowCharging());
|
|
|
item.setPeakValue(stationInfoVO.getPeakValue());
|
|
|
@@ -1111,13 +1152,9 @@ public class ThirdPartyTokenServiceImpl implements ThirdPartyTokenService {
|
|
|
|
|
|
// 4. 从Header中解析并验证Token
|
|
|
String accessToken = parseAccessToken(authorization);
|
|
|
- if (StrUtil.isBlank(accessToken)) {
|
|
|
- log.warn("Token为空或格式错误, operatorId: {}", request.getOperatorId());
|
|
|
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
|
|
|
- }
|
|
|
- if (!validateAccessToken(accessToken, request.getOperatorId())) {
|
|
|
- log.warn("Token验证失败, operatorId: {}", request.getOperatorId());
|
|
|
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
|
|
|
+ ThirdPartyResponse accessTokenValidationResponse = validateAccessTokenAndReplay(accessToken, request, thirdPartyInfo);
|
|
|
+ if (accessTokenValidationResponse != null) {
|
|
|
+ return accessTokenValidationResponse;
|
|
|
}
|
|
|
|
|
|
// 5. 解密并解析业务参数
|
|
|
@@ -1137,6 +1174,7 @@ public class ThirdPartyTokenServiceImpl implements ThirdPartyTokenService {
|
|
|
// 6. 构建启动充电表单
|
|
|
AppInvokeChargeForm formData = new AppInvokeChargeForm();
|
|
|
formData.setOrderType(2); // 渠道方订单
|
|
|
+ formData.setOperatorId(request.getOperatorId());
|
|
|
formData.setEquipmentId(invokeRequest.getEquipmentId());
|
|
|
formData.setStationId(invokeRequest.getStationId());
|
|
|
formData.setConnectorId(invokeRequest.getConnectorId());
|
|
|
@@ -1187,13 +1225,9 @@ public class ThirdPartyTokenServiceImpl implements ThirdPartyTokenService {
|
|
|
|
|
|
// 4. 从Header中解析并验证Token
|
|
|
String accessToken = parseAccessToken(authorization);
|
|
|
- if (StrUtil.isBlank(accessToken)) {
|
|
|
- log.warn("Token为空或格式错误, operatorId: {}", request.getOperatorId());
|
|
|
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
|
|
|
- }
|
|
|
- if (!validateAccessToken(accessToken, request.getOperatorId())) {
|
|
|
- log.warn("Token验证失败, operatorId: {}", request.getOperatorId());
|
|
|
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
|
|
|
+ ThirdPartyResponse accessTokenValidationResponse = validateAccessTokenAndReplay(accessToken, request, thirdPartyInfo);
|
|
|
+ if (accessTokenValidationResponse != null) {
|
|
|
+ return accessTokenValidationResponse;
|
|
|
}
|
|
|
|
|
|
// 5. 解密并解析业务参数
|
|
|
@@ -1208,10 +1242,16 @@ public class ThirdPartyTokenServiceImpl implements ThirdPartyTokenService {
|
|
|
if (stopRequest == null || StrUtil.isBlank(stopRequest.getChargeOrderNo())) {
|
|
|
return buildErrorResponse(4003, "请求的业务参数不合法", thirdPartyInfo);
|
|
|
}
|
|
|
+ ChargeOrderInfo chargeOrderInfo = getCurrentOperatorChargeOrder(stopRequest.getChargeOrderNo(), request.getOperatorId());
|
|
|
+ if (chargeOrderInfo == null) {
|
|
|
+ StopChargeResponseData failData = StopChargeResponseData.fail("充电订单不存在或不属于当前运营商");
|
|
|
+ return buildSuccessResponse(failData, thirdPartyInfo);
|
|
|
+ }
|
|
|
|
|
|
// 6. 构建停止充电表单
|
|
|
AppStopChargeForm formData = new AppStopChargeForm();
|
|
|
formData.setChargeOrderNo(stopRequest.getChargeOrderNo());
|
|
|
+ formData.setOperatorId(request.getOperatorId());
|
|
|
|
|
|
// 7. 调用停止充电服务
|
|
|
AppChargeVO chargeVO = chargeOrderInfoService.stopCharge(formData);
|
|
|
@@ -1256,13 +1296,9 @@ public class ThirdPartyTokenServiceImpl implements ThirdPartyTokenService {
|
|
|
|
|
|
// 4. 从Header中解析并验证Token
|
|
|
String accessToken = parseAccessToken(authorization);
|
|
|
- if (StrUtil.isBlank(accessToken)) {
|
|
|
- log.warn("Token为空或格式错误, operatorId: {}", request.getOperatorId());
|
|
|
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
|
|
|
- }
|
|
|
- if (!validateAccessToken(accessToken, request.getOperatorId())) {
|
|
|
- log.warn("Token验证失败, operatorId: {}", request.getOperatorId());
|
|
|
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
|
|
|
+ ThirdPartyResponse accessTokenValidationResponse = validateAccessTokenAndReplay(accessToken, request, thirdPartyInfo);
|
|
|
+ if (accessTokenValidationResponse != null) {
|
|
|
+ return accessTokenValidationResponse;
|
|
|
}
|
|
|
|
|
|
// 5. 解密并解析业务参数
|
|
|
@@ -1281,7 +1317,7 @@ public class ThirdPartyTokenServiceImpl implements ThirdPartyTokenService {
|
|
|
// 6. 构建查询条件(只查询渠道类型订单 order_type=2)
|
|
|
LambdaQueryWrapper<com.zsElectric.boot.business.model.entity.ChargeOrderInfo> queryWrapper = Wrappers.lambdaQuery();
|
|
|
queryWrapper.eq(com.zsElectric.boot.business.model.entity.ChargeOrderInfo::getOrderType, SystemConstants.CHARGE_ORDER_TYPE_CHANNEL);
|
|
|
- queryWrapper.eq(com.zsElectric.boot.business.model.entity.ChargeOrderInfo::getOperatorId, listRequest.getOperatorId());
|
|
|
+ queryWrapper.eq(com.zsElectric.boot.business.model.entity.ChargeOrderInfo::getOperatorId, request.getOperatorId());
|
|
|
queryWrapper.eq(com.zsElectric.boot.business.model.entity.ChargeOrderInfo::getIsDeleted, 0);
|
|
|
|
|
|
// 可选条件:userId
|
|
|
@@ -1394,13 +1430,9 @@ public class ThirdPartyTokenServiceImpl implements ThirdPartyTokenService {
|
|
|
|
|
|
// 4. 从Header中解析并验证Token
|
|
|
String accessToken = parseAccessToken(authorization);
|
|
|
- if (StrUtil.isBlank(accessToken)) {
|
|
|
- log.warn("Token为空或格式错误, operatorId: {}", request.getOperatorId());
|
|
|
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
|
|
|
- }
|
|
|
- if (!validateAccessToken(accessToken, request.getOperatorId())) {
|
|
|
- log.warn("Token验证失败, operatorId: {}", request.getOperatorId());
|
|
|
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
|
|
|
+ ThirdPartyResponse accessTokenValidationResponse = validateAccessTokenAndReplay(accessToken, request, thirdPartyInfo);
|
|
|
+ if (accessTokenValidationResponse != null) {
|
|
|
+ return accessTokenValidationResponse;
|
|
|
}
|
|
|
|
|
|
// 5. 解密并解析业务参数
|
|
|
@@ -1417,13 +1449,7 @@ public class ThirdPartyTokenServiceImpl implements ThirdPartyTokenService {
|
|
|
}
|
|
|
|
|
|
// 6. 查询订单(只查询渠道类型订单 order_type=2)
|
|
|
- com.zsElectric.boot.business.model.entity.ChargeOrderInfo order = chargeOrderInfoService.getOne(
|
|
|
- Wrappers.<com.zsElectric.boot.business.model.entity.ChargeOrderInfo>lambdaQuery()
|
|
|
- .eq(com.zsElectric.boot.business.model.entity.ChargeOrderInfo::getChargeOrderNo, detailRequest.getChargeOrderNo())
|
|
|
- .eq(com.zsElectric.boot.business.model.entity.ChargeOrderInfo::getOrderType, SystemConstants.CHARGE_ORDER_TYPE_CHANNEL)
|
|
|
- .eq(com.zsElectric.boot.business.model.entity.ChargeOrderInfo::getIsDeleted, 0)
|
|
|
- .last("LIMIT 1")
|
|
|
- );
|
|
|
+ ChargeOrderInfo order = getCurrentOperatorChargeOrder(detailRequest.getChargeOrderNo(), request.getOperatorId());
|
|
|
|
|
|
if (order == null) {
|
|
|
log.warn("充电订单不存在或不是渠道订单, chargeOrderNo: {}", detailRequest.getChargeOrderNo());
|
|
|
@@ -1504,13 +1530,9 @@ public class ThirdPartyTokenServiceImpl implements ThirdPartyTokenService {
|
|
|
|
|
|
// 4. 从Header中解析并验证Token
|
|
|
String accessToken = parseAccessToken(authorization);
|
|
|
- if (StrUtil.isBlank(accessToken)) {
|
|
|
- log.warn("Token为空或格式错误, operatorId: {}", request.getOperatorId());
|
|
|
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
|
|
|
- }
|
|
|
- if (!validateAccessToken(accessToken, request.getOperatorId())) {
|
|
|
- log.warn("Token验证失败, operatorId: {}", request.getOperatorId());
|
|
|
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
|
|
|
+ ThirdPartyResponse accessTokenValidationResponse = validateAccessTokenAndReplay(accessToken, request, thirdPartyInfo);
|
|
|
+ if (accessTokenValidationResponse != null) {
|
|
|
+ return accessTokenValidationResponse;
|
|
|
}
|
|
|
|
|
|
// 5. 解密并解析业务参数
|
|
|
@@ -1525,6 +1547,11 @@ public class ThirdPartyTokenServiceImpl implements ThirdPartyTokenService {
|
|
|
if (costRequest == null || StrUtil.isBlank(costRequest.getChargeOrderNo())) {
|
|
|
return buildErrorResponse(4003, "请求的业务参数不合法,chargeOrderNo不能为空", thirdPartyInfo);
|
|
|
}
|
|
|
+ ChargeOrderInfo chargeOrderInfo = getCurrentOperatorChargeOrder(costRequest.getChargeOrderNo(), request.getOperatorId());
|
|
|
+ if (chargeOrderInfo == null) {
|
|
|
+ QueryChargingCostResponseData failData = QueryChargingCostResponseData.fail("充电订单不存在或不属于当前运营商");
|
|
|
+ return buildSuccessResponse(failData, thirdPartyInfo);
|
|
|
+ }
|
|
|
|
|
|
// 6. 调用AppletHomeService查询充电订单实时费用
|
|
|
AppChargingCostVO chargingCost = appletHomeService.getChargingCost(costRequest.getChargeOrderNo());
|
|
|
@@ -1588,13 +1615,9 @@ public class ThirdPartyTokenServiceImpl implements ThirdPartyTokenService {
|
|
|
|
|
|
// 4. 从Header中解析并验证Token
|
|
|
String accessToken = parseAccessToken(authorization);
|
|
|
- if (StrUtil.isBlank(accessToken)) {
|
|
|
- log.warn("Token为空或格式错误, operatorId: {}", request.getOperatorId());
|
|
|
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
|
|
|
- }
|
|
|
- if (!validateAccessToken(accessToken, request.getOperatorId())) {
|
|
|
- log.warn("Token验证失败, operatorId: {}", request.getOperatorId());
|
|
|
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
|
|
|
+ ThirdPartyResponse accessTokenValidationResponse = validateAccessTokenAndReplay(accessToken, request, thirdPartyInfo);
|
|
|
+ if (accessTokenValidationResponse != null) {
|
|
|
+ return accessTokenValidationResponse;
|
|
|
}
|
|
|
|
|
|
// 5. 解密并解析业务参数
|
|
|
@@ -1662,6 +1685,95 @@ public class ThirdPartyTokenServiceImpl implements ThirdPartyTokenService {
|
|
|
return buildErrorResponse(500, "系统错误: " + e.getMessage(), null);
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
+ @Override
|
|
|
+ public ThirdPartyResponse queryStationPriceList(ThirdPartyRequest request, String authorization) {
|
|
|
+ try {
|
|
|
+ // 1. 参数校验
|
|
|
+ if (!validateRequestParams(request)) {
|
|
|
+ return buildErrorResponse(4003, "参数不合法,缺少必需的参数", null);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 通过operatorId查询第三方配置信息
|
|
|
+ ThirdPartyInfo thirdPartyInfo = getThirdPartyInfoByOperatorId(request.getOperatorId());
|
|
|
+ if (thirdPartyInfo == null) {
|
|
|
+ log.warn("运营商不存在, operatorId: {}", request.getOperatorId());
|
|
|
+ return buildErrorResponse(4004, "运营商不存在", null);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 验证签名
|
|
|
+ String signContent = request.getOperatorId() + request.getData() + request.getTimeStamp() + request.getSeq();
|
|
|
+ if (!HmacMD5Util.verify(signContent, thirdPartyInfo.getSigSecret(), request.getSig())) {
|
|
|
+ log.warn("签名验证失败, operatorId: {}", request.getOperatorId());
|
|
|
+ return buildErrorResponse(4001, "签名错误", thirdPartyInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 从Header中解析并验证Token
|
|
|
+ String accessToken = parseAccessToken(authorization);
|
|
|
+ ThirdPartyResponse accessTokenValidationResponse = validateAccessTokenAndReplay(accessToken, request, thirdPartyInfo);
|
|
|
+ if (accessTokenValidationResponse != null) {
|
|
|
+ return accessTokenValidationResponse;
|
|
|
+ }
|
|
|
|
|
|
+ // 5. 解密并解析业务参数
|
|
|
+ String decryptedData = AESCryptoUtils.decrypt(
|
|
|
+ request.getData(),
|
|
|
+ thirdPartyInfo.getDataSecret(),
|
|
|
+ thirdPartyInfo.getDataSecretIV()
|
|
|
+ );
|
|
|
+ log.info("解密后的请求数据: {}", decryptedData);
|
|
|
+
|
|
|
+ StationPriceListRequestData priceRequest = objectMapper.readValue(decryptedData, StationPriceListRequestData.class);
|
|
|
+ if (priceRequest == null || priceRequest.getStationId() == null) {
|
|
|
+ return buildErrorResponse(4003, "请求的业务参数不合法", thirdPartyInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 6. 调用已有服务获取电站价格列表
|
|
|
+ com.zsElectric.boot.business.model.vo.AppletStationPriceListVO priceListVO = appletHomeService.getStationPriceList(priceRequest.getStationId());
|
|
|
+ if (priceListVO == null) {
|
|
|
+ return buildErrorResponse(4004, "充电站不存在", thirdPartyInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 7. 转换为第三方响应数据
|
|
|
+ StationPriceListResponseData responseData = convertToStationPriceList(priceListVO);
|
|
|
+
|
|
|
+ log.info("查询电站价格列表成功, operatorId: {}, stationId: {}", request.getOperatorId(), priceRequest.getStationId());
|
|
|
+ return buildSuccessResponse(responseData, thirdPartyInfo);
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("处理query_station_price_list请求异常", e);
|
|
|
+ return buildErrorResponse(500, "系统错误", null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 转换电站价格列表为第三方响应数据
|
|
|
+ */
|
|
|
+ private StationPriceListResponseData convertToStationPriceList(com.zsElectric.boot.business.model.vo.AppletStationPriceListVO priceListVO) {
|
|
|
+ StationPriceListResponseData responseData = new StationPriceListResponseData();
|
|
|
+ responseData.setStationId(priceListVO.getStationId());
|
|
|
+ responseData.setStationName(priceListVO.getStationName());
|
|
|
+ responseData.setTips(priceListVO.getTips());
|
|
|
+
|
|
|
+ if (priceListVO.getPriceList() != null) {
|
|
|
+ List<StationPriceListResponseData.PriceItem> priceItems = priceListVO.getPriceList().stream()
|
|
|
+ .map(item -> {
|
|
|
+ StationPriceListResponseData.PriceItem priceItem = new StationPriceListResponseData.PriceItem();
|
|
|
+ priceItem.setTimePeriod(item.getTimePeriod());
|
|
|
+ priceItem.setPeriodFlag(item.getPeriodFlag());
|
|
|
+ priceItem.setPeriodFlagName(item.getPeriodFlagName());
|
|
|
+ priceItem.setElecPrice(item.getElecPrice());
|
|
|
+ priceItem.setServicePrice(item.getServicePrice());
|
|
|
+ priceItem.setTotalPrice(item.getTotalPrice());
|
|
|
+ priceItem.setCurrentPeriod(item.getCurrentPeriod());
|
|
|
+ return priceItem;
|
|
|
+ })
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ responseData.setPriceList(priceItems);
|
|
|
+ } else {
|
|
|
+ responseData.setPriceList(new ArrayList<>());
|
|
|
+ }
|
|
|
+
|
|
|
+ return responseData;
|
|
|
+ }
|
|
|
+}
|