make(Illuminate\Contracts\Console\Kernel::class)->bootstrap(); use App\Models\Plan; use App\Models\Server; use App\Models\ServerGroup; use App\Models\User; use Illuminate\Support\Facades\DB; $opts = getopt('', ['backup:', 'plans:', 'group:']); $dir = $opts['backup'] ?? throw new RuntimeException('Missing backup'); $ids = array_map('intval', explode(',', $opts['plans'] ?? '')); if (!$ids || in_array(0, $ids, true)) throw new RuntimeException('Explicit plan IDs required'); $m = json_decode(file_get_contents("$dir/manifest.json"), true, flags: JSON_THROW_ON_ERROR); $groupId = (int)($opts['group'] ?? $m['group_id']); $node = Server::findOrFail($m['node_id']); $qa = User::findOrFail($m['test_user_id']); if (!$node->is_online || $qa->u + $qa->d <= 0) throw new RuntimeException('Online and traffic evidence missing'); if (is_file("$dir/promoted.json")) { echo "Already promoted; verify current state separately\n"; exit; } $plans = Plan::whereIn('id', $ids)->get(); if ($plans->count() !== count($ids)) throw new RuntimeException('Plan list mismatch'); foreach ($plans as $p) if ($p->group_id !== null && $p->group_id !== $groupId) throw new RuntimeException('Plan already assigned elsewhere'); $users = User::whereIn('plan_id', $ids)->whereNull('group_id')->get(['id','group_id','updated_at']); umask(0077); file_put_contents("$dir/before-promotion.json", json_encode([ 'plans' => $plans->map->getAttributes(), 'user_groups' => $users, 'node_groups' => $node->group_ids, 'group' => ServerGroup::findOrFail($groupId)->getAttributes(), 'subscribe_url' => admin_setting('subscribe_url'), 'qa_banned' => $qa->banned, ], JSON_THROW_ON_ERROR)); DB::transaction(function () use ($ids, $users, $node, $qa, $groupId) { $group = ServerGroup::findOrFail($groupId); if (str_starts_with($group->name, 'dpl 接入验收 ')) { $group->name = '基础节点'; $group->save(); } Plan::whereIn('id', $ids)->whereNull('group_id')->update(['group_id' => $groupId]); User::whereIn('id', $users->pluck('id'))->whereNull('group_id')->update(['group_id' => $groupId]); $node->group_ids = [(string)$groupId]; $node->save(); $qa->banned = 1; $qa->saveQuietly(); admin_setting(['subscribe_url' => 'https://c2.deeplink-subscribe.com']); }); $result = ['node_id' => $node->id, 'group_id' => $groupId, 'plan_ids' => $ids, 'existing_users_assigned' => $users->count(), 'qa_disabled' => true]; file_put_contents("$dir/promoted.json", json_encode($result, JSON_THROW_ON_ERROR)); echo json_encode($result) . PHP_EOL;