argument('tenant_id'); $dryRun = $this->option('dry-run'); // 檢查租戶是否存在 $tenant = Tenant::find($tenantId); if (!$tenant) { $this->error("租戶 '{$tenantId}' 不存在!請先建立租戶。"); return self::FAILURE; } $this->info("開始遷移資料到租戶: {$tenantId}"); $this->info("租戶資料庫: tenant{$tenantId}"); if ($dryRun) { $this->warn('⚠️ Dry Run 模式 - 不會實際遷移資料'); } // 取得 central 資料庫連線 $centralConnection = config('database.default'); $tenantDbName = 'tenant' . $tenantId; foreach ($this->tablesToMigrate as $table) { // 檢查表是否存在於 central if (!Schema::connection($centralConnection)->hasTable($table)) { $this->line(" ⏭️ 跳過 {$table} (表不存在)"); continue; } // 計算資料筆數 $count = DB::connection($centralConnection)->table($table)->count(); if ($count === 0) { $this->line(" ⏭️ 跳過 {$table} (無資料)"); continue; } if ($dryRun) { $this->info(" 📋 {$table}: {$count} 筆資料"); continue; } // 實際遷移資料 $this->info(" 🔄 遷移 {$table}: {$count} 筆資料..."); try { // 使用租戶上下文執行 $tenant->run(function () use ($centralConnection, $table) { // 取得 central 資料 $data = DB::connection($centralConnection)->table($table)->get(); if ($data->isEmpty()) { return; } // 關閉外鍵檢查 DB::statement('SET FOREIGN_KEY_CHECKS=0'); // 清空目標表 DB::table($table)->truncate(); // 分批插入 (每批 100 筆) foreach ($data->chunk(100) as $chunk) { DB::table($table)->insert($chunk->map(fn($item) => (array) $item)->toArray()); } // 恢復外鍵檢查 DB::statement('SET FOREIGN_KEY_CHECKS=1'); }); $this->info(" ✅ {$table} 遷移完成"); } catch (\Exception $e) { $this->error(" ❌ {$table} 遷移失敗: " . $e->getMessage()); return self::FAILURE; } } $this->newLine(); $this->info('🎉 資料遷移完成!'); return self::SUCCESS; } }