where('id', 'in', $userIds)->field('id,nickname,mobile')->select(); if (!$foundUsers) { echo "未找到测试用户 (900001~900004),无需清理。\n"; exit(0); } echo "将处理的测试用户:\n"; foreach ($foundUsers as $row) { echo " - {$row['id']} {$row['nickname']} ({$row['mobile']})\n"; } echo "\n"; $stats = []; try { if ($dryRun) { previewCleanup($userIds, $stats); } else { Db::startTrans(); runCleanup($userIds, $stats); Db::commit(); } } catch (\Throwable $e) { if (!$dryRun) { Db::rollback(); } fwrite(STDERR, "失败: " . $e->getMessage() . "\n"); exit(1); } echo "\n========== 汇总 ==========\n"; foreach ($stats as $label => $count) { echo sprintf(" %-28s %d\n", $label, $count); } echo $dryRun ? "\n确认无误后请加 --confirm 执行删除。\n" : "\n清理完成。\n"; function previewCleanup(array $userIds, array &$stats) { collectRelatedIds($userIds, $orderIds, $orderItemIds, $commissionOrderIds); countWhere($stats, '订单', 'shopro_order', ['id' => ['in', $orderIds ?: [0]]]); countWhere($stats, '订单商品', 'shopro_order_item', ['order_id' => ['in', $orderIds ?: [0]]]); countWhere($stats, '发票', 'shopro_order_invoice', ['order_id' => ['in', $orderIds ?: [0]]]); countWhere($stats, '分销订单', 'shopro_commission_order', function ($q) use ($userIds, $orderIds) { $q->where(function ($sub) use ($userIds, $orderIds) { $sub->where('buyer_id', 'in', $userIds)->whereOr('agent_id', 'in', $userIds); if ($orderIds) { $sub->whereOr('order_id', 'in', $orderIds); } }); }); countWhere($stats, '佣金记录', 'shopro_commission_reward', function ($q) use ($userIds, $orderIds) { $q->where(function ($sub) use ($userIds, $orderIds) { $sub->where('agent_id', 'in', $userIds)->whereOr('buyer_id', 'in', $userIds); if ($orderIds) { $sub->whereOr('order_id', 'in', $orderIds); } }); }); countWhere($stats, '分销动态', 'shopro_commission_log', ['agent_id' => ['in', $userIds]]); countWhere($stats, '分享记录', 'shopro_share', function ($q) use ($userIds) { $q->where('user_id', 'in', $userIds)->whereOr('share_id', 'in', $userIds); }); countWhere($stats, '钱包流水', 'shopro_user_wallet_log', ['user_id' => ['in', $userIds]]); countWhere($stats, '余额日志', 'user_money_log', ['user_id' => ['in', $userIds]]); countWhere($stats, '积分日志', 'user_score_log', ['user_id' => ['in', $userIds]]); countWhere($stats, '用户优惠券', 'shopro_user_coupons', ['user_id' => ['in', $userIds]]); countWhere($stats, '商品评价', 'shopro_goods_comment', ['user_id' => ['in', $userIds]]); countWhere($stats, '收货地址', 'shopro_user_address', ['user_id' => ['in', $userIds]]); countWhere($stats, '购物车', 'shopro_cart', ['user_id' => ['in', $userIds]]); countWhere($stats, '第三方授权', 'shopro_user_oauth', ['user_id' => ['in', $userIds]]); countWhere($stats, '分销商', 'shopro_commission_agent', ['user_id' => ['in', $userIds]]); countWhere($stats, '用户Token', 'user_token', ['user_id' => ['in', $userIds]]); countWhere($stats, '用户账号', 'user', ['id' => ['in', $userIds]]); $orphanParent = Db::name('user')->where('parent_user_id', 'in', $userIds)->count(); $stats['解除上级引用(将置0)'] = $orphanParent; } function runCleanup(array $userIds, array &$stats) { collectRelatedIds($userIds, $orderIds, $orderItemIds, $commissionOrderIds); // 解除其他用户对测试账号的上级引用 $stats['解除上级引用'] = Db::name('user')->where('parent_user_id', 'in', $userIds)->update(['parent_user_id' => 0]); // 佣金 $stats['佣金记录'] = deleteWhere('shopro_commission_reward', function ($q) use ($userIds, $orderIds) { $q->where(function ($sub) use ($userIds, $orderIds) { $sub->where('agent_id', 'in', $userIds)->whereOr('buyer_id', 'in', $userIds); if ($orderIds) { $sub->whereOr('order_id', 'in', $orderIds); } }); }); $stats['分销订单'] = deleteWhere('shopro_commission_order', function ($q) use ($userIds, $orderIds) { $q->where(function ($sub) use ($userIds, $orderIds) { $sub->where('buyer_id', 'in', $userIds)->whereOr('agent_id', 'in', $userIds); if ($orderIds) { $sub->whereOr('order_id', 'in', $orderIds); } }); }); $stats['分销动态'] = deleteWhere('shopro_commission_log', ['agent_id' => ['in', $userIds]]); // 订单附属 if ($orderIds) { $stats['发票'] = safeDelete('shopro_order_invoice', 'order_id', $orderIds); $stats['售后日志'] = safeDelete('shopro_order_aftersale_log', 'order_id', $orderIds); $stats['售后单'] = safeDelete('shopro_order_aftersale', 'order_id', $orderIds); $stats['物流日志'] = safeDelete('shopro_order_express_log', 'order_id', $orderIds); $stats['物流单'] = safeDelete('shopro_order_express', 'order_id', $orderIds); $stats['订单操作'] = safeDelete('shopro_order_action', 'order_id', $orderIds); $stats['订单商品'] = safeDelete('shopro_order_item', 'order_id', $orderIds); $stats['订单'] = safeDelete('shopro_order', 'id', $orderIds); } else { $stats['订单'] = 0; } $stats['分享记录'] = deleteWhere('shopro_share', function ($q) use ($userIds) { $q->where('user_id', 'in', $userIds)->whereOr('share_id', 'in', $userIds); }); $stats['钱包流水'] = deleteWhere('shopro_user_wallet_log', ['user_id' => ['in', $userIds]]); $stats['余额日志'] = deleteWhere('user_money_log', ['user_id' => ['in', $userIds]]); $stats['积分日志'] = deleteWhere('user_score_log', ['user_id' => ['in', $userIds]]); $stats['用户优惠券'] = deleteWhere('shopro_user_coupons', ['user_id' => ['in', $userIds]]); $stats['商品评价'] = deleteWhere('shopro_goods_comment', ['user_id' => ['in', $userIds]]); $stats['收货地址'] = deleteWhere('shopro_user_address', ['user_id' => ['in', $userIds]]); $stats['购物车'] = deleteWhere('shopro_cart', ['user_id' => ['in', $userIds]]); $stats['第三方授权'] = deleteWhere('shopro_user_oauth', ['user_id' => ['in', $userIds]]); $stats['用户Token'] = deleteWhere('user_token', ['user_id' => ['in', $userIds]]); $stats['分销商'] = deleteWhere('shopro_commission_agent', ['user_id' => ['in', $userIds]]); $stats['用户账号'] = deleteWhere('user', ['id' => ['in', $userIds]]); } function collectRelatedIds(array $userIds, &$orderIds, &$orderItemIds, &$commissionOrderIds) { $orderIds = Db::name('shopro_order')->where('user_id', 'in', $userIds)->column('id'); $orderIds = array_values(array_unique(array_map('intval', $orderIds ?: []))); $orderItemIds = []; if ($orderIds) { $orderItemIds = Db::name('shopro_order_item')->where('order_id', 'in', $orderIds)->column('id'); } $commissionOrderIds = Db::name('shopro_commission_order') ->where(function ($q) use ($userIds, $orderIds) { $q->where('buyer_id', 'in', $userIds)->whereOr('agent_id', 'in', $userIds); if ($orderIds) { $q->whereOr('order_id', 'in', $orderIds); } }) ->column('id'); } function tableExists($table) { static $cache = []; if (!isset($cache[$table])) { $cache[$table] = !empty(Db::query("SHOW TABLES LIKE '" . config('database.prefix') . $table . "'")); } return $cache[$table]; } function safeDelete($table, $field, array $ids) { if (!$ids || !tableExists($table)) { return 0; } return Db::name($table)->where($field, 'in', $ids)->delete(); } function deleteWhere($table, $where) { if (!tableExists($table)) { return 0; } $query = Db::name($table); if (is_callable($where)) { $where($query); } else { $query->where($where); } return $query->delete(); } function countWhere(array &$stats, $label, $table, $where) { if (!tableExists($table)) { $stats[$label] = 0; return; } $query = Db::name($table); if (is_callable($where)) { $where($query); } else { $query->where($where); } $stats[$label] = $query->count(); }