-- 手工补录订单推荐人 + 与支付回调一致的分佣累计(pending_earnings、referral_bindings) -- 逻辑对齐 soul-api/internal/handler/miniprogram.go processReferralCommission -- 与 referral_commission.go computeOrderCommission -- -- 使用前填写下面两个变量,并在测试库先执行「第四节」预览佣金。 -- MySQL 5.7+ / 8.0+(需 JSON 函数) -- -- 若报 1267 Illegal mix of collations:表字段与客户端/会话默认 collation 不一致(常见 unicode_ci vs general_ci)。 -- 下面 SET NAMES + 字符串比较处 COLLATE 已对齐;若库表统一为 general_ci,可把脚本中 utf8mb4_unicode_ci 全部改为 utf8mb4_general_ci。 SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci; -- ============ 1. 填写 ============ SET @order_sn = 'MP20260508082957878950'; SET @referrer_id = 'ogpTW5QBRQNUOm4-zvg8it2XySrI'; -- ================================= SET @cfg := ( SELECT config_value FROM system_config WHERE config_key COLLATE utf8mb4_unicode_ci = CONVERT('referral_config' USING utf8mb4) COLLATE utf8mb4_unicode_ci LIMIT 1 ); SELECT id, user_id, amount, product_type, status, pay_time INTO @order_id, @buyer_id, @amt, @ptype, @ostatus, @pay_time FROM orders WHERE order_sn COLLATE utf8mb4_unicode_ci = (@order_sn COLLATE utf8mb4_unicode_ci) LIMIT 1; SELECT COUNT(*) INTO @ref_exists FROM users WHERE id COLLATE utf8mb4_unicode_ci = (@referrer_id COLLATE utf8mb4_unicode_ci); SET @ref_code := NULL; SELECT referral_code INTO @ref_code FROM users WHERE id COLLATE utf8mb4_unicode_ci = (@referrer_id COLLATE utf8mb4_unicode_ci) LIMIT 1; SET @dist_pct := COALESCE(CAST(JSON_UNQUOTE(JSON_EXTRACT(@cfg, '$.distributorShare')) AS DECIMAL(18,6)), 90); SET @disc_pct := COALESCE(CAST(JSON_UNQUOTE(JSON_EXTRACT(@cfg, '$.userDiscount')) AS DECIMAL(18,6)), 0); SET @vip_vip_pct := COALESCE(CAST(JSON_UNQUOTE(JSON_EXTRACT(@cfg, '$.vipOrderShareVip')) AS DECIMAL(18,6)), 20); SET @vip_non_pct := COALESCE(CAST(JSON_UNQUOTE(JSON_EXTRACT(@cfg, '$.vipOrderShareNonVip')) AS DECIMAL(18,6)), 10); SET @disc := @disc_pct / 100; SET @dist := @dist_pct / 100; SET @ref_is_vip := IFNULL(( SELECT (COALESCE(u.is_vip, 0) <> 0) AND (u.vip_expire_date IS NULL OR u.vip_expire_date > NOW()) FROM users u WHERE u.id COLLATE utf8mb4_unicode_ci = (@referrer_id COLLATE utf8mb4_unicode_ci) LIMIT 1 ), 0); SET @commission := CASE WHEN @order_id IS NULL THEN NULL WHEN @ref_exists = 0 THEN NULL WHEN (@ostatus COLLATE utf8mb4_unicode_ci) <> (CONVERT('paid' USING utf8mb4) COLLATE utf8mb4_unicode_ci) THEN NULL WHEN (@buyer_id COLLATE utf8mb4_unicode_ci) = (@referrer_id COLLATE utf8mb4_unicode_ci) THEN 0 WHEN @ptype COLLATE utf8mb4_unicode_ci IN ( CONVERT('link_karuo_tip' USING utf8mb4) COLLATE utf8mb4_unicode_ci, CONVERT('mentor_consultation' USING utf8mb4) COLLATE utf8mb4_unicode_ci ) THEN 0 WHEN (@ptype COLLATE utf8mb4_unicode_ci) = (CONVERT('vip' USING utf8mb4) COLLATE utf8mb4_unicode_ci) THEN @amt * IF( @ref_is_vip, @vip_vip_pct / 100, @vip_non_pct / 100 ) ELSE ( CASE WHEN @disc > 0 THEN @amt / (1 - @disc) ELSE @amt END ) * @dist END; SET @commission := ROUND(IFNULL(@commission, 0), 2); -- ============ 4. 预览(先单独执行到上一行,检查变量)============ SELECT @order_id AS order_id, @order_sn AS order_sn, @buyer_id AS buyer_user_id, @referrer_id AS referrer_user_id, @amt AS amount, @ptype AS product_type, @ostatus AS order_status, @commission AS commission_to_add, @ref_code AS referrer_code_for_order, @pay_time AS order_pay_time; -- 若 @order_id / @ref_exists / status 异常,不要执行下面事务。 -- ============ 5. 执行变更(确认预览无误后执行)============ START TRANSACTION; UPDATE orders SET referrer_id = @referrer_id, referral_code = IFNULL(@ref_code, referral_code) WHERE id = @order_id AND order_sn COLLATE utf8mb4_unicode_ci = (@order_sn COLLATE utf8mb4_unicode_ci) AND @ref_exists > 0 AND (@buyer_id COLLATE utf8mb4_unicode_ci) <> (@referrer_id COLLATE utf8mb4_unicode_ci); UPDATE users SET pending_earnings = COALESCE(pending_earnings, 0) + @commission WHERE id COLLATE utf8mb4_unicode_ci = (@referrer_id COLLATE utf8mb4_unicode_ci) AND @commission > 0; UPDATE referral_bindings rb INNER JOIN ( SELECT id FROM referral_bindings WHERE referee_id COLLATE utf8mb4_unicode_ci = (@buyer_id COLLATE utf8mb4_unicode_ci) AND referrer_id COLLATE utf8mb4_unicode_ci = (@referrer_id COLLATE utf8mb4_unicode_ci) AND status COLLATE utf8mb4_unicode_ci = (CONVERT('active' USING utf8mb4) COLLATE utf8mb4_unicode_ci) ORDER BY binding_date DESC LIMIT 1 ) t ON rb.id = t.id SET last_purchase_date = COALESCE(@pay_time, NOW()), purchase_count = COALESCE(purchase_count, 0) + 1, total_commission = COALESCE(total_commission, 0) + @commission WHERE @commission > 0; COMMIT; -- ============ 6. 备注 ============ -- · 若 referral_bindings 无对应 (买家,推荐人) 的 active 行,UPDATE 影响 0 行,属正常; -- 需业务上是否补插绑定记录另行处理。 -- · 若订单已有 referrer_id,本脚本会覆盖为 @referrer_id。 -- · commission 为 0 时仍会更新 orders 的推荐人字段,但不加 pending_earnings / 绑定累计。