@page "/bots/{BotId:int}/channels" @inject BotManagementService BotManagement @inject TelegramPanel.Core.Services.Telegram.BotTelegramService BotTelegram @inject ISnackbar Snackbar @inject IDialogService DialogService @inject NavigationManager Navigation @inject IJSRuntime JS @using TelegramPanel.Data.Entities Bot 频道 - Telegram Panel Bot 频道 @if (bot != null) { @bot.Name @(!string.IsNullOrWhiteSpace(bot.Username) ? $"(@{bot.Username})" : "") } 频道 (@channels.Count) 全部分类 未分类 @foreach (var c in categories) { @c.Name } 同步 Bot 频道 导出邀请(已选) 刷新 频道名称 用户名 分类 最后同步 操作 @context.Title @if (!string.IsNullOrWhiteSpace(context.Username)) { @context.Username } else { - } 未分类 @foreach (var c in categories) { @c.Name } @context.SyncedAt.ToString("yyyy-MM-dd HH:mm") 复制链接 复制邀请 暂无频道 新增分类 创建 @code { [Parameter] public int BotId { get; set; } private bool loading = true; private Bot? bot; private List categories = new(); private List channels = new(); private HashSet selected = new(); private int filterCategoryId = 0; private string search = ""; private string newCategoryName = ""; private string newCategoryDesc = ""; private IEnumerable filtered => channels.Where(c => { if (filterCategoryId == -1 && c.CategoryId != null) return false; if (filterCategoryId > 0 && c.CategoryId != filterCategoryId) return false; if (string.IsNullOrWhiteSpace(search)) return true; return c.Title.Contains(search, StringComparison.OrdinalIgnoreCase) || (c.Username?.Contains(search, StringComparison.OrdinalIgnoreCase) ?? false); }); protected override async Task OnInitializedAsync() { await LoadAll(); } private async Task LoadAll() { loading = true; try { bot = await BotManagement.GetBotAsync(BotId); if (bot == null) { Snackbar.Add("机器人不存在", Severity.Error); Navigation.NavigateTo("/bots"); return; } categories = (await BotManagement.GetCategoriesAsync(BotId)).ToList(); channels = (await BotManagement.GetChannelsAsync(BotId)).ToList(); // 清理已选 var ids = channels.Select(x => x.Id).ToHashSet(); selected = selected.Where(x => ids.Contains(x.Id)).ToHashSet(); } catch (Exception ex) { Snackbar.Add($"加载失败:{ex.Message}", Severity.Error); } finally { loading = false; } } private async Task Sync() { loading = true; try { var count = await BotTelegram.SyncBotChannelsAsync(BotId, CancellationToken.None); Snackbar.Add($"同步完成:{count} 个频道", Severity.Success); await LoadAll(); } catch (Exception ex) { Snackbar.Add($"同步失败:{ex.Message}", Severity.Error); } finally { loading = false; } } private async Task CreateCategoryAsync() { if (string.IsNullOrWhiteSpace(newCategoryName)) { Snackbar.Add("请输入分类名称", Severity.Warning); return; } loading = true; try { await BotManagement.CreateCategoryAsync(BotId, newCategoryName, newCategoryDesc); newCategoryName = ""; newCategoryDesc = ""; await LoadAll(); Snackbar.Add("分类已创建", Severity.Success); } catch (Exception ex) { Snackbar.Add($"创建失败:{ex.Message}", Severity.Error); } finally { loading = false; } } private async Task SetCategoryAsync(BotChannel channel, int? categoryId) { try { await BotManagement.SetChannelCategoryAsync(channel.Id, categoryId); channel.CategoryId = categoryId; Snackbar.Add("已保存分类", Severity.Success); } catch (Exception ex) { Snackbar.Add($"保存失败:{ex.Message}", Severity.Error); } } private async Task CopyPublicLinkAsync(BotChannel channel) { try { if (string.IsNullOrWhiteSpace(channel.Username)) { Snackbar.Add("该频道没有公开链接(无用户名)", Severity.Info); return; } var link = $"https://t.me/{channel.Username.Trim().TrimStart('@')}"; await JS.InvokeVoidAsync("telegramPanel.copyText", link); Snackbar.Add("已复制链接", Severity.Success); } catch (Exception ex) { Snackbar.Add($"复制失败:{ex.Message}", Severity.Error); } } private async Task CopyInviteAsync(BotChannel channel) { loading = true; try { var link = await BotTelegram.ExportInviteLinkAsync(BotId, channel.TelegramId, CancellationToken.None); await JS.InvokeVoidAsync("telegramPanel.copyText", link); Snackbar.Add("已复制邀请链接", Severity.Success); } catch (Exception ex) { Snackbar.Add($"获取邀请失败:{ex.Message}", Severity.Error); } finally { loading = false; } } private async Task ExportInvites() { if (selected.Count == 0) { Snackbar.Add("请先选择频道", Severity.Info); return; } bool? result = await DialogService.ShowMessageBox( "确认导出", $"将为 {selected.Count} 个频道生成邀请链接并导出(需要机器人具备管理权限)。是否继续?", yesText: "继续", cancelText: "取消"); if (result != true) return; var ids = string.Join(",", selected.Select(x => x.TelegramId)); var url = $"/downloads/bots/{BotId}/invites.txt?ids={Uri.EscapeDataString(ids)}"; Navigation.NavigateTo(url, forceLoad: true); await Task.CompletedTask; } }