puzhibing
2026-05-22 d6e09bae199e8980f97dd4cdd2000ab6c2b7f06b
合并代码
1个文件已添加
13个文件已修改
925 ■■■■■ 已修改文件
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/AliPaymentFallbackFactory.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/WxPaymentFallbackFactory.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/feignClient/AliPaymentClient.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/feignClient/WxPaymentClient.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/model/QueryRefundResp.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/TChargingOrderService.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java 652 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/task/TaskUtil.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/UpdateOrderPaymentAmountDto.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/controller/AliPayController.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/controller/WxPayController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/utils/WxAbstractPay.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-payment/src/main/java/com/ruoyi/payment/wx/utils/WxV3Pay.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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());
            }
        };
    }
}
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());
            }
        };
    }
}
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);
}
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);
}
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秒以上再发起退款查询请求。
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;
@@ -2365,5 +2354,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();
    }
}
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/TChargingOrderService.java
@@ -391,4 +391,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);
}
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
@@ -18,6 +18,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;
@@ -67,9 +68,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;
@@ -369,7 +368,10 @@
            }
            myChargingOrderInfo.setPower(power);
        }
        myChargingOrderInfo.setActionable(myChargingOrderInfo.getEndTime() + 604800000L < System.currentTimeMillis() ? 0 : 1);
        myChargingOrderInfo.setActionable(0);
        if(null != myChargingOrderInfo.getEndTime()){
            myChargingOrderInfo.setActionable(myChargingOrderInfo.getEndTime() + 604800000L < System.currentTimeMillis() ? 0 : 1);
        }
        long count = orderAppealService.count(Wrappers.lambdaQuery(TOrderAppeal.class)
                .eq(TOrderAppeal::getOrderId, id));
        myChargingOrderInfo.setIsAppeal(count > 0 ? 0 : 1);
@@ -2367,6 +2369,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) {
@@ -3024,7 +3032,7 @@
            chargingOrderRefund.setRefundRemark(payOrderQueryDto.getRemark());
            chargingOrderRefund.setRefundTotalAmount(tChargingOrder.getRefundAmount().add(payOrderQueryDto.getRefundAmount()));
            chargingOrderRefund.setPayAmount(tChargingOrder.getPaymentAmount());
            if (1 == tChargingOrder.getRechargePaymentType()) {
                WxPaymentRefundModel model = new WxPaymentRefundModel();
                model.setOut_trade_no(tChargingOrder.getCode());
@@ -3064,7 +3072,7 @@
                    chargingOrderRefund.setRefundAmount((tChargingOrder.getRefundAmount() == null ? BigDecimal.valueOf(0) : tChargingOrder.getRefundAmount()).add(payOrderQueryDto.getRefundAmount()));
                    this.baseMapper.updateById(tChargingOrder);
                    chargingOrderRefundService.save(chargingOrderRefund);
                }
            }
            if (3 == tChargingOrder.getRechargePaymentType()) {
@@ -3119,7 +3127,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());
@@ -4540,4 +4548,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();
        }
    }
}
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/task/TaskUtil.java
@@ -260,12 +260,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);
                        }
                    }
@@ -293,6 +293,8 @@
    @Scheduled(cron = "0 30 0 * * ?")
    public void taskMonth() {
        if(null != port && port == 5400){
            //推送三方引流平台数据
            pushOrderDrainagePlatform();
            //添加充电算账单汇总数据
            addChargingSettlementBill();
            //添加账户结算账单数据
@@ -981,4 +983,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);
        }
    }
}
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/vo/UpdateOrderPaymentAmountDto.java
New file
@@ -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;
}
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
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);
    }
    /**
     * 支付回调
     */
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);
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);
    }
    
    
    /**