125 lines
3.9 KiB
PHP
125 lines
3.9 KiB
PHP
<?php
|
|
|
|
namespace App\Imports;
|
|
|
|
use App\Models\Song;
|
|
use App\Models\Artist;
|
|
use App\Models\SongCategory;
|
|
use App\Enums\ArtistCategory;
|
|
use App\Enums\SongLanguageType;
|
|
use App\Enums\SongSituation;
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\Str;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Maatwebsite\Excel\Concerns\ToCollection;
|
|
use Maatwebsite\Excel\Concerns\WithHeadingRow;
|
|
use Maatwebsite\Excel\Concerns\WithChunkReading;
|
|
|
|
class SongDataImport implements ToCollection, WithHeadingRow, WithChunkReading
|
|
{
|
|
protected array $artistCache = [];
|
|
protected array $categoryMap = [];
|
|
|
|
public function __construct()
|
|
{
|
|
// 快取分類代碼對應 ID
|
|
$this->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;
|
|
}
|
|
} |