|
|
@@ -141,11 +141,12 @@ public class ChargingReceptionServiceImpl implements ChargingReceptionService {
|
|
|
* 通用充电请求处理模板
|
|
|
*/
|
|
|
private ResponseParmsEntity processChargeRequest(RequestParmsEntity requestDTO, Consumer<JsonNode> businessHandler) {
|
|
|
+ String startChargeSeq = null;
|
|
|
try {
|
|
|
JsonNode jsonNode = verifyAndDecrypt(requestDTO);
|
|
|
|
|
|
//查询订单
|
|
|
- String startChargeSeq = getTextValue(jsonNode, "StartChargeSeq");
|
|
|
+ startChargeSeq = getTextValue(jsonNode, "StartChargeSeq");
|
|
|
String stopReason = getTextValue(jsonNode, "StopReason");
|
|
|
String endTime = getTextValue(jsonNode, "EndTime");
|
|
|
String startTime = getTextValue(jsonNode, "StartTime");
|
|
|
@@ -155,233 +156,259 @@ public class ChargingReceptionServiceImpl implements ChargingReceptionService {
|
|
|
String totalSeviceMoney = getTextValue(jsonNode, "TotalSeviceMoney");
|
|
|
String connectorID = getTextValue(jsonNode, "ConnectorID");
|
|
|
|
|
|
- ChargeOrderInfo chargeOrderInfo = chargeOrderInfoService.getOne(new LambdaQueryWrapper<ChargeOrderInfo>()
|
|
|
- .eq(ChargeOrderInfo::getStartChargeSeq, startChargeSeq).last("LIMIT 1"));
|
|
|
-
|
|
|
- if (ObjectUtil.isNotEmpty(chargeOrderInfo)) {
|
|
|
- if (Objects.equals(chargeOrderInfo.getOrderType(), SystemConstants.CHARGE_ORDER_TYPE_CHANNEL)) {
|
|
|
- //订单信息渠道方推送
|
|
|
- Map<String, Object> map = objectMapper.convertValue(jsonNode, Map.class);
|
|
|
- map.put("chargeOrderNo", chargeOrderInfo.getChargeOrderNo());
|
|
|
- FirmInfo firmInfo = firmInfoMapper.selectById(chargeOrderInfo.getFirmId());
|
|
|
- if (ObjectUtil.isNotNull(firmInfo)) {
|
|
|
- okHttpUtil.doPostForm(firmInfo.getChannelUrl() + "/notification_charge_order_info", map, null);
|
|
|
- }
|
|
|
- }
|
|
|
- //推送订单明细
|
|
|
- chargeOrderInfo.setChargeDetails(jsonNode.toString());
|
|
|
-
|
|
|
- //优惠单价
|
|
|
- BigDecimal discountPrice = BigDecimal.ZERO;
|
|
|
-
|
|
|
- if (Objects.equals(chargeOrderInfo.getOrderType(), SystemConstants.CHARGE_ORDER_TYPE_PLATFORM)) {
|
|
|
- //判断当前订单是否为首单
|
|
|
- Long userId = chargeOrderInfo.getUserId();
|
|
|
- List<ChargeOrderInfo> list = chargeOrderInfoService.list(Wrappers.<ChargeOrderInfo>lambdaQuery().eq(ChargeOrderInfo::getUserId, userId).eq(ChargeOrderInfo::getStatus,
|
|
|
- SystemConstants.STATUS_THREE));
|
|
|
- if (ObjectUtil.isEmpty(list)) {
|
|
|
- DiscountsActivity discountsActivity = discountsActivityMapper.selectOne(Wrappers.<DiscountsActivity>lambdaQuery()
|
|
|
- .eq(DiscountsActivity::getType, SystemConstants.STATUS_ONE)
|
|
|
- .eq(DiscountsActivity::getStatus, SystemConstants.STATUS_ONE)
|
|
|
- .last("LIMIT 1"));
|
|
|
- if (ObjectUtil.isNotEmpty(discountsActivity)) {
|
|
|
- chargeOrderInfo.setDiscountInfoId(discountsActivity.getId());
|
|
|
- chargeOrderInfo.setDiscountDesc(discountsActivity.getActivityDesc());
|
|
|
- discountPrice = discountsActivity.getDiscount();
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- chargeOrderInfo.setStopReason(stopReason);
|
|
|
- chargeOrderInfo.setStartTime(startTime);
|
|
|
- chargeOrderInfo.setEndTime(endTime);
|
|
|
- chargeOrderInfo.setTotalCharge(new BigDecimal(totalPower));
|
|
|
-
|
|
|
- chargeOrderInfo.setThirdPartyTotalCost(new BigDecimal(totalMoney));
|
|
|
- chargeOrderInfo.setThirdPartyServerfee(new BigDecimal(totalSeviceMoney));
|
|
|
- chargeOrderInfo.setThirdPartyElecfee(new BigDecimal(totalElecMoney));
|
|
|
-
|
|
|
- ThirdPartyConnectorInfo thirdPartyConnectorInfo = connectorInfoMapper.selectOne(Wrappers.<ThirdPartyConnectorInfo>lambdaQuery()
|
|
|
- .eq(ThirdPartyConnectorInfo::getConnectorId, connectorID).last("LIMIT 1"));
|
|
|
- String stationId = thirdPartyConnectorInfo.getStationId();
|
|
|
- ThirdPartyStationInfo thirdPartyStationInfo = thirdPartyStationInfoMapper.selectOne(Wrappers.<ThirdPartyStationInfo>lambdaQuery()
|
|
|
- .eq(ThirdPartyStationInfo::getStationId, stationId).last("LIMIT 1"));
|
|
|
- if (ObjectUtil.isEmpty(thirdPartyConnectorInfo)) {
|
|
|
- log.error("thirdPartyConnectorInfo" + "为空===============================================");
|
|
|
- }
|
|
|
+ // 使用分布式锁防止并发操作
|
|
|
+ String lockKey = CHARGE_ORDER_LOCK_KEY + startChargeSeq;
|
|
|
+ RLock lock = redissonClient.getLock(lockKey);
|
|
|
+ final String finalStartChargeSeq = startChargeSeq;
|
|
|
+
|
|
|
+ try {
|
|
|
+ if (lock.tryLock(LOCK_WAIT_TIME, LOCK_LEASE_TIME, java.util.concurrent.TimeUnit.SECONDS)) {
|
|
|
+ try {
|
|
|
+ // 加锁后重新查询订单状态,确保状态最新
|
|
|
+ ChargeOrderInfo chargeOrderInfo = chargeOrderInfoService.getOne(new LambdaQueryWrapper<ChargeOrderInfo>()
|
|
|
+ .eq(ChargeOrderInfo::getStartChargeSeq, finalStartChargeSeq).last("LIMIT 1"));
|
|
|
|
|
|
- //平台服务费
|
|
|
- BigDecimal serviceFee = BigDecimal.ZERO;
|
|
|
- //优惠金额
|
|
|
- BigDecimal discountFee = BigDecimal.ZERO;
|
|
|
- JsonNode chargeDetails = jsonNode.get("ChargeDetails");
|
|
|
- if (ObjectUtil.isNotEmpty(chargeDetails)) {
|
|
|
- for (JsonNode node : chargeDetails) {
|
|
|
- //提取字段值
|
|
|
- String itemFlag = node.get("ItemFlag").asText();
|
|
|
- node.get("DetailPower").asText();
|
|
|
- BigDecimal detailPower = new BigDecimal(node.get("DetailPower").asText());
|
|
|
- PolicyFee policyFee = policyFeeMapper.selectOne(Wrappers.<PolicyFee>lambdaQuery()
|
|
|
- .eq(PolicyFee::getStationInfoId, thirdPartyStationInfo.getId())
|
|
|
- .eq(PolicyFee::getPeriodFlag, Integer.parseInt(itemFlag))
|
|
|
- .last("LIMIT 1"));
|
|
|
- if (ObjectUtil.isNotEmpty(policyFee)) {
|
|
|
- BigDecimal opFee = policyFee.getOpFee();
|
|
|
- if (ObjectUtil.isNotEmpty(chargeOrderInfo.getDiscountInfoId())) {
|
|
|
- opFee = opFee.subtract(discountPrice);
|
|
|
+ if (ObjectUtil.isNotEmpty(chargeOrderInfo)) {
|
|
|
+ // 检查订单状态,如果已经是已完成状态,则跳过处理
|
|
|
+ if (Objects.equals(chargeOrderInfo.getStatus(), SystemConstants.STATUS_THREE)) {
|
|
|
+ log.info("订单已完成,跳过处理 - startChargeSeq: {}", finalStartChargeSeq);
|
|
|
+ businessHandler.accept(jsonNode);
|
|
|
+ return buildChargeResponse(finalStartChargeSeq);
|
|
|
}
|
|
|
- log.info("策略费用:{}", opFee);
|
|
|
- serviceFee = serviceFee.add(opFee.multiply(detailPower));
|
|
|
- discountFee = discountFee.add(discountPrice.multiply(detailPower));
|
|
|
- }
|
|
|
- }
|
|
|
- } else {
|
|
|
- log.error("充电订单明细为空===============================================");
|
|
|
- if (chargeOrderInfo.getThirdPartyTotalCost().compareTo(BigDecimal.ZERO) > 0 && chargeOrderInfo.getTotalCharge().compareTo(BigDecimal.ZERO) > 0) {
|
|
|
- //判断当前订单创建时间在哪个时段
|
|
|
- ThirdPartyChargeStatus thirdPartyChargeStatus = chargeStatusMapper.selectOne(Wrappers.<ThirdPartyChargeStatus>lambdaQuery()
|
|
|
- .eq(ThirdPartyChargeStatus::getStartChargeSeq, chargeOrderInfo.getStartChargeSeq()));
|
|
|
-
|
|
|
- ThirdPartyEquipmentPricePolicy thirdPartyEquipmentPricePolicy = thirdPartyEquipmentPricePolicyMapper.selectOne(Wrappers.<ThirdPartyEquipmentPricePolicy>lambdaQuery()
|
|
|
- .eq(ThirdPartyEquipmentPricePolicy::getConnectorId, thirdPartyChargeStatus.getConnectorId())
|
|
|
- .last("LIMIT 1"));
|
|
|
-
|
|
|
- // 查询该价格策略下的所有时段信息,按startTime升序排列
|
|
|
- List<ThirdPartyPolicyInfo> allPolicyInfos = thirdPartyPolicyInfoMapper.selectList(Wrappers.<ThirdPartyPolicyInfo>lambdaQuery()
|
|
|
- .eq(ThirdPartyPolicyInfo::getPricePolicyId, thirdPartyEquipmentPricePolicy.getId())
|
|
|
- .orderByAsc(ThirdPartyPolicyInfo::getStartTime));
|
|
|
-
|
|
|
- // 将充电开始时间和结束时间转换为HHmmss格式字符串进行匹配
|
|
|
- LocalDateTime chargeStartTime = thirdPartyChargeStatus.getStartTime();
|
|
|
- LocalDateTime chargeEndTime = thirdPartyChargeStatus.getEndTime();
|
|
|
- String chargeStartTimeStr = chargeStartTime.format(DateTimeFormatter.ofPattern("HHmmss"));
|
|
|
- String chargeEndTimeStr = chargeEndTime.format(DateTimeFormatter.ofPattern("HHmmss"));
|
|
|
-
|
|
|
- // 找到充电开始时间所在的时段索引
|
|
|
- int startIndex = -1;
|
|
|
- for (int i = allPolicyInfos.size() - 1; i >= 0; i--) {
|
|
|
- if (chargeStartTimeStr.compareTo(allPolicyInfos.get(i).getStartTime()) >= 0) {
|
|
|
- startIndex = i;
|
|
|
- break;
|
|
|
+
|
|
|
+ if (Objects.equals(chargeOrderInfo.getOrderType(), SystemConstants.CHARGE_ORDER_TYPE_CHANNEL)) {
|
|
|
+ //订单信息渠道方推送
|
|
|
+ Map<String, Object> map = objectMapper.convertValue(jsonNode, Map.class);
|
|
|
+ map.put("chargeOrderNo", chargeOrderInfo.getChargeOrderNo());
|
|
|
+ FirmInfo firmInfo = firmInfoMapper.selectById(chargeOrderInfo.getFirmId());
|
|
|
+ if (ObjectUtil.isNotNull(firmInfo)) {
|
|
|
+ okHttpUtil.doPostForm(firmInfo.getChannelUrl() + "/notification_charge_order_info", map, null);
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
- if (startIndex == -1 && !allPolicyInfos.isEmpty()) {
|
|
|
- startIndex = allPolicyInfos.size() - 1;
|
|
|
- }
|
|
|
-
|
|
|
- // 找到充电结束时间所在的时段索引
|
|
|
- int endIndex = -1;
|
|
|
- for (int i = allPolicyInfos.size() - 1; i >= 0; i--) {
|
|
|
- if (chargeEndTimeStr.compareTo(allPolicyInfos.get(i).getStartTime()) >= 0) {
|
|
|
- endIndex = i;
|
|
|
- break;
|
|
|
+ //推送订单明细
|
|
|
+ chargeOrderInfo.setChargeDetails(jsonNode.toString());
|
|
|
+
|
|
|
+ //优惠单价
|
|
|
+ BigDecimal discountPrice = BigDecimal.ZERO;
|
|
|
+
|
|
|
+ if (Objects.equals(chargeOrderInfo.getOrderType(), SystemConstants.CHARGE_ORDER_TYPE_PLATFORM)) {
|
|
|
+ //判断当前订单是否为首单
|
|
|
+ Long userId = chargeOrderInfo.getUserId();
|
|
|
+ List<ChargeOrderInfo> list = chargeOrderInfoService.list(Wrappers.<ChargeOrderInfo>lambdaQuery().eq(ChargeOrderInfo::getUserId, userId).eq(ChargeOrderInfo::getStatus,
|
|
|
+ SystemConstants.STATUS_THREE));
|
|
|
+ if (ObjectUtil.isEmpty(list)) {
|
|
|
+ DiscountsActivity discountsActivity = discountsActivityMapper.selectOne(Wrappers.<DiscountsActivity>lambdaQuery()
|
|
|
+ .eq(DiscountsActivity::getType, SystemConstants.STATUS_ONE)
|
|
|
+ .eq(DiscountsActivity::getStatus, SystemConstants.STATUS_ONE)
|
|
|
+ .last("LIMIT 1"));
|
|
|
+ if (ObjectUtil.isNotEmpty(discountsActivity)) {
|
|
|
+ chargeOrderInfo.setDiscountInfoId(discountsActivity.getId());
|
|
|
+ chargeOrderInfo.setDiscountDesc(discountsActivity.getActivityDesc());
|
|
|
+ discountPrice = discountsActivity.getDiscount();
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
- if (endIndex == -1 && !allPolicyInfos.isEmpty()) {
|
|
|
- endIndex = allPolicyInfos.size() - 1;
|
|
|
- }
|
|
|
-
|
|
|
- // 获取充电时间跨越的所有时段集合
|
|
|
- List<ThirdPartyPolicyInfo> matchedPolicyInfos = new ArrayList<>();
|
|
|
- if (startIndex != -1 && endIndex != -1) {
|
|
|
- if (startIndex <= endIndex) {
|
|
|
- // 同一天内:从开始时段到结束时段
|
|
|
- for (int i = startIndex; i <= endIndex; i++) {
|
|
|
- matchedPolicyInfos.add(allPolicyInfos.get(i));
|
|
|
+
|
|
|
+ chargeOrderInfo.setStopReason(stopReason);
|
|
|
+ chargeOrderInfo.setStartTime(startTime);
|
|
|
+ chargeOrderInfo.setEndTime(endTime);
|
|
|
+ chargeOrderInfo.setTotalCharge(new BigDecimal(totalPower));
|
|
|
+
|
|
|
+ chargeOrderInfo.setThirdPartyTotalCost(new BigDecimal(totalMoney));
|
|
|
+ chargeOrderInfo.setThirdPartyServerfee(new BigDecimal(totalSeviceMoney));
|
|
|
+ chargeOrderInfo.setThirdPartyElecfee(new BigDecimal(totalElecMoney));
|
|
|
+
|
|
|
+ ThirdPartyConnectorInfo thirdPartyConnectorInfo = connectorInfoMapper.selectOne(Wrappers.<ThirdPartyConnectorInfo>lambdaQuery()
|
|
|
+ .eq(ThirdPartyConnectorInfo::getConnectorId, connectorID).last("LIMIT 1"));
|
|
|
+ String stationId = thirdPartyConnectorInfo.getStationId();
|
|
|
+ ThirdPartyStationInfo thirdPartyStationInfo = thirdPartyStationInfoMapper.selectOne(Wrappers.<ThirdPartyStationInfo>lambdaQuery()
|
|
|
+ .eq(ThirdPartyStationInfo::getStationId, stationId).last("LIMIT 1"));
|
|
|
+ if (ObjectUtil.isEmpty(thirdPartyConnectorInfo)) {
|
|
|
+ log.error("thirdPartyConnectorInfo" + "为空===============================================");
|
|
|
+ }
|
|
|
+
|
|
|
+ //平台服务费
|
|
|
+ BigDecimal serviceFee = BigDecimal.ZERO;
|
|
|
+ //优惠金额
|
|
|
+ BigDecimal discountFee = BigDecimal.ZERO;
|
|
|
+ JsonNode chargeDetails = jsonNode.get("ChargeDetails");
|
|
|
+ if (ObjectUtil.isNotEmpty(chargeDetails)) {
|
|
|
+ for (JsonNode node : chargeDetails) {
|
|
|
+ //提取字段值
|
|
|
+ String itemFlag = node.get("ItemFlag").asText();
|
|
|
+ node.get("DetailPower").asText();
|
|
|
+ BigDecimal detailPower = new BigDecimal(node.get("DetailPower").asText());
|
|
|
+ PolicyFee policyFee = policyFeeMapper.selectOne(Wrappers.<PolicyFee>lambdaQuery()
|
|
|
+ .eq(PolicyFee::getStationInfoId, thirdPartyStationInfo.getId())
|
|
|
+ .eq(PolicyFee::getPeriodFlag, Integer.parseInt(itemFlag))
|
|
|
+ .last("LIMIT 1"));
|
|
|
+ if (ObjectUtil.isNotEmpty(policyFee)) {
|
|
|
+ BigDecimal opFee = policyFee.getOpFee();
|
|
|
+ if (ObjectUtil.isNotEmpty(chargeOrderInfo.getDiscountInfoId())) {
|
|
|
+ opFee = opFee.subtract(discountPrice);
|
|
|
+ }
|
|
|
+ log.info("策略费用:{}", opFee);
|
|
|
+ serviceFee = serviceFee.add(opFee.multiply(detailPower));
|
|
|
+ discountFee = discountFee.add(discountPrice.multiply(detailPower));
|
|
|
+ }
|
|
|
}
|
|
|
} else {
|
|
|
- // 跨天情况:从开始时段到最后 + 从第一个到结束时段
|
|
|
- for (int i = startIndex; i < allPolicyInfos.size(); i++) {
|
|
|
- matchedPolicyInfos.add(allPolicyInfos.get(i));
|
|
|
- }
|
|
|
- for (int i = 0; i <= endIndex; i++) {
|
|
|
- matchedPolicyInfos.add(allPolicyInfos.get(i));
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- log.info("充电时间段:{} - {},匹配到{}个时段", chargeStartTimeStr, chargeEndTimeStr, matchedPolicyInfos.size());
|
|
|
-
|
|
|
- // 遍历所有匹配的时段,找到费用最高的时段计算服务费
|
|
|
- if (!matchedPolicyInfos.isEmpty()) {
|
|
|
- PolicyFee maxPolicyFee = null;
|
|
|
- ThirdPartyPolicyInfo maxPolicyInfo = null;
|
|
|
- for (ThirdPartyPolicyInfo policyInfo : matchedPolicyInfos) {
|
|
|
- PolicyFee policyFee = policyFeeMapper.selectOne(Wrappers.<PolicyFee>lambdaQuery()
|
|
|
- .eq(PolicyFee::getStationInfoId, thirdPartyStationInfo.getId())
|
|
|
- .eq(PolicyFee::getPeriodFlag, policyInfo.getPeriodFlag())
|
|
|
- .last("LIMIT 1"));
|
|
|
- if (ObjectUtil.isNotEmpty(policyFee)) {
|
|
|
- if (maxPolicyFee == null || policyFee.getOpFee().compareTo(maxPolicyFee.getOpFee()) > 0) {
|
|
|
- maxPolicyFee = policyFee;
|
|
|
- maxPolicyInfo = policyInfo;
|
|
|
+ log.error("充电订单明细为空===============================================");
|
|
|
+ if (chargeOrderInfo.getThirdPartyTotalCost().compareTo(BigDecimal.ZERO) > 0 && chargeOrderInfo.getTotalCharge().compareTo(BigDecimal.ZERO) > 0) {
|
|
|
+ //判断当前订单创建时间在哪个时段
|
|
|
+ ThirdPartyChargeStatus thirdPartyChargeStatus = chargeStatusMapper.selectOne(Wrappers.<ThirdPartyChargeStatus>lambdaQuery()
|
|
|
+ .eq(ThirdPartyChargeStatus::getStartChargeSeq, chargeOrderInfo.getStartChargeSeq()));
|
|
|
+
|
|
|
+ ThirdPartyEquipmentPricePolicy thirdPartyEquipmentPricePolicy = thirdPartyEquipmentPricePolicyMapper.selectOne(Wrappers.<ThirdPartyEquipmentPricePolicy>lambdaQuery()
|
|
|
+ .eq(ThirdPartyEquipmentPricePolicy::getConnectorId, thirdPartyChargeStatus.getConnectorId())
|
|
|
+ .last("LIMIT 1"));
|
|
|
+
|
|
|
+ // 查询该价格策略下的所有时段信息,按startTime升序排列
|
|
|
+ List<ThirdPartyPolicyInfo> allPolicyInfos = thirdPartyPolicyInfoMapper.selectList(Wrappers.<ThirdPartyPolicyInfo>lambdaQuery()
|
|
|
+ .eq(ThirdPartyPolicyInfo::getPricePolicyId, thirdPartyEquipmentPricePolicy.getId())
|
|
|
+ .orderByAsc(ThirdPartyPolicyInfo::getStartTime));
|
|
|
+
|
|
|
+ // 将充电开始时间和结束时间转换为HHmmss格式字符串进行匹配
|
|
|
+ LocalDateTime chargeStartTime = thirdPartyChargeStatus.getStartTime();
|
|
|
+ LocalDateTime chargeEndTime = thirdPartyChargeStatus.getEndTime();
|
|
|
+ String chargeStartTimeStr = chargeStartTime.format(DateTimeFormatter.ofPattern("HHmmss"));
|
|
|
+ String chargeEndTimeStr = chargeEndTime.format(DateTimeFormatter.ofPattern("HHmmss"));
|
|
|
+
|
|
|
+ // 找到充电开始时间所在的时段索引
|
|
|
+ int startIndex = -1;
|
|
|
+ for (int i = allPolicyInfos.size() - 1; i >= 0; i--) {
|
|
|
+ if (chargeStartTimeStr.compareTo(allPolicyInfos.get(i).getStartTime()) >= 0) {
|
|
|
+ startIndex = i;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (startIndex == -1 && !allPolicyInfos.isEmpty()) {
|
|
|
+ startIndex = allPolicyInfos.size() - 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 找到充电结束时间所在的时段索引
|
|
|
+ int endIndex = -1;
|
|
|
+ for (int i = allPolicyInfos.size() - 1; i >= 0; i--) {
|
|
|
+ if (chargeEndTimeStr.compareTo(allPolicyInfos.get(i).getStartTime()) >= 0) {
|
|
|
+ endIndex = i;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (endIndex == -1 && !allPolicyInfos.isEmpty()) {
|
|
|
+ endIndex = allPolicyInfos.size() - 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取充电时间跨越的所有时段集合
|
|
|
+ List<ThirdPartyPolicyInfo> matchedPolicyInfos = new ArrayList<>();
|
|
|
+ if (startIndex != -1 && endIndex != -1) {
|
|
|
+ if (startIndex <= endIndex) {
|
|
|
+ // 同一天内:从开始时段到结束时段
|
|
|
+ for (int i = startIndex; i <= endIndex; i++) {
|
|
|
+ matchedPolicyInfos.add(allPolicyInfos.get(i));
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 跨天情况:从开始时段到最后 + 从第一个到结束时段
|
|
|
+ for (int i = startIndex; i < allPolicyInfos.size(); i++) {
|
|
|
+ matchedPolicyInfos.add(allPolicyInfos.get(i));
|
|
|
+ }
|
|
|
+ for (int i = 0; i <= endIndex; i++) {
|
|
|
+ matchedPolicyInfos.add(allPolicyInfos.get(i));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("充电时间段:{} - {},匹配到{}个时段", chargeStartTimeStr, chargeEndTimeStr, matchedPolicyInfos.size());
|
|
|
+
|
|
|
+ // 遍历所有匹配的时段,找到费用最高的时段计算服务费
|
|
|
+ if (!matchedPolicyInfos.isEmpty()) {
|
|
|
+ PolicyFee maxPolicyFee = null;
|
|
|
+ ThirdPartyPolicyInfo maxPolicyInfo = null;
|
|
|
+ for (ThirdPartyPolicyInfo policyInfo : matchedPolicyInfos) {
|
|
|
+ PolicyFee policyFee = policyFeeMapper.selectOne(Wrappers.<PolicyFee>lambdaQuery()
|
|
|
+ .eq(PolicyFee::getStationInfoId, thirdPartyStationInfo.getId())
|
|
|
+ .eq(PolicyFee::getPeriodFlag, policyInfo.getPeriodFlag())
|
|
|
+ .last("LIMIT 1"));
|
|
|
+ if (ObjectUtil.isNotEmpty(policyFee)) {
|
|
|
+ if (maxPolicyFee == null || policyFee.getOpFee().compareTo(maxPolicyFee.getOpFee()) > 0) {
|
|
|
+ maxPolicyFee = policyFee;
|
|
|
+ maxPolicyInfo = policyInfo;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (maxPolicyFee != null) {
|
|
|
+ log.info("使用最高费用时段:startTime={}, periodFlag={}, opFee={}",
|
|
|
+ maxPolicyInfo.getStartTime(), maxPolicyInfo.getPeriodFlag(), maxPolicyFee.getOpFee());
|
|
|
+ serviceFee = serviceFee.add(maxPolicyFee.getOpFee().multiply(chargeOrderInfo.getTotalCharge()));
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- if (maxPolicyFee != null) {
|
|
|
- log.info("使用最高费用时段:startTime={}, periodFlag={}, opFee={}",
|
|
|
- maxPolicyInfo.getStartTime(), maxPolicyInfo.getPeriodFlag(), maxPolicyFee.getOpFee());
|
|
|
- serviceFee = serviceFee.add(maxPolicyFee.getOpFee().multiply(chargeOrderInfo.getTotalCharge()));
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
- log.info("计算后的平台服务费:{}", serviceFee);
|
|
|
- if (chargeOrderInfo.getOrderType().equals(SystemConstants.CHARGE_ORDER_TYPE_PLATFORM)) {
|
|
|
- chargeOrderInfo.setDiscountMoney(discountFee);
|
|
|
- chargeOrderInfo.setRealServiceCost(serviceFee.setScale(2, RoundingMode.HALF_UP));
|
|
|
- //订单结算:平台实际收取金额 = 互联互通金额 + 中数电动金额(平台总服务费)
|
|
|
- chargeOrderInfo.setRealCost(chargeOrderInfo.getRealServiceCost().add(chargeOrderInfo.getThirdPartyTotalCost()));
|
|
|
+ log.info("计算后的平台服务费:{}", serviceFee);
|
|
|
+ if (chargeOrderInfo.getOrderType().equals(SystemConstants.CHARGE_ORDER_TYPE_PLATFORM)) {
|
|
|
+ chargeOrderInfo.setDiscountMoney(discountFee);
|
|
|
+ chargeOrderInfo.setRealServiceCost(serviceFee.setScale(2, RoundingMode.HALF_UP));
|
|
|
+ //订单结算:平台实际收取金额 = 互联互通金额 + 中数电动金额(平台总服务费)
|
|
|
+ chargeOrderInfo.setRealCost(chargeOrderInfo.getRealServiceCost().add(chargeOrderInfo.getThirdPartyTotalCost()));
|
|
|
|
|
|
- //订单状态->已完成
|
|
|
- chargeOrderInfo.setStatus(SystemConstants.STATUS_THREE);
|
|
|
+ //订单状态->已完成
|
|
|
+ chargeOrderInfo.setStatus(SystemConstants.STATUS_THREE);
|
|
|
|
|
|
- //计算充电时间
|
|
|
- chargeOrderInfo.setChargeTime(DateUtils.getDuration(chargeOrderInfo.getStartTime(), chargeOrderInfo.getEndTime()));
|
|
|
+ //计算充电时间
|
|
|
+ chargeOrderInfo.setChargeTime(DateUtils.getDuration(chargeOrderInfo.getStartTime(), chargeOrderInfo.getEndTime()));
|
|
|
|
|
|
- //修改订单
|
|
|
- chargeOrderInfoService.updateById(chargeOrderInfo);
|
|
|
+ //修改订单
|
|
|
+ chargeOrderInfoService.updateById(chargeOrderInfo);
|
|
|
|
|
|
- //账户余额扣减(积分增加)
|
|
|
- log.info("执行账户余额扣减(积分增加)");
|
|
|
- chargeOrderInfoService.orderSettlement(chargeOrderInfo.getId());
|
|
|
- }
|
|
|
- if (chargeOrderInfo.getOrderType().equals(SystemConstants.CHARGE_ORDER_TYPE_CHANNEL)) {
|
|
|
- chargeOrderInfo.setRealServiceCost(BigDecimal.ZERO);
|
|
|
- //订单结算:平台实际收取金额 = 互联互通金额 + 中数电动金额(平台总服务费)
|
|
|
- chargeOrderInfo.setRealCost(chargeOrderInfo.getRealServiceCost().add(chargeOrderInfo.getThirdPartyTotalCost()));
|
|
|
- //订单状态->已完成
|
|
|
- chargeOrderInfo.setStatus(SystemConstants.STATUS_THREE);
|
|
|
- //计算充电时间
|
|
|
- chargeOrderInfo.setChargeTime(DateUtils.getDuration(chargeOrderInfo.getStartTime(), chargeOrderInfo.getEndTime()));
|
|
|
- //修改订单
|
|
|
- chargeOrderInfoService.updateById(chargeOrderInfo);
|
|
|
- //渠道方账户余额扣减
|
|
|
- BigDecimal cost = chargeOrderInfo.getRealCost();
|
|
|
- FirmInfo firmInfo = firmInfoMapper.selectById(chargeOrderInfo.getFirmId());
|
|
|
- FirmAccountLog accountLog = new FirmAccountLog();
|
|
|
- accountLog.setFirmId(firmInfo.getId());
|
|
|
- accountLog.setFirmType(firmInfo.getFirmType());
|
|
|
- accountLog.setEventDesc("渠道方充电订单下账");
|
|
|
- accountLog.setSerialNo(chargeOrderInfo.getChargeOrderNo());
|
|
|
- accountLog.setIncomeType(2);
|
|
|
- accountLog.setBeforeChange(firmInfo.getBalance());
|
|
|
- accountLog.setAfterChange(firmInfo.getBalance().subtract(cost));
|
|
|
- accountLog.setMoneyChange(cost);
|
|
|
- firmAccountLogMapper.insert(accountLog);
|
|
|
-
|
|
|
- // 渠道方账户余额修改
|
|
|
- firmInfo.setBalance(firmInfo.getBalance().subtract(cost));
|
|
|
- firmInfoMapper.updateById(firmInfo);
|
|
|
+ //账户余额扣减(积分增加)
|
|
|
+ log.info("执行账户余额扣减(积分增加)");
|
|
|
+ chargeOrderInfoService.orderSettlement(chargeOrderInfo.getId());
|
|
|
+ }
|
|
|
+ if (chargeOrderInfo.getOrderType().equals(SystemConstants.CHARGE_ORDER_TYPE_CHANNEL)) {
|
|
|
+ chargeOrderInfo.setRealServiceCost(BigDecimal.ZERO);
|
|
|
+ //订单结算:平台实际收取金额 = 互联互通金额 + 中数电动金额(平台总服务费)
|
|
|
+ chargeOrderInfo.setRealCost(chargeOrderInfo.getRealServiceCost().add(chargeOrderInfo.getThirdPartyTotalCost()));
|
|
|
+ //订单状态->已完成
|
|
|
+ chargeOrderInfo.setStatus(SystemConstants.STATUS_THREE);
|
|
|
+ //计算充电时间
|
|
|
+ chargeOrderInfo.setChargeTime(DateUtils.getDuration(chargeOrderInfo.getStartTime(), chargeOrderInfo.getEndTime()));
|
|
|
+ //修改订单
|
|
|
+ chargeOrderInfoService.updateById(chargeOrderInfo);
|
|
|
+ //渠道方账户余额扣减
|
|
|
+ BigDecimal cost = chargeOrderInfo.getRealCost();
|
|
|
+ FirmInfo firmInfo = firmInfoMapper.selectById(chargeOrderInfo.getFirmId());
|
|
|
+ FirmAccountLog accountLog = new FirmAccountLog();
|
|
|
+ accountLog.setFirmId(firmInfo.getId());
|
|
|
+ accountLog.setFirmType(firmInfo.getFirmType());
|
|
|
+ accountLog.setEventDesc("渠道方充电订单下账");
|
|
|
+ accountLog.setSerialNo(chargeOrderInfo.getChargeOrderNo());
|
|
|
+ accountLog.setIncomeType(2);
|
|
|
+ accountLog.setBeforeChange(firmInfo.getBalance());
|
|
|
+ accountLog.setAfterChange(firmInfo.getBalance().subtract(cost));
|
|
|
+ accountLog.setMoneyChange(cost);
|
|
|
+ firmAccountLogMapper.insert(accountLog);
|
|
|
+
|
|
|
+ // 渠道方账户余额修改
|
|
|
+ firmInfo.setBalance(firmInfo.getBalance().subtract(cost));
|
|
|
+ firmInfoMapper.updateById(firmInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 执行业务处理
|
|
|
+ businessHandler.accept(jsonNode);
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ lock.unlock();
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ log.warn("获取订单锁失败 - StartChargeSeq: {}", finalStartChargeSeq);
|
|
|
}
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ Thread.currentThread().interrupt();
|
|
|
+ log.error("获取订单锁被中断 - StartChargeSeq: {}", finalStartChargeSeq);
|
|
|
}
|
|
|
|
|
|
- // 执行业务处理
|
|
|
- businessHandler.accept(jsonNode);
|
|
|
-
|
|
|
// 构建响应
|
|
|
- return buildChargeResponse(getTextValue(jsonNode, "StartChargeSeq"));
|
|
|
+ return buildChargeResponse(startChargeSeq);
|
|
|
} catch (BusinessException e) {
|
|
|
throw e;
|
|
|
} catch (Exception e) {
|
|
|
@@ -447,16 +474,22 @@ public class ChargingReceptionServiceImpl implements ChargingReceptionService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 充电订单分布式锁前缀
|
|
|
+ */
|
|
|
+ private static final String CHARGE_ORDER_LOCK_KEY = "charging:order:lock:";
|
|
|
+
|
|
|
/**
|
|
|
* 处理停止充电结果推送请求
|
|
|
* 数据格式:{"ConnectorID":"xxx","FailReason":0,"StartChargeSeq":"xxx","StartChargeSeqStat":4,"SuccStat":0}
|
|
|
*/
|
|
|
private ResponseParmsEntity processStopChargeResultRequest(RequestParmsEntity requestDTO) {
|
|
|
+ String startChargeSeq = null;
|
|
|
try {
|
|
|
JsonNode jsonNode = verifyAndDecrypt(requestDTO);
|
|
|
|
|
|
// 停止充电结果业务处理
|
|
|
- String startChargeSeq = getTextValue(jsonNode, "StartChargeSeq");
|
|
|
+ startChargeSeq = getTextValue(jsonNode, "StartChargeSeq");
|
|
|
Integer startChargeSeqStat = getIntValue(jsonNode, "StartChargeSeqStat");
|
|
|
Integer succStat = getIntValue(jsonNode, "SuccStat");
|
|
|
Integer failReason = getIntValue(jsonNode, "FailReason");
|
|
|
@@ -464,33 +497,53 @@ public class ChargingReceptionServiceImpl implements ChargingReceptionService {
|
|
|
log.info("停止充电结果 - StartChargeSeq: {}, Stat: {}, SuccStat: {}, FailReason: {}",
|
|
|
startChargeSeq, startChargeSeqStat, succStat, failReason);
|
|
|
|
|
|
- ChargeOrderInfo chargeOrderInfo = chargeOrderInfoService.getOne(new LambdaQueryWrapper<ChargeOrderInfo>()
|
|
|
- .eq(ChargeOrderInfo::getStartChargeSeq, startChargeSeq).last("LIMIT 1"));
|
|
|
-
|
|
|
- if (startChargeSeqStat != null && ObjectUtil.isNotEmpty(chargeOrderInfo)) {
|
|
|
+ if (startChargeSeqStat != null && startChargeSeqStat == 4) {
|
|
|
+ // 使用分布式锁防止并发操作
|
|
|
+ String lockKey = CHARGE_ORDER_LOCK_KEY + startChargeSeq;
|
|
|
+ RLock lock = redissonClient.getLock(lockKey);
|
|
|
+ try {
|
|
|
+ if (lock.tryLock(LOCK_WAIT_TIME, LOCK_LEASE_TIME, java.util.concurrent.TimeUnit.SECONDS)) {
|
|
|
+ try {
|
|
|
+ // 加锁后重新查询订单状态,确保状态最新
|
|
|
+ ChargeOrderInfo chargeOrderInfo = chargeOrderInfoService.getOne(new LambdaQueryWrapper<ChargeOrderInfo>()
|
|
|
+ .eq(ChargeOrderInfo::getStartChargeSeq, startChargeSeq).last("LIMIT 1"));
|
|
|
+
|
|
|
+ if (ObjectUtil.isNotEmpty(chargeOrderInfo)) {
|
|
|
+ log.info("已结束 - StartChargeSeq: {}, 当前订单状态: {}", startChargeSeq, chargeOrderInfo.getStatus());
|
|
|
+ // 仅当状态为0(待充电)或1(充电中)时才更新为结算中,已完成(3)的订单不再处理
|
|
|
+ if (Objects.equals(chargeOrderInfo.getStatus(), 0) ||
|
|
|
+ Objects.equals(chargeOrderInfo.getStatus(), 1)) {
|
|
|
+ chargeOrderInfo.setStatus(SystemConstants.STATUS_TWO);
|
|
|
+ chargeOrderInfoService.updateById(chargeOrderInfo);
|
|
|
+ log.info("更新订单状态为结算中 - orderId: {}", chargeOrderInfo.getId());
|
|
|
+
|
|
|
+ // 推送停止充电订单结果
|
|
|
+ FirmInfo firmInfo = firmInfoMapper.selectById(chargeOrderInfo.getFirmId());
|
|
|
+ if (ObjectUtil.isNotNull(firmInfo)) {
|
|
|
+ HashMap<String, Object> map = new HashMap<>();
|
|
|
+ map.put("chargeOrderNo", chargeOrderInfo.getChargeOrderNo());
|
|
|
+ map.put("status", SystemConstants.STATUS_TWO);
|
|
|
+ okHttpUtil.doPostForm(firmInfo.getChannelUrl() + "/notification_stop_charge_result", map, null);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ log.info("订单状态已更新,跳过处理 - orderId: {}, status: {}", chargeOrderInfo.getId(), chargeOrderInfo.getStatus());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ lock.unlock();
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ log.warn("获取订单锁失败 - StartChargeSeq: {}", startChargeSeq);
|
|
|
+ }
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ Thread.currentThread().interrupt();
|
|
|
+ log.error("获取订单锁被中断 - StartChargeSeq: {}", startChargeSeq);
|
|
|
+ }
|
|
|
+ } else if (startChargeSeqStat != null) {
|
|
|
switch (startChargeSeqStat) {
|
|
|
case 1 -> log.info("启动中 - StartChargeSeq: {}", startChargeSeq);
|
|
|
case 2 -> log.info("充电中 - StartChargeSeq: {}", startChargeSeq);
|
|
|
case 3 -> log.info("停止中 - StartChargeSeq: {}", startChargeSeq);
|
|
|
- case 4 -> {
|
|
|
- log.info("已结束 - StartChargeSeq: {}", startChargeSeq);
|
|
|
- // 修改订单状态为结算中
|
|
|
- if (Objects.equals(chargeOrderInfo.getStatus(), 0) ||
|
|
|
- Objects.equals(chargeOrderInfo.getStatus(), 1)) {
|
|
|
- chargeOrderInfo.setStatus(SystemConstants.STATUS_TWO);
|
|
|
- chargeOrderInfoService.updateById(chargeOrderInfo);
|
|
|
- log.info("更新订单状态为结算中 - orderId: {}", chargeOrderInfo.getId());
|
|
|
-
|
|
|
- // 推送停止充电订单结果
|
|
|
- FirmInfo firmInfo = firmInfoMapper.selectById(chargeOrderInfo.getFirmId());
|
|
|
- if (ObjectUtil.isNotNull(firmInfo)) {
|
|
|
- HashMap<String, Object> map = new HashMap<>();
|
|
|
- map.put("chargeOrderNo", chargeOrderInfo.getChargeOrderNo());
|
|
|
- map.put("status", SystemConstants.STATUS_TWO);
|
|
|
- okHttpUtil.doPostForm(firmInfo.getChannelUrl() + "/notification_stop_charge_result", map, null);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
case 5 -> log.info("未知 - StartChargeSeq: {}", startChargeSeq);
|
|
|
default -> log.warn("未知状态 - StartChargeSeq: {}, Stat: {}", startChargeSeq, startChargeSeqStat);
|
|
|
}
|
|
|
@@ -742,7 +795,7 @@ public class ChargingReceptionServiceImpl implements ChargingReceptionService {
|
|
|
pushChargeStatusTask(startChargeSeq, chargeStatus);
|
|
|
|
|
|
// 熔断保护 - 余额不足判断
|
|
|
- isNeedBreak(chargeStatus, chargeOrderInfo);
|
|
|
+// isNeedBreak(chargeStatus, chargeOrderInfo);
|
|
|
} catch (Exception e) {
|
|
|
log.error("保存充电状态数据失败", e);
|
|
|
}
|