$scenario) { echo str_repeat('-', 60) . "\n"; echo "{$scenario['title']}\n"; echo str_repeat('-', 60) . "\n"; echo "操作步骤:\n"; foreach ($scenario['steps'] as $i => $step) { echo " {$step}\n"; } echo "\n预期佣金:\n"; $result = CommissionScenarioCalculator::calculate($scenario['options']); $byPerson = []; foreach ($result['rewards'] as $row) { $name = $row['name']; if (!isset($byPerson[$name])) { $byPerson[$name] = []; } $byPerson[$name][] = $row; } printf(" %-16s %-10s %-6s %s\n", '人员', '类型', '层级', '金额(元)'); foreach ($result['rewards'] as $row) { $typeMap = [ 'chain' => '推广佣金', 'differential' => '级差奖', 'management' => '管理奖', 'repurchase_self' => '复购返现', ]; $typeName = $typeMap[$row['award_type']] ?? $row['award_type']; printf(" %-16s %-10s %-6s %.2f\n", $row['name'], $typeName, $row['commission_level'], $row['commission']); } echo "\n 合计发放: {$result['total']} 元\n"; echo "\n 按人汇总:\n"; foreach ($byPerson as $name => $rows) { $sum = 0; $parts = []; foreach ($rows as $r) { $sum += $r['commission']; $parts[] = ($r['award_type'] === 'chain' ? '推广' : ($r['award_type'] === 'differential' ? '级差' : ($r['award_type'] === 'management' ? '管理' : '复购'))) . $r['commission']; } echo " {$name}: " . implode(' + ', $parts) . " = " . round($sum, 2) . " 元\n"; } echo "\n"; } echo str_repeat('=', 60) . "\n"; echo "验证 SQL(支付后执行):\n"; echo " SELECT r.id, r.agent_id, u.nickname, r.commission, r.commission_level, r.commission_rules, r.status\n"; echo " FROM fa_shopro_commission_reward r\n"; echo " LEFT JOIN fa_user u ON u.id = r.agent_id\n"; echo " WHERE r.order_item_id = {订单明细ID}\n"; echo " ORDER BY r.id;\n\n"; if ($withDbHint) { echo "当前环境配置:\n"; listConfig(false); } } function listConfig($withHeader = true) { if ($withHeader) { echo "=== 分销配置 ===\n"; } $keys = [ 'chain_commission_enable', 'differential_commission_enable', 'management_award_enable', 'repurchase_referrer_enable', 'repurchase_self_enable', 'repurchase_self_type', 'repurchase_self_amount', 'commission_level', 'self_buy', 'commission_price_type', ]; $rows = Db::name('shopro_commission_config')->where('name', 'in', $keys)->column('value', 'name'); foreach ($keys as $k) { echo " {$k}: " . ($rows[$k] ?? '(未配置)') . "\n"; } echo "\n=== 分销商等级档位 ===\n"; $levels = Db::name('shopro_commission_agent_level')->order('level asc')->select(); foreach ($levels as $lv) { $rules = is_string($lv['commission_rules']) ? json_decode($lv['commission_rules'], true) : $lv['commission_rules']; $rules = is_array($rules) ? $rules : []; echo " [{$lv['level']}] {$lv['name']}: "; echo "链 " . ($rules['commission_1'] ?? 0) . "/" . ($rules['commission_2'] ?? 0) . "/" . ($rules['commission_3'] ?? 0) . "%"; echo " | 级差档 " . ($rules['differential_amount'] ?? 0) . " 元"; echo " | 管理奖 " . ($rules['management_rate'] ?? 0) . "%\n"; } echo "\n"; } function verifyOrderItem($itemId) { echo "=== 验证订单明细 #{$itemId} ===\n\n"; $item = Db::name('shopro_order_item')->where('id', $itemId)->find(); if (!$item) { fwrite(STDERR, "订单明细不存在\n"); exit(1); } $order = Db::name('shopro_order')->where('id', $item['order_id'])->find(); $buyer = Db::name('user')->where('id', $item['user_id'])->field('id,nickname,parent_user_id')->find(); $goodsCommission = Db::name('shopro_commission_goods')->where('goods_id', $item['goods_id'])->find(); echo "订单: {$order['order_sn']} | 买家: {$buyer['nickname']}({$buyer['id']})\n"; echo "商品ID: {$item['goods_id']} | 数量: {$item['goods_num']} | pay_price: {$item['pay_price']}\n"; if ($goodsCommission) { echo "分销商品: 参与=" . ($goodsCommission['status'] ?? 0); echo " 级差=" . ($goodsCommission['differential_enable'] ?? 0); echo " 管理=" . ($goodsCommission['management_enable'] ?? 0); echo " 复购=" . ($goodsCommission['repurchase_enable'] ?? 0) . "\n"; } else { echo "分销商品: 未配置\n"; } $commissionOrder = Db::name('shopro_commission_order')->where('order_item_id', $itemId)->find(); if (!$commissionOrder) { echo "\n[WARN] 尚无分销订单记录,请确认已支付且商品参与分销\n"; exit(0); } echo "分销订单ID: {$commissionOrder['id']} | 结算金额: {$commissionOrder['amount']} | 自购: {$commissionOrder['self_buy']}\n"; $priorOrders = Db::name('shopro_order') ->where('user_id', $item['user_id']) ->where('status', 'in', [1, 2]) ->where('id', '<', $item['order_id']) ->count(); echo "是否复购: " . ($priorOrders > 0 ? '是' : '否') . " (历史有效订单 {$priorOrders} 笔)\n\n"; $rewards = Db::name('shopro_commission_reward') ->alias('r') ->join('user u', 'u.id = r.agent_id', 'LEFT') ->where('r.order_item_id', $itemId) ->field('r.*, u.nickname') ->order('r.id asc') ->select(); if (!$rewards) { echo "[WARN] 无佣金记录\n"; exit(0); } $typeMap = [ 'chain' => '推广佣金', 'differential' => '级差奖', 'management' => '管理奖', 'repurchase_self' => '复购返现', ]; echo "实际佣金记录:\n"; printf(" %-6s %-8s %-14s %-8s %-6s %s\n", 'ID', '用户ID', '昵称', '类型', '层级', '金额'); $total = 0; foreach ($rewards as $r) { $rules = json_decode($r['commission_rules'], true); $type = $rules['award_type'] ?? 'chain'; if ($type === 'chain' && intval($r['commission_level']) === 0) { $type = 'repurchase_self'; } $typeName = $typeMap[$type] ?? $type; printf(" %-6s %-8s %-14s %-8s %-6s %.2f\n", $r['id'], $r['agent_id'], $r['nickname'] ?? '-', $typeName, $r['commission_level'], $r['commission']); $total += floatval($r['commission']); } echo "\n 实际合计: " . round($total, 2) . " 元\n"; $chain = buildAgentChain(intval($commissionOrder['agent_id']), intval(Db::name('shopro_commission_config')->where('name', 'commission_level')->value('value') ?: 3)); if ($chain) { echo "\n上级链(从分销订单 agent_id 起): " . implode(' → ', array_column($chain, 'name')) . "\n"; } echo "\n[INFO] 可将等级档位改为与内置场景一致后,用 scenarios 命令对照预期\n"; } function buildAgentChain($startUserId, $maxLevel) { $chain = []; $userId = $startUserId; $depth = 1; while ($userId && $depth <= $maxLevel) { $agent = Db::name('shopro_commission_agent')->where('user_id', $userId)->where('status', 'normal')->find(); if (!$agent) { break; } $user = Db::name('user')->where('id', $userId)->field('id,nickname,parent_user_id')->find(); $chain[] = [ 'name' => ($user['nickname'] ?? $userId) . "(L{$depth})", 'user_id' => $userId, ]; $userId = intval($user['parent_user_id'] ?? 0); $depth++; } return $chain; }