liujie
2026-04-28 d889384ce863cc128eb7b24f9032b6570dda95b9
p0功能 小程序
7个文件已修改
168 ■■■■■ 已修改文件
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/TChargingOrder.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/TExchangeCodeDetail.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/TExchangeCodeUseRecord.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/dto/AddChargingOrder.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TChargingOrderMapper.xml 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TExchangeCodePackageServiceImpl.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/TChargingOrder.java
@@ -144,6 +144,26 @@
    @TableField("recharge_payment_status")
    private Integer rechargePaymentStatus;
    @ApiModelProperty(value = "充电支付模式:1=余额支付,2=余额组合支付,3=第三方支付")
    @TableField("pay_method")
    private Integer payMethod;
    @ApiModelProperty(value = "余额支付金额")
    @TableField("balance_pay_amount")
    private BigDecimal balancePayAmount;
    @ApiModelProperty(value = "第三方支付金额")
    @TableField("third_pay_amount")
    private BigDecimal thirdPayAmount;
    @ApiModelProperty(value = "余额退款金额")
    @TableField("balance_refund_amount")
    private BigDecimal balanceRefundAmount;
    @ApiModelProperty(value = "第三方退款金额")
    @TableField("third_refund_amount")
    private BigDecimal thirdRefundAmount;
    @ApiModelProperty(value = "充值支付第三方流水号")
    @TableField("recharge_serial_number")
    private String rechargeSerialNumber;
ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/TExchangeCodeDetail.java
@@ -48,6 +48,10 @@
    @ApiModelProperty("已使用金额")
    private BigDecimal usedAmount;
    @TableField("gift_ratio")
    @ApiModelProperty("赠送金额比例")
    private BigDecimal giftRatio;
    @TableField("bind_user_id")
    @ApiModelProperty("绑定用户ID")
    private Long bindUserId;
ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/TExchangeCodeUseRecord.java
@@ -38,6 +38,17 @@
    @TableField("used_amount")
    @ApiModelProperty("本次使用金额")
    private BigDecimal usedAmount;
    @TableField("refund_no")
    @ApiModelProperty("退款单号/退款流水号")
    private String refundNo;
    @TableField("change_type")
    @ApiModelProperty("变动类型:1=兑换入账,2=充电消费,3=退款返还")
    private Integer recordChangeType;
    @TableField("gift_used_amount")
    @ApiModelProperty("本次使用赠送金额")
    private BigDecimal giftUsedAmount;
    @TableField(exist = false)
    private String uid;
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/dto/AddChargingOrder.java
@@ -23,6 +23,8 @@
    private Long appUserCarId;
    @ApiModelProperty("支付方式(1=微信,2=支付宝 3=支付宝h5)")
    private Integer paymentType;
    @ApiModelProperty("充电支付模式:1=余额支付,2=余额组合支付,3=第三方支付")
    private Integer payMethod;
    @ApiModelProperty("回跳地址")
    private String returnUrl;
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
@@ -334,7 +334,7 @@
        List<UploadRealTimeMonitoringData> dataList = uploadRealTimeMonitoringDataService.getDataByOrderCode(chargingOrder.getCode());
        if (null != dataList) {
            //在MongoDB中获取数据
            SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
            List<UploadRealTimeMonitoringData> dataLists = new ArrayList<>();
            String t = "";
            for (UploadRealTimeMonitoringData uploadRealTimeMonitoringData : dataList) {
@@ -421,10 +421,43 @@
     * @param addChargingOrder
     * @return
     */
    private boolean isBalancePayMode(Integer payMethod) {
        return payMethod != null && (payMethod == 1 || payMethod == 2);
    }
    private BigDecimal money(BigDecimal amount) {
        return amount == null ? BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP) : amount.setScale(2, RoundingMode.HALF_UP);
    }
    private void changeUserBalance(Long userId, BigDecimal delta) {
        if (userId == null || delta == null || delta.compareTo(BigDecimal.ZERO) == 0) {
            return;
        }
        TAppUser appUser = appUserClient.getUserById(userId).getData();
        if (appUser == null) {
            throw new RuntimeException("用户不存在");
        }
        appUser.setBalance(money(appUser.getBalance()).add(delta).setScale(2, RoundingMode.HALF_UP));
        appUserClient.updateAppUser(appUser);
    }
    @Override
    public AjaxResult paymentChargingOrder(AddChargingOrder addChargingOrder) {
        Long userId = tokenService.getLoginUserApplet().getUserId();
        TAppUser appUser = appUserClient.getUserById(userId).getData();
        Integer payMethod = addChargingOrder.getPayMethod() == null ? 3 : addChargingOrder.getPayMethod();
        BigDecimal rechargeAmount = money(addChargingOrder.getPaymentAmount());
        BigDecimal userBalance = money(appUser.getBalance());
        BigDecimal balancePayAmount = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
        BigDecimal thirdPayAmount = rechargeAmount;
        if (isBalancePayMode(payMethod)) {
            addChargingOrder.setAppUserCouponId(null);
            if (payMethod == 1 && userBalance.compareTo(rechargeAmount) < 0) {
                return AjaxResult.error("余额不足,请选择组合支付或第三方支付");
            }
            balancePayAmount = payMethod == 1 ? rechargeAmount : userBalance.min(rechargeAmount).setScale(2, RoundingMode.HALF_UP);
            thirdPayAmount = rechargeAmount.subtract(balancePayAmount).setScale(2, RoundingMode.HALF_UP);
        }
        //查询待支付状态的订单,没有支付则删除订单
        List<TChargingOrder> list = this.list(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getAppUserId, userId)
                .eq(TChargingOrder::getRechargePaymentStatus, 1).eq(TChargingOrder::getDelFlag, 0));
@@ -542,7 +575,12 @@
        chargingOrder.setChargingGunId(addChargingOrder.getId());
        chargingOrder.setRechargePaymentType(addChargingOrder.getPaymentType());
        chargingOrder.setRechargePaymentStatus(1);
        chargingOrder.setRechargeAmount(addChargingOrder.getPaymentAmount());
        chargingOrder.setPayMethod(payMethod);
        chargingOrder.setBalancePayAmount(balancePayAmount);
        chargingOrder.setThirdPayAmount(thirdPayAmount);
        chargingOrder.setBalanceRefundAmount(BigDecimal.ZERO);
        chargingOrder.setThirdRefundAmount(BigDecimal.ZERO);
        chargingOrder.setRechargeAmount(rechargeAmount);
        chargingOrder.setAppCouponId(addChargingOrder.getAppUserCouponId());
        chargingOrder.setVipDiscountAmount(BigDecimal.ZERO);
        chargingOrder.setOrderSource(1);
@@ -557,7 +595,7 @@
        TAccountingStrategy accountingStrategy = accountingStrategyClient.getAccountingStrategyById(accountingStrategyId).getData();
        
        //直营站点才可以享受会员折扣
        if (null != appUser.getVipId() && 1 == site.getBusinessCategory()) {
        if (!isBalancePayMode(payMethod) && null != appUser.getVipId() && 1 == site.getBusinessCategory()) {
            TVip vip = vipClient.getInfo1(appUser.getVipId()).getData();
            BigDecimal discount = null;
            if (1 == vip.getType()) {
@@ -597,12 +635,18 @@
        }
        accountingStrategyDetailOrderService.saveBatch(list1);
        
        if (balancePayAmount.compareTo(BigDecimal.ZERO) > 0) {
            changeUserBalance(userId, balancePayAmount.negate());
        }
        if (thirdPayAmount.compareTo(BigDecimal.ZERO) == 0) {
            return chargingOrderCallback(addChargingOrder.getPaymentType(), chargingOrder.getCode(), "BALANCE", null);
        }
        //会员优惠折扣将其计入增加充电时长(增加总充电金额)
        //如果充电总金额未使用完,则需要退回费用=(原金额/总金额)*(总金额-实际充电金额)
        if (1 == addChargingOrder.getPaymentType()) {
            PaymentOrder paymentOrder = new PaymentOrder();
            paymentOrder.setCode(chargingOrder.getCode());
            paymentOrder.setAmount(addChargingOrder.getPaymentAmount());
            paymentOrder.setAmount(thirdPayAmount);
            paymentOrder.setOpenId(appUser.getWxOpenid());
            paymentOrder.setDescription("充电充值");
            paymentOrder.setNotifyUrl("/payment/wx/pay/notify");
@@ -612,7 +656,7 @@
        if (2 == addChargingOrder.getPaymentType()) {
            AliPaymentReq req = new AliPaymentReq();
            req.setOutTradeNo(chargingOrder.getCode());
            req.setTotalAmount(addChargingOrder.getPaymentAmount().toString());
            req.setTotalAmount(thirdPayAmount.toString());
            req.setSubject("充电充值");
            req.setBuyerOpenId(appUser.getAliOpenid());
            req.setBody("充电充值");
@@ -625,7 +669,7 @@
        if (3 == addChargingOrder.getPaymentType()) {
            AliPaymentReq req = new AliPaymentReq();
            req.setOutTradeNo(chargingOrder.getCode());
            req.setTotalAmount(addChargingOrder.getPaymentAmount().toString());
            req.setTotalAmount(thirdPayAmount.toString());
            req.setSubject("充电充值");
            req.setBuyerOpenId(appUser.getAliOpenid());
            req.setBody("充电充值");
@@ -2617,7 +2661,7 @@
                //计算优惠券
                BigDecimal couponDiscount = BigDecimal.ZERO;
                if (null != chargingOrder.getAppCouponId()) {
                if (!isBalancePayMode(chargingOrder.getPayMethod()) && null != chargingOrder.getAppCouponId()) {
                    //判断实际充电金额是否满足优惠券使用条件,如果不满足则不适用优惠券。
                    TAppCoupon appCoupon = appCouponClient.getAppCouponById(chargingOrder.getAppCouponId()).getData();
                    String couponJson = appCoupon.getCouponJson();
@@ -2676,23 +2720,37 @@
                }
                chargingOrder.setCouponDiscountAmount(couponDiscount.setScale(2, RoundingMode.HALF_EVEN));
                chargingOrder.setServiceCharge(serviceCharge_total.setScale(2, RoundingMode.HALF_EVEN));
                BigDecimal exchangeCodeDeductAmount = BigDecimal.ZERO;
                if (chargingOrder.getAppUserId() != null && payAmount.compareTo(BigDecimal.ZERO) > 0) {
                    ExchangeCodeConsumeDTO exchangeCodeConsumeDTO = new ExchangeCodeConsumeDTO();
                    exchangeCodeConsumeDTO.setUserId(chargingOrder.getAppUserId());
                    exchangeCodeConsumeDTO.setOrderId(chargingOrder.getId());
                    exchangeCodeConsumeDTO.setAmount(payAmount.setScale(2, RoundingMode.HALF_EVEN));
                    R<ExchangeCodeConsumeResultVO> consumeResult = otherClient.consumeExchangeCodeBalance(exchangeCodeConsumeDTO);
                    if (consumeResult != null && consumeResult.getData() != null
                            && consumeResult.getData().getDeductedAmount() != null) {
                        exchangeCodeDeductAmount = consumeResult.getData().getDeductedAmount();
                BigDecimal balanceUsedAmount = BigDecimal.ZERO;
                if (isBalancePayMode(chargingOrder.getPayMethod()) && chargingOrder.getAppUserId() != null && payAmount.compareTo(BigDecimal.ZERO) > 0) {
                    balanceUsedAmount = money(chargingOrder.getBalancePayAmount()).min(payAmount).setScale(2, RoundingMode.HALF_UP);
                    if (balanceUsedAmount.compareTo(BigDecimal.ZERO) > 0) {
                        ExchangeCodeConsumeDTO exchangeCodeConsumeDTO = new ExchangeCodeConsumeDTO();
                        exchangeCodeConsumeDTO.setUserId(chargingOrder.getAppUserId());
                        exchangeCodeConsumeDTO.setOrderId(chargingOrder.getId());
                        exchangeCodeConsumeDTO.setAmount(balanceUsedAmount);
                        R<ExchangeCodeConsumeResultVO> consumeResult = otherClient.consumeExchangeCodeBalance(exchangeCodeConsumeDTO);
                        if (consumeResult != null && consumeResult.getData() != null
                                && consumeResult.getData().getDeductedAmount() != null) {
                            balanceUsedAmount = consumeResult.getData().getDeductedAmount();
                        }
                    }
                }
                payAmount = payAmount.subtract(exchangeCodeDeductAmount);
                if (payAmount.compareTo(BigDecimal.ZERO) < 0) {
                    payAmount = BigDecimal.ZERO;
                BigDecimal balanceRefundAmount = money(chargingOrder.getBalancePayAmount()).subtract(balanceUsedAmount);
                if (balanceRefundAmount.compareTo(BigDecimal.ZERO) > 0) {
                    changeUserBalance(chargingOrder.getAppUserId(), balanceRefundAmount);
                }
                chargingOrder.setPaymentAmount(payAmount.setScale(2, RoundingMode.HALF_EVEN));
                BigDecimal actualThirdPayAmount = payAmount.subtract(balanceUsedAmount);
                if (actualThirdPayAmount.compareTo(BigDecimal.ZERO) < 0) {
                    actualThirdPayAmount = BigDecimal.ZERO;
                }
                BigDecimal thirdRefundAmount = money(chargingOrder.getThirdPayAmount()).subtract(actualThirdPayAmount);
                if (thirdRefundAmount.compareTo(BigDecimal.ZERO) < 0) {
                    thirdRefundAmount = BigDecimal.ZERO;
                }
                refundAmount = thirdRefundAmount.add(balanceRefundAmount);
                chargingOrder.setBalanceRefundAmount(balanceRefundAmount.setScale(2, RoundingMode.HALF_UP));
                chargingOrder.setThirdRefundAmount(thirdRefundAmount.setScale(2, RoundingMode.HALF_UP));
                chargingOrder.setPaymentAmount(actualThirdPayAmount.setScale(2, RoundingMode.HALF_EVEN));
                chargingOrder.setRefundAmount(refundAmount.setScale(2, RoundingMode.HALF_EVEN));
                chargingOrder.setRefundStatus(1);
                UploadRealTimeMonitoringData asc = uploadRealTimeMonitoringDataService.getDataByOrderCode(chargingOrder.getCode(), "asc");
ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TChargingOrderMapper.xml
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.order.mapper.TChargingOrderMapper">
@@ -23,6 +23,11 @@
        <result column="recharge_amount" property="rechargeAmount"/>
        <result column="recharge_payment_type" property="rechargePaymentType"/>
        <result column="recharge_payment_status" property="rechargePaymentStatus"/>
        <result column="pay_method" property="payMethod"/>
        <result column="balance_pay_amount" property="balancePayAmount"/>
        <result column="third_pay_amount" property="thirdPayAmount"/>
        <result column="balance_refund_amount" property="balanceRefundAmount"/>
        <result column="third_refund_amount" property="thirdRefundAmount"/>
        <result column="recharge_serial_number" property="rechargeSerialNumber"/>
        <result column="residual_amount" property="residualAmount"/>
        <result column="order_amount" property="orderAmount"/>
@@ -46,7 +51,7 @@
    <sql id="Base_Column_List">
        id, code, order_type, order_classification, app_user_id, app_user_car_id,site_id, parking_lot_id,
        charging_pile_id, charging_gun_id,
        start_time, end_time, status, recharge_amount, recharge_payment_type, recharge_payment_status,
        start_time, end_time, status, recharge_amount, recharge_payment_type, recharge_payment_status, pay_method, balance_pay_amount, third_pay_amount, balance_refund_amount, third_refund_amount,
        recharge_serial_number,
        order_amount, app_coupon_id, coupon_discount_amount, vip_discount, vip_discount_amount, payment_amount,
        refund_code,
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TExchangeCodePackageServiceImpl.java
@@ -283,7 +283,8 @@
        record.setDetailId(detail.getId());
        record.setOrderId(0L);
        record.setUserId(userId);
        record.setUsedAmount(amount);
        fillUseRecordAmount(record, amount, detail.getGiftRatio());
        record.setRecordChangeType(1);
        useRecordMapper.insert(record);
        refreshPackageStats(exchangePackage.getId());
        ExchangeCodeBindResultVO resultVO = new ExchangeCodeBindResultVO();
@@ -382,7 +383,8 @@
            record.setDetailId(detail.getId());
            record.setOrderId(dto.getOrderId());
            record.setUserId(dto.getUserId());
            record.setUsedAmount(useAmount);
            fillUseRecordAmount(record, useAmount, detail.getGiftRatio());
            record.setRecordChangeType(2);
            useRecordMapper.insert(record);
            remainingNeed = remainingNeed.subtract(useAmount);
            deductedAmount = deductedAmount.add(useAmount);
@@ -582,6 +584,22 @@
        }
    }
    private void fillUseRecordAmount(TExchangeCodeUseRecord record, BigDecimal amount, BigDecimal giftRatio) {
        BigDecimal usedAmount = defaultMoney(amount);
        BigDecimal ratio = giftRatio == null ? BigDecimal.ZERO : giftRatio;
        if (ratio.compareTo(BigDecimal.ZERO) < 0) {
            ratio = BigDecimal.ZERO;
        }
        BigDecimal giftUsedAmount = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
        if (ratio.compareTo(BigDecimal.ZERO) > 0) {
            BigDecimal divisor = BigDecimal.ONE.add(ratio);
            BigDecimal principalAmount = usedAmount.divide(divisor, 2, RoundingMode.HALF_UP);
            giftUsedAmount = usedAmount.subtract(principalAmount).setScale(2, RoundingMode.HALF_UP);
        }
        record.setUsedAmount(usedAmount);
        record.setGiftUsedAmount(giftUsedAmount);
    }
    private BigDecimal defaultMoney(BigDecimal amount) {
        return amount == null ? BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP)
                : amount.setScale(2, RoundingMode.HALF_UP);