mirror of
https://codeup.aliyun.com/67c68d4e484ca2f0a13ac3c1/ydc/jsowell-charger-web.git
synced 2026-08-10 00:03:44 +08:00
统一保险订单资金口径:payAmount=充电金额,明细=完整实付(充电+保险)
规则:order_basic_info.pay_amount 只记充电金额(不含保险);order_pay_record 汇总为用户完整实付(充电+保险);凭证校验以 payAmount+保险==明细 为准。 - 在线支付(OrderService.adapayCallback):payAmount 存 amount-保险(充电金额), 回退f11b781c2的"完整金额"写入;下发桩额度直接用 payAmount,避免结算多退保险。 - 余额支付(Not/DelayMerchantProgramLogic.balancePayOrderV2):与在线一致,从钱包 扣 充电+保险,order_pay_record 记完整实付,payAmount 仍只记充电金额;余额不足 (<充电+保险)直接拒绝。会员交易流水记完整实付。 - 凭证校验(OrderBasicInfoServiceImpl.inspectOrderPayment):余额/非余额支路统一 改为容错对比 payAmount==明细 或 payAmount+保险==明细;补偿回写只写充电金额, 修复余额支路仍按 payAmount==明细 会误判新余额保险单的问题。 - 新增 docs/sql/fix_online_insurance_pay_amount_20260725.sql:矫正f11b781c2期间 在线保险单被写成完整金额的 payAmount(dry-run/备份/回滚齐全)。 - 新增单测:calculateBalanceRefund 6 例 + inspectOrderPayment 5 例(计算层,不连库)。
This commit is contained in:
131
docs/sql/fix_online_insurance_pay_amount_20260725.sql
Normal file
131
docs/sql/fix_online_insurance_pay_amount_20260725.sql
Normal file
@@ -0,0 +1,131 @@
|
||||
-- ============================================================================
|
||||
-- 矫正在线支付「保险订单」的 pay_amount
|
||||
-- 背景:提交 f11b781c2 上线到本次回退期间,在线支付回调把 order_basic_info.pay_amount
|
||||
-- 写成了「完整实付(充电+保险)」。规则应为:
|
||||
-- order_basic_info.pay_amount = 充电金额(不含保险)
|
||||
-- order_pay_record 汇总 = 完整实付(充电 + 保险)
|
||||
-- 故需把这批订单的 pay_amount 从「完整金额」矫正为「pay_amount - insurance_amount」。
|
||||
-- 适用:MySQL 5.7+(未用 CTE,5.7 可直接跑)
|
||||
-- 日期:2026-07-25
|
||||
--
|
||||
-- 识别口径:在线支付(微信'4'/支付宝'5') + 已支付 + insurance>0 + pay_amount≈明细汇总。
|
||||
-- · 正确订单:pay_amount = 明细 - 保险 < 明细
|
||||
-- · 错误订单:pay_amount = 明细(含保险) => 命中本脚本
|
||||
--
|
||||
-- ⚠️ 关于「已完成(order_status='6')」订单:结算时已用错误的 pay_amount 计算过
|
||||
-- 退款(residue = pay_amount - 消费),即保险已被多退,本脚本无法追回那笔钱;
|
||||
-- 对已完成订单矫正 pay_amount 只是让「记录」变正确,且会与已落库的 refund_amount
|
||||
-- 不再自洽。是否处理已完成订单请按业务决定(见第 3 步的两种 WHERE)。
|
||||
-- ============================================================================
|
||||
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- 第 1 步:DRY-RUN 预览(务必先只跑这个,核对数量与金额)
|
||||
-- ---------------------------------------------------------------------------
|
||||
SELECT
|
||||
o.order_code,
|
||||
o.order_status,
|
||||
CASE o.order_status WHEN '6' THEN '已完成' WHEN '4' THEN '异常' ELSE '未完成' END AS status_desc,
|
||||
o.pay_mode,
|
||||
o.pay_amount AS cur_pay_amount, -- 当前(错误,含保险)
|
||||
o.insurance_amount AS insurance_amount,
|
||||
pr.pay_record_sum AS pay_record_sum, -- 明细汇总(完整实付)
|
||||
(o.pay_amount - o.insurance_amount) AS corrected_pay_amount -- 矫正后(充电金额)
|
||||
FROM order_basic_info o
|
||||
JOIN (
|
||||
SELECT order_code, SUM(pay_amount) AS pay_record_sum
|
||||
FROM order_pay_record
|
||||
WHERE del_flag = '0'
|
||||
GROUP BY order_code
|
||||
) pr ON pr.order_code = o.order_code
|
||||
WHERE o.pay_mode IN ('4','5') -- 在线支付(微信/支付宝)
|
||||
AND o.pay_status = '1' -- 已支付
|
||||
AND o.insurance_amount > 0 -- 有保险
|
||||
AND ABS(o.pay_amount - pr.pay_record_sum) < 0.005 -- pay_amount == 明细汇总 => 含了保险(错误)
|
||||
ORDER BY o.order_status, o.order_code;
|
||||
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- 第 2 步:备份受影响行(建议执行,便于回滚)
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS bak_order_pay_amount_fix_20260725 (
|
||||
order_code VARCHAR(64) PRIMARY KEY,
|
||||
old_pay_amount DECIMAL(10,2),
|
||||
insurance_amount DECIMAL(10,2),
|
||||
new_pay_amount DECIMAL(10,2),
|
||||
order_status VARCHAR(4),
|
||||
backup_time DATETIME
|
||||
);
|
||||
|
||||
INSERT INTO bak_order_pay_amount_fix_20260725
|
||||
(order_code, old_pay_amount, insurance_amount, new_pay_amount, order_status, backup_time)
|
||||
SELECT o.order_code, o.pay_amount, o.insurance_amount,
|
||||
(o.pay_amount - o.insurance_amount), o.order_status, NOW()
|
||||
FROM order_basic_info o
|
||||
JOIN (
|
||||
SELECT order_code, SUM(pay_amount) AS pay_record_sum
|
||||
FROM order_pay_record WHERE del_flag = '0' GROUP BY order_code
|
||||
) pr ON pr.order_code = o.order_code
|
||||
WHERE o.pay_mode IN ('4','5')
|
||||
AND o.pay_status = '1'
|
||||
AND o.insurance_amount > 0
|
||||
AND ABS(o.pay_amount - pr.pay_record_sum) < 0.005
|
||||
ON DUPLICATE KEY UPDATE backup_time = NOW();
|
||||
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- 第 3 步:正式矫正(确认第 1 步无误后执行)
|
||||
-- pay_amount = pay_amount - insurance_amount = 充电金额
|
||||
--
|
||||
-- ▸ 方案 A(推荐):只矫正「未完成」订单,避免动已结算/已退款的历史账
|
||||
-- —— 防止这些单将来结算时多退保险。把下面这条的注释去掉执行:
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- UPDATE order_basic_info o
|
||||
-- JOIN (
|
||||
-- SELECT order_code, SUM(pay_amount) AS pay_record_sum
|
||||
-- FROM order_pay_record WHERE del_flag = '0' GROUP BY order_code
|
||||
-- ) pr ON pr.order_code = o.order_code
|
||||
-- SET o.pay_amount = o.pay_amount - o.insurance_amount
|
||||
-- WHERE o.pay_mode IN ('4','5')
|
||||
-- AND o.pay_status = '1'
|
||||
-- AND o.insurance_amount > 0
|
||||
-- AND ABS(o.pay_amount - pr.pay_record_sum) < 0.005
|
||||
-- AND o.order_status NOT IN ('6','7'); -- 排除已完成/已关闭
|
||||
|
||||
-- ▸ 方案 B:矫正「全部」受影响订单(含已完成,仅让记录口径一致;已多退的保险无法追回)
|
||||
-- 如需按此执行,去掉下面这条的注释:
|
||||
-- UPDATE order_basic_info o
|
||||
-- JOIN (
|
||||
-- SELECT order_code, SUM(pay_amount) AS pay_record_sum
|
||||
-- FROM order_pay_record WHERE del_flag = '0' GROUP BY order_code
|
||||
-- ) pr ON pr.order_code = o.order_code
|
||||
-- SET o.pay_amount = o.pay_amount - o.insurance_amount
|
||||
-- WHERE o.pay_mode IN ('4','5')
|
||||
-- AND o.pay_status = '1'
|
||||
-- AND o.insurance_amount > 0
|
||||
-- AND ABS(o.pay_amount - pr.pay_record_sum) < 0.005;
|
||||
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- 第 4 步:矫正后复核(应为 0 行)
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- 复核逻辑:矫正后 正确订单应满足 pay_amount + insurance = 明细汇总;
|
||||
-- 若仍有 pay_amount == 明细汇总 且 insurance>0,说明还有漏网的。
|
||||
SELECT COUNT(*) AS still_wrong
|
||||
FROM order_basic_info o
|
||||
JOIN (
|
||||
SELECT order_code, SUM(pay_amount) AS pay_record_sum
|
||||
FROM order_pay_record WHERE del_flag = '0' GROUP BY order_code
|
||||
) pr ON pr.order_code = o.order_code
|
||||
WHERE o.pay_mode IN ('4','5')
|
||||
AND o.pay_status = '1'
|
||||
AND o.insurance_amount > 0
|
||||
AND ABS(o.pay_amount - pr.pay_record_sum) < 0.005;
|
||||
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- 回滚(如需):从备份表还原
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- UPDATE order_basic_info o
|
||||
-- JOIN bak_order_pay_amount_fix_20260725 b ON b.order_code = o.order_code
|
||||
-- SET o.pay_amount = b.old_pay_amount;
|
||||
Reference in New Issue
Block a user