categoryMap = SongCategory::pluck('id', 'code')->toArray(); } public function collection(Collection $rows) { $songsToInsert = []; $artistMap = []; // [song_id => [artist_id]] $categoryMap = []; // [song_id => [category_id]] foreach ($rows as $row) { $songId = trim($row['編號'] ?? ''); if (!$songId) { continue; } // 準備 song 資料 $songsToInsert[] = [ 'id' => $songId, 'name' => trim($row['歌名'] ?? ''), 'adddate' => trim($row['日期'] ?? null), 'filename' => trim($row['檔名'] ?? ''), 'language_type' => SongLanguageType::tryFrom(trim($row['語別'] ?? '')) ?? SongLanguageType::Unset, 'db_change' => trim($row['分貝增減'] ?? 0), 'vocal' => trim($row['人聲'] ?? 0), 'situation' => SongSituation::tryFrom(trim($row['情境'] ?? '')) ?? SongSituation::Unset, 'copyright01' => trim($row['版權01'] ?? ''), 'copyright02' => trim($row['版權02'] ?? ''), 'note01' => trim($row['備註01'] ?? ''), 'note02' => trim($row['備註02'] ?? ''), 'note03' => trim($row['備註03'] ?? ''), 'note04' => trim($row['備註04'] ?? ''), 'enable' => trim($row['狀態'] ?? 1), 'song_counts' => trim($row['點播次數'] ?? 0), ]; // 歌星 A/B 處理 foreach (['歌星A', '歌星B'] as $key) { $artistName = trim($row[$key] ?? ''); if ($artistName === '') continue; $artistId = $this->getOrCreateArtistId($artistName); $artistMap[$songId][] = $artistId; } // 分類處理(多個用 , 分隔) if (!empty($row['分類'])) { $codes = explode(',', $row['分類']); foreach ($codes as $code) { $code = trim($code); if (isset($this->categoryMap[$code])) { $categoryMap[$songId][] = $this->categoryMap[$code]; } } } } // 寫入資料庫 Song::insert($songsToInsert); // 同步關聯(建議可用事件或批次處理) foreach ($artistMap as $songId => $artistIds) { $song = Song::find($songId); if ($song) { $song->artists()->sync($artistIds); } } foreach ($categoryMap as $songId => $categoryIds) { $song = Song::find($songId); if ($song) { $song->categories()->sync($categoryIds); } } } protected function getOrCreateArtistId(string $name): int { if (isset($this->artistCache[$name])) { return $this->artistCache[$name]; } $artist = Artist::firstOrCreate( ['name' => $name], ['category' => ArtistCategory::Unset] ); return $this->artistCache[$name] = $artist->id; } public function chunkSize(): int { return 1000; } public function headingRow(): int { return 1; } }