2025-08-27 13:03:26 +08:00
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Livewire\Pages;
|
|
|
|
|
|
|
|
|
|
use Livewire\Component;
|
2025-08-27 14:17:55 +08:00
|
|
|
|
use App\Models\Artist;
|
2025-08-27 13:03:26 +08:00
|
|
|
|
use App\Models\Song;
|
|
|
|
|
|
|
|
|
|
class SearchSong extends Component
|
|
|
|
|
{
|
|
|
|
|
public string $search = '';
|
|
|
|
|
public $searchCategory = '';
|
|
|
|
|
public $selectedLanguage = '國語'; // 預設語言
|
2025-08-27 14:17:55 +08:00
|
|
|
|
public $selectedArtists = []; // 儲存已選的歌手 id
|
|
|
|
|
public $artistOptions = []; // API 回傳的搜尋結果
|
|
|
|
|
public string $artistSearch = ''; // 即時搜尋文字
|
2025-08-27 13:03:26 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 初始化(接收外部傳入的分類參數)
|
|
|
|
|
*/
|
|
|
|
|
public function mount(string $searchCategory = '')
|
|
|
|
|
{
|
|
|
|
|
$this->searchCategory = $searchCategory;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 切換語言標籤
|
|
|
|
|
*/
|
|
|
|
|
public function selectLanguage(string $lang): void
|
|
|
|
|
{
|
|
|
|
|
$this->selectedLanguage = $lang;
|
|
|
|
|
}
|
2025-08-27 14:17:55 +08:00
|
|
|
|
/**
|
|
|
|
|
* 搜尋歌手(透過 API)
|
|
|
|
|
*/
|
|
|
|
|
public function updatedArtistSearch()
|
|
|
|
|
{
|
|
|
|
|
$search = $this->artistSearch;
|
|
|
|
|
|
|
|
|
|
if ($search) {
|
|
|
|
|
// 即時搜尋歌手,從資料庫查詢
|
|
|
|
|
$this->artistOptions = \App\Models\Artist::query()
|
|
|
|
|
->where('name', 'like', "{$search}%")
|
|
|
|
|
->limit(100)
|
|
|
|
|
->get(['id', 'name'])
|
|
|
|
|
->toArray();
|
|
|
|
|
} else {
|
|
|
|
|
$this->artistOptions = [];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public function addArtist($id, $name)
|
|
|
|
|
{
|
|
|
|
|
$this->selectedArtists[$id] = $name;
|
|
|
|
|
$this->artistSearch = ''; // 清空搜尋框
|
|
|
|
|
$this->artistOptions = [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function removeArtist($id)
|
|
|
|
|
{
|
|
|
|
|
unset($this->selectedArtists[$id]);
|
|
|
|
|
}
|
2025-08-27 13:03:26 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 點歌
|
|
|
|
|
*/
|
|
|
|
|
public function orderSong(int $songId): void
|
|
|
|
|
{
|
|
|
|
|
// TODO: 加入已點歌曲邏輯,例如:
|
|
|
|
|
// auth()->user()->room->addSong($songId);
|
|
|
|
|
|
|
|
|
|
$this->dispatchBrowserEvent('notify', [
|
|
|
|
|
'message' => '已加入已點歌曲'
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 取得歌曲清單
|
|
|
|
|
*/
|
|
|
|
|
protected function loadSongs()
|
|
|
|
|
{
|
|
|
|
|
return Song::query()
|
2025-08-27 14:17:55 +08:00
|
|
|
|
->when($this->search, fn($q) => $q->where('name', 'like', "%{$this->search}%"))
|
|
|
|
|
->when($this->selectedLanguage, fn($q) => $q->where('language_type', $this->selectedLanguage))
|
|
|
|
|
->when($this->selectedArtists, fn ($q) => $q->whereHas('artists', fn ($q2) => $q2->whereIn('id', array_keys($this->selectedArtists))))
|
|
|
|
|
->when($this->searchCategory === 'New', fn($q) => $q->orderByDesc('created_at'))
|
|
|
|
|
->when($this->searchCategory === 'Hot', fn($q) => $q->orderByDesc('song_counts'), fn($q) => $q->orderByDesc('id'))
|
|
|
|
|
//->take($this->search || $this->artistSearch ? 100 : 1000)
|
|
|
|
|
->take(1000)
|
|
|
|
|
->get();
|
2025-08-27 13:03:26 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Render
|
|
|
|
|
*/
|
|
|
|
|
public function render()
|
|
|
|
|
{
|
|
|
|
|
$songs = $this->loadSongs();
|
|
|
|
|
|
|
|
|
|
return view('livewire.pages.search-song', [
|
|
|
|
|
'songs' => $songs,
|
|
|
|
|
'languages' => \App\Enums\SongLanguageType::options(),
|
|
|
|
|
'selectedLanguage' => $this->selectedLanguage,
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
}
|