From e420e8e8b5e60c37fc21b41421dbfb2582a92834 Mon Sep 17 00:00:00 2001 From: meoacgx Date: Thu, 22 Jan 2026 04:58:38 +0800 Subject: [PATCH] feat(kick): filter by bot channel categories --- .../Components/ModulePages/KickApiPage.razor | 173 ++++++++++++++---- 1 file changed, 141 insertions(+), 32 deletions(-) diff --git a/src/TelegramPanel.Web/Components/ModulePages/KickApiPage.razor b/src/TelegramPanel.Web/Components/ModulePages/KickApiPage.razor index cbc38ef..5b19542 100644 --- a/src/TelegramPanel.Web/Components/ModulePages/KickApiPage.razor +++ b/src/TelegramPanel.Web/Components/ModulePages/KickApiPage.razor @@ -32,11 +32,41 @@ - + - @if (!useAllChats && selectedBotId != 0) + @if (selectedBotId != 0 && !useAllChats) { + + 选择分类:@selectedCategories.Count / @categories.Count + + + 全选 + + + 清空 + + + + + + 分类 + 说明 + + + @context.Name + @(!string.IsNullOrWhiteSpace(context.Description) ? context.Description : "-") + + + 暂无分类 + + + + + @@ -62,13 +92,25 @@ private bool loading = true; private List bots = new(); + private List categories = new(); private int selectedBotId = 0; private long userId; private bool permanentBan; private bool useAllChats = true; + private HashSet selectedCategories = new(); + private bool includeUncategorized; private string chatIdsText = ""; - private bool CanSubmit => !loading && userId > 0 && (selectedBotId == 0 || bots.Any(x => x.Id == selectedBotId)); + private bool CanSubmit + => !loading + && userId > 0 + && (selectedBotId == 0 || bots.Any(x => x.Id == selectedBotId)) + && ( + selectedBotId == 0 + || useAllChats + || includeUncategorized + || selectedCategories.Count > 0 + || !string.IsNullOrWhiteSpace(chatIdsText)); protected override async Task OnInitializedAsync() { @@ -78,6 +120,17 @@ .Where(b => b.IsActive) .OrderBy(b => b.Id) .ToList(); + + categories = (await BotManagement.GetCategoriesAsync()) + .OrderBy(c => c.Name, StringComparer.OrdinalIgnoreCase) + .ToList(); + + // 默认不对“全部机器人/全部频道”开火 + if (bots.Count > 0) + { + selectedBotId = bots[0].Id; + useAllChats = false; + } } catch (Exception ex) { @@ -91,9 +144,40 @@ private async Task OnSelectedBotChanged(int id) { + var previous = selectedBotId; selectedBotId = id; if (selectedBotId == 0) useAllChats = true; + else if (previous == 0) + useAllChats = false; + + selectedCategories = new HashSet(); + includeUncategorized = false; + chatIdsText = ""; + await Task.CompletedTask; + } + + private async Task OnUseAllChatsChanged() + { + if (useAllChats) + { + selectedCategories = new HashSet(); + includeUncategorized = false; + chatIdsText = ""; + } + await Task.CompletedTask; + } + + private async Task SelectAllCategories() + { + selectedCategories = categories.ToHashSet(); + await Task.CompletedTask; + } + + private async Task ClearCategories() + { + selectedCategories = new HashSet(); + includeUncategorized = false; await Task.CompletedTask; } @@ -104,12 +188,62 @@ var botId = selectedBotId; var runUseAllChats = botId == 0 ? true : useAllChats; - var chatIds = runUseAllChats ? new List() : ParseChatIds(chatIdsText); loading = true; try { - var total = await CountTargetsAsync(botId, runUseAllChats, chatIds); + var total = 0; + var targetChatIds = new List(); + + if (botId == 0) + { + foreach (var b in bots) + total += (await BotManagement.GetChatsAsync(b.Id)).Count(); + } + else + { + var chats = (await BotManagement.GetChatsAsync(botId)).ToList(); + if (runUseAllChats) + { + total = chats.Count; + } + else + { + var selectedIds = new HashSet(); + var selectedCategoryIdSet = selectedCategories.Select(x => x.Id).ToHashSet(); + + if (selectedCategoryIdSet.Count > 0 || includeUncategorized) + { + foreach (var c in chats) + { + if (c.CategoryId.HasValue) + { + if (selectedCategoryIdSet.Contains(c.CategoryId.Value)) + selectedIds.Add(c.TelegramId); + } + else + { + if (includeUncategorized) + selectedIds.Add(c.TelegramId); + } + } + } + + foreach (var id in ParseChatIds(chatIdsText)) + selectedIds.Add(id); + + if (selectedIds.Count > 0) + { + total = chats.Count(c => selectedIds.Contains(c.TelegramId)); + var knownIds = chats.Select(c => c.TelegramId).ToHashSet(); + targetChatIds = selectedIds + .Where(knownIds.Contains) + .OrderBy(x => x) + .ToList(); + } + } + } + if (total <= 0) { Snackbar.Add("未匹配到任何可操作的频道/群组(请先同步 Bot 频道数据,或检查 chat_id 列表)", Severity.Warning); @@ -121,7 +255,7 @@ ApiName = "模块页面", BotId = botId, UseAllChats = runUseAllChats, - ChatIds = chatIds.Where(x => x != 0).Distinct().OrderBy(x => x).ToList(), + ChatIds = runUseAllChats ? new List() : targetChatIds, UserId = userId, PermanentBan = permanentBan, RequestedAtUtc = DateTime.UtcNow @@ -150,31 +284,6 @@ } } - private async Task CountTargetsAsync(int botId, bool runUseAllChats, IReadOnlyCollection chatIds) - { - if (botId > 0) - { - var chats = (await BotManagement.GetChatsAsync(botId)).ToList(); - if (!runUseAllChats && chatIds.Count > 0) - chats = chats.Where(c => chatIds.Contains(c.TelegramId)).ToList(); - return chats.Count; - } - - // botId==0: all bots (force useAllChats) - var botsList = (await BotManagement.GetAllBotsAsync()) - .Where(b => b.IsActive) - .OrderBy(b => b.Id) - .ToList(); - - var total = 0; - foreach (var b in botsList) - { - var chats = await BotManagement.GetChatsAsync(b.Id); - total += chats.Count(); - } - return total; - } - private static List ParseChatIds(string raw) { raw = (raw ?? "").Trim();