From c825a6f7e52ce1d61b21c352861c1da082a9fcb6 Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期二, 13 十月 2026 17:50:24 +0800
Subject: [PATCH] 修改小程序bug

---
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java |  845 +++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 746 insertions(+), 99 deletions(-)

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 38a1afb..8d08113 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
@@ -15,6 +15,7 @@
 import com.ruoyi.account.api.vo.GetAppUserVipDetail;
 import com.ruoyi.account.api.vo.GetInviteUser;
 import com.ruoyi.chargingPile.api.dto.GetSiteListDTO;
+import com.ruoyi.chargingPile.api.dto.TBillingTemplateDTO;
 import com.ruoyi.chargingPile.api.feignClient.*;
 import com.ruoyi.chargingPile.api.model.*;
 import com.ruoyi.chargingPile.api.support.ReservationTimeRangeSupport;
@@ -55,11 +56,13 @@
 import com.ruoyi.order.mapper.TChargingOrderMapper;
 import com.ruoyi.order.mapper.TChargingOrderShareRecordMapper;
 import com.ruoyi.order.mapper.TSettlementConfirmMapper;
+import com.ruoyi.order.mapper.TVinChargingOrderMapper;
 import com.ruoyi.order.service.TChargingOrderAccountingStrategyService;
 import com.ruoyi.order.service.TChargingOrderRefundService;
 import com.ruoyi.order.service.TChargingOrderService;
 import com.ruoyi.order.service.TOrderEvaluateService;
 import com.ruoyi.order.service.*;
+import com.ruoyi.order.support.ChargeAccountSupport;
 import com.ruoyi.order.support.ReservationOrderSupport;
 import com.ruoyi.order.support.ReservationRecommendationCalculator;
 import com.ruoyi.order.util.mongodb.service.PlatformStartChargingReplyService;
@@ -74,6 +77,8 @@
 import com.ruoyi.other.api.domain.*;
 import com.ruoyi.order.vo.ChargingOrderListInfoVO;
 import com.ruoyi.other.api.domain.TVip;
+import com.ruoyi.other.api.dto.ChargeAuthorizationDTO;
+import com.ruoyi.other.api.dto.CompanyPreferentialDTO;
 import com.ruoyi.other.api.dto.ExchangeCodeConsumeDTO;
 import com.ruoyi.other.api.feignClient.*;
 import com.ruoyi.other.api.vo.ExchangeCodeConsumeResultVO;
@@ -136,8 +141,6 @@
 
     private Logger log = LoggerFactory.getLogger(TChargingOrderServiceImpl.class);
     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;
     private static final String SHARE_AFTER_COMMIT_RESOURCE_PREFIX = "chargingOrderShareAfterCommit:";
     private static final String SPECIAL_REFUND_TITLE = "特殊退款处理";
     private static final int RESERVATION_RECOMMENDATION_HISTORY_DAYS = 30;
@@ -238,6 +241,8 @@
     private AppCouponClient appCouponClient;
     @Resource
     private AppUserWhitelistClient appUserWhitelistClient;
+    @Resource
+    private GroupCompanyClient groupCompanyClient;
 
     @Resource
     private AppUserVipDetailClient appUserVipDetailClient;
@@ -247,6 +252,9 @@
 
     @Resource
     private UploadRealTimeMonitoringDataService uploadRealTimeMonitoringDataService;
+
+    @Resource
+    private TVinChargingOrderMapper vinChargingOrderMapper;
 
     @Resource
     private TCECClient tcecClient;
@@ -267,6 +275,12 @@
 
     @Resource
     private AccountingStrategyClient accountingStrategyClient;
+
+    @Resource
+    private ChargeAccountSupport chargeAccountSupport;
+
+    @Resource
+    private ChargeAuthorizationClient chargeAuthorizationClient;
 
     @Resource
     private PlatformStartChargingReplyService platformStartChargingReplyService;
@@ -766,6 +780,140 @@
     }
 
     /**
+     * 判断订单是否为白名单专属订单(企业账户流程订单或历史白名单权益订单):
+     * 此类订单按企业优惠/历史权益结算,不参与会员折扣、优惠券等普通用户特权;
+     * 白名单用户选择第三方支付的订单(无企业账户模式、无权益类型)不在此列,按普通用户流程执行。
+     *
+     * @param chargingOrder 充电订单
+     * @return true=白名单专属订单
+     */
+    private boolean isWhitelistSpecialOrder(TChargingOrder chargingOrder) {
+        return isWhitelistOrder(chargingOrder)
+                && (chargingOrder.getAccountMode() != null || chargingOrder.getWhitelistBenefitType() != null);
+    }
+
+    /**
+     * 判断订单是否为白名单企业账户订单(企业账户流程的唯一判定口径):
+     * 白名单订单且已写入账户模式(共享/分配)时按企业优惠与额度结算,第三方支付白名单订单/历史权益订单返回false。
+     *
+     * @param chargingOrder 充电订单
+     * @return true=白名单企业账户订单
+     */
+    @Override
+    public boolean isWhitelistEnterpriseOrder(TChargingOrder chargingOrder) {
+        return null != chargingOrder && isWhitelistSpecialOrder(chargingOrder) && null != chargingOrder.getAccountMode();
+    }
+
+    /**
+     * 解析白名单企业账户充电上下文(白名单用户选择余额支付时调用):
+     * 1) 校验归属公司存在且启用,未归属/停用直接拒绝;
+     * 2) 校验企业充电授权(站点范围、可用时段/电价阶段)并计算授权截止时间,未配置授权按放行处理(对齐 VIN 口径);
+     * 3) 下发额度 = min(用户输入充值金额, 账户可用额度, 企业设定的充值金额):
+     *    - 账户可用额度:共享模式=公司可用余额,分配模式=白名单账户余额;
+     *    - 企业设定充值金额=授权配置下发金额,未配置默认 200 元;
+     *    - 用户输入金额为空或非正数时按 min(企业设定充值金额, 账户可用额度) 下发。
+     *
+     * @param whitelist       白名单命中结果(含归属公司与账户余额快照)
+     * @param userInputAmount 用户输入的充值金额
+     * @param siteId          站点ID(授权站点范围校验用)
+     * @param strategyId      计费策略ID(指定电价时段授权校验用)
+     * @return 企业账户上下文;失败时 failReason 为提示文案
+     */
+    private ChargeAccountSupport.ChargeContext resolveWhitelistEnterpriseContext(AppUserWhitelistMatchVO whitelist,
+                                                                                BigDecimal userInputAmount,
+                                                                                Integer siteId,
+                                                                                Integer strategyId) {
+        Integer companyId = whitelist.getCompanyId();
+        if (companyId == null) {
+            return ChargeAccountSupport.ChargeContext.fail(2, "账号未归属公司,无法使用企业额度充电,请选择其他支付方式");
+        }
+        TGroupCompany company;
+        try {
+            R<TGroupCompany> companyResult = groupCompanyClient.getCompanyById(companyId);
+            company = companyResult == null ? null : companyResult.getData();
+        } catch (Exception ex) {
+            log.error("[CD建单] 查询所属公司失败 companyId={}", companyId, ex);
+            return ChargeAccountSupport.ChargeContext.fail(2, "查询所属公司失败,请稍后重试或选择其他支付方式");
+        }
+        if (company == null) {
+            return ChargeAccountSupport.ChargeContext.fail(2, "所属公司不存在,无法使用企业额度充电");
+        }
+        if (company.getStatus() != null && company.getStatus() != 1) {
+            return ChargeAccountSupport.ChargeContext.fail(2, "所属公司已停用,无法使用企业额度充电");
+        }
+        int accountMode = company.getAccountMode() == null
+                ? ChargeAccountSupport.ACCOUNT_MODE_SHARED : company.getAccountMode();
+
+        ChargeAuthorizationDTO authorization = null;
+        try {
+            R<ChargeAuthorizationDTO> authResult = chargeAuthorizationClient.getDetailByCompanyId(companyId);
+            authorization = authResult == null ? null : authResult.getData();
+        } catch (Exception ex) {
+            log.error("[CD建单] 查询充电授权失败,按未配置授权放行 companyId={}", companyId, ex);
+        }
+        LocalDateTime maxEndTime = null;
+        if (authorization != null) {
+            if (authorization.getSiteIds() != null && !authorization.getSiteIds().isEmpty()
+                    && (siteId == null || !authorization.getSiteIds().contains(siteId))) {
+                return ChargeAccountSupport.ChargeContext.fail(5, "当前站点不在企业充电授权范围内,请选择其他支付方式");
+            }
+            ChargeAccountSupport.AuthorizationWindow window = chargeAccountSupport
+                    .resolveAuthorizationWindow(authorization, strategyId, companyId);
+            if (window == null) {
+                return ChargeAccountSupport.ChargeContext.fail(2, "当前时间不在企业充电授权时段内,请选择其他支付方式");
+            }
+            maxEndTime = window.getMaxEndTime();
+        }
+
+        BigDecimal usableAmount = accountMode == ChargeAccountSupport.ACCOUNT_MODE_ALLOCATED
+                ? whitelist.getBalance() : company.getAvailableBalance();
+        BigDecimal usable = money(usableAmount);
+        if (usable.compareTo(BigDecimal.ZERO) <= 0) {
+            return ChargeAccountSupport.ChargeContext.fail(3, "企业额度不足,请选择其他支付方式");
+        }
+        BigDecimal enterpriseLimit = authorization == null ? null : authorization.getDispatchAmount();
+        if (enterpriseLimit == null || enterpriseLimit.compareTo(BigDecimal.ZERO) <= 0) {
+            enterpriseLimit = ChargeAccountSupport.DEFAULT_DISPATCH_AMOUNT;
+        }
+        BigDecimal dispatch = money(userInputAmount);
+        dispatch = dispatch.compareTo(BigDecimal.ZERO) <= 0
+                ? enterpriseLimit.min(usable)
+                : dispatch.min(enterpriseLimit).min(usable);
+        return ChargeAccountSupport.ChargeContext.ok(accountMode, dispatch.setScale(2, RoundingMode.HALF_UP), maxEndTime);
+    }
+
+    /**
+     * 锁定企业充电额度(共享=企业账户余额,分配=白名单账户余额),返回是否锁定成功
+     *
+     * @param context   企业账户上下文(含账户模式与下发额度)
+     * @param whitelist 白名单命中结果(含白名单ID与归属公司ID)
+     * @return true=锁定成功
+     */
+    private boolean lockWhitelistEnterpriseAmount(ChargeAccountSupport.ChargeContext context,
+                                                  AppUserWhitelistMatchVO whitelist) {
+        try {
+            R<BigDecimal> result;
+            if (Integer.valueOf(ChargeAccountSupport.ACCOUNT_MODE_ALLOCATED).equals(context.getAccountMode())) {
+                result = appUserWhitelistClient.lockBalance(whitelist.getWhitelistId(), context.getDispatchAmount());
+            } else {
+                result = groupCompanyClient.lockBalance(whitelist.getCompanyId(), context.getDispatchAmount());
+            }
+            if (result == null || result.getCode() != R.SUCCESS) {
+                log.error("[CD建单] 锁定企业额度失败 accountMode={} companyId={} whitelistId={} amount={} msg={}",
+                        context.getAccountMode(), whitelist.getCompanyId(), whitelist.getWhitelistId(),
+                        context.getDispatchAmount(), result == null ? "null" : result.getMsg());
+                return false;
+            }
+            return true;
+        } catch (Exception ex) {
+            log.error("[CD建单] 锁定企业额度异常 accountMode={} companyId={} whitelistId={} amount={}",
+                    context.getAccountMode(), whitelist.getCompanyId(), whitelist.getWhitelistId(),
+                    context.getDispatchAmount(), ex);
+            return false;
+        }
+    }
+
+    /**
      * 按白名单权益拆分电费和服务费减免金额,财务统计需要分开展示两类退款金额
      *
      * @param chargingOrder  充电订单
@@ -774,11 +922,229 @@
      * @return 数组下标0=电费减免,下标1=服务费减免
      */
     private BigDecimal[] calculateWhitelistRefundSplit(TChargingOrder chargingOrder, BigDecimal electrovalence, BigDecimal serviceCharge) {
-        return ChargingCouponSupport.calculateWhitelistRefundSplit(
+        return ChargingCouponSupport.calculateWhitelistRefundSplitByBenefitType(
                 isWhitelistOrder(chargingOrder),
-                isWhitelistAllFreeOrder(chargingOrder),
+                chargingOrder == null ? null : chargingOrder.getWhitelistBenefitType(),
                 electrovalence,
                 serviceCharge);
+    }
+
+    /**
+     * 结算企业账户额度(白名单企业账户流程):
+     * 共享模式结算公司余额,分配模式结算白名单账户余额;按实际消费扣减锁定额度、差额退回原账户,
+     * 结算失败返回false,由调用方回滚订单状态等待补偿重试。
+     *
+     * @param chargingOrder 充电订单(含companyId/accountMode/lockedAmount/whitelistId)
+     * @param actualAmount  实际消费金额
+     * @return true=结算成功或非企业账户订单
+     */
+    @Override
+    public boolean settleWhitelistEnterpriseAccount(TChargingOrder chargingOrder, BigDecimal actualAmount) {
+        if (!isWhitelistEnterpriseOrder(chargingOrder)) {
+            return true;
+        }
+        BigDecimal lockedAmount = money(chargingOrder.getLockedAmount());
+        BigDecimal actual = money(actualAmount).max(BigDecimal.ZERO);
+        if (lockedAmount.compareTo(BigDecimal.ZERO) <= 0) {
+            log.info("[CD结算] 企业账户订单无锁定金额,跳过额度结算 code={}", chargingOrder.getCode());
+            return true;
+        }
+        boolean allocated = Integer.valueOf(ChargeAccountSupport.ACCOUNT_MODE_ALLOCATED).equals(chargingOrder.getAccountMode());
+        BigDecimal afterBalance;
+        try {
+            R<BigDecimal> settleResult;
+            if (allocated && null != chargingOrder.getWhitelistId()) {
+                settleResult = appUserWhitelistClient.settleBalance(chargingOrder.getWhitelistId(), lockedAmount, actual);
+            } else {
+                // 订单侧自行写消费流水,此处不传订单号(账户侧仅在订单号非空时做幂等与流水,避免重复记账)
+                settleResult = groupCompanyClient.settleBalance(chargingOrder.getCompanyId(), lockedAmount, actual,
+                        null, null, null, null);
+            }
+            if (null == settleResult || R.SUCCESS != settleResult.getCode()) {
+                log.error("[CD结算] 企业账户额度结算失败 code={} accountMode={} companyId={} locked={} actual={} msg={}",
+                        chargingOrder.getCode(), chargingOrder.getAccountMode(), chargingOrder.getCompanyId(),
+                        lockedAmount, actual, null == settleResult ? "null" : settleResult.getMsg());
+                return false;
+            }
+            afterBalance = settleResult.getData();
+        } catch (Exception ex) {
+            log.error("[CD结算] 企业账户额度结算异常 code={} accountMode={} companyId={} locked={} actual={}",
+                    chargingOrder.getCode(), chargingOrder.getAccountMode(), chargingOrder.getCompanyId(), lockedAmount, actual, ex);
+            return false;
+        }
+        recordWhitelistEnterpriseConsume(chargingOrder, actual, lockedAmount, afterBalance, allocated);
+        log.info("[CD结算] 企业账户额度结算完成 code={} accountMode={} locked={} actual={} balance={}",
+                chargingOrder.getCode(), chargingOrder.getAccountMode(), lockedAmount, actual, afterBalance);
+        return true;
+    }
+
+    /**
+     * 写企业额度分配记录-消费流水:分配模式记白名单账户,共享模式记企业账户;
+     * 消费前余额 = 结算后余额 + 实际消费 - 锁定额度(实扣冻结口径反推),流水失败不影响结算结果。
+     */
+    private void recordWhitelistEnterpriseConsume(TChargingOrder chargingOrder, BigDecimal actual, BigDecimal lockedAmount,
+                                                  BigDecimal afterBalance, boolean allocated) {
+        if (actual.compareTo(BigDecimal.ZERO) <= 0) {
+            return;
+        }
+        String userInfo;
+        String userName;
+        if (allocated) {
+            userInfo = null == chargingOrder.getWhitelistId() ? null : String.valueOf(chargingOrder.getWhitelistId());
+            userName = userInfo;
+        } else {
+            TGroupCompany company = chargeAccountSupport.queryCompanyQuietly(chargingOrder.getCompanyId());
+            String companyName = null == company ? null : company.getName();
+            userInfo = null == companyName || companyName.isEmpty() ? String.valueOf(chargingOrder.getCompanyId()) : companyName;
+            userName = companyName;
+        }
+        BigDecimal after = null == afterBalance ? BigDecimal.ZERO : afterBalance;
+        BigDecimal before = after.add(actual).subtract(lockedAmount);
+        chargeAccountSupport.recordConsume(chargingOrder.getCompanyId(),
+                allocated ? TCompanyAllocateRecord.USER_TYPE_WHITELIST : TCompanyAllocateRecord.USER_TYPE_COMPANY,
+                userInfo, userName, before, actual.negate(), chargingOrder.getCode(), "充电桩充电结算");
+    }
+
+    /**
+     * 释放企业账户锁定额度(订单未结算/关单时调用;失败仅记录日志,不影响主流程)
+     * 释放幂等:先用条件更新抢占 lock_released 标记(0->1),保证同一订单的锁定额在多路径并发或
+     * 重复补偿下只释放一次;释放失败把标记回滚为 0,留待后续补偿或人工重试。
+     */
+    @Override
+    public void unlockWhitelistEnterpriseAmountQuietly(TChargingOrder chargingOrder, String scene) {
+        if (!isWhitelistEnterpriseOrder(chargingOrder)) {
+            return;
+        }
+        BigDecimal lockedAmount = money(chargingOrder.getLockedAmount());
+        if (lockedAmount.compareTo(BigDecimal.ZERO) <= 0) {
+            return;
+        }
+        boolean claimed;
+        try {
+            claimed = lambdaUpdate()
+                    .eq(TChargingOrder::getId, chargingOrder.getId())
+                    .eq(TChargingOrder::getLockReleased, 0)
+                    .set(TChargingOrder::getLockReleased, 1)
+                    .update();
+        } catch (Exception ex) {
+            log.error("[CD关单] 抢占锁定额释放标记异常 scene={} code={}", scene, chargingOrder.getCode(), ex);
+            return;
+        }
+        if (!claimed) {
+            log.info("[CD关单] 锁定额已释放,跳过重复释放 scene={} code={}", scene, chargingOrder.getCode());
+            return;
+        }
+        boolean unlocked = false;
+        try {
+            R<BigDecimal> result;
+            if (Integer.valueOf(ChargeAccountSupport.ACCOUNT_MODE_ALLOCATED).equals(chargingOrder.getAccountMode())
+                    && null != chargingOrder.getWhitelistId()) {
+                result = appUserWhitelistClient.unlockBalance(chargingOrder.getWhitelistId(), lockedAmount);
+            } else {
+                result = groupCompanyClient.unlockBalance(chargingOrder.getCompanyId(), lockedAmount);
+            }
+            if (null == result || R.SUCCESS != result.getCode()) {
+                log.error("[CD关单] 释放企业账户锁定额度失败 scene={} code={} companyId={} amount={} msg={}",
+                        scene, chargingOrder.getCode(), chargingOrder.getCompanyId(), lockedAmount,
+                        null == result ? "null" : result.getMsg());
+            } else {
+                unlocked = true;
+                log.info("[CD关单] 释放企业账户锁定额度完成 scene={} code={} amount={}", scene, chargingOrder.getCode(), lockedAmount);
+            }
+        } catch (Exception ex) {
+            log.error("[CD关单] 释放企业账户锁定额度异常 scene={} code={} companyId={} amount={}",
+                    scene, chargingOrder.getCode(), chargingOrder.getCompanyId(), lockedAmount, ex);
+        }
+        if (!unlocked) {
+            // 释放失败回滚标记(1->0),保证锁定额不被“标记已释放”而漏释放,可被后续补偿重试
+            lambdaUpdate()
+                    .eq(TChargingOrder::getId, chargingOrder.getId())
+                    .eq(TChargingOrder::getLockReleased, 1)
+                    .set(TChargingOrder::getLockReleased, 0)
+                    .update();
+        }
+    }
+
+    /**
+     * 企业账户订单无任何设备数据/账单时的兜底关单:释放锁定额度并终结订单(金额0、状态5、结算完成标记),
+     * 保证订单不被任何补偿任务重复扫描重跑。释放幂等由 lock_released 抢占保证;状态条件更新保证只终结一次。
+     */
+    @Override
+    public void closeEnterpriseOrderWithoutData(TChargingOrder chargingOrder) {
+        if (!isWhitelistEnterpriseOrder(chargingOrder) || null == chargingOrder.getStatus()) {
+            return;
+        }
+        if (2 != chargingOrder.getStatus() && 3 != chargingOrder.getStatus() && 4 != chargingOrder.getStatus()) {
+            return;
+        }
+        // 释放企业账户锁定额度(lock_released 抢占保证只释放一次,失败回滚标记留待后续补偿重试)
+        unlockWhitelistEnterpriseAmountQuietly(chargingOrder, "无设备数据关单");
+        boolean closed = lambdaUpdate()
+                .eq(TChargingOrder::getId, chargingOrder.getId())
+                .in(TChargingOrder::getStatus, 2, 3, 4)
+                .set(TChargingOrder::getStatus, 5)
+                .set(TChargingOrder::getSettleStatus, 1)
+                .set(TChargingOrder::getRefundStatus, 2)
+                .set(TChargingOrder::getEndMode, 1)
+                .set(TChargingOrder::getEndTime, LocalDateTime.now())
+                .update();
+        if (closed) {
+            log.info("[CD关单] 企业账户订单无设备数据兜底关单完成 code={} companyId={} lockedAmount={}",
+                    chargingOrder.getCode(), chargingOrder.getCompanyId(), chargingOrder.getLockedAmount());
+        } else {
+            log.info("[CD关单] 企业账户订单状态已变更,跳过无设备数据兜底关单 code={}", chargingOrder.getCode());
+        }
+    }
+
+    /**
+     * 判断是否触发授权时间到期主动停充(白名单企业账户订单按授权截止时间提前下发停充指令)
+     */
+    private boolean needAuthorizeStop(TChargingOrder chargingOrder) {
+        if (null == chargingOrder || !isWhitelistSpecialOrder(chargingOrder) || null == chargingOrder.getMaxEndTime()) {
+            return false;
+        }
+        LocalDateTime startTime = null != chargingOrder.getStartTime() ? chargingOrder.getStartTime() : chargingOrder.getCreateTime();
+        return chargeAccountSupport.needAuthorizeStop(chargingOrder.getMaxEndTime(), startTime);
+    }
+
+    /**
+     * 授权时间到期主动停充:复用小程序主动停充口径(状态3-&gt;4、结束方式1)并下发硬件停止充电指令
+     */
+    private void stopByAuthorizeExpired(TChargingOrder chargingOrder) {
+        TChargingGun gun;
+        TChargingPile pile;
+        try {
+            R<TChargingGun> gunResult = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId());
+            gun = null == gunResult ? null : gunResult.getData();
+            R<TChargingPile> pileResult = null == chargingOrder.getChargingPileId() ? null
+                    : chargingPileClient.getChargingPileById(chargingOrder.getChargingPileId());
+            pile = null == pileResult ? null : pileResult.getData();
+        } catch (Exception ex) {
+            log.error("[CD停充] 授权到期停充查询设备异常 code={}", chargingOrder.getCode(), ex);
+            return;
+        }
+        if (null == gun || null == pile) {
+            log.error("[CD停充] 授权到期停充缺少设备信息 code={} gunId={}", chargingOrder.getCode(), chargingOrder.getChargingGunId());
+            return;
+        }
+        boolean updated = this.lambdaUpdate()
+                .eq(TChargingOrder::getId, chargingOrder.getId())
+                .eq(TChargingOrder::getStatus, 3)
+                .set(TChargingOrder::getStatus, 4)
+                .set(TChargingOrder::getEndMode, 1)
+                .set(TChargingOrder::getEndTime, LocalDateTime.now())
+                .update();
+        if (!updated) {
+            return;
+        }
+        chargingOrder.setStatus(4);
+        chargingOrder.setEndMode(1);
+        chargingOrder.setEndTime(LocalDateTime.now());
+        PlatformStopCharging platformStopCharging = new PlatformStopCharging();
+        platformStopCharging.setCharging_pile_code(pile.getCode());
+        platformStopCharging.setCharging_gun_code(gun.getCode());
+        sendMessageClient.platformStopCharging(platformStopCharging);
+        log.warn("[CD停充] 授权时间到期主动停充 code={} maxEndTime={}", chargingOrder.getCode(), chargingOrder.getMaxEndTime());
     }
 
     private TVip getVipSnapshot(TAppUserVipDetail vipDetail, Integer vipId) {
@@ -834,34 +1200,44 @@
         }
         AppUserWhitelistMatchVO whitelist = appUserWhitelistClient.matchWhitelist(userId, tChargingGun.getSiteId()).getData();
         boolean whitelistMatched = whitelist != null && Boolean.TRUE.equals(whitelist.getMatched());
-        if (whitelistMatched) {
-            addChargingOrder.setAppUserCouponId(null);
+        if (whitelistMatched && Integer.valueOf(2).equals(payMethod)) {
+            // 白名单用户不支持组合支付:仅支持余额支付(企业额度)与第三方支付
+            return AjaxResult.error("白名单用户不支持组合支付,请选择余额支付或第三方支付");
         }
-        boolean whitelistAllFree = whitelistMatched
-                && Integer.valueOf(WHITELIST_BENEFIT_ALL_FREE).equals(whitelist.getBenefitType());
+        // 白名单用户按支付方式分流:余额支付=企业账户流程(锁定额度+公司优惠结算),第三方支付=按普通用户流程执行
+        boolean enterpriseCharging = whitelistMatched && Integer.valueOf(1).equals(payMethod);
         BigDecimal userBalance = money(appUser.getBalance());
         BigDecimal balancePayAmount = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
-        if (payMethod == 2 && userBalance.compareTo(rechargeAmount) >= 0) {
-            payMethod = 1;
-            addChargingOrder.setPayMethod(1);
-        }
-        if (isBalancePayMode(payMethod)) {
+        BigDecimal payableAmount;
+        BigDecimal thirdPayAmount;
+        if (enterpriseCharging) {
+            // 企业账户流程不使用用户余额与优惠券,额度在企业上下文解析后锁定并作为下发金额
             addChargingOrder.setAppUserCouponId(null);
-        } else if (!whitelistMatched && addChargingOrder.getAppUserCouponId() != null) {
-            // 这里只校验优惠券,不抵扣预付金额;实际门槛和优惠金额在充电结束时计算。
-            validateSelectedChargingCoupon(addChargingOrder.getAppUserCouponId(), userId);
-        }
-        BigDecimal payableAmount = ChargingCouponSupport.calculatePrepaymentAmount(rechargeAmount, whitelistAllFree);
-        BigDecimal thirdPayAmount = payableAmount;
-        if (isBalancePayMode(payMethod)) {
-            if (payMethod == 1 && userBalance.compareTo(payableAmount) < 0) {
-                return AjaxResult.error("余额不足,请选择组合支付或第三方支付");
+            payableAmount = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
+            thirdPayAmount = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
+        } else {
+            if (payMethod == 2 && userBalance.compareTo(rechargeAmount) >= 0) {
+                payMethod = 1;
+                addChargingOrder.setPayMethod(1);
             }
-            balancePayAmount = payMethod == 1 ? payableAmount : userBalance.min(payableAmount).setScale(2, RoundingMode.HALF_UP);
-            thirdPayAmount = payableAmount.subtract(balancePayAmount).setScale(2, RoundingMode.HALF_UP);
+            if (isBalancePayMode(payMethod)) {
+                addChargingOrder.setAppUserCouponId(null);
+            } else if (addChargingOrder.getAppUserCouponId() != null) {
+                // 这里只校验优惠券,不抵扣预付金额;实际门槛和优惠金额在充电结束时计算。
+                validateSelectedChargingCoupon(addChargingOrder.getAppUserCouponId(), userId);
+            }
+            payableAmount = ChargingCouponSupport.calculatePrepaymentAmount(rechargeAmount, false);
+            thirdPayAmount = payableAmount;
+            if (isBalancePayMode(payMethod)) {
+                if (payMethod == 1 && userBalance.compareTo(payableAmount) < 0) {
+                    return AjaxResult.error("余额不足,请选择组合支付或第三方支付");
+                }
+                balancePayAmount = payMethod == 1 ? payableAmount : userBalance.min(payableAmount).setScale(2, RoundingMode.HALF_UP);
+                thirdPayAmount = payableAmount.subtract(balancePayAmount).setScale(2, RoundingMode.HALF_UP);
+            }
+            payMethod = ChargingPaymentSupport.resolvePayMethod(balancePayAmount, thirdPayAmount, payMethod);
+            addChargingOrder.setPayMethod(payMethod);
         }
-        payMethod = ChargingPaymentSupport.resolvePayMethod(balancePayAmount, thirdPayAmount, payMethod);
-        addChargingOrder.setPayMethod(payMethod);
         //检查当前枪是否是正在使用中
         TChargingOrder one = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getChargingGunId, addChargingOrder.getId())
                 .in(TChargingOrder::getStatus, Arrays.asList(3)).eq(TChargingOrder::getDelFlag, 0));
@@ -958,7 +1334,10 @@
         chargingOrder.setCouponDiscountAmount(BigDecimal.ZERO);
         chargingOrder.setIsWhitelist(whitelistMatched ? 1 : 0);
         chargingOrder.setWhitelistId(whitelistMatched ? whitelist.getWhitelistId() : null);
-        chargingOrder.setWhitelistBenefitType(whitelistMatched ? whitelist.getBenefitType() : null);
+        // 白名单权益已下线:订单不再记录权益类型,企业优惠通过 discount_* 列体现
+        chargingOrder.setWhitelistBenefitType(null);
+        chargingOrder.setCompanyId(whitelistMatched ? whitelist.getCompanyId() : null);
+        chargingOrder.setFleetId(whitelistMatched ? whitelist.getFleetId() : null);
         chargingOrder.setWhitelistDiscountAmount(BigDecimal.ZERO);
         chargingOrder.setWhitelistElectricRefundAmount(BigDecimal.ZERO);
         chargingOrder.setWhitelistServiceRefundAmount(BigDecimal.ZERO);
@@ -981,8 +1360,26 @@
         }
         TAccountingStrategy accountingStrategy = accountingStrategyClient.getAccountingStrategyById(accountingStrategyId).getData();
 
-        //会员折扣支持直营网点和加盟商站点
-        if (!whitelistMatched && Integer.valueOf(1).equals(site.getMemberDiscountFlag()) && null != appUser.getVipId()) {
+        // 白名单企业账户流程:解析企业授权上下文并锁定额度(下发额度=min(用户输入充值金额, 账户可用额度, 企业设定充值金额))
+        if (enterpriseCharging) {
+            ChargeAccountSupport.ChargeContext chargeContext =
+                    resolveWhitelistEnterpriseContext(whitelist, rechargeAmount, tChargingGun.getSiteId(), accountingStrategyId);
+            if (!chargeContext.isOk()) {
+                return AjaxResult.error(chargeContext.getFailReason());
+            }
+            if (!lockWhitelistEnterpriseAmount(chargeContext, whitelist)) {
+                return AjaxResult.error("企业额度锁定失败,请稍后重试或选择其他支付方式");
+            }
+            chargingOrder.setRechargeAmount(chargeContext.getDispatchAmount());
+            chargingOrder.setAccountMode(chargeContext.getAccountMode());
+            chargingOrder.setLockedAmount(chargeContext.getDispatchAmount());
+            chargingOrder.setMaxEndTime(chargeContext.getMaxEndTime());
+            // 企业优惠快照落库(建单时固化,结算/补偿优先读快照,抵抗公司优惠设置后续变更)
+            chargeAccountSupport.fillPreferentialSnapshot(chargingOrder, whitelist.getCompanyId());
+        }
+
+        //会员折扣支持直营网点和加盟商站点;余额支付(含组合支付)与企业账户流程不参与会员折扣
+        if (!enterpriseCharging && !isBalancePayMode(payMethod) && Integer.valueOf(1).equals(site.getMemberDiscountFlag()) && null != appUser.getVipId()) {
             GetAppUserVipDetail getAppUserVipDetail = new GetAppUserVipDetail();
             getAppUserVipDetail.setAppUserId(appUser.getId());
             getAppUserVipDetail.setVipId(appUser.getVipId());
@@ -998,29 +1395,37 @@
         }
         this.save(chargingOrder);
 
-        //添加订单的计费策略
-        List<TAccountingStrategyDetail> strategyDetailList = accountingStrategyDetailClient.getListByAccountingStrategyId(accountingStrategyId).getData();
-        AccountingStrategyOrder accountingStrategyOrder = new AccountingStrategyOrder();
-        BeanUtils.copyProperties(accountingStrategy, accountingStrategyOrder);
-        accountingStrategyOrder.setChargingOrderId(chargingOrder.getId());
-        accountingStrategyOrderService.save(accountingStrategyOrder);
-        List<AccountingStrategyDetailOrder> list1 = new ArrayList<>();
-        for (TAccountingStrategyDetail tAccountingStrategyDetail : strategyDetailList) {
-            AccountingStrategyDetailOrder accountingStrategyDetailOrder = new AccountingStrategyDetailOrder();
-            BeanUtils.copyProperties(tAccountingStrategyDetail, accountingStrategyDetailOrder);
-            accountingStrategyDetailOrder.setChargingOrderId(chargingOrder.getId());
-            accountingStrategyDetailOrder.setCreateTime(LocalDateTime.now());
-            accountingStrategyDetailOrder.setDelFlag(false);
-            list1.add(accountingStrategyDetailOrder);
-        }
-        accountingStrategyDetailOrderService.saveBatch(list1);
+        try {
+            //添加订单的计费策略
+            List<TAccountingStrategyDetail> strategyDetailList = accountingStrategyDetailClient.getListByAccountingStrategyId(accountingStrategyId).getData();
+            AccountingStrategyOrder accountingStrategyOrder = new AccountingStrategyOrder();
+            BeanUtils.copyProperties(accountingStrategy, accountingStrategyOrder);
+            accountingStrategyOrder.setChargingOrderId(chargingOrder.getId());
+            accountingStrategyOrderService.save(accountingStrategyOrder);
+            List<AccountingStrategyDetailOrder> list1 = new ArrayList<>();
+            for (TAccountingStrategyDetail tAccountingStrategyDetail : strategyDetailList) {
+                AccountingStrategyDetailOrder accountingStrategyDetailOrder = new AccountingStrategyDetailOrder();
+                BeanUtils.copyProperties(tAccountingStrategyDetail, accountingStrategyDetailOrder);
+                accountingStrategyDetailOrder.setChargingOrderId(chargingOrder.getId());
+                accountingStrategyDetailOrder.setCreateTime(LocalDateTime.now());
+                accountingStrategyDetailOrder.setDelFlag(false);
+                list1.add(accountingStrategyDetailOrder);
+            }
+            accountingStrategyDetailOrderService.saveBatch(list1);
 
-        if (thirdPayAmount.compareTo(BigDecimal.ZERO) == 0 && balancePayAmount.compareTo(BigDecimal.ZERO) > 0) {
-            changeUserBalance(userId, balancePayAmount.negate());
-            recordBalanceConsume(chargingOrder, balancePayAmount);
-        }
-        if (thirdPayAmount.compareTo(BigDecimal.ZERO) == 0) {
-            return completeChargingOrderPayment(chargingOrder, whitelistMatched ? "WHITELIST" : "BALANCE");
+            if (thirdPayAmount.compareTo(BigDecimal.ZERO) == 0 && balancePayAmount.compareTo(BigDecimal.ZERO) > 0) {
+                changeUserBalance(userId, balancePayAmount.negate());
+                recordBalanceConsume(chargingOrder, balancePayAmount);
+            }
+            if (thirdPayAmount.compareTo(BigDecimal.ZERO) == 0) {
+                return completeChargingOrderPayment(chargingOrder, enterpriseCharging ? "WHITELIST" : "BALANCE");
+            }
+        } catch (RuntimeException ex) {
+            if (enterpriseCharging) {
+                //企业账户流程:建单后续流程异常时释放已锁定的企业额度,避免企业额度被长期占用
+                unlockWhitelistEnterpriseAmountQuietly(chargingOrder, "建单后续流程异常");
+            }
+            throw ex;
         }
         //会员优惠折扣将其计入增加充电时长(增加总充电金额)
         //如果充电总金额未使用完,则需要退回费用=(原金额/总金额)*(总金额-实际充电金额)
@@ -1553,8 +1958,8 @@
         BigDecimal s_degrees = tChargingGun.getRatedPower().divide(new BigDecimal(3600), 6, RoundingMode.HALF_EVEN);
 
         TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData();
-        //判断会员是否还有充电优惠次数,计算会员优惠的折扣金额
-        if (!isWhitelistOrder(chargingOrder) && null != appUser.getVipId() && isEffectiveVipDiscount(discount)) {
+        //判断会员是否还有充电优惠次数,计算会员优惠的折扣金额;余额支付(含组合支付)不参与会员折扣
+        if (!isWhitelistOrder(chargingOrder) && !isBalancePayMode(chargingOrder.getPayMethod()) && null != appUser.getVipId() && isEffectiveVipDiscount(discount)) {
             GetAppUserVipDetail getAppUserVipDetail = new GetAppUserVipDetail();
             getAppUserVipDetail.setAppUserId(chargingOrder.getAppUserId());
             getAppUserVipDetail.setVipId(appUser.getVipId());
@@ -2068,10 +2473,16 @@
                             changeUserBalance(chargingOrder.getAppUserId(), balanceRefundAmount);
                             recordBalanceRefund(chargingOrder, balanceRefundAmount, chargingOrderRefund.getRefundCode());
                         }
-                        chargingOrderRefund.setRefundStatus(2);
-                        chargingOrderRefund.setRefundSerialNumber(isWhitelistAllFreeOrder(chargingOrder) ? "WHITELIST" : "BALANCE");
-                        chargingOrderRefund.setRefundTime(LocalDateTime.now());
-                        chargingOrderRefundService.save(chargingOrderRefund);
+                        //企业账户流程:启动失败全额释放已锁定的企业额度(订单未产生消费)
+                        unlockWhitelistEnterpriseAmountQuietly(chargingOrder, "启动失败退款");
+                        //企业账户订单资金全部来自企业账户额度,无用户侧渠道/余额退款,不落退款明细(保持 0 行),
+                        //仅更新订单退款快照字段与状态,避免 0 元退款记录进入退款对账
+                        if (!isWhitelistEnterpriseOrder(chargingOrder)) {
+                            chargingOrderRefund.setRefundStatus(2);
+                            chargingOrderRefund.setRefundSerialNumber(isWhitelistAllFreeOrder(chargingOrder) ? "WHITELIST" : "BALANCE");
+                            chargingOrderRefund.setRefundTime(LocalDateTime.now());
+                            chargingOrderRefundService.save(chargingOrderRefund);
+                        }
                         this.updateById(chargingOrder);
                         return;
                     }
@@ -2360,7 +2771,19 @@
                 .orderByDesc(TChargingOrder::getCreateTime)
                 .last(" limit 0, 1"));
         if (null == one || !one.getAppUserId().equals(userId)) {
-            return null;
+            // VIN 码充电订单兜底:VD 订单存于 t_vin_charging_order,且后付模式无支付动作,
+            // 不按 rechargePaymentStatus 过滤;TVinChargingOrder 继承 TChargingOrder,后续组装原样复用
+            TVinChargingOrder vinOrder = vinChargingOrderMapper.selectOne(new LambdaQueryWrapper<TVinChargingOrder>()
+                    .eq(TVinChargingOrder::getAppUserId, userId)
+                    .eq(TVinChargingOrder::getChargingGunId, id)
+                    .in(TVinChargingOrder::getStatus, Arrays.asList(2, 3, 4))
+                    .eq(TVinChargingOrder::getDelFlag, 0)
+                    .orderByDesc(TVinChargingOrder::getCreateTime)
+                    .last(" limit 0, 1"));
+            if (null == vinOrder) {
+                return null;
+            }
+            one = vinOrder;
         }
         ChargingDetails chargingDetails = new ChargingDetails();
         chargingDetails.setId(one.getId().toString());
@@ -2718,6 +3141,7 @@
         fillChargingOrderBalanceIncome(list);
         fillChargingOrderShareIncome(list);
         fillChargingOrderPageExtra(list, dto.getSiteIds(), sysUser, roleType);
+        fillChargingOrderCompanyFleetNames(list);
         pageInfo.setRecords(list);
         return pageInfo;
     }
@@ -2793,6 +3217,8 @@
                 && dto.getIsWhitelist() == null
                 && dto.getPaymentType() == null
                 && dto.getOrderSource() == null
+                && dto.getCompanyId() == null
+                && dto.getFleetId() == null
                 && (dto.getUserIds() == null || dto.getUserIds().isEmpty());
     }
 
@@ -2883,6 +3309,73 @@
             chargingOrderVO.setCount(strategies.size());
             chargingOrderVO.setLicensePlate(chargingOrderVO.getPlateNum());
         }
+    }
+
+    /**
+     * 回填充电桩订单所属公司/车队名称:按订单快照 companyId/fleetId 批量远程取名(公司/车队改名后列表即时生效),
+     * 远程调用失败仅跳过回填,不影响列表其他字段。
+     */
+    private void fillChargingOrderCompanyFleetNames(List<ChargingOrderVO> list) {
+        if (list == null || list.isEmpty()) {
+            return;
+        }
+        List<Integer> companyIds = list.stream().map(ChargingOrderVO::getCompanyId)
+                .filter(Objects::nonNull).distinct().collect(Collectors.toList());
+        if (!companyIds.isEmpty()) {
+            Map<Integer, String> companyNames = loadChargingOrderCompanyNames(companyIds);
+            for (ChargingOrderVO item : list) {
+                String name = item.getCompanyId() == null ? null : companyNames.get(item.getCompanyId());
+                if (StringUtils.hasLength(name)) {
+                    item.setCompanyName(name);
+                }
+            }
+        }
+        List<Integer> fleetIds = list.stream().map(ChargingOrderVO::getFleetId)
+                .filter(Objects::nonNull).distinct().collect(Collectors.toList());
+        if (fleetIds.isEmpty()) {
+            return;
+        }
+        Map<Integer, String> fleetNames = loadChargingOrderFleetNames(fleetIds);
+        for (ChargingOrderVO item : list) {
+            String name = item.getFleetId() == null ? null : fleetNames.get(item.getFleetId());
+            if (StringUtils.hasLength(name)) {
+                item.setFleetName(name);
+            }
+        }
+    }
+
+    /** 批量查询公司名称,失败返回已取到的数据 */
+    private Map<Integer, String> loadChargingOrderCompanyNames(List<Integer> companyIds) {
+        Map<Integer, String> result = new HashMap<>();
+        try {
+            List<TGroupCompany> companies = Optional.ofNullable(groupCompanyClient.listCompaniesByIds(companyIds).getData())
+                    .orElse(Collections.emptyList());
+            for (TGroupCompany company : companies) {
+                if (company != null && company.getId() != null && StringUtils.hasLength(company.getName())) {
+                    result.put(company.getId(), company.getName());
+                }
+            }
+        } catch (Exception e) {
+            log.warn("[充电桩订单回填] 批量查询公司名称失败 ids={}", companyIds, e);
+        }
+        return result;
+    }
+
+    /** 批量查询车队名称,失败返回已取到的数据 */
+    private Map<Integer, String> loadChargingOrderFleetNames(List<Integer> fleetIds) {
+        Map<Integer, String> result = new HashMap<>();
+        try {
+            List<TFleet> fleets = Optional.ofNullable(groupCompanyClient.listFleetsByIds(fleetIds).getData())
+                    .orElse(Collections.emptyList());
+            for (TFleet fleet : fleets) {
+                if (fleet != null && fleet.getId() != null && StringUtils.hasLength(fleet.getFleetName())) {
+                    result.put(fleet.getId(), fleet.getFleetName());
+                }
+            }
+        } catch (Exception e) {
+            log.warn("[充电桩订单回填] 批量查询车队名称失败 ids={}", fleetIds, e);
+        }
+        return result;
     }
 
     /**
@@ -3077,6 +3570,7 @@
                 platformIncomeTotal = platformIncomeTotal.add(getSummaryDecimal(batchMap, "platformIncomeTotal"));
                 partnerIncomeTotal = partnerIncomeTotal.add(getSummaryDecimal(batchMap, "partnerIncomeTotal"));
             }
+            platformIncomeTotal = platformIncomeTotal.add(nullToZero(this.baseMapper.sumWhitelistRefundByOrderIds(batchIds)));
         }
         totalMap.put("platformIncomeTotal", platformIncomeTotal);
         totalMap.put("partnerIncomeTotal", partnerIncomeTotal);
@@ -3844,12 +4338,12 @@
     }
 
     /**
-     * 统计近六月订单收入支付方式占比;服务层聚合避免复杂CASE SQL在当前数据库驱动中转换异常。
+     * 统计近六月订单收入支付方式占比;历史订单缺少支付渠道时归入其他支付,避免漏算。
      */
     @Override
     public List<SixIncomeCircleDto> payTypeCircle(LocalDate sixBefore, List<Integer> siteIds, Boolean partnerView) {
         if (siteIds == null || siteIds.isEmpty()) {
-            return buildPayTypeCircleData(BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO);
+            return buildPayTypeCircleData(BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO);
         }
         if (Boolean.TRUE.equals(partnerView)) {
             return buildPartnerShareCircleData(this.baseMapper.chargingOrderShareIncomeByPayChannel(sixBefore, siteIds));
@@ -3869,28 +4363,31 @@
         BigDecimal wechatAmount = BigDecimal.ZERO;
         BigDecimal alipayAmount = BigDecimal.ZERO;
         BigDecimal balanceAmount = BigDecimal.ZERO;
+        BigDecimal otherAmount = BigDecimal.ZERO;
         for (TChargingOrder order : orders) {
             BigDecimal thirdPayAmount = getThirdPayNetAmount(order);
             BigDecimal balancePayAmount = getBalancePayNetAmount(order);
             Integer rechargePaymentType = order.getRechargePaymentType();
             if (Integer.valueOf(1).equals(rechargePaymentType)) {
                 wechatAmount = wechatAmount.add(thirdPayAmount);
-            }
-            if (Integer.valueOf(2).equals(rechargePaymentType) || Integer.valueOf(3).equals(rechargePaymentType)) {
+            } else if (Integer.valueOf(2).equals(rechargePaymentType) || Integer.valueOf(3).equals(rechargePaymentType)) {
                 alipayAmount = alipayAmount.add(thirdPayAmount);
+            } else {
+                otherAmount = otherAmount.add(thirdPayAmount);
             }
             Integer payMethod = order.getPayMethod();
             if (Integer.valueOf(1).equals(payMethod) || Integer.valueOf(2).equals(payMethod)) {
                 balanceAmount = balanceAmount.add(balancePayAmount);
             }
         }
-        return buildPayTypeCircleData(wechatAmount, alipayAmount, balanceAmount);
+        return buildPayTypeCircleData(wechatAmount, alipayAmount, balanceAmount, otherAmount);
     }
 
     private List<SixIncomeCircleDto> buildPartnerShareCircleData(List<Map<String, Object>> rows) {
         BigDecimal wechatAmount = BigDecimal.ZERO;
         BigDecimal alipayAmount = BigDecimal.ZERO;
         BigDecimal balanceAmount = BigDecimal.ZERO;
+        BigDecimal otherAmount = BigDecimal.ZERO;
         if (rows != null) {
             for (Map<String, Object> row : rows) {
                 String channel = row.get("payChannel") == null ? "" : row.get("payChannel").toString();
@@ -3902,21 +4399,23 @@
                 } else if ("BALANCE".equalsIgnoreCase(channel) || "WHITELIST".equalsIgnoreCase(channel)) {
                     balanceAmount = balanceAmount.add(shareAmount);
                 } else {
-                    wechatAmount = wechatAmount.add(shareAmount);
+                    otherAmount = otherAmount.add(shareAmount);
                 }
             }
         }
-        return buildPayTypeCircleData(wechatAmount, alipayAmount, balanceAmount);
+        return buildPayTypeCircleData(wechatAmount, alipayAmount, balanceAmount, otherAmount);
     }
 
     /**
      * 构造固定三类支付方式数据,保证前端饼图在无订单时也有稳定结构。
      */
-    private List<SixIncomeCircleDto> buildPayTypeCircleData(BigDecimal wechatAmount, BigDecimal alipayAmount, BigDecimal balanceAmount) {
+    private List<SixIncomeCircleDto> buildPayTypeCircleData(BigDecimal wechatAmount, BigDecimal alipayAmount,
+                                                            BigDecimal balanceAmount, BigDecimal otherAmount) {
         List<SixIncomeCircleDto> data = new ArrayList<>();
         data.add(buildIncomeCircleDto("微信支付", wechatAmount));
         data.add(buildIncomeCircleDto("支付宝支付", alipayAmount));
         data.add(buildIncomeCircleDto("余额支付", balanceAmount));
+        data.add(buildIncomeCircleDto("其他支付", otherAmount));
         return data;
     }
 
@@ -4558,9 +5057,52 @@
         }
         dto.setSiteIds(siteIds);
         List<ChargingOrderListVO> list1 = this.baseMapper.chargingList(dto, startTime1, startTime2, endTime1, endTime2);
+        fillChargingPeriodCouponSource(list1);
         fillChargingPeriodExportBalanceIncome(list1);
         fillChargingPeriodShareIncome(list1);
         return list1;
+    }
+
+    private void fillChargingPeriodCouponSource(List<ChargingOrderListVO> list) {
+        if (list == null || list.isEmpty()) {
+            return;
+        }
+        List<Long> couponIds = list.stream()
+                .map(ChargingOrderListVO::getAppCouponId)
+                .filter(Objects::nonNull)
+                .distinct()
+                .collect(Collectors.toList());
+        if (couponIds.isEmpty()) {
+            return;
+        }
+        Map<Long, TAppCoupon> couponMap = new HashMap<>();
+        int batchSize = 500;
+        for (int i = 0; i < couponIds.size(); i += batchSize) {
+            List<Long> batchIds = couponIds.subList(i, Math.min(i + batchSize, couponIds.size()));
+            R<List<TAppCoupon>> response = appCouponClient.getAppCouponByIds(batchIds);
+            List<TAppCoupon> coupons = response == null ? null : response.getData();
+            couponMap.putAll(indexByLongId(coupons, TAppCoupon::getId));
+        }
+        for (ChargingOrderListVO order : list) {
+            TAppCoupon coupon = couponMap.get(order.getAppCouponId());
+            if (coupon == null || coupon.getWaysToObtain() == null) {
+                continue;
+            }
+            switch (coupon.getWaysToObtain()) {
+                case 1:
+                    order.setCouponSource("积分兑换");
+                    break;
+                case 2:
+                    order.setCouponSource("会员购买");
+                    break;
+                case 3:
+                case 4:
+                    order.setCouponSource("后台赠送");
+                    break;
+                default:
+                    break;
+            }
+        }
     }
 
     private void fillChargingPeriodShareIncome(List<ChargingOrderListVO> list) {
@@ -4596,7 +5138,8 @@
         if (item == null) {
             return;
         }
-        item.setPlatformIncome(getSummaryDecimal(row, "platformIncome"));
+        item.setPlatformIncome(getSummaryDecimal(row, "platformIncome")
+                .add(getSummaryDecimal(row, "whitelistRefund")));
         item.setPartnerIncome(getSummaryDecimal(row, "partnerIncome"));
     }
 
@@ -4648,7 +5191,8 @@
         }
         for (ChargingOrderVO item : list) {
             Map<String, Object> row = incomeMap.get(item.getId());
-            item.setPlatformIncome(getSummaryDecimal(row, "platformIncome"));
+            item.setPlatformIncome(getSummaryDecimal(row, "platformIncome")
+                    .add(getSummaryDecimal(row, "whitelistRefund")));
             item.setPartnerIncome(getSummaryDecimal(row, "partnerIncome"));
         }
     }
@@ -4783,6 +5327,14 @@
         if (com.ruoyi.common.core.utils.StringUtils.isNotEmpty(query.getTransaction_serial_number())) {
             //获取当前的计费策略
             TChargingOrder chargingOrder1 = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, query.getTransaction_serial_number()));
+            if (null == chargingOrder1) {
+                return;
+            }
+            //企业账户流程:充电中授权时间到期主动停充(按授权截止时间提前下发停充指令)
+            if (Integer.valueOf(3).equals(chargingOrder1.getStatus()) && needAuthorizeStop(chargingOrder1)) {
+                stopByAuthorizeExpired(chargingOrder1);
+                return;
+            }
             BigDecimal residualAmount = chargingOrder1.getRechargeAmount().add(chargingOrder1.getVipDiscountAmount()).subtract(query.getPaid_amount());
             TChargingOrder chargingOrder = new TChargingOrder();
             chargingOrder.setId(chargingOrder1.getId());
@@ -5013,6 +5565,15 @@
                     }
                 }
 
+                //企业账户流程:白名单企业账户订单按企业优惠结算(方式2=服务费比例优惠,方式3=按计费模板同阶段单价)
+                //优惠口径优先取订单快照(建单时固化,策略后续变更不影响本单结算),快照为空的历史订单实时查询并回填
+                boolean enterpriseSettlement = isWhitelistEnterpriseOrder(chargingOrder);
+                ChargeAccountSupport.PreferentialSnapshot enterprisePreferential = enterpriseSettlement
+                        ? chargeAccountSupport.resolvePreferential(chargingOrder) : null;
+                Integer enterprisePreferentialType = null == enterprisePreferential ? null : enterprisePreferential.getPreferentialType();
+                TBillingTemplateDTO enterpriseTemplate = null == enterprisePreferential ? null : enterprisePreferential.getTemplate();
+                BigDecimal enterpriseElectricDiscount = BigDecimal.ZERO;
+                BigDecimal enterpriseServiceDiscount = BigDecimal.ZERO;
                 //开始处理明细
                 for (int i = 0; i < lists.size(); i++) {
                     AccountingStrategyDetailOrderVo strategyDetail = lists.get(i);
@@ -5038,15 +5599,46 @@
                     }
 
                     //已充电总度数
-                    BigDecimal electrovalenc = strategyDetail.getElectrovalence().multiply(sharp_peak_charge);
+                    BigDecimal finalElectricPrice = strategyDetail.getElectrovalence();
+                    BigDecimal finalServicePrice = strategyDetail.getServiceCharge();
+                    //企业账户流程:按企业优惠计算最终用电单价
+                    if (enterpriseSettlement) {
+                        if (Integer.valueOf(ChargeAccountSupport.PREFERENTIAL_TYPE_RATE).equals(enterprisePreferentialType)) {
+                            //方式2:服务费按比例优惠
+                            finalServicePrice = ChargeAccountSupport.applyServiceDiscountRate(finalServicePrice, enterprisePreferential.getServiceDiscountRate());
+                        } else if (Integer.valueOf(ChargeAccountSupport.PREFERENTIAL_TYPE_TEMPLATE).equals(enterprisePreferentialType)) {
+                            //方式3:按计费模板同电价阶段单价
+                            TBillingTemplateDetail templateDetail = ChargeAccountSupport.findTemplateDetail(enterpriseTemplate, strategyDetail.getType());
+                            if (null == templateDetail) {
+                                log.error("[CD结算] 计费模板缺少对应电价阶段,该阶段按原价结算 code={} type={}", chargingOrder.getCode(), strategyDetail.getType());
+                            } else {
+                                if (null != templateDetail.getElectrovalence()) {
+                                    finalElectricPrice = templateDetail.getElectrovalence();
+                                }
+                                if (null != templateDetail.getServiceCharge()) {
+                                    finalServicePrice = templateDetail.getServiceCharge();
+                                }
+                            }
+                        }
+                    }
+                    BigDecimal electrovalenc = finalElectricPrice.multiply(sharp_peak_charge);
                     BigDecimal originalServicePrice = strategyDetail.getServiceCharge().multiply(sharp_peak_charge);
-                    BigDecimal serviceCharge = originalServicePrice;
+                    BigDecimal serviceCharge = finalServicePrice.multiply(sharp_peak_charge);
                     BigDecimal vipDiscountAmount = BigDecimal.ZERO;
-                    //计算优惠金额
-                    if (null != chargingOrder.getVipDiscount()) {
+                    //计算优惠金额;企业账户流程按企业优惠结算,其余订单中余额支付(含组合支付)不参与会员折扣
+                    if (enterpriseSettlement) {
+                        //企业优惠金额(原价-优惠价),用于订单优惠统计与 whitelist_* 快照
+                        enterpriseElectricDiscount = enterpriseElectricDiscount.add(strategyDetail.getElectrovalence().multiply(sharp_peak_charge).subtract(electrovalenc));
+                        enterpriseServiceDiscount = enterpriseServiceDiscount.add(originalServicePrice.subtract(serviceCharge));
+                    } else if (!isWhitelistOrder(chargingOrder) && !isBalancePayMode(chargingOrder.getPayMethod()) && null != chargingOrder.getVipDiscount()) {
                         //0.58折
                         vipDiscountAmount = serviceCharge.multiply(new BigDecimal(1).subtract(chargingOrder.getVipDiscount()));
                         serviceCharge = serviceCharge.multiply(chargingOrder.getVipDiscount());
+                    }
+                    //企业账户流程:明细单价记录优惠后单价,金额与单价口径一致
+                    if (enterpriseSettlement) {
+                        chargingOrderAccountingStrategy.setElectrovalence(finalElectricPrice);
+                        chargingOrderAccountingStrategy.setServiceCharge(finalServicePrice);
                     }
                     chargingOrderAccountingStrategy.setChargingCapacity(sharp_peak_charge);
                     chargingOrderAccountingStrategy.setPeriodElectricPrice(electrovalenc.setScale(4, RoundingMode.HALF_EVEN));
@@ -5139,9 +5731,20 @@
                 payAmount = payAmount.subtract(couponDiscount).max(BigDecimal.ZERO);
                 serviceCharge_total = serviceCharge_total.subtract(couponDiscount).max(BigDecimal.ZERO);
                 chargingOrder.setCouponDiscountAmount(couponDiscount.setScale(2, RoundingMode.HALF_EVEN));
-                chargingOrder.setWhitelistDiscountAmount(whitelistDiscount.setScale(2, RoundingMode.HALF_EVEN));
-                chargingOrder.setWhitelistElectricRefundAmount(electricDiscount.setScale(2, RoundingMode.HALF_EVEN));
-                chargingOrder.setWhitelistServiceRefundAmount(serviceDiscount.setScale(2, RoundingMode.HALF_EVEN));
+                //企业账户流程:企业优惠金额与 whitelist_* 三列快照双写(订单优惠统计沿用 whitelist_* 口径)
+                BigDecimal enterpriseElectricDiscountAmount = enterpriseElectricDiscount.max(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_EVEN);
+                BigDecimal enterpriseServiceDiscountAmount = enterpriseServiceDiscount.max(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_EVEN);
+                if (enterpriseSettlement) {
+                    chargingOrder.setDiscountElectrovalence(enterpriseElectricDiscountAmount);
+                    chargingOrder.setDiscountServiceCharge(enterpriseServiceDiscountAmount);
+                    chargingOrder.setWhitelistElectricRefundAmount(enterpriseElectricDiscountAmount);
+                    chargingOrder.setWhitelistServiceRefundAmount(enterpriseServiceDiscountAmount);
+                    chargingOrder.setWhitelistDiscountAmount(enterpriseElectricDiscountAmount.add(enterpriseServiceDiscountAmount));
+                } else {
+                    chargingOrder.setWhitelistDiscountAmount(whitelistDiscount.setScale(2, RoundingMode.HALF_EVEN));
+                    chargingOrder.setWhitelistElectricRefundAmount(electricDiscount.setScale(2, RoundingMode.HALF_EVEN));
+                    chargingOrder.setWhitelistServiceRefundAmount(serviceDiscount.setScale(2, RoundingMode.HALF_EVEN));
+                }
                 chargingOrder.setElectrovalence(periodElectricPrice_total.setScale(2, RoundingMode.HALF_EVEN));
                 chargingOrder.setServiceCharge(serviceCharge_total.setScale(2, RoundingMode.HALF_EVEN));
                 refundAmount = refundAmount.max(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP);
@@ -5174,6 +5777,17 @@
                 if (actualBalancePayAmount.compareTo(BigDecimal.ZERO) < 0) {
                     actualBalancePayAmount = BigDecimal.ZERO;
                 }
+                if (enterpriseSettlement) {
+                    // 企业账户流程:资金来自企业账户额度(差额结算时退回企业账户),订单无用户侧退款,实付金额=实际消费金额
+                    recordedRefundAmount = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
+                    refundAmount = recordedRefundAmount;
+                    channelRefundAmount = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
+                    thirdRefundAmount = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
+                    balanceRefundAmount = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
+                    actualThirdPayAmount = BigDecimal.ZERO;
+                    actualBalancePayAmount = payAmount.setScale(2, RoundingMode.HALF_EVEN);
+                    chargingOrder.setBalancePayAmount(payAmount.setScale(2, RoundingMode.HALF_EVEN));
+                }
                 refundAmount = recordedRefundAmount;
                 chargingOrder.setBalanceRefundAmount(balanceRefundAmount.setScale(2, RoundingMode.HALF_UP));
                 chargingOrder.setThirdRefundAmount(thirdRefundAmount.setScale(2, RoundingMode.HALF_UP));
@@ -5189,8 +5803,26 @@
                 if (null != desc) {
                     chargingOrder.setEndSoc(new BigDecimal(desc.getSoc()));
                 }
+                //企业账户流程:历史订单(快照为空)实时解析的优惠结果回填订单快照列,保证后续补偿重算口径一致;
+                //同时置结算完成标记,兜底扫描(findEndChargingOrder)不再回退已结算订单,防止重复结算与重复扣款
+                if (enterpriseSettlement) {
+                    if (null != enterprisePreferential && enterprisePreferential.needBackfill()) {
+                        chargingOrder.setPreferentialType(enterprisePreferential.getPreferentialType());
+                        chargingOrder.setServiceDiscountRate(enterprisePreferential.getServiceDiscountRate());
+                        chargingOrder.setBillingTemplateId(enterprisePreferential.getBillingTemplateId());
+                        chargingOrder.setBillingTemplateSnapshot(
+                                ChargeAccountSupport.serializeTemplateSnapshot(enterprisePreferential.getTemplate()));
+                        chargingOrder.setPreferentialSnapshotTime(LocalDateTime.now());
+                    }
+                    chargingOrder.setSettleStatus(1);
+                }
                 this.updateById(chargingOrder);
 
+                //企业账户流程:结算企业额度(按实际消费扣减锁定额度、差额退回企业账户)并写消费流水
+                if (enterpriseSettlement && !settleWhitelistEnterpriseAccount(chargingOrder, payAmount)) {
+                    // 结算失败抛异常回滚本地状态,订单保持停止中,由补偿任务重新结算
+                    throw new ServiceException("企业账户额度结算失败,订单未结算,请稍后重试 code=" + chargingOrder.getCode());
+                }
                 chargingOrder = this.getById(chargingOrder.getId());
                 Site site = siteClient.getSiteByIds(Arrays.asList(chargingOrder.getSiteId())).getData().get(0);
                 //推送三方平台
@@ -5586,6 +6218,10 @@
 
     private BigDecimal getManualRefundableAmount(TChargingOrder order) {
         if (order == null || order.getId() == null) {
+            return BigDecimal.ZERO;
+        }
+        //企业账户流程:企业账户订单资金来自企业额度,差额在结算时退回企业账户,不支持后台手动退款
+        if (isWhitelistEnterpriseOrder(order)) {
             return BigDecimal.ZERO;
         }
         List<TChargingOrderRefund> successfulRefunds = chargingOrderRefundService.list(
@@ -7082,26 +7718,27 @@
         if (cached != null) {
             return cached;
         }
-        LocalDate currentMonth = LocalDate.now().withDayOfMonth(1);
+        LocalDate currentDay = LocalDate.now();
         List<SixChargingDto> result = new ArrayList<>();
         try {
-            String sixBeforeMonth = sixBefore.withDayOfMonth(1).format(LARGE_SCREEN_MONTH_FMT);
-            List<SixChargingDto> incomeList = this.baseMapper.incomeTrendFromStat(siteIds, sixBeforeMonth);
-            Map<String, SixChargingDto> incomeByMonth = new HashMap<>();
+            List<SixChargingDto> incomeList = this.baseMapper.incomeTrendFromOrders(siteIds,
+                    sixBefore.atStartOfDay().format(LARGE_SCREEN_SQL_FMT),
+                    currentDay.plusDays(1).atStartOfDay().format(LARGE_SCREEN_SQL_FMT));
+            Map<String, SixChargingDto> incomeByDay = new HashMap<>();
             if (incomeList != null) {
                 for (SixChargingDto income : incomeList) {
                     if (income != null && income.getMonth() != null) {
-                        incomeByMonth.put(income.getMonth(), income);
+                        incomeByDay.put(income.getMonth(), income);
                     }
                 }
             }
-            LocalDate month = sixBefore.withDayOfMonth(1);
-            while (!month.isAfter(currentMonth)) {
-                SixChargingDto income = incomeByMonth.get(month.format(LARGE_SCREEN_MONTH_FMT));
+            LocalDate day = sixBefore;
+            while (!day.isAfter(currentDay)) {
+                SixChargingDto income = incomeByDay.get(day.format(LARGE_SCREEN_DAY_FMT));
                 if (income == null) {
                     income = new SixChargingDto();
                 }
-                income.setMonth(String.format("%02d", month.getMonthValue()));
+                income.setMonth(day.format(LARGE_SCREEN_DAY_FMT));
                 if (income.getElectrovalence() == null) {
                     income.setElectrovalence(BigDecimal.ZERO);
                 }
@@ -7109,18 +7746,18 @@
                     income.setServiceCharge(BigDecimal.ZERO);
                 }
                 result.add(income);
-                month = month.plusMonths(1);
+                day = day.plusDays(1);
             }
         } catch (Exception e) {
             log.warn("大屏收入趋势读取预聚合表失败, siteIds={}, sixBefore={}", siteIds, sixBefore, e);
-            LocalDate month = sixBefore.withDayOfMonth(1);
-            while (!month.isAfter(currentMonth)) {
+            LocalDate day = sixBefore;
+            while (!day.isAfter(currentDay)) {
                 SixChargingDto income = new SixChargingDto();
-                income.setMonth(String.format("%02d", month.getMonthValue()));
+                income.setMonth(day.format(LARGE_SCREEN_DAY_FMT));
                 income.setElectrovalence(BigDecimal.ZERO);
                 income.setServiceCharge(BigDecimal.ZERO);
                 result.add(income);
-                month = month.plusMonths(1);
+                day = day.plusDays(1);
             }
         }
         redisService.setCacheObject(cacheKey, result, LARGE_SCREEN_CACHE_SECONDS, TimeUnit.SECONDS);
@@ -7333,9 +7970,11 @@
             stat.put("orderCount", decimalValue(row, "order_count"));
             stat.put("userCount", BigDecimal.ZERO);
             stat.put("capacity", BigDecimal.ZERO);
-            stat.put("electricFee", BigDecimal.ZERO);
-            stat.put("serviceFee", BigDecimal.ZERO);
-            stat.put("income", BigDecimal.ZERO);
+            BigDecimal electricFee = decimalValue(row, "electric_fee");
+            BigDecimal serviceFee = decimalValue(row, "service_fee");
+            stat.put("electricFee", electricFee);
+            stat.put("serviceFee", serviceFee);
+            stat.put("income", electricFee.add(serviceFee));
             stat.put("totalPower", decimalValue(row, "total_power"));
             stat.put("registeredUserCount", 0L);
             statRows.add(stat);
@@ -7435,6 +8074,14 @@
     public EndOfChargePageInfo getEndOfChargePageInfo(String id) {
         EndOfChargePageInfo info = new EndOfChargePageInfo();
         TChargingOrder chargingOrder = this.getById(id);
+        if (chargingOrder == null) {
+            // VIN 码充电订单兜底:VD 订单存于 t_vin_charging_order(继承 TChargingOrder,字段兼容;
+            // 结算已写 paymentAmount/startTime/endTime,后续组装原样复用)
+            chargingOrder = vinChargingOrderMapper.selectById(id);
+        }
+        if (chargingOrder == null) {
+            throw new RuntimeException("充电订单不存在");
+        }
         Long userId = tokenService.getLoginUserApplet().getUserId();
         if (!chargingOrder.getAppUserId().equals(userId)) {
             throw new RuntimeException("权限不足");
@@ -7795,7 +8442,7 @@
             for (List<Integer> chunk : chunkList(gunIds, 500)) {
                 Long chunkCount = this.baseMapper.selectCount(new LambdaQueryWrapper<TChargingOrder>()
                         .eq(TChargingOrder::getDelFlag, 0)//未删除
-                        .in(TChargingOrder::getStatus, Arrays.asList(3, 5))//充电中、已结束
+                        .in(TChargingOrder::getStatus, Arrays.asList(3, 4, 5))//充电中、停止中、已结束
                         .in(TChargingOrder::getChargingGunId, chunk));//符合条件的充电枪
                 total += chunkCount == null ? 0L : chunkCount;
             }
@@ -7804,7 +8451,7 @@
         List<LocalDate> dates = new ArrayList<>();
         List<Integer> counts = new ArrayList<>();
         LocalDate today = LocalDate.now();
-        for (int i = 7; i >= 1; i--) {//升序
+        for (int i = 6; i >= 0; i--) {//升序,最近七日(含当天)
             LocalDate day = today.minusDays(i);
             LocalDateTime dayStart = day.atStartOfDay();
             LocalDateTime dayEnd = day.plusDays(1).atStartOfDay();
@@ -8190,8 +8837,8 @@
                     BigDecimal originalServicePrice = strategyDetail.getServiceCharge().multiply(sharp_peak_charge);
                     BigDecimal serviceCharge = originalServicePrice;
                     BigDecimal vipDiscountAmount = BigDecimal.ZERO;
-                    //计算优惠金额
-                    if (null != chargingOrder.getVipDiscount()) {
+                    //计算优惠金额;余额支付(含组合支付)不参与会员折扣
+                    if (!isWhitelistOrder(chargingOrder) && !isBalancePayMode(chargingOrder.getPayMethod()) && null != chargingOrder.getVipDiscount()) {
                         //0.58折
                         vipDiscountAmount = serviceCharge.multiply(new BigDecimal(1).subtract(chargingOrder.getVipDiscount()));
                         serviceCharge = serviceCharge.multiply(chargingOrder.getVipDiscount());
@@ -8379,7 +9026,7 @@
                                 BigDecimal serviceCharge = originalServicePrice;
                                 BigDecimal vipDiscountAmount = BigDecimal.ZERO;
                                 //计算优惠金额
-                                if (null != chargingOrder.getVipDiscount()) {
+                                if (!isWhitelistOrder(chargingOrder) && null != chargingOrder.getVipDiscount()) {
                                     //0.58折
                                     vipDiscountAmount = serviceCharge.multiply(new BigDecimal(1).subtract(chargingOrder.getVipDiscount()));
                                     serviceCharge = serviceCharge.multiply(chargingOrder.getVipDiscount());
@@ -8682,7 +9329,7 @@
         BigDecimal shareElectricityAmount = getChargingOrderShareElectricityAmount(chargingOrder);
         BigDecimal shareServiceAmount = getChargingOrderShareServiceAmount(chargingOrder);
         BigDecimal shareBaseAmount = shareElectricityAmount.add(shareServiceAmount).setScale(2, RoundingMode.HALF_UP);
-        if (actualTotalPay.compareTo(BigDecimal.ZERO) <= 0 && isWhitelistOrder(chargingOrder)) {
+        if (actualTotalPay.compareTo(BigDecimal.ZERO) <= 0 && isWhitelistAllFreeOrder(chargingOrder)) {
             actualTotalPay = shareBaseAmount;
         }
         if (actualTotalPay.compareTo(BigDecimal.ZERO) <= 0) {
@@ -8702,7 +9349,7 @@
             records.add(buildChargingOrderShareRecord(chargingOrder, site, partner, resolveThirdPayChannel(chargingOrder), actualThirdPay,
                     BigDecimal.ZERO, actualTotalPay, shareElectricityAmount, shareServiceAmount));
         }
-        if (records.isEmpty() && isWhitelistOrder(chargingOrder)) {
+        if (records.isEmpty() && isWhitelistAllFreeOrder(chargingOrder)) {
             records.add(buildChargingOrderShareRecord(chargingOrder, site, partner, "WHITELIST", actualTotalPay,
                     BigDecimal.ZERO, actualTotalPay, shareElectricityAmount, shareServiceAmount));
         }

--
Gitblit v1.7.1