ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TCardChargingOrderServiceImpl.java
@@ -740,7 +740,7 @@ * 1) 企业状态校验(未归属/不存在/停用 -> 失败码2),账户模式取企业配置(默认共享); * 2) 企业充电授权校验:站点范围(超范围 -> 失败码2)、可用时段(不在时段 -> 失败码2),未配置授权按放行处理; * 3) 可用余额校验(共享=企业可用余额,分配=卡可用余额,<=0 -> 失败码3); * 4) 下发金额 = min(授权下发额, 可用余额),锁定额度与下发金额一致;授权截止时间用于监控提前停充。 * 4) 下发金额:共享模式=min(授权下发额, 可用余额),分配模式=卡账户余额;锁定额度与下发金额一致;授权截止时间用于监控提前停充。 */ private ChargeAccountSupport.ChargeContext resolveCardChargeContext(Integer siteId, Integer strategyId, TChargingCard card) { @@ -796,11 +796,16 @@ return ChargeAccountSupport.ChargeContext.fail(3, "账户可用余额不足"); } // 4. 下发金额 = min(授权下发额, 可用余额),锁定金额与下发金额一致 BigDecimal dispatchAmount = authorization == null || authorization.getDispatchAmount() == null ? ChargeAccountSupport.DEFAULT_DISPATCH_AMOUNT : authorization.getDispatchAmount(); if (dispatchAmount.compareTo(usable) > 0) { // 4. 下发金额:共享模式=min(授权下发额, 可用余额),分配模式=卡账户余额;锁定金额与下发金额一致 BigDecimal dispatchAmount; if (Integer.valueOf(ChargeAccountSupport.ACCOUNT_MODE_ALLOCATED).equals(accountMode)) { dispatchAmount = usable; } else { dispatchAmount = authorization == null || authorization.getDispatchAmount() == null ? ChargeAccountSupport.DEFAULT_DISPATCH_AMOUNT : authorization.getDispatchAmount(); if (dispatchAmount.compareTo(usable) > 0) { dispatchAmount = usable; } } if (dispatchAmount.compareTo(BigDecimal.ZERO) <= 0) { return ChargeAccountSupport.ChargeContext.fail(3, "账户可用余额不足"); ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
@@ -808,10 +808,10 @@ * 解析白名单企业账户充电上下文(白名单用户选择余额支付时调用): * 1) 校验归属公司存在且启用,未归属/停用直接拒绝; * 2) 校验企业充电授权(站点范围、可用时段/电价阶段)并计算授权截止时间,未配置授权按放行处理(对齐 VIN 口径); * 3) 下发额度 = min(用户输入充值金额, 账户可用额度, 企业设定的充值金额): * 3) 下发额度: * - 账户可用额度:共享模式=公司可用余额,分配模式=白名单账户余额; * - 企业设定充值金额=授权配置下发金额,未配置默认 200 元; * - 用户输入金额为空或非正数时按 min(企业设定充值金额, 账户可用额度) 下发。 * - 共享模式=min(用户输入充值金额, 账户可用额度, 企业设定充值金额),企业设定充值金额=授权配置下发金额,未配置默认 200 元; * - 分配模式=min(用户输入充值金额, 白名单账户余额),用户输入为空或非正数时直接下发白名单账户余额(不再受企业设定充值金额限制)。 * * @param whitelist 白名单命中结果(含归属公司与账户余额快照) * @param userInputAmount 用户输入的充值金额 @@ -871,14 +871,19 @@ 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); if (accountMode == ChargeAccountSupport.ACCOUNT_MODE_ALLOCATED) { // 分配模式:直接下发白名单账户余额(用户输入正数时以用户输入为上限),不再受公司充电下发金额限制 dispatch = dispatch.compareTo(BigDecimal.ZERO) <= 0 ? usable : dispatch.min(usable); } else { BigDecimal enterpriseLimit = authorization == null ? null : authorization.getDispatchAmount(); if (enterpriseLimit == null || enterpriseLimit.compareTo(BigDecimal.ZERO) <= 0) { enterpriseLimit = ChargeAccountSupport.DEFAULT_DISPATCH_AMOUNT; } 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); } ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TVinChargingOrderServiceImpl.java
@@ -1107,12 +1107,18 @@ if (usable.compareTo(ZERO_AMOUNT) <= 0) { return VinChargeContext.fail(3, "账户可用余额为0 accountMode=" + accountMode + " companyId=" + companyId); } BigDecimal dispatch = authorization == null ? null : authorization.getDispatchAmount(); if (dispatch == null || dispatch.compareTo(ZERO_AMOUNT) <= 0) { dispatch = VD_DEFAULT_DISPATCH_AMOUNT; } if (dispatch.compareTo(usable) > 0) { BigDecimal dispatch; if (accountMode == ACCOUNT_MODE_ALLOCATED) { // 分配模式:直接下发 VIN 账户余额,不再受公司充电下发金额限制 dispatch = usable; } else { dispatch = authorization == null ? null : authorization.getDispatchAmount(); if (dispatch == null || dispatch.compareTo(ZERO_AMOUNT) <= 0) { dispatch = VD_DEFAULT_DISPATCH_AMOUNT; } if (dispatch.compareTo(usable) > 0) { dispatch = usable; } } return VinChargeContext.ok(accountMode, dispatch, maxEndTime); }