@namespace TelegramPanel.Web.Components.Dialogs @inject BotManagementService BotManagement @inject BatchTaskManagementService TaskManagement @inject ISnackbar Snackbar @inject TelegramPanel.Web.Services.BotAdminPresetsService PresetsService @inject TelegramPanel.Web.Services.BotChannelAdminDefaultsService DefaultsService @inject IDialogService DialogService @using System.Linq @using System.Text.Json @using TelegramPanel.Core.BatchTasks @using TelegramPanel.Data.Entities 请输入要设置为管理员的 Telegram 用户 ID(不是手机号/用户名)。机器人需要在目标频道具备"添加管理员/添加新管理员"权限,否则会失败。提交后在后台执行,关闭/刷新页面不影响任务。 (不使用预设) @foreach (var p in Presets) { @p.Name } 删除预设 保存为预设 如何获取用户 ID?
  1. 打开网页版:登录 Telegram 网页版 (web.telegram.org)
  2. 找到联系人:点击进入你想查询的用户的私聊窗口
  3. 查看链接:在浏览器地址栏中,链接最后的那串数字(如 web.telegram.org 中的 123456789)就是对方的 UserID
权限 保存为默认权限 将对已选频道批量执行 promoteChatMember;失败明细会完整记录到任务详情(按频道聚合并换行展示)。
取消 @if (saving) { 提交中... } else { 提交后台任务 }
@code { [CascadingParameter] private MudDialogInstance MudDialog { get; set; } = default!; [Parameter] public int BotId { get; set; } [Parameter] public IReadOnlyList ChannelTelegramIds { get; set; } = Array.Empty(); private string userIdInput = ""; private string selectedPresetName = ""; private string presetNameToSave = ""; private bool saving; private RightsModel rights = new(); private List Presets { get; set; } = new(); private TelegramPanel.Core.Services.Telegram.BotTelegramService.BotAdminRights SelectedRights => new( ManageChat: rights.ManageChat, ChangeInfo: rights.ChangeInfo, PostMessages: rights.PostMessages, EditMessages: rights.EditMessages, DeleteMessages: rights.DeleteMessages, InviteUsers: rights.InviteUsers, RestrictMembers: rights.RestrictMembers, PinMessages: rights.PinMessages, PromoteMembers: rights.PromoteMembers ); protected override async Task OnInitializedAsync() { // 默认权限:优先读取上次保存的默认值;否则给出一个"常用"权限组合,减少操作成本 var defaults = await DefaultsService.GetAsync(); if (defaults?.Rights != null) { ApplyRights(defaults.Rights); } else { rights.ManageChat = true; rights.ChangeInfo = true; rights.InviteUsers = true; } await ReloadPresetsAsync(); } private void ApplyRights(TelegramPanel.Core.Services.Telegram.BotTelegramService.BotAdminRights selected) { rights = new RightsModel { ManageChat = selected.ManageChat, ChangeInfo = selected.ChangeInfo, PostMessages = selected.PostMessages, EditMessages = selected.EditMessages, DeleteMessages = selected.DeleteMessages, InviteUsers = selected.InviteUsers, RestrictMembers = selected.RestrictMembers, PinMessages = selected.PinMessages, PromoteMembers = selected.PromoteMembers }; } private async Task SaveAsDefaultRightsAsync() { try { await DefaultsService.SaveAsync(new TelegramPanel.Web.Services.BotChannelAdminDefaults(SelectedRights)); Snackbar.Add("已保存为默认权限", Severity.Success); } catch (Exception ex) { Snackbar.Add($"保存默认权限失败:{ex.Message}", Severity.Error); } } private async Task ReloadPresetsAsync() { Presets = (await PresetsService.GetPresetsAsync()) .Where(x => !string.IsNullOrWhiteSpace(x.Name) && x.UserIds.Count > 0) .ToList(); } private Task OnPresetChanged(string value) { selectedPresetName = value ?? ""; if (string.IsNullOrWhiteSpace(selectedPresetName)) return Task.CompletedTask; var preset = Presets.FirstOrDefault(p => string.Equals(p.Name, selectedPresetName, StringComparison.OrdinalIgnoreCase)); if (preset != null) { userIdInput = string.Join(Environment.NewLine, preset.UserIds); } return Task.CompletedTask; } private async Task SavePreset() { var name = (presetNameToSave ?? "").Trim(); if (string.IsNullOrWhiteSpace(name)) { Snackbar.Add("请输入预设名称", Severity.Warning); return; } var userIds = ParseUserIds(userIdInput); if (userIds.Count == 0) { Snackbar.Add("请输入用户 ID", Severity.Warning); return; } try { await PresetsService.SavePresetAsync(name, userIds); await ReloadPresetsAsync(); selectedPresetName = name; Snackbar.Add($"已保存预设:{name}", Severity.Success); } catch (Exception ex) { Snackbar.Add($"保存预设失败:{ex.Message}", Severity.Error); } } private async Task DeleteSelectedPreset() { if (string.IsNullOrWhiteSpace(selectedPresetName)) return; bool? ok = await DialogService.ShowMessageBox( title: "删除预设", message: $"确定删除预设“{selectedPresetName}”吗?", yesText: "删除", cancelText: "取消"); if (ok != true) return; try { await PresetsService.DeletePresetAsync(selectedPresetName); selectedPresetName = ""; Snackbar.Add("已删除预设", Severity.Success); await ReloadPresetsAsync(); } catch (Exception ex) { Snackbar.Add($"删除预设失败:{ex.Message}", Severity.Error); } } private async Task Save() { if (saving) return; if (BotId <= 0) { Snackbar.Add("BotId 无效", Severity.Error); return; } if (ChannelTelegramIds.Count == 0) { Snackbar.Add("请先选择频道", Severity.Warning); return; } var userIds = ParseUserIds(userIdInput); if (userIds.Count == 0) { Snackbar.Add("请输入用户 ID", Severity.Warning); return; } saving = true; try { var channelIds = ChannelTelegramIds.Distinct().ToList(); var channels = await ResolveChannelItemsAsync(channelIds); var rightsArg = SelectedRights; var config = new BotSetAdminsTaskConfig { BotId = BotId, UserIds = userIds, Channels = channels, Rights = new BotSetAdminsRightsPayload { ManageChat = rightsArg.ManageChat, ChangeInfo = rightsArg.ChangeInfo, PostMessages = rightsArg.PostMessages, EditMessages = rightsArg.EditMessages, DeleteMessages = rightsArg.DeleteMessages, InviteUsers = rightsArg.InviteUsers, RestrictMembers = rightsArg.RestrictMembers, PinMessages = rightsArg.PinMessages, PromoteMembers = rightsArg.PromoteMembers }, RequestedAtUtc = DateTime.UtcNow }; var task = new BatchTask { TaskType = BatchTaskTypes.BotSetAdmins, Total = channelIds.Count * userIds.Count, Completed = 0, Failed = 0, Config = JsonSerializer.Serialize(config, new JsonSerializerOptions { WriteIndented = true }) }; var created = await TaskManagement.CreateTaskAsync(task); Snackbar.Add($"已提交后台任务 #{created.Id}。关闭或刷新页面不影响执行,可到【任务中心】查看进度与失败明细。", Severity.Success); MudDialog.Close(DialogResult.Ok(created.Id)); } catch (Exception ex) { Snackbar.Add($"提交失败:{ex.Message}", Severity.Error); } finally { saving = false; } } private async Task> ResolveChannelItemsAsync(IReadOnlyCollection channelIds) { var titleById = (await BotManagement.GetChatsAsync(BotId)) .Where(x => channelIds.Contains(x.TelegramId)) .GroupBy(x => x.TelegramId) .ToDictionary( x => x.Key, x => { var title = (x.First().Title ?? string.Empty).Trim(); return string.IsNullOrWhiteSpace(title) ? x.Key.ToString() : title; }); return channelIds .Select(id => new BotTaskChannelItem { TelegramId = id, Title = titleById.TryGetValue(id, out var title) ? title : id.ToString() }) .ToList(); } private void Cancel() { MudDialog.Cancel(); } private static List ParseUserIds(string? input) { var list = new List(); var raw = (input ?? string.Empty).Trim(); if (string.IsNullOrWhiteSpace(raw)) return list; // UI 提示:每行一个 ID;解析时仍做宽松处理,避免粘贴时带上空格/逗号导致失败 var parts = raw.Split(new[] { '\r', '\n', ',', ',', ';', ';', '\t', ' ' }, StringSplitOptions.RemoveEmptyEntries); foreach (var p in parts) { var s = p.Trim(); if (string.IsNullOrWhiteSpace(s)) continue; if (long.TryParse(s, out var id) && id > 0) list.Add(id); } return list.Distinct().ToList(); } private sealed class RightsModel { public bool ManageChat { get; set; } public bool ChangeInfo { get; set; } public bool PostMessages { get; set; } public bool EditMessages { get; set; } public bool DeleteMessages { get; set; } public bool InviteUsers { get; set; } public bool RestrictMembers { get; set; } public bool PinMessages { get; set; } public bool PromoteMembers { get; set; } } }