@page "/admin" @attribute [Authorize] @inject SongCatalogService Catalog @inject SiteSettingsService SiteSettings @inject ISnackbar Snackbar 歌单管理
歌单管理 添加歌曲、隐藏曲目、清理标签和调整点歌文案。
退出
歌曲 @_songs.Count 首
添加
@if (_songs.Count == 0) { 还没有歌曲。之后可以从这里手动添加,或直接导入数据库。 } else {
@foreach (var song in _songs) {
@foreach (var tag in song.Tags) { @tag }
保存 删除
}
}
站点设置 保存设置
标签 @_tags.Count 个
@if (_tags.Count == 0) { 暂无标签。 } else {
@foreach (var tag in _tags) {
改名 合并
}
}
@code { private readonly List _songs = []; private readonly List _tags = []; private string _newSongTitle = string.Empty; private string _requestTemplate = "点歌《{title}》"; protected override async Task OnInitializedAsync() { await LoadAsync(); } private async Task LoadAsync() { var songs = await Catalog.GetAdminSongsAsync(); var tags = await Catalog.GetAdminTagsAsync(); _requestTemplate = await SiteSettings.GetRequestTemplateAsync(); _songs.Clear(); _songs.AddRange(songs.Select(AdminSongState.From)); _tags.Clear(); _tags.AddRange(tags.Select(AdminTagState.From)); } private async Task CreateSong() { await RunAdminAction(async () => { await Catalog.CreateSongAsync(_newSongTitle); _newSongTitle = string.Empty; Snackbar.Add("歌曲已添加", Severity.Success); }); } private async Task SaveSong(AdminSongState song) { await RunAdminAction(async () => { await Catalog.UpdateSongAsync(song.Id, song.Title, song.IsHidden); Snackbar.Add("歌曲已保存", Severity.Success); }); } private async Task DeleteSong(AdminSongState song) { await RunAdminAction(async () => { await Catalog.DeleteSongAsync(song.Id); Snackbar.Add("歌曲已删除", Severity.Success); }); } private async Task SaveRequestTemplate() { await RunAdminAction(async () => { await SiteSettings.SaveRequestTemplateAsync(_requestTemplate); Snackbar.Add("设置已保存", Severity.Success); }, reload: false); } private async Task RenameTag(AdminTagState tag) { await RunAdminAction(async () => { await Catalog.RenameTagAsync(tag.Id, tag.Name); Snackbar.Add("标签已更新", Severity.Success); }); } private async Task MergeTag(AdminTagState tag) { await RunAdminAction(async () => { await Catalog.MergeTagAsync(tag.Id, tag.MergeTarget); Snackbar.Add("标签已合并", Severity.Success); }); } private async Task DeleteTag(AdminTagState tag) { await RunAdminAction(async () => { await Catalog.DeleteTagAsync(tag.Id); Snackbar.Add("标签已删除", Severity.Success); }); } private async Task RunAdminAction(Func action, bool reload = true) { try { await action(); if (reload) { await LoadAsync(); } } catch (InvalidOperationException ex) { Snackbar.Add(ex.Message, Severity.Warning); } } private sealed class AdminSongState { public int Id { get; init; } public string Title { get; set; } = string.Empty; public bool IsHidden { get; set; } public IReadOnlyList Tags { get; init; } = []; public static AdminSongState From(AdminSongItem item) { return new AdminSongState { Id = item.Id, Title = item.Title, IsHidden = item.IsHidden, Tags = item.Tags }; } } private sealed class AdminTagState { public int Id { get; init; } public string Name { get; set; } = string.Empty; public string MergeTarget { get; set; } = string.Empty; public int SongCount { get; init; } public static AdminTagState From(AdminTagItem item) { return new AdminTagState { Id = item.Id, Name = item.Name, SongCount = item.SongCount }; } } }