From 03adfbce477422cd24c715a6f9c5589b0cf014f2 Mon Sep 17 00:00:00 2001
From: liujie <1793218484@qq.com>
Date: 星期一, 25 五月 2026 15:35:33 +0800
Subject: [PATCH] Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/java/mx_charging_pile
---
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java | 659 ++++++++++++++++++++++++++++++++++++++++
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/utils/WxV3Pay.java | 13
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/feignClient/WxPaymentClient.java | 8
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/controller/AliPayController.java | 11
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/WxPaymentFallbackFactory.java | 5
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/task/TaskUtil.java | 23 +
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/AliPaymentFallbackFactory.java | 7
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/model/QueryRefundResp.java | 9
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/TChargingOrderService.java | 13
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/UpdateOrderPaymentAmountDto.java | 14
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/controller/WxPayController.java | 22 +
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/utils/WxAbstractPay.java | 72 ++++
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/feignClient/AliPaymentClient.java | 11
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java | 65 +++
14 files changed, 903 insertions(+), 29 deletions(-)
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/AliPaymentFallbackFactory.java b/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/AliPaymentFallbackFactory.java
index 58d0545..f1b3d22 100644
--- a/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/AliPaymentFallbackFactory.java
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/AliPaymentFallbackFactory.java
@@ -2,6 +2,8 @@
import com.ruoyi.common.core.domain.R;
import com.ruoyi.payment.api.feignClient.AliPaymentClient;
+import com.ruoyi.payment.api.model.QueryRefundReq;
+import com.ruoyi.payment.api.model.QueryRefundResp;
import com.ruoyi.payment.api.model.RefundReq;
import com.ruoyi.payment.api.model.RefundResp;
import com.ruoyi.payment.api.vo.AliPaymentReq;
@@ -47,6 +49,11 @@
public R<RefundResp> refund(RefundReq dto) {
return R.fail("支付宝退款失败:" + throwable.getMessage());
}
+
+ @Override
+ public R<QueryRefundResp> queryRefund(QueryRefundReq dto) {
+ return R.fail("支付宝退款查询失败:" + throwable.getMessage());
+ }
};
}
}
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/WxPaymentFallbackFactory.java b/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/WxPaymentFallbackFactory.java
index 82666b1..6c5da82 100644
--- a/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/WxPaymentFallbackFactory.java
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/WxPaymentFallbackFactory.java
@@ -48,6 +48,11 @@
public R<Map<String, Object>> refundOrderR(WxPaymentRefundModel model) {
return R.fail("微信退款失败:" + throwable.getMessage());
}
+
+ @Override
+ public R<Map<String, Object>> queryRefund(String refund_out_trade_no) {
+ return R.fail("查询退款失败:" + throwable.getMessage());
+ }
};
}
}
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/feignClient/AliPaymentClient.java b/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/feignClient/AliPaymentClient.java
index 357bdc9..fc22b2f 100644
--- a/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/feignClient/AliPaymentClient.java
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/feignClient/AliPaymentClient.java
@@ -3,6 +3,8 @@
import com.ruoyi.common.core.constant.ServiceNameConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.payment.api.factory.WxPaymentFallbackFactory;
+import com.ruoyi.payment.api.model.QueryRefundReq;
+import com.ruoyi.payment.api.model.QueryRefundResp;
import com.ruoyi.payment.api.model.RefundReq;
import com.ruoyi.payment.api.model.RefundResp;
import com.ruoyi.payment.api.vo.AliPaymentReq;
@@ -49,4 +51,13 @@
*/
@PostMapping("/ali/refund")
public R<RefundResp> refund(@RequestBody RefundReq dto);
+
+
+ /**
+ * 退款查询
+ * @param dto
+ * @return
+ */
+ @PostMapping("/ali/queryRefund")
+ R<QueryRefundResp> queryRefund(@RequestBody QueryRefundReq dto);
}
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/feignClient/WxPaymentClient.java b/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/feignClient/WxPaymentClient.java
index dfa9730..a4ff44a 100644
--- a/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/feignClient/WxPaymentClient.java
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/feignClient/WxPaymentClient.java
@@ -52,4 +52,12 @@
@ApiOperation("订单退款")
@PostMapping(value = "/wx/refundOrderR")
R<Map<String, Object>> refundOrderR(@RequestBody WxPaymentRefundModel model);
+
+
+ /**
+ * 订单退款查询
+ * @return
+ */
+ @PostMapping(value = "/wx/queryRefund")
+ R<Map<String, Object>> queryRefund(@RequestParam("refund_out_trade_no") String refund_out_trade_no);
}
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/model/QueryRefundResp.java b/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/model/QueryRefundResp.java
index 5293c35..b045bb6 100644
--- a/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/model/QueryRefundResp.java
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/model/QueryRefundResp.java
@@ -1,7 +1,10 @@
package com.ruoyi.payment.api.model;
+import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonSetter;
import lombok.Data;
+
+import java.time.LocalDateTime;
/**
* @author zhibing.pu
@@ -34,6 +37,12 @@
*/
@JsonSetter("refund_amount")
private Double refundAmount;
+ /**
+ * 本次退款金额
+ */
+ @JsonSetter("gmt_refund_pay")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private String refundTime;
/**
* 退款状态
* REFUND_SUCCESS 退款处理成功; 未返回该字段表示退款请求未收到或者退款失败; 注:如果退款查询发起时间早于退款时间,或者间隔退款发起时间太短,可能出现退款查询时还没处理成功,后面又处理成功的情况,建议商户在退款发起后间隔10秒以上再发起退款查询请求。
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java
index a7dfe70..d7fc008 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java
@@ -1,6 +1,6 @@
package com.ruoyi.order.controller;
import com.alibaba.fastjson2.JSON;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import java.math.BigDecimal;
@@ -24,7 +24,6 @@
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.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.log.enums.OperatorType;
@@ -34,12 +33,6 @@
import com.ruoyi.common.security.service.TokenService;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.page.PageInfo;
-import com.ruoyi.integration.api.model.PageChargingOrderAndUploadRealTimeMonitoringDataDto;
-import com.ruoyi.integration.api.model.UploadRealTimeMonitoringData;
-import com.ruoyi.common.security.utils.SecurityUtils;
-import com.ruoyi.integration.api.feignClient.UploadRealTimeMonitoringDataClient;
-import com.ruoyi.integration.api.model.ChargingOrderAndUploadRealTimeMonitoringDataDto;
-import com.ruoyi.integration.api.model.UploadRealTimeMonitoringPageData;
import com.ruoyi.order.api.dto.ChargingStatisticeDTO;
import com.ruoyi.order.api.model.*;
import com.ruoyi.order.api.query.ChargingOrderQuery;
@@ -61,12 +54,12 @@
import com.ruoyi.order.util.mongodb.service.UploadRealTimeMonitoringDataService;
import com.ruoyi.order.vo.EndOfChargePageInfo;
import com.ruoyi.order.vo.StatisticsOfBatteryVO;
+import com.ruoyi.order.vo.UpdateOrderPaymentAmountDto;
import com.ruoyi.order.vo.WatchChargingOrderVo;
import com.ruoyi.other.api.feignClient.RoleSiteClient;
import com.ruoyi.other.api.feignClient.UserSiteClient;
import com.ruoyi.payment.api.feignClient.AliPaymentClient;
import com.ruoyi.payment.api.feignClient.WxPaymentClient;
-import com.ruoyi.payment.api.vo.AliQueryOrder;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.feignClient.SysUserClient;
import com.ruoyi.system.api.feignClient.SysUserRoleClient;
@@ -79,11 +72,7 @@
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
-import javax.servlet.http.HttpServletResponse;
-import java.io.PrintWriter;
import java.time.format.DateTimeFormatter;
-import java.time.temporal.ChronoUnit;
-import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;
@@ -2370,5 +2359,55 @@
}
+ /**
+ * 手动查询订单和退款数据,完善退款记录
+ * @param orderId
+ * @param refund_out_trade_no
+ * @return
+ */
+ @PostMapping("/orderQueryRefund")
+ public R<?> orderQueryRefund(@RequestParam("orderId") Long orderId, @RequestParam("refund_out_trade_no") String refund_out_trade_no){
+ chargingOrderService.orderQueryRefund(orderId, refund_out_trade_no);
+ return R.ok();
+ }
+ /**
+ * 手动查询订单和退款数据,批量完善退款记录
+ * @return
+ */
+ @PostMapping("/orderQueryRefundList")
+ public R<?> orderQueryRefundList(@RequestBody List<String> dto){
+ for (String s : dto) {
+ String[] split = s.split(",");
+ chargingOrderService.orderQueryRefund(Long.valueOf(split[0]), split[1]);
+ }
+ return R.ok();
+ }
+
+
+ /**
+ * 手动添加完善订单费用明细
+ * @param orderId
+ * @return
+ */
+ @PostMapping("/addOrderExpenseBreakdown")
+ public R<?> addOrderExpenseBreakdown(@RequestParam("orderId") Long orderId){
+ chargingOrderService.addOrderExpenseBreakdown(orderId);
+ return R.ok();
+ }
+
+
+ /**
+ * 手动批量修改订单支付金额
+ * @param dtos
+ * @return
+ */
+ @PostMapping("/updateOrderPaymentAmount")
+ public R<?> updateOrderPaymentAmount(@RequestBody List<UpdateOrderPaymentAmountDto> dtos){
+ for (UpdateOrderPaymentAmountDto dto : dtos) {
+ chargingOrderService.update(new UpdateWrapper<TChargingOrder>().eq("id", dto.getOrderId())
+ .set("payment_amount", dto.getPaymentAmount()));
+ }
+ return R.ok();
+ }
}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/TChargingOrderService.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/TChargingOrderService.java
index b295a82..b80ced4 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/TChargingOrderService.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/TChargingOrderService.java
@@ -395,4 +395,17 @@
* @return
*/
List<Map<String, Object>> getAccountSettlementStatement(String startTime, String endTime, Integer rechargePaymentType);
+
+ /**
+ * 手动处理退款数据
+ * @param refund_out_trade_no 退款商户单号
+ */
+ void orderQueryRefund(Long orderId, String refund_out_trade_no);
+
+
+ /**
+ * 手动添加完善订单费用明细
+ * @param orderId
+ */
+ void addOrderExpenseBreakdown(Long orderId);
}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
index 328bc82..c068a4a 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
@@ -19,6 +19,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.exception.ServiceException;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.domain.BasePojo;
import com.ruoyi.common.core.web.page.PageInfo;
@@ -70,9 +71,7 @@
import com.ruoyi.payment.api.feignClient.AliPaymentClient;
import com.ruoyi.payment.api.feignClient.H5AliPaymentClient;
import com.ruoyi.payment.api.feignClient.WxPaymentClient;
-import com.ruoyi.payment.api.model.RefundReq;
-import com.ruoyi.payment.api.model.RefundResp;
-import com.ruoyi.payment.api.model.WxPaymentRefundModel;
+import com.ruoyi.payment.api.model.*;
import com.ruoyi.payment.api.vo.*;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.feignClient.SysUserClient;
@@ -119,7 +118,7 @@
private static final int WHITELIST_BENEFIT_ALL_FREE = 1;
private static final int WHITELIST_BENEFIT_ELECTRIC_FREE = 2;
private static final int WHITELIST_BENEFIT_SERVICE_FREE = 3;
-
+
@Resource
private ChargingGunClient chargingGunClient;
@Resource
@@ -155,7 +154,7 @@
private AppCouponClient appCouponClient;
@Resource
private AppUserWhitelistClient appUserWhitelistClient;
-
+
@Resource
private AppUserVipDetailClient appUserVipDetailClient;
@@ -211,7 +210,7 @@
private VipClient vipClient;
@Resource
private OtherClient otherClient;
-
+
@Resource
private UserTagClient userTagClient;
@@ -427,7 +426,7 @@
* @param addChargingOrder
* @return
*/
-
+
/**
* 判断订单是否使用余额或余额组合支付
*
@@ -2031,7 +2030,7 @@
item.setBalanceGiftIncome(getSummaryDecimal(row, "balanceGiftIncome"));
}
}
-
+
private void setChargingOrderAuthSiteIds(ChargingOrderQuery dto, SysUser sysUser, Long userId, Integer roleType) {
List<Integer> siteIds = new ArrayList<>();
if (dto.getSiteId() == null) {
@@ -2359,7 +2358,7 @@
private BigDecimal nonNegative(BigDecimal value) {
return value.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : value;
}
-
+
@Override
public List<Map<String, Object>> getSumByType(LocalDate start, LocalDate end, List<Integer> siteIds) {
LocalDateTime start1 = start.atStartOfDay();
@@ -2798,7 +2797,7 @@
item.setBalanceGiftIncome(getSummaryDecimal(row, "balanceGiftIncome"));
}
}
-
+
@Override
public ChargingOrderListInfoVO chargingInfo(String uid) {
@@ -2992,6 +2991,12 @@
RLock lock = redissonClient.getLock("endOrder:" + vo.getTransaction_serial_number());
try {
boolean tryLock = lock.tryLock(60, 60, TimeUnit.SECONDS);
+ //添加redis缓存数据,过期时间,用于防止处理缓慢且硬件重复发送报文导致的重复退款
+ Boolean hasKey = redisService.hasKey("END_ORDER:" + vo.getTransaction_serial_number());
+ if(hasKey){
+ return R.fail("不能重复退款");
+ }
+ redisService.setCacheObject("END_ORDER:" + vo.getTransaction_serial_number(), System.currentTimeMillis() + "", 10L, TimeUnit.MINUTES);
if(tryLock){
TChargingOrder chargingOrder = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, vo.getTransaction_serial_number()));
if (null == chargingOrder) {
@@ -3758,7 +3763,7 @@
}
chargingOrderRefund.setBalanceRefundAmount(balanceRefundAmount);
chargingOrderRefund.setThirdRefundAmount(thirdRefundAmount);
-
+
if (thirdRefundAmount.compareTo(BigDecimal.ZERO) == 0) {
chargingOrderRefund.setRefundSerialNumber("BALANCE");
finishManualChargingRefund(tChargingOrder, chargingOrderRefund, manualRefundAmount, balanceRefundAmount, thirdRefundAmount);
@@ -3848,7 +3853,7 @@
shoppingOrderRefund.setRefundRemark(payOrderQueryDto.getRemark());
shoppingOrderRefund.setRefundTotalAmount(shoppingOrder.getRefundAmount().add(payOrderQueryDto.getRefundAmount()));
shoppingOrderRefund.setPayAmount(shoppingOrder.getPaymentAmount());
-
+
if (1 == shoppingOrder.getPaymentType()) {
WxPaymentRefundModel model = new WxPaymentRefundModel();
model.setOut_trade_no(shoppingOrder.getCode());
@@ -5269,4 +5274,634 @@
public List<Map<String, Object>> getAccountSettlementStatement(String startTime, String endTime, Integer rechargePaymentType) {
return this.baseMapper.getAccountSettlementStatement(startTime, endTime, rechargePaymentType);
}
+
+
+ /**
+ * 手动处理退款数据
+ * @param refund_out_trade_no 退款商户单号
+ */
+ @Override
+ public void orderQueryRefund(Long orderId, String refund_out_trade_no) {
+ TChargingOrder chargingOrder = this.getById(orderId);
+ BigDecimal rechargeAmount = chargingOrder.getRechargeAmount();
+ List<TChargingOrderRefund> orderRefunds = chargingOrderRefundService.list(new QueryWrapper<TChargingOrderRefund>().eq("charging_order_id", orderId));
+ List<String> collect = orderRefunds.stream().map(TChargingOrderRefund::getRefundCode).collect(Collectors.toList());
+ if(!collect.contains(refund_out_trade_no)){
+ if(1 == chargingOrder.getRechargePaymentType()){
+ Map<String, Object> data = wxPaymentClient.queryRefund(refund_out_trade_no).getData();
+ if(null == data){
+ throw new ServiceException("退款查询失败");
+ }
+ log.info("退款查询结果:{}", JSON.toJSONString(data));
+ Map<String, Object> amount = (Map<String, Object>)data.get("amount");
+ TChargingOrderRefund chargingOrderRefund = new TChargingOrderRefund();
+ chargingOrderRefund.setChargingOrderId(chargingOrder.getId());
+ chargingOrderRefund.setRefundCode(refund_out_trade_no);
+ chargingOrderRefund.setRefundAmount(new BigDecimal(amount.get("refund").toString()).divide(new BigDecimal(100)));
+ chargingOrderRefund.setRefundStatus(2);
+ chargingOrderRefund.setPayType(1);
+ chargingOrderRefund.setRefundSerialNumber(data.get("refund_id").toString());
+ String success_time = data.get("success_time").toString();
+ success_time = success_time.replace("T", " ");
+ success_time = success_time.substring(0, success_time.lastIndexOf("+"));
+ chargingOrderRefund.setRefundTime(LocalDateTime.parse(success_time, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+ chargingOrderRefund.setCode(chargingOrder.getCode());
+ chargingOrderRefund.setRefundTitle(rechargeAmount.compareTo(chargingOrderRefund.getRefundAmount()) == 0 ? "充电失败" : "充电完成退款");
+ chargingOrderRefund.setRefundContent(rechargeAmount.compareTo(chargingOrderRefund.getRefundAmount()) == 0 ? "充电失败" : "充电完成退款");
+ chargingOrderRefund.setRefundReason(rechargeAmount.compareTo(chargingOrderRefund.getRefundAmount()) == 0 ? "充电失败" : "充电完成退款");
+ chargingOrderRefund.setRefundRemark(rechargeAmount.compareTo(chargingOrderRefund.getRefundAmount()) == 0 ? "充电失败" : "充电完成退款");
+ chargingOrderRefund.setRefundTotalAmount(new BigDecimal(amount.get("refund").toString()).divide(new BigDecimal(100)));
+ chargingOrderRefund.setPayAmount(rechargeAmount);
+ chargingOrderRefund.setCreateTime(chargingOrderRefund.getRefundTime());
+ chargingOrderRefundService.save(chargingOrderRefund);
+ if(rechargeAmount.compareTo(chargingOrderRefund.getRefundAmount()) == 0){
+ chargingOrder.setStatus(-1);
+ }else{
+ chargingOrder.setStatus(5);
+ }
+ this.updateById(chargingOrder);
+ }
+ if(2 == chargingOrder.getRechargePaymentType()){
+ QueryRefundReq dto = new QueryRefundReq();
+ dto.setOutTradeNo(refund_out_trade_no);
+ QueryRefundResp data = aliPaymentClient.queryRefund(dto).getData();
+ if(null == data){
+ throw new ServiceException("退款查询失败");
+ }
+ TChargingOrderRefund chargingOrderRefund = new TChargingOrderRefund();
+ chargingOrderRefund.setChargingOrderId(chargingOrder.getId());
+ chargingOrderRefund.setRefundCode(refund_out_trade_no);
+ chargingOrderRefund.setRefundAmount(new BigDecimal(data.getRefundAmount()));
+ chargingOrderRefund.setRefundStatus(2);
+ chargingOrderRefund.setPayType(1);
+ chargingOrderRefund.setRefundSerialNumber(data.getOutRequestNo());
+ chargingOrderRefund.setRefundTime(LocalDateTime.parse(data.getRefundTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+ chargingOrderRefund.setCode(chargingOrder.getCode());
+ chargingOrderRefund.setRefundTitle(rechargeAmount.compareTo(chargingOrderRefund.getRefundAmount()) == 0 ? "充电失败" : "充电完成退款");
+ chargingOrderRefund.setRefundContent(rechargeAmount.compareTo(chargingOrderRefund.getRefundAmount()) == 0 ? "充电失败" : "充电完成退款");
+ chargingOrderRefund.setRefundReason(rechargeAmount.compareTo(chargingOrderRefund.getRefundAmount()) == 0 ? "充电失败" : "充电完成退款");
+ chargingOrderRefund.setRefundRemark(rechargeAmount.compareTo(chargingOrderRefund.getRefundAmount()) == 0 ? "充电失败" : "充电完成退款");
+ chargingOrderRefund.setRefundTotalAmount(new BigDecimal(data.getRefundAmount()));
+ chargingOrderRefund.setPayAmount(rechargeAmount);
+ chargingOrderRefund.setCreateTime(chargingOrderRefund.getRefundTime());
+ chargingOrderRefundService.save(chargingOrderRefund);
+
+ if(rechargeAmount.compareTo(chargingOrderRefund.getRefundAmount()) == 0){
+ chargingOrder.setStatus(-1);
+ }else{
+ chargingOrder.setStatus(5);
+ }
+ this.updateById(chargingOrder);
+ }
+ }
+ }
+
+
+ /**
+ * 手动添加完善订单费用明细
+ * @param orderId
+ */
+ @Override
+ public void addOrderExpenseBreakdown(Long orderId) {
+ try {
+ TChargingOrder chargingOrder = this.getById(orderId);
+ TransactionRecord one = transactionRecordService.findOne(chargingOrder.getCode());
+ if(null != one){
+ TransactionRecordMessageVO vo = new TransactionRecordMessageVO();
+ BeanUtils.copyProperties(one, vo);
+ //如果使用优惠券需要判断优惠券是否满足使用条件
+ //退款金额=优惠券金额+剩余充电金额
+ BigDecimal periodElectricPrice_total = BigDecimal.ZERO;
+ BigDecimal periodServicePrice_total = BigDecimal.ZERO;
+ BigDecimal vipDiscountAmount_total = BigDecimal.ZERO;
+ BigDecimal serviceCharge_total = BigDecimal.ZERO;
+ BigDecimal total = BigDecimal.ZERO;
+
+ //获取订单的计费策略
+ List<AccountingStrategyDetailOrder> accountingStrategyDetailOrderList = accountingStrategyDetailOrderClient.getAllAccountingStrategyDetailOrder(chargingOrder.getId()).getData();
+ if (accountingStrategyDetailOrderList.isEmpty()) {
+ throw new ServiceException("计费策略为空,无法计算费用");
+ }
+ accountingStrategyDetailOrderList.get(accountingStrategyDetailOrderList.size() - 1).setEndTime("23:59");
+ //开始处理计费明细数据和优惠数据
+ chargingOrderAccountingStrategyService.remove(new LambdaQueryWrapper<TChargingOrderAccountingStrategy>().eq(TChargingOrderAccountingStrategy::getChargingOrderId, chargingOrder.getId()));
+ SimpleDateFormat sdfs = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ List<AccountingStrategyDetailOrderVo> lists = new ArrayList<>();
+ List<UploadRealTimeMonitoringData> dataList = uploadRealTimeMonitoringDataService.getDataByOrderCode(chargingOrder.getCode());
+ if(!dataList.isEmpty()){
+ vo.setStart_time(sdfs.format(dataList.get(dataList.size() - 1).getCreate_time()) + ".00");
+ vo.setEnd_time(sdfs.format(dataList.get(0).getCreate_time()) + ".00");
+ }
+
+ //跨天
+ if (!vo.getStart_time().split(" ")[0].equals(vo.getEnd_time().split(" ")[0])) {
+ //当天的
+ //开始通过计费策略遍历解析每个时段的费用明细
+ String start_time = vo.getStart_time();
+ String end_time = vo.getEnd_time();
+ long start = sdfs.parse(start_time).getTime();
+ long end = sdfs.parse(end_time).getTime();
+ Class<? extends TransactionRecordMessageVO> clazz = vo.getClass();
+ /**
+ * "start_time": "2025-01-03 23:06:43.00",
+ * "end_time": "2025-01-04 00:39:39.00",
+ */
+ for (int i = accountingStrategyDetailOrderList.size(); i > 0; i--) {
+ AccountingStrategyDetailOrder strategyDetail = accountingStrategyDetailOrderList.get(i - 1);
+ long time = sdfs.parse(start_time.split(" ")[0] + " " + strategyDetail.getEndTime() + ":00").getTime();
+ if (time < start) {
+ break;
+ }
+ //阶段(1=尖阶段,2=峰阶段,3=平阶段,4=谷阶段)
+ Object invoke = null;
+ switch (strategyDetail.getType()) {
+ case 1:
+ //充电度数
+ invoke = clazz.getMethod("getSpike_charge" + (i)).invoke(vo);
+ break;
+ case 2:
+ //充电度数
+ invoke = clazz.getMethod("getPeak_charge" + (i)).invoke(vo);
+ break;
+ case 3:
+ //充电度数
+ invoke = clazz.getMethod("getFlat_charge" + (i)).invoke(vo);
+ break;
+ case 4:
+ //充电度数
+ invoke = clazz.getMethod("getValley_charge" + (i)).invoke(vo);
+ break;
+ }
+ if (null == invoke || Double.valueOf(invoke.toString()) == 0) {
+ continue;
+ }
+ BigDecimal sharp_peak_charge = new BigDecimal(invoke.toString());
+ AccountingStrategyDetailOrderVo vo1 = new AccountingStrategyDetailOrderVo();
+ BeanUtils.copyProperties(strategyDetail, vo1);
+ vo1.setChargingCapacity(sharp_peak_charge);
+ lists.add(0, vo1);
+ }
+
+ //第二天的
+ //开始通过计费策略遍历解析每个时段的费用明细
+ for (int i = 0; i < accountingStrategyDetailOrderList.size(); i++) {
+ AccountingStrategyDetailOrder strategyDetail = accountingStrategyDetailOrderList.get(i);
+ long time = sdfs.parse(end_time.split(" ")[0] + " " + strategyDetail.getStartTime() + ":00").getTime();
+ if (time > end) {
+ break;
+ }
+ //阶段(1=尖阶段,2=峰阶段,3=平阶段,4=谷阶段)
+ Object invoke = null;
+ switch (strategyDetail.getType()) {
+ case 1:
+ //充电度数
+ invoke = clazz.getMethod("getSpike_charge" + (i + 1)).invoke(vo);
+ break;
+ case 2:
+ //充电度数
+ invoke = clazz.getMethod("getPeak_charge" + (i + 1)).invoke(vo);
+ break;
+ case 3:
+ //充电度数
+ invoke = clazz.getMethod("getFlat_charge" + (i + 1)).invoke(vo);
+ break;
+ case 4:
+ //充电度数
+ invoke = clazz.getMethod("getValley_charge" + (i + 1)).invoke(vo);
+ break;
+ }
+ if (null == invoke || Double.valueOf(invoke.toString()) == 0) {
+ continue;
+ }
+ BigDecimal sharp_peak_charge = new BigDecimal(invoke.toString());
+ AccountingStrategyDetailOrderVo vo1 = new AccountingStrategyDetailOrderVo();
+ BeanUtils.copyProperties(strategyDetail, vo1);
+ vo1.setChargingCapacity(sharp_peak_charge);
+ lists.add(vo1);
+ }
+ } else {
+ for (int i = 0; i < accountingStrategyDetailOrderList.size(); i++) {
+ Class<? extends TransactionRecordMessageVO> clazz = vo.getClass();
+ AccountingStrategyDetailOrder strategyDetail = accountingStrategyDetailOrderList.get(i);
+ //阶段(1=尖阶段,2=峰阶段,3=平阶段,4=谷阶段)
+ Object invoke = null;
+ switch (strategyDetail.getType()) {
+ case 1:
+ //充电度数
+ invoke = clazz.getMethod("getSpike_charge" + (i + 1)).invoke(vo);
+ break;
+ case 2:
+ //充电度数
+ invoke = clazz.getMethod("getPeak_charge" + (i + 1)).invoke(vo);
+ break;
+ case 3:
+ //充电度数
+ invoke = clazz.getMethod("getFlat_charge" + (i + 1)).invoke(vo);
+ break;
+ case 4:
+ //充电度数
+ invoke = clazz.getMethod("getValley_charge" + (i + 1)).invoke(vo);
+ break;
+ }
+ if (null == invoke || Double.valueOf(invoke.toString()) == 0) {
+ continue;
+ }
+ BigDecimal sharp_peak_charge = new BigDecimal(invoke.toString());
+ AccountingStrategyDetailOrderVo vo1 = new AccountingStrategyDetailOrderVo();
+ BeanUtils.copyProperties(strategyDetail, vo1);
+ vo1.setChargingCapacity(sharp_peak_charge);
+ lists.add(vo1);
+ }
+ }
+
+ //开始处理明细
+ for (int i = 0; i < lists.size(); i++) {
+ AccountingStrategyDetailOrderVo strategyDetail = lists.get(i);
+ BigDecimal sharp_peak_charge = strategyDetail.getChargingCapacity();
+ TChargingOrderAccountingStrategy chargingOrderAccountingStrategy = new TChargingOrderAccountingStrategy();
+ chargingOrderAccountingStrategy.setChargingOrderId(chargingOrder.getId());
+ chargingOrderAccountingStrategy.setAccountingStrategyDetailId(strategyDetail.getId());
+ chargingOrderAccountingStrategy.setType(strategyDetail.getType());
+ chargingOrderAccountingStrategy.setElectrovalence(strategyDetail.getElectrovalence());
+ chargingOrderAccountingStrategy.setServiceCharge(strategyDetail.getServiceCharge());
+ chargingOrderAccountingStrategy.setCostServiceCharge(strategyDetail.getCostServiceCharge());
+ if (i == 0) {
+ String time = vo.getStart_time().split(" ")[1];
+ chargingOrderAccountingStrategy.setStartTime(time.substring(0, time.lastIndexOf(":")));
+ } else {
+ chargingOrderAccountingStrategy.setStartTime(strategyDetail.getStartTime());
+ }
+ if (i == lists.size() - 1) {
+ String time = vo.getEnd_time().split(" ")[1];
+ chargingOrderAccountingStrategy.setEndTime(time.substring(0, time.lastIndexOf(":")));
+ } else {
+ chargingOrderAccountingStrategy.setEndTime(strategyDetail.getEndTime());
+ }
+
+ //已充电总度数
+ BigDecimal electrovalenc = strategyDetail.getElectrovalence().multiply(sharp_peak_charge);
+ BigDecimal originalServicePrice = strategyDetail.getServiceCharge().multiply(sharp_peak_charge);
+ BigDecimal serviceCharge = originalServicePrice;
+ BigDecimal vipDiscountAmount = BigDecimal.ZERO;
+ //计算优惠金额
+ if (null != chargingOrder.getVipDiscount()) {
+ //0.58折
+ vipDiscountAmount = serviceCharge.multiply(new BigDecimal(1).subtract(chargingOrder.getVipDiscount()));
+ serviceCharge = serviceCharge.multiply(chargingOrder.getVipDiscount());
+ }
+ chargingOrderAccountingStrategy.setChargingCapacity(sharp_peak_charge);
+ chargingOrderAccountingStrategy.setPeriodElectricPrice(electrovalenc.setScale(4, RoundingMode.HALF_EVEN));
+ chargingOrderAccountingStrategy.setPeriodServicePrice(serviceCharge.setScale(4, RoundingMode.HALF_EVEN));
+ chargingOrderAccountingStrategy.setPeriodOriginalServicePrice(originalServicePrice.setScale(4, RoundingMode.HALF_EVEN));
+ chargingOrderAccountingStrategy.setVipDiscountAmount(vipDiscountAmount.setScale(4, RoundingMode.HALF_EVEN));
+ chargingOrderAccountingStrategy.setCreateTime(LocalDateTime.now());
+ chargingOrderAccountingStrategyService.save(chargingOrderAccountingStrategy);
+ //电费
+ periodElectricPrice_total = periodElectricPrice_total.add(electrovalenc);
+ //服务费(含折扣)
+ serviceCharge_total = serviceCharge_total.add(serviceCharge);
+ //服务费(不含折扣)
+ periodServicePrice_total = periodServicePrice_total.add(originalServicePrice);
+ //会员折扣优惠金额
+ vipDiscountAmount_total = vipDiscountAmount_total.add(vipDiscountAmount);
+ //原始总金额(不含折扣)
+ total = total.add(electrovalenc.add(originalServicePrice));
+ }
+
+ BigDecimal orderAmount = BigDecimal.valueOf(total.doubleValue());
+ //原金额
+ BigDecimal rechargeAmount = chargingOrder.getRechargeAmount();
+ //支付金额
+ BigDecimal payAmount = periodElectricPrice_total.add(serviceCharge_total);
+ //退款金额=充值金额-实际支付金额
+ BigDecimal refundAmount = rechargeAmount.subtract(payAmount);
+
+ UploadRealTimeMonitoringData uploadRealTimeMonitoringData = uploadRealTimeMonitoringDataService.getLastDataById(chargingOrder.getCode());
+ if (null != uploadRealTimeMonitoringData && null == chargingOrder.getEndMode()) {
+ Integer soc = uploadRealTimeMonitoringData.getSoc();
+ if (soc >= 98) {
+ chargingOrder.setEndMode(2);
+ } else if (null != chargingOrder.getResidualAmount() && chargingOrder.getResidualAmount().compareTo(new BigDecimal(1)) <= 0) {
+ chargingOrder.setEndMode(3);
+ } else {
+ chargingOrder.setEndMode(1);
+ }
+ }
+ chargingOrder.setResidualAmount(rechargeAmount.subtract(total).setScale(2, RoundingMode.HALF_EVEN));
+
+ chargingOrder.setStartTime(LocalDateTime.parse(vo.getStart_time(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SS")));
+ chargingOrder.setEndTime(LocalDateTime.parse(vo.getEnd_time(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SS")));
+ chargingOrder.setStatus(5);
+ chargingOrder.setOrderAmount(orderAmount.setScale(2, RoundingMode.HALF_EVEN));
+ chargingOrder.setElectrovalence(periodElectricPrice_total.setScale(2, RoundingMode.HALF_EVEN));
+ chargingOrder.setChargingCapacity(vo.getTotal_electricity());
+ chargingOrder.setElectricity(vo.getTotal_electricity());
+ chargingOrder.setVipDiscountAmount(vipDiscountAmount_total);
+ if (vipDiscountAmount_total.compareTo(BigDecimal.ZERO) == 0) {
+ chargingOrder.setVipDiscount(BigDecimal.valueOf(1));
+ }
+
+ //计算优惠券
+ BigDecimal couponDiscount = BigDecimal.ZERO;
+ if (null != chargingOrder.getAppCouponId()) {
+ //判断实际充电金额是否满足优惠券使用条件,如果不满足则不适用优惠券。
+ TAppCoupon appCoupon = appCouponClient.getAppCouponById(chargingOrder.getAppCouponId()).getData();
+ String couponJson = appCoupon.getCouponJson();
+ TCoupon tCoupon = JSON.parseObject(couponJson, TCoupon.class);
+ Integer preferentialMode = tCoupon.getPreferentialMode();
+ if (1 == preferentialMode) {
+ //满减
+ if (payAmount.compareTo(tCoupon.getMeetTheConditions()) >= 0) {
+ BigDecimal couponDiscountAmount = tCoupon.getDiscountAmount();
+ //如果优惠金额大于服务费金额,以服务费作为最大限制
+ if (serviceCharge_total.compareTo(couponDiscountAmount) < 0) {
+ couponDiscount = serviceCharge_total;
+ serviceCharge_total = BigDecimal.ZERO;
+ } else {
+ couponDiscount = couponDiscountAmount;
+ }
+ appCoupon.setStatus(2);
+ appCouponClient.updateAppCoupon(appCoupon);
+ } else {
+ appCouponClient.refund(chargingOrder.getAppCouponId().toString());
+ chargingOrder.setAppCouponId(null);
+ chargingOrder.setCouponDiscountAmount(BigDecimal.ZERO);
+ }
+ }
+ if (2 == preferentialMode) {
+ //抵扣
+ if (payAmount.compareTo(tCoupon.getMeetTheConditions()) >= 0) {
+ //折扣金额
+ BigDecimal divide = payAmount.multiply(new BigDecimal(10).subtract(tCoupon.getDiscount())).divide(new BigDecimal(10));
+ divide = divide.compareTo(tCoupon.getMaximumDiscountAmount()) > 0 ? tCoupon.getMaximumDiscountAmount() : divide;
+ //如果优惠金额大于服务费金额,以服务费作为最大限制
+ if (serviceCharge_total.compareTo(divide) < 0) {
+ couponDiscount = serviceCharge_total;
+ serviceCharge_total = BigDecimal.ZERO;
+ } else {
+ couponDiscount = divide;
+ }
+
+ appCoupon.setStatus(2);
+ appCouponClient.updateAppCoupon(appCoupon);
+ } else {
+ chargingOrder.setAppCouponId(null);
+ chargingOrder.setCouponDiscountAmount(BigDecimal.ZERO);
+ appCouponClient.refund(chargingOrder.getAppCouponId().toString());
+ }
+ }
+ }
+ //优惠券优惠金额
+ couponDiscount = couponDiscount.setScale(4, RoundingMode.HALF_EVEN);
+ //退款金额+优惠券
+ refundAmount = refundAmount.add(couponDiscount);
+ //实际支付金额-优惠券
+ payAmount = payAmount.subtract(couponDiscount);
+ if (serviceCharge_total.compareTo(BigDecimal.ZERO) > 0) {
+ serviceCharge_total = serviceCharge_total.subtract(couponDiscount);
+ }
+ chargingOrder.setCouponDiscountAmount(couponDiscount.setScale(2, RoundingMode.HALF_EVEN));
+ chargingOrder.setServiceCharge(serviceCharge_total.setScale(2, RoundingMode.HALF_EVEN));
+ chargingOrder.setPaymentAmount(payAmount.setScale(2, RoundingMode.HALF_EVEN));
+ chargingOrder.setRefundAmount(refundAmount.setScale(2, RoundingMode.HALF_EVEN));
+ chargingOrder.setRefundStatus(1);
+ UploadRealTimeMonitoringData asc = uploadRealTimeMonitoringDataService.getDataByOrderCode(chargingOrder.getCode(), "asc");
+ UploadRealTimeMonitoringData desc = uploadRealTimeMonitoringDataService.getDataByOrderCode(chargingOrder.getCode(), "desc");
+ if(null != asc){
+ chargingOrder.setStartSoc(new BigDecimal(asc.getSoc()));
+ }
+ if(null != desc){
+ chargingOrder.setEndSoc(new BigDecimal(desc.getSoc()));
+ }
+ this.updateById(chargingOrder);
+ }else{
+ List<UploadRealTimeMonitoringData> dataList = uploadRealTimeMonitoringDataService.getDataByOrderCode(chargingOrder.getCode());
+ if(!dataList.isEmpty()) {
+ //获取当前订单的计费规则,然后分段计算总的度数和充电金额
+ List<AccountingStrategyDetailOrder> detailOrders = accountingStrategyDetailOrderService.list(new LambdaQueryWrapper<AccountingStrategyDetailOrder>()
+ .eq(AccountingStrategyDetailOrder::getChargingOrderId, chargingOrder.getId()).last(" order by start_time"));
+ detailOrders.get(detailOrders.size() - 1).setEndTime("23:59");
+ SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
+ //开始解析每个时段的充电度数
+ BigDecimal decimal = BigDecimal.ZERO;
+ //如果使用优惠券需要判断优惠券是否满足使用条件
+ //退款金额=优惠券金额+剩余充电金额
+ BigDecimal periodElectricPrice_total = BigDecimal.ZERO;
+ BigDecimal periodServicePrice_total = BigDecimal.ZERO;
+ BigDecimal vipDiscountAmount_total = BigDecimal.ZERO;
+ BigDecimal serviceCharge_total = BigDecimal.ZERO;
+ BigDecimal total = BigDecimal.ZERO;
+ //判断实时数据是否跨天
+ SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
+ Date end_time = dataList.get(0).getCreate_time();
+ String end = sdf2.format(end_time);
+ Date start_time = dataList.get(dataList.size() - 1).getCreate_time();
+ String start = sdf2.format(start_time);
+ if (!end.equals(start)) {
+ List<AccountingStrategyDetailOrder> list = detailOrders.stream().map(s -> {
+ AccountingStrategyDetailOrder accountingStrategyDetailOrder = new AccountingStrategyDetailOrder();
+ BeanUtils.copyProperties(s, accountingStrategyDetailOrder);
+ return accountingStrategyDetailOrder;
+ }).collect(Collectors.toList());
+ for (AccountingStrategyDetailOrder detailOrder : detailOrders) {
+ detailOrder.setStartTime(start + " " + detailOrder.getStartTime());
+ detailOrder.setEndTime(start + " " + detailOrder.getEndTime());
+ }
+ for (AccountingStrategyDetailOrder detailOrder : list) {
+ detailOrder.setStartTime(end + " " + detailOrder.getStartTime());
+ detailOrder.setEndTime(end + " " + detailOrder.getEndTime());
+ }
+ detailOrders.addAll(list);
+ } else {
+ for (AccountingStrategyDetailOrder detailOrder : detailOrders) {
+ detailOrder.setStartTime(start + " " + detailOrder.getStartTime());
+ detailOrder.setEndTime(start + " " + detailOrder.getEndTime());
+ }
+ }
+
+ SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMddHHmm");
+ List<TChargingOrderAccountingStrategy> list = new ArrayList<>();
+ for (AccountingStrategyDetailOrder detailOrder : detailOrders) {
+ long startTime = Long.parseLong(detailOrder.getStartTime().replaceAll("-", "").replaceAll(" ", "").replaceAll(":", ""));
+ long endTime = Long.parseLong(detailOrder.getEndTime().replaceAll("-", "").replaceAll(" ", "").replaceAll(":", ""));
+ List<UploadRealTimeMonitoringData> collect = dataList.stream().filter(s -> Long.parseLong(sdf1.format(s.getCreate_time())) > startTime && Long.parseLong(sdf1.format(s.getCreate_time())) <= endTime).collect(Collectors.toList());
+
+ if (!collect.isEmpty()) {
+ //升序排序
+ collect.sort(new Comparator<UploadRealTimeMonitoringData>() {
+ @Override
+ public int compare(UploadRealTimeMonitoringData o1, UploadRealTimeMonitoringData o2) {
+ return o1.getCharging_degree().compareTo(o2.getCharging_degree());
+ }
+ });
+ UploadRealTimeMonitoringData uploadRealTimeMonitoringData = collect.get(collect.size() - 1);
+ BigDecimal chargingDegree = uploadRealTimeMonitoringData.getCharging_degree();
+ BigDecimal subtract = chargingDegree.subtract(decimal);
+ decimal = chargingDegree;
+ if (subtract.compareTo(BigDecimal.ZERO) > 0) {
+ //组装充电明细数据
+ TChargingOrderAccountingStrategy chargingOrderAccountingStrategy = new TChargingOrderAccountingStrategy();
+ chargingOrderAccountingStrategy.setChargingOrderId(chargingOrder.getId());
+ chargingOrderAccountingStrategy.setAccountingStrategyDetailId(detailOrder.getId());
+ chargingOrderAccountingStrategy.setType(detailOrder.getType());
+ chargingOrderAccountingStrategy.setElectrovalence(detailOrder.getElectrovalence());
+ chargingOrderAccountingStrategy.setServiceCharge(detailOrder.getServiceCharge());
+ chargingOrderAccountingStrategy.setCostServiceCharge(detailOrder.getCostServiceCharge());
+ chargingOrderAccountingStrategy.setChargingCapacity(subtract);
+ chargingOrderAccountingStrategy.setCreateTime(LocalDateTime.now());
+
+ if (list.size() == 0) {
+ String time = sdf.format(collect.get(0).getCreate_time());
+ chargingOrderAccountingStrategy.setStartTime(time);
+ } else {
+ chargingOrderAccountingStrategy.setStartTime(detailOrder.getStartTime().split(" ")[1]);
+ }
+ chargingOrderAccountingStrategy.setEndTime(detailOrder.getEndTime().split(" ")[1]);
+
+ //已充电总度数
+ BigDecimal electrovalenc = detailOrder.getElectrovalence().multiply(subtract);
+ BigDecimal originalServicePrice = detailOrder.getServiceCharge().multiply(subtract);
+ BigDecimal serviceCharge = originalServicePrice;
+ BigDecimal vipDiscountAmount = BigDecimal.ZERO;
+ //计算优惠金额
+ if (null != chargingOrder.getVipDiscount()) {
+ //0.58折
+ vipDiscountAmount = serviceCharge.multiply(new BigDecimal(1).subtract(chargingOrder.getVipDiscount()));
+ serviceCharge = serviceCharge.multiply(chargingOrder.getVipDiscount());
+ }
+ chargingOrderAccountingStrategy.setPeriodElectricPrice(electrovalenc.setScale(4, RoundingMode.HALF_EVEN));
+ chargingOrderAccountingStrategy.setPeriodServicePrice(serviceCharge.setScale(4, RoundingMode.HALF_EVEN));
+ chargingOrderAccountingStrategy.setPeriodOriginalServicePrice(originalServicePrice.setScale(4, RoundingMode.HALF_EVEN));
+ chargingOrderAccountingStrategy.setVipDiscountAmount(vipDiscountAmount.setScale(4, RoundingMode.HALF_EVEN));
+ chargingOrderAccountingStrategy.setCreateTime(LocalDateTime.now());
+ list.add(chargingOrderAccountingStrategy);
+ //电费
+ periodElectricPrice_total = periodElectricPrice_total.add(electrovalenc);
+ //服务费(含折扣)
+ serviceCharge_total = serviceCharge_total.add(serviceCharge);
+ //服务费(不含折扣)
+ periodServicePrice_total = periodServicePrice_total.add(originalServicePrice);
+ //会员折扣优惠金额
+ vipDiscountAmount_total = vipDiscountAmount_total.add(vipDiscountAmount);
+ //原始总金额(不含折扣)
+ total = total.add(electrovalenc.add(originalServicePrice));
+ }
+ }
+
+ }
+ list.get(list.size() - 1).setEndTime(sdf.format(dataList.get(0).getCreate_time()));
+ chargingOrderAccountingStrategyService.saveBatch(list);
+
+ BigDecimal orderAmount = BigDecimal.valueOf(total.doubleValue());
+ //原金额
+ BigDecimal rechargeAmount = chargingOrder.getRechargeAmount();
+ //支付金额
+ BigDecimal payAmount = periodElectricPrice_total.add(serviceCharge_total);
+ //退款金额=充值金额-实际支付金额
+ BigDecimal refundAmount = rechargeAmount.subtract(payAmount);
+
+ UploadRealTimeMonitoringData uploadRealTimeMonitoringData = uploadRealTimeMonitoringDataService.getLastDataById(chargingOrder.getCode());
+ if (null != uploadRealTimeMonitoringData && null == chargingOrder.getEndMode()) {
+ Integer soc = uploadRealTimeMonitoringData.getSoc();
+ if (soc >= 98) {
+ chargingOrder.setEndMode(2);
+ } else if (null != chargingOrder.getResidualAmount() && chargingOrder.getResidualAmount().compareTo(new BigDecimal(1)) <= 0) {
+ chargingOrder.setEndMode(3);
+ } else {
+ chargingOrder.setEndMode(1);
+ }
+ }
+
+ chargingOrder.setResidualAmount(rechargeAmount.subtract(total).setScale(2, RoundingMode.HALF_EVEN));
+ chargingOrder.setStartTime(list.get(0).getCreateTime());
+ chargingOrder.setEndTime(list.get(list.size() - 1).getCreateTime());
+ chargingOrder.setStatus(5);
+ chargingOrder.setOrderAmount(orderAmount.setScale(2, RoundingMode.HALF_EVEN));
+ chargingOrder.setElectrovalence(periodElectricPrice_total.setScale(2, RoundingMode.HALF_EVEN));
+ chargingOrder.setChargingCapacity(list.get(list.size() - 1).getChargingCapacity());
+ chargingOrder.setElectricity(list.get(list.size() - 1).getChargingCapacity());
+ chargingOrder.setVipDiscountAmount(vipDiscountAmount_total);
+ if (vipDiscountAmount_total.compareTo(BigDecimal.ZERO) == 0) {
+ chargingOrder.setVipDiscount(BigDecimal.valueOf(1));
+ }
+
+ //计算优惠券
+ BigDecimal couponDiscount = BigDecimal.ZERO;
+ if (null != chargingOrder.getAppCouponId()) {
+ //判断实际充电金额是否满足优惠券使用条件,如果不满足则不适用优惠券。
+ TAppCoupon appCoupon = appCouponClient.getAppCouponById(chargingOrder.getAppCouponId()).getData();
+ String couponJson = appCoupon.getCouponJson();
+ TCoupon tCoupon = com.alibaba.fastjson2.JSON.parseObject(couponJson, TCoupon.class);
+ Integer preferentialMode = tCoupon.getPreferentialMode();
+ if (1 == preferentialMode) {
+ //满减
+ if (payAmount.compareTo(tCoupon.getMeetTheConditions()) >= 0) {
+ BigDecimal couponDiscountAmount = tCoupon.getDiscountAmount();
+ //如果优惠金额大于服务费金额,以服务费作为最大限制
+ if (serviceCharge_total.compareTo(couponDiscountAmount) < 0) {
+ couponDiscount = serviceCharge_total;
+ serviceCharge_total = BigDecimal.ZERO;
+ } else {
+ couponDiscount = couponDiscountAmount;
+ }
+ appCoupon.setStatus(2);
+ appCouponClient.updateAppCoupon(appCoupon);
+ } else {
+ appCouponClient.refund(chargingOrder.getAppCouponId().toString());
+ chargingOrder.setAppCouponId(null);
+ chargingOrder.setCouponDiscountAmount(BigDecimal.ZERO);
+ }
+ }
+ if (2 == preferentialMode) {
+ //抵扣
+ if (payAmount.compareTo(tCoupon.getMeetTheConditions()) >= 0) {
+ //折扣金额
+ BigDecimal divide = payAmount.multiply(new BigDecimal(10).subtract(tCoupon.getDiscount())).divide(new BigDecimal(10));
+ divide = divide.compareTo(tCoupon.getMaximumDiscountAmount()) > 0 ? tCoupon.getMaximumDiscountAmount() : divide;
+ //如果优惠金额大于服务费金额,以服务费作为最大限制
+ if (serviceCharge_total.compareTo(divide) < 0) {
+ couponDiscount = serviceCharge_total;
+ serviceCharge_total = BigDecimal.ZERO;
+ } else {
+ couponDiscount = divide;
+ }
+
+ appCoupon.setStatus(2);
+ appCouponClient.updateAppCoupon(appCoupon);
+ } else {
+ chargingOrder.setAppCouponId(null);
+ chargingOrder.setCouponDiscountAmount(BigDecimal.ZERO);
+ appCouponClient.refund(chargingOrder.getAppCouponId().toString());
+ }
+ }
+ }
+ //优惠券优惠金额
+ couponDiscount = couponDiscount.setScale(4, RoundingMode.HALF_EVEN);
+ //退款金额+优惠券
+ refundAmount = refundAmount.add(couponDiscount);
+ //实际支付金额-优惠券
+ payAmount = payAmount.subtract(couponDiscount);
+ if (serviceCharge_total.compareTo(BigDecimal.ZERO) > 0) {
+ serviceCharge_total = serviceCharge_total.subtract(couponDiscount);
+ }
+ chargingOrder.setCouponDiscountAmount(couponDiscount.setScale(2, RoundingMode.HALF_EVEN));
+ chargingOrder.setServiceCharge(serviceCharge_total.setScale(2, RoundingMode.HALF_EVEN));
+ chargingOrder.setPaymentAmount(payAmount.setScale(2, RoundingMode.HALF_EVEN));
+ chargingOrder.setRefundAmount(refundAmount.setScale(2, RoundingMode.HALF_EVEN));
+ chargingOrder.setRefundStatus(1);
+ UploadRealTimeMonitoringData asc = uploadRealTimeMonitoringDataService.getDataByOrderCode(chargingOrder.getCode(), "asc");
+ UploadRealTimeMonitoringData desc = uploadRealTimeMonitoringDataService.getDataByOrderCode(chargingOrder.getCode(), "desc");
+ if (null != asc) {
+ chargingOrder.setStartSoc(new BigDecimal(asc.getSoc()));
+ }
+ if (null != desc) {
+ chargingOrder.setEndSoc(new BigDecimal(desc.getSoc()));
+ }
+ chargingOrderService.updateById(chargingOrder);
+ }
+ }
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+ }
}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/task/TaskUtil.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/task/TaskUtil.java
index d1d0b5e..173f3da 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/task/TaskUtil.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/task/TaskUtil.java
@@ -379,12 +379,12 @@
R r = chargingOrderService.endChargeBillingCharge(vo);
log.info("定时任务执行,充电中的订单处理结果:{}", JSON.toJSONString(r));
}else{
- //判断充电流水超过15分钟没有更新,则判定为充电结束
+ //判断充电流水超过10分钟没有更新,则判定为充电结束
List<UploadRealTimeMonitoringData> dataList = uploadRealTimeMonitoringDataService.getDataByOrderCode(order.getCode());
if(!dataList.isEmpty()){
UploadRealTimeMonitoringData uploadRealTimeMonitoringData = dataList.get(0);
Date createTime = uploadRealTimeMonitoringData.getCreate_time();
- if(System.currentTimeMillis() - createTime.getTime() - (8 * 60 * 60 * 1000) > 1000 * 60 * 30){
+ if(System.currentTimeMillis() - createTime.getTime() - (8 * 60 * 60 * 1000) > 1000 * 60 * 10){
endOrder(order);
}
}
@@ -412,6 +412,8 @@
@Scheduled(cron = "0 30 0 * * ?")
public void taskMonth() {
if(null != port && port == 5400){
+ //推送三方引流平台数据
+ pushOrderDrainagePlatform();
//添加充电算账单汇总数据
addChargingSettlementBill();
//添加账户结算账单数据
@@ -1175,4 +1177,21 @@
e.printStackTrace();
}
}
+
+
+ /**
+ * 推送三方引流平台充电数据
+ */
+ public void pushOrderDrainagePlatform(){
+ String format = LocalDateTime.now().minusDays(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+ List<TChargingOrder> list = chargingOrderService.list(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getStatus, 5)
+ .eq(TChargingOrder::getOrderSource, 2).eq(TChargingOrder::getDelFlag, 0)
+ .isNotNull(TChargingOrder::getStartChargeSeq).isNotNull(TChargingOrder::getOperatorId)
+ .last(" and DATE_FORMAT(end_time, '%Y-%m-%d') = '" + format + "'"));
+ for (TChargingOrder tChargingOrder : list) {
+ String code = tChargingOrder.getCode();
+ chargingOrderService.pushOrderInfo(code);
+ }
+
+ }
}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/UpdateOrderPaymentAmountDto.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/UpdateOrderPaymentAmountDto.java
new file mode 100644
index 0000000..5d391c7
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/UpdateOrderPaymentAmountDto.java
@@ -0,0 +1,14 @@
+package com.ruoyi.order.vo;
+
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class UpdateOrderPaymentAmountDto {
+
+ private Long orderId;
+
+ private BigDecimal paymentAmount;
+}
diff --git a/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/controller/AliPayController.java b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/controller/AliPayController.java
index 0d927f1..62c370e 100644
--- a/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/controller/AliPayController.java
+++ b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/controller/AliPayController.java
@@ -95,6 +95,17 @@
}
+ /**
+ * 退款查询
+ * @param dto
+ * @return
+ */
+ @PostMapping("/queryRefund")
+ public R<QueryRefundResp> queryRefund(@RequestBody QueryRefundReq dto){
+ return R.ok(appletPayUtil.queryRefund(dto));
+ }
+
+
@Resource
private OrderClient orderClient;
@Resource
diff --git a/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/controller/WxPayController.java b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/controller/WxPayController.java
index 5754f3b..aad7c5d 100644
--- a/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/controller/WxPayController.java
+++ b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/controller/WxPayController.java
@@ -119,6 +119,28 @@
String status = result.get("status").toString();
return R.ok(result);
}
+
+
+ @ApiOperation("订单退款查询")
+ @PostMapping(value = "queryRefund")
+ public R<Map<String, Object>> queryRefund(@RequestParam("refund_out_trade_no") String refund_out_trade_no) {
+ Map<String, Object> result = wxV3Pay.queryRefund(refund_out_trade_no);
+ log.info("订单退款查询结果:{}", result);
+ // 微信支付退款单号
+ String refund_id = result.get("refund_id").toString();
+ // 商户退款单号
+ String out_refund_no = result.get("out_refund_no").toString();
+ // 微信支付订单号
+ String transaction_id = result.get("transaction_id").toString();
+ // 商户订单号 tradeNo
+ String out_trade_no = result.get("out_trade_no").toString();
+ // 退款成功时间
+ String success_time = Objects.nonNull(result.get("success_time")) ? result.get("success_time").toString() : null;
+ // 退款状态 RefundEnum
+ String status = result.get("status").toString();
+ return R.ok(result);
+ }
+
/**
* 支付回调
*/
diff --git a/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/utils/WxAbstractPay.java b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/utils/WxAbstractPay.java
index 629c51f..f4e309a 100644
--- a/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/utils/WxAbstractPay.java
+++ b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/utils/WxAbstractPay.java
@@ -260,8 +260,76 @@
* @return
*/
public abstract Map<String, Object> refund(WxPaymentRefundModel refundModel);
-
-
+
+
+ /**
+ * 退款查询
+ *
+ * @param refund_out_trade_no
+ * @return
+ */
+ public abstract Map<String, Object> queryRefund(String refund_out_trade_no);
+
+
+ /**
+ * 订单查询
+ *
+ * @param httpClient
+ * @param socketTimeout
+ * @param connectTimeout
+ * @param url
+ * @return com.abl.biz.center.payment.wx.v3.NotifyV3PayDecodeRespBody
+ * @author xiaochen
+ * @date 2021-12-20 17:12
+ */
+ protected Map<String, Object> queryRefund(CloseableHttpClient httpClient, int socketTimeout, int connectTimeout, String url) {
+ //请求URL
+ HttpGet httpGet = requestGet(
+ url
+ , socketTimeout
+ , connectTimeout);
+ CloseableHttpResponse response = null;
+ try {
+ response = httpClient.execute(httpGet);
+ int statusCode = response.getStatusLine().getStatusCode();
+ String respBodyStr = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
+ if (WxUtils.getLogger().isDebugEnabled()) {
+ WxUtils.debug("请求成功:{}", respBodyStr);
+ }
+ if(404 == statusCode){
+ return null;
+ }
+ // 成功相应
+ if (STATUS_CODE == statusCode || OTHER_STATUS_CODE == statusCode ) {
+ return WxJsonUtils.parseObject(respBodyStr, Map.class);
+ } else {
+ WxUtils.error("failed,resp code = {},return body = {}", statusCode, respBodyStr);
+ throw new RuntimeException(respBodyStr);
+ }
+ } catch (ConnectTimeoutException e) {
+ e.printStackTrace();
+ throw new RuntimeException("接口超时");
+ } catch (SocketTimeoutException e) {
+ e.printStackTrace();
+ throw new RuntimeException("读取接口数据超时");
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new RuntimeException("接口请求失败,请尝试检查网络环境或请求接口是否能正常访问");
+ } finally {
+ // 关闭响应
+ try {
+ if (response != null) {
+ //关闭结果集
+ response.getEntity().getContent().close();
+ response.close();
+ }
+ } catch (IOException e) {
+ throw new RuntimeException("关闭流异常");
+ }
+ }
+ }
+
+
public abstract String close(String out_trade_no);
diff --git a/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/utils/WxV3Pay.java b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/utils/WxV3Pay.java
index e322861..6be5659 100644
--- a/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/utils/WxV3Pay.java
+++ b/ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/utils/WxV3Pay.java
@@ -194,6 +194,19 @@
refundModel.setNotify_url(this.config.getV3().getNotifyRefundUrl() + refundModel.getNotify_url());
return refund(this.httpClient, "/v3/refund/domestic/refunds", this.config.getHttpReadTimeoutMs(), this.config.getHttpConnectTimeoutMs(), refundModel);
}
+
+
+ /**
+ * 退款查询
+ * @param refund_out_trade_no
+ * @return
+ */
+ @Override
+ public Map<String, Object> queryRefund(String refund_out_trade_no){
+ String url = String.format("/v3/refund/domestic/refunds/%s", refund_out_trade_no);
+ return queryRefund(this.httpClient, this.config.getHttpReadTimeoutMs(), this.config.getHttpConnectTimeoutMs(), url);
+ }
+
/**
--
Gitblit v1.7.1