f
This commit is contained in:
285
deploy/sql/repair_order_refund_q176967208700018143d9f6.sql
Normal file
285
deploy/sql/repair_order_refund_q176967208700018143d9f6.sql
Normal file
@@ -0,0 +1,285 @@
|
||||
-- =============================================================================
|
||||
-- 修复订单 Q_176967208700018143d9f6:支付宝已退款成功,但库内未完成
|
||||
-- =============================================================================
|
||||
--
|
||||
-- 【原因简述】
|
||||
-- 后台发起支付宝退款后,支付宝侧已退款成功,但创建退款记录时因 unique_refund_no
|
||||
-- 冲突(Duplicate entry 'refund-Q_176967208700018143d9f6')导致 createRefundRecordAndUpdateOrder
|
||||
-- 失败,后续流程未执行:订单未置为 refunded、未写退款记录、未扣代理佣金与钱包。
|
||||
--
|
||||
-- 【本单实际退款金额】支付宝已退 99.5 元(非整单金额)
|
||||
--
|
||||
-- 【与 adminrefundorderlogic 退款链路对照】
|
||||
-- 代码路径:AdminRefundOrder -> handleAlipayRefund -> createRefundRecordAndUpdateOrder + HandleCommissionAndWalletDeduction
|
||||
--
|
||||
-- handleAlipayRefund 成功分支:
|
||||
-- 1) createRefundRecordAndUpdateOrder(order, req, refundNo, refundResp.TradeNo, ...)
|
||||
-- -> 事务内:Insert order_refund(refund_no, platform_refund_id=TradeNo, order_id, user_id, product_id, refund_amount, status=success, refund_time=NOW())
|
||||
-- -> 事务内:Update order(仅 code 中赋了 status=refunded,未显式设 refund_time/version)
|
||||
-- 2) HandleCommissionAndWalletDeduction(ctx, svcCtx, nil, order, req.RefundAmount)
|
||||
-- -> 该订单下 agent_commission:按 refundAmount 比例冲减,refunded_amount 增加,满额则 status=2(UpdateWithVersion)
|
||||
-- -> 按代理汇总扣减额,agent_wallet 先扣冻结再扣可用(UpdateWithVersion)
|
||||
-- -> agent_wallet_transaction 插入 type=refund、金额为负的流水
|
||||
--
|
||||
-- 本 SQL 对应关系:
|
||||
-- Step 2 = createRefundRecordAndUpdateOrder 的 Insert order_refund(platform_refund_id 修复时无支付宝 TradeNo 填 NULL,可从支付宝补)
|
||||
-- Step 3 = createRefundRecordAndUpdateOrder 的 Update order,并显式补全 refund_time、version+1
|
||||
-- Step 4 = HandleCommissionAndWalletDeduction 对 agent_commission 的冲减(按 99.5 比例)
|
||||
-- Step 5 = HandleCommissionAndWalletDeduction 对 agent_wallet 扣减 + agent_wallet_transaction 插入
|
||||
--
|
||||
-- 【执行前请确认】
|
||||
-- 1)该订单在支付宝侧已退款成功;2)已备份相关表或先在测试环境执行。
|
||||
-- Step 2~5 已包在事务中:任一步报错请执行 ROLLBACK;若 step 1 未查到订单(_order_not_found=1)勿执行后续。
|
||||
-- =============================================================================
|
||||
|
||||
-- 与表字段 collation 一致,避免 #1267 Illegal mix of collations(若表为 utf8mb4_general_ci 则改为 COLLATE utf8mb4_general_ci)
|
||||
SET
|
||||
@order_no = CONVERT(
|
||||
'Q_176967208700018143d9f6' USING utf8mb4
|
||||
) COLLATE utf8mb4_general_ci;
|
||||
-- 本单实际退款金额(元)
|
||||
SET @repair_refund_amount = 99.5;
|
||||
|
||||
-- 1) 取订单信息
|
||||
SELECT
|
||||
id,
|
||||
user_id,
|
||||
product_id,
|
||||
amount,
|
||||
version INTO @order_id,
|
||||
@user_id,
|
||||
@product_id,
|
||||
@order_amount,
|
||||
@order_version
|
||||
FROM `order`
|
||||
WHERE
|
||||
order_no = @order_no
|
||||
AND del_state = 0
|
||||
LIMIT 1;
|
||||
|
||||
SET @refund_amount = @repair_refund_amount;
|
||||
|
||||
-- 若无记录则说明订单号错误,终止
|
||||
SELECT IF(@order_id IS NULL, 1, 0) AS _order_not_found;
|
||||
-- 若 _order_not_found=1 请勿继续执行后续语句
|
||||
|
||||
-- ---------- 以下为事务:任一步报错请执行 ROLLBACK ----------
|
||||
START TRANSACTION;
|
||||
|
||||
-- 2) 补写退款记录(若该订单尚无成功状态的退款记录)
|
||||
-- 代码中 platform_refund_id 来自支付宝 refundResp.TradeNo;修复时无则填 NULL,如有支付宝退款单号可事后 UPDATE 补上
|
||||
INSERT INTO
|
||||
order_refund (
|
||||
refund_no,
|
||||
order_id,
|
||||
user_id,
|
||||
product_id,
|
||||
platform_refund_id,
|
||||
refund_amount,
|
||||
refund_reason,
|
||||
status,
|
||||
del_state,
|
||||
version,
|
||||
refund_time,
|
||||
close_time,
|
||||
delete_time
|
||||
)
|
||||
SELECT
|
||||
CONCAT(
|
||||
'refund-',
|
||||
@order_no,
|
||||
'-repair'
|
||||
),
|
||||
@order_id,
|
||||
@user_id,
|
||||
@product_id,
|
||||
NULL,
|
||||
@refund_amount,
|
||||
NULL,
|
||||
'success',
|
||||
0,
|
||||
0,
|
||||
NOW(),
|
||||
NULL,
|
||||
NULL
|
||||
FROM (
|
||||
SELECT 1
|
||||
) _one
|
||||
WHERE
|
||||
NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM order_refund
|
||||
WHERE
|
||||
order_id = @order_id
|
||||
AND status = 'success'
|
||||
AND del_state = 0
|
||||
);
|
||||
|
||||
-- 3) 订单状态改为已退款
|
||||
UPDATE `order`
|
||||
SET
|
||||
status = 'refunded',
|
||||
refund_time = NOW(),
|
||||
version = version + 1,
|
||||
update_time = NOW()
|
||||
WHERE
|
||||
id = @order_id
|
||||
AND del_state = 0
|
||||
AND status = 'paid';
|
||||
|
||||
-- 4) 代理佣金:按本次退款 99.5 元在该订单的佣金上比例冲减(refunded_amount 增加,满额则 status=2)
|
||||
SET
|
||||
@total_available = (
|
||||
SELECT COALESCE(
|
||||
SUM(amount - refunded_amount), 0
|
||||
)
|
||||
FROM agent_commission
|
||||
WHERE
|
||||
order_id = @order_id
|
||||
AND del_state = 0
|
||||
);
|
||||
|
||||
UPDATE agent_commission
|
||||
SET
|
||||
refunded_amount = LEAST(
|
||||
amount,
|
||||
refunded_amount + @repair_refund_amount * (amount - refunded_amount) / NULLIF(@total_available, 0)
|
||||
),
|
||||
status = CASE
|
||||
WHEN LEAST(
|
||||
amount,
|
||||
refunded_amount + @repair_refund_amount * (amount - refunded_amount) / NULLIF(@total_available, 0)
|
||||
) >= amount THEN 2
|
||||
ELSE status
|
||||
END,
|
||||
version = version + 1,
|
||||
update_time = NOW()
|
||||
WHERE
|
||||
order_id = @order_id
|
||||
AND del_state = 0
|
||||
AND @total_available > 0;
|
||||
|
||||
-- 5) 代理钱包扣减 + 流水(仅对尚未存在本单退款流水的代理扣减,避免重复执行导致重复扣款)
|
||||
DROP TEMPORARY TABLE IF EXISTS _repair_wallet_snapshot;
|
||||
|
||||
CREATE TEMPORARY TABLE _repair_wallet_snapshot (
|
||||
agent_id BIGINT NOT NULL,
|
||||
balance_before DECIMAL(20, 4) NOT NULL,
|
||||
frozen_before DECIMAL(20, 4) NOT NULL,
|
||||
total_deduct DECIMAL(20, 4) NOT NULL,
|
||||
PRIMARY KEY (agent_id)
|
||||
);
|
||||
|
||||
-- 按 99.5 元在该订单各代理间按“可退佣金”比例分配扣减额(与 step 4 一致),仅扣减额>0 的代理
|
||||
INSERT INTO
|
||||
_repair_wallet_snapshot (
|
||||
agent_id,
|
||||
balance_before,
|
||||
frozen_before,
|
||||
total_deduct
|
||||
)
|
||||
SELECT
|
||||
agent_id,
|
||||
balance_before,
|
||||
frozen_before,
|
||||
total_deduct
|
||||
FROM (
|
||||
SELECT
|
||||
c.agent_id, w.balance AS balance_before, w.frozen_balance AS frozen_before, @repair_refund_amount * COALESCE(
|
||||
SUM(c.amount - c.refunded_amount), 0
|
||||
) / NULLIF(@total_available, 0) AS total_deduct
|
||||
FROM
|
||||
agent_commission c
|
||||
JOIN agent_wallet w ON w.agent_id = c.agent_id
|
||||
AND w.del_state = 0
|
||||
WHERE
|
||||
c.order_id = @order_id
|
||||
AND c.del_state = 0
|
||||
AND @total_available > 0
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM agent_wallet_transaction t
|
||||
WHERE
|
||||
t.agent_id = c.agent_id
|
||||
AND t.transaction_id = @order_no
|
||||
AND t.transaction_type = 'refund'
|
||||
AND t.del_state = 0
|
||||
)
|
||||
GROUP BY
|
||||
c.agent_id, w.balance, w.frozen_balance
|
||||
) _agent_deduct
|
||||
WHERE
|
||||
total_deduct > 0;
|
||||
|
||||
-- 从钱包扣减:优先扣冻结余额,不足再扣可用余额
|
||||
UPDATE agent_wallet w
|
||||
INNER JOIN _repair_wallet_snapshot r ON w.agent_id = r.agent_id
|
||||
SET
|
||||
w.frozen_balance = w.frozen_balance - LEAST(
|
||||
r.total_deduct,
|
||||
w.frozen_balance
|
||||
),
|
||||
w.balance = w.balance - (
|
||||
r.total_deduct - LEAST(
|
||||
r.total_deduct,
|
||||
w.frozen_balance
|
||||
)
|
||||
),
|
||||
w.version = w.version + 1,
|
||||
w.update_time = NOW()
|
||||
WHERE
|
||||
w.del_state = 0;
|
||||
|
||||
-- 插入退款流水(金额为负数)
|
||||
INSERT INTO
|
||||
agent_wallet_transaction (
|
||||
delete_time,
|
||||
del_state,
|
||||
version,
|
||||
agent_id,
|
||||
transaction_type,
|
||||
amount,
|
||||
balance_before,
|
||||
balance_after,
|
||||
frozen_balance_before,
|
||||
frozen_balance_after,
|
||||
transaction_id,
|
||||
related_user_id,
|
||||
remark
|
||||
)
|
||||
SELECT
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
r.agent_id,
|
||||
'refund',
|
||||
- r.total_deduct,
|
||||
r.balance_before,
|
||||
r.balance_before - (
|
||||
r.total_deduct - LEAST(
|
||||
r.total_deduct,
|
||||
r.frozen_before
|
||||
)
|
||||
),
|
||||
r.frozen_before,
|
||||
r.frozen_before - LEAST(
|
||||
r.total_deduct,
|
||||
r.frozen_before
|
||||
),
|
||||
@order_no,
|
||||
NULL,
|
||||
'订单退款修复(支付宝已退,库内补单)'
|
||||
FROM _repair_wallet_snapshot r;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS _repair_wallet_snapshot;
|
||||
|
||||
COMMIT;
|
||||
-- ---------- 事务结束 ----------
|
||||
|
||||
-- 6) 校验(可选)
|
||||
-- 订单应为 refunded
|
||||
-- SELECT id, order_no, status, refund_time FROM `order` WHERE id = @order_id;
|
||||
-- 应有 success 退款记录,refund_amount = 99.5
|
||||
-- SELECT * FROM order_refund WHERE order_id = @order_id AND del_state = 0;
|
||||
-- 佣金 refunded_amount 按 99.5 比例增加,满额则 status=2
|
||||
-- SELECT id, agent_id, order_id, amount, refunded_amount, status FROM agent_commission WHERE order_id = @order_id;
|
||||
Reference in New Issue
Block a user