From 0e513d7ecc482c63c05c02d04fe3994db310530a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=AF=E4=B9=90=E5=8A=A0=E5=86=B0?= <11869599+addie66@user.noreply.gitee.com> Date: Tue, 29 Sep 2026 11:52:53 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=86=E8=B4=A6=E6=A0=B8=E9=AA=8C=E6=9B=B4?= =?UTF-8?q?=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shopro/library/split/SplitCalculator.php | 16 +++- .../shopro/tests/split_commission_verify.php | 73 ++++++++++++++----- .../shopro/tests/split_commission_verify.sql | 36 ++++++--- 3 files changed, 95 insertions(+), 30 deletions(-) diff --git a/addons/shopro/library/split/SplitCalculator.php b/addons/shopro/library/split/SplitCalculator.php index a75f09b..72e1285 100644 --- a/addons/shopro/library/split/SplitCalculator.php +++ b/addons/shopro/library/split/SplitCalculator.php @@ -58,6 +58,20 @@ class SplitCalculator return $items; } + protected function getRegionalRewardsByOrderId($orderId) + { + try { + return RegionalReward::where('order_id', $orderId)->where('status', '>=', 0)->select(); + } catch (\Exception $e) { + return RegionalReward::alias('rr') + ->join('shopro_regional_agent_order ro', 'ro.id = rr.regional_order_id') + ->where('ro.order_id', $orderId) + ->where('rr.status', '>=', 0) + ->field('rr.*') + ->select(); + } + } + protected function calculateFromCommission($orderId) { $items = []; @@ -80,7 +94,7 @@ class SplitCalculator $items[] = $this->buildItem('promoter', $userId, $receiver, $amount, '推广员差价'); } - $regionalRewards = RegionalReward::where('order_id', $orderId)->where('status', '>=', 0)->select(); + $regionalRewards = $this->getRegionalRewardsByOrderId($orderId); foreach ($regionalRewards as $reward) { $receiver = $this->getReceiver('regional_agent', $reward['agent_user_id']); if (!$receiver) { diff --git a/addons/shopro/tests/split_commission_verify.php b/addons/shopro/tests/split_commission_verify.php index c3e22b4..d88b036 100644 --- a/addons/shopro/tests/split_commission_verify.php +++ b/addons/shopro/tests/split_commission_verify.php @@ -66,6 +66,53 @@ switch ($command) { exit(1); } +function tableHasColumn($table, $column) +{ + static $cache = []; + $key = $table . '.' . $column; + if (array_key_exists($key, $cache)) { + return $cache[$key]; + } + $full = config('database.prefix') . $table; + try { + $col = str_replace(['`', "'"], '', $column); + $rows = Db::query("SHOW COLUMNS FROM `{$full}` LIKE '{$col}'"); + } catch (\Exception $e) { + $cache[$key] = false; + return false; + } + $cache[$key] = !empty($rows); + return $cache[$key]; +} + +/** 按订单查区域佣金(兼容无 order_id 字段的旧表结构) */ +function selectRegionalRewardsByOrderId($orderId) +{ + if (tableHasColumn('shopro_regional_agent_reward', 'order_id')) { + return Db::name('shopro_regional_agent_reward')->where('order_id', $orderId)->select(); + } + return Db::name('shopro_regional_agent_reward')->alias('rr') + ->join('shopro_regional_agent_order ro', 'ro.id = rr.regional_order_id') + ->where('ro.order_id', $orderId) + ->field('rr.*') + ->select(); +} + +/** 订单是否存在分销/区域佣金(用于筛选) */ +function sqlOrderHasAnyReward($orderIdExpr = 'o.id') +{ + $pfx = config('database.prefix'); + $dist = "EXISTS (SELECT 1 FROM {$pfx}shopro_commission_reward cr WHERE cr.order_id = {$orderIdExpr} AND cr.status >= 0)"; + if (tableHasColumn('shopro_regional_agent_reward', 'order_id')) { + $reg = "EXISTS (SELECT 1 FROM {$pfx}shopro_regional_agent_reward rr WHERE rr.order_id = {$orderIdExpr} AND rr.status >= 0)"; + } else { + $reg = "EXISTS (SELECT 1 FROM {$pfx}shopro_regional_agent_reward rr " + . "INNER JOIN {$pfx}shopro_regional_agent_order ro ON ro.id = rr.regional_order_id " + . "WHERE ro.order_id = {$orderIdExpr} AND rr.status >= 0)"; + } + return "({$dist} OR {$reg})"; +} + function splitConfigMap() { return Db::name('shopro_split_config')->column('value', 'name'); @@ -269,17 +316,7 @@ function fetchMissingSplitOrders($since, $limit = 20) ->where('so.channel', 'huifu') ->where('so.status', 'in', [1, 2, 3]); }) - ->where(function ($q) { - $q->whereExists(function ($sq) { - $sq->name('shopro_commission_reward')->alias('cr') - ->whereRaw('cr.order_id = o.id') - ->where('cr.status', '>=', 0); - })->whereOr(function ($sq) { - $sq->name('shopro_regional_agent_reward')->alias('rr') - ->whereRaw('rr.order_id = o.id') - ->where('rr.status', '>=', 0); - }); - }) + ->whereRaw(sqlOrderHasAnyReward('o.id')) ->field('o.id, o.order_sn, o.pay_fee, o.pay_type, o.paytime, o.transaction_id') ->order('o.id desc') ->limit($limit) @@ -337,10 +374,10 @@ function diagnoseOrderSplitBlockers($orderId) $rc = $recv ? $recv['receiver_account'] : '无 receiver'; $reasons[] = " 推广员 user_id={$uid} 佣金={$rw['commission']} 进件={$ob} split_receiver={$rc}"; } - $regRewards = Db::name('shopro_regional_agent_reward') - ->where('order_id', $orderId) - ->where('status', '>=', 0) - ->select(); + $regRewards = selectRegionalRewardsByOrderId($orderId); + $regRewards = array_filter($regRewards, function ($rw) { + return intval($rw['status']) >= 0; + }); foreach ($regRewards as $rw) { $uid = $rw['agent_user_id']; $recv = Db::name('shopro_split_receiver') @@ -365,7 +402,9 @@ function diagnoseOrderSplitBlockers($orderId) $walletCnt = 0; $crIds = Db::name('shopro_commission_reward')->where('order_id', $orderId)->where('status', 1)->column('id'); - $rrIds = Db::name('shopro_regional_agent_reward')->where('order_id', $orderId)->where('status', 1)->column('id'); + $rrIds = array_column(array_filter(selectRegionalRewardsByOrderId($orderId), function ($r) { + return intval($r['status']) === 1; + }), 'id'); $allIds = array_merge($crIds ?: [], $rrIds ?: []); if ($allIds) { $walletCnt = Db::name('shopro_user_wallet_log') @@ -458,7 +497,7 @@ function printOrderDetail($orderSn) } $cr = Db::name('shopro_commission_reward')->where('order_id', $oid)->select(); - $rr = Db::name('shopro_regional_agent_reward')->where('order_id', $oid)->select(); + $rr = selectRegionalRewardsByOrderId($oid); echo "\n【分销/区域佣金记录(业务层)】\n"; echo "commission_reward: " . count($cr) . " 条\n"; echo "regional_reward: " . count($rr) . " 条\n"; diff --git a/addons/shopro/tests/split_commission_verify.sql b/addons/shopro/tests/split_commission_verify.sql index edd9b12..5336aef 100644 --- a/addons/shopro/tests/split_commission_verify.sql +++ b/addons/shopro/tests/split_commission_verify.sql @@ -210,12 +210,13 @@ LEFT JOIN ( GROUP BY order_id ) cr ON cr.order_id = so.order_id LEFT JOIN ( - SELECT order_id, - SUM(commission) AS reg_commission, - SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) AS reg_accounted - FROM fa_shopro_regional_agent_reward - WHERE status >= 0 - GROUP BY order_id + SELECT ro.order_id, + SUM(rr.commission) AS reg_commission, + SUM(CASE WHEN rr.status = 1 THEN 1 ELSE 0 END) AS reg_accounted + FROM fa_shopro_regional_agent_reward rr + INNER JOIN fa_shopro_regional_agent_order ro ON ro.id = rr.regional_order_id + WHERE rr.status >= 0 + GROUP BY ro.order_id ) rr ON rr.order_id = so.order_id LEFT JOIN ( SELECT order_id, @@ -231,13 +232,14 @@ LEFT JOIN ( WHERE cr.status = 1 GROUP BY cr.order_id UNION ALL - SELECT rr.order_id, 0, + SELECT ro.order_id, 0, SUM(CASE WHEN wl.type = 'regional_agent_income' THEN wl.wallet ELSE 0 END) FROM fa_shopro_regional_agent_reward rr + INNER JOIN fa_shopro_regional_agent_order ro ON ro.id = rr.regional_order_id INNER JOIN fa_shopro_user_wallet_log wl ON wl.item_id = rr.id AND wl.type = 'regional_agent_income' AND wl.wallet_type = 'money' WHERE rr.status = 1 - GROUP BY rr.order_id + GROUP BY ro.order_id ) wsum GROUP BY order_id ) wl ON wl.order_id = so.order_id @@ -265,8 +267,11 @@ LEFT JOIN ( FROM fa_shopro_commission_reward WHERE status >= 0 GROUP BY order_id ) cr ON cr.order_id = o.id LEFT JOIN ( - SELECT order_id, COUNT(*) AS reward_cnt, SUM(commission) AS reward_sum - FROM fa_shopro_regional_agent_reward WHERE status >= 0 GROUP BY order_id + SELECT ro.order_id, COUNT(*) AS reward_cnt, SUM(rr.commission) AS reward_sum + FROM fa_shopro_regional_agent_reward rr + INNER JOIN fa_shopro_regional_agent_order ro ON ro.id = rr.regional_order_id + WHERE rr.status >= 0 + GROUP BY ro.order_id ) rr ON rr.order_id = o.id LEFT JOIN fa_shopro_split_order so ON so.order_id = o.id AND so.channel = 'huifu' WHERE o.pay_type = 'huifu_wechat' @@ -353,7 +358,10 @@ LEFT JOIN fa_shopro_split_receiver sr ON sr.id = sor.receiver_id WHERE sor.split_order_id IN (SELECT id FROM fa_shopro_split_order WHERE order_sn = @order_sn); SELECT * FROM fa_shopro_commission_reward WHERE order_id = (SELECT id FROM fa_shopro_order WHERE order_sn = @order_sn LIMIT 1); -SELECT * FROM fa_shopro_regional_agent_reward WHERE order_id = (SELECT id FROM fa_shopro_order WHERE order_sn = @order_sn LIMIT 1); +SELECT rr.* +FROM fa_shopro_regional_agent_reward rr +INNER JOIN fa_shopro_regional_agent_order ro ON ro.id = rr.regional_order_id +WHERE ro.order_id = (SELECT id FROM fa_shopro_order WHERE order_sn = @order_sn LIMIT 1); SELECT wl.* FROM fa_shopro_user_wallet_log wl @@ -361,7 +369,11 @@ WHERE wl.wallet_type = 'money' AND wl.type IN ('commission_income', 'regional_agent_income', 'commission_back', 'regional_agent_back') AND ( wl.item_id IN (SELECT id FROM fa_shopro_commission_reward WHERE order_id = (SELECT id FROM fa_shopro_order WHERE order_sn = @order_sn LIMIT 1)) - OR wl.item_id IN (SELECT id FROM fa_shopro_regional_agent_reward WHERE order_id = (SELECT id FROM fa_shopro_order WHERE order_sn = @order_sn LIMIT 1)) + OR wl.item_id IN ( + SELECT rr.id FROM fa_shopro_regional_agent_reward rr + INNER JOIN fa_shopro_regional_agent_order ro ON ro.id = rr.regional_order_id + WHERE ro.order_id = (SELECT id FROM fa_shopro_order WHERE order_sn = @order_sn LIMIT 1) + ) ); SELECT * FROM fa_shopro_huifu_pay_ext WHERE order_id = (SELECT id FROM fa_shopro_order WHERE order_sn = @order_sn LIMIT 1);