From 63d48bec59f8b79af6778609aeafee077984db5f Mon Sep 17 00:00:00 2001 From: meoacgx Date: Fri, 19 Dec 2025 15:00:04 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A2=91=E9=81=93=E5=88=97=E8=A1=A8=E5=AE=8C?= =?UTF-8?q?=E5=96=84=EF=BC=9A=E8=AF=A6=E6=83=85=E6=98=BE=E7=A4=BA=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E8=80=85/=E6=97=B6=E9=97=B4/=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=91=98=EF=BC=8C=E6=94=AF=E6=8C=81=E7=BC=96=E8=BE=91=E4=B8=8E?= =?UTF-8?q?=E8=B8=A2=E4=BA=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Dialogs/ChannelDetailsDialog.razor | 230 ++++++++++++++++++ .../Dialogs/ChannelEditDialog.razor | 136 +++++++++++ .../Components/Pages/Channels.razor | 28 ++- .../Components/Pages/Home.razor | 3 +- .../Components/Pages/Settings.razor | 3 +- 5 files changed, 392 insertions(+), 8 deletions(-) create mode 100644 src/TelegramPanel.Web/Components/Dialogs/ChannelDetailsDialog.razor create mode 100644 src/TelegramPanel.Web/Components/Dialogs/ChannelEditDialog.razor diff --git a/src/TelegramPanel.Web/Components/Dialogs/ChannelDetailsDialog.razor b/src/TelegramPanel.Web/Components/Dialogs/ChannelDetailsDialog.razor new file mode 100644 index 0000000..2916b1a --- /dev/null +++ b/src/TelegramPanel.Web/Components/Dialogs/ChannelDetailsDialog.razor @@ -0,0 +1,230 @@ +@namespace TelegramPanel.Web.Components.Dialogs +@inject ChannelManagementService ChannelManagement +@inject AccountManagementService AccountManagement +@inject IChannelService ChannelService +@inject ISnackbar Snackbar +@inject IDialogService DialogService +@using TelegramPanel.Data.Entities + + + + @if (loading) + { + + } + else if (channel == null) + { + 未找到频道数据 + } + else + { + + @channel.Title + + + + TelegramId:@channel.TelegramId + 用户名:@(string.IsNullOrWhiteSpace(channel.Username) ? "(私密)" : "@" + channel.Username) + 成员数:@channel.MemberCount + + + 创建者:@creatorDisplay + 创建时间:@(channel.CreatedAt?.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss") ?? "(未知)") + 最后同步:@channel.SyncedAt.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss") + + + + @if (!string.IsNullOrWhiteSpace(channel.About)) + { + 简介: + + @channel.About + + } + + + + + 管理员 + + + 刷新 + + + + @if (adminsLoading) + { + + } + else if (admins.Count == 0) + { + 暂无管理员数据(或无权限获取) + } + else + { + + + 身份 + 昵称 + 用户名 + 头衔 + + + + + @(context.IsCreator ? "创建者" : "管理员") + + + @context.DisplayName + @(!string.IsNullOrWhiteSpace(context.Username) ? "@" + context.Username : "-") + @(string.IsNullOrWhiteSpace(context.Rank) ? "-" : context.Rank) + + + } + + + + 踢出成员 + + 输入 @@用户名 执行踢出;“非永久”会使用短时间封禁达到踢出效果,随后自动解除,方便对方重新加入。 + + + + + + @if (kickLoading) + { + + 处理中... + } + else + { + 踢出 + } + + + + } + + + @if (channel != null) + { + 编辑频道 + } + 关闭 + + + +@code +{ + [CascadingParameter] private MudDialogInstance MudDialog { get; set; } = default!; + [Parameter] public int ChannelDbId { get; set; } + + private bool loading = true; + private Channel? channel; + private string creatorDisplay = "-"; + + private bool adminsLoading; + private List admins = new(); + + private string kickUsername = ""; + private bool kickPermanent; + private bool kickLoading; + + protected override async Task OnInitializedAsync() + { + await LoadChannel(); + await LoadAdmins(); + } + + private async Task LoadChannel() + { + loading = true; + try + { + channel = await ChannelManagement.GetChannelAsync(ChannelDbId); + if (channel == null) + return; + + var creator = await AccountManagement.GetAccountAsync(channel.CreatorAccountId); + creatorDisplay = creator == null + ? $"账号 {channel.CreatorAccountId}" + : $"{creator.Phone}({creator.Nickname ?? creator.Username ?? creator.UserId.ToString()})"; + } + catch (Exception ex) + { + Snackbar.Add($"加载频道失败:{ex.Message}", Severity.Error); + } + finally + { + loading = false; + } + } + + private async Task LoadAdmins() + { + if (channel == null) + return; + + adminsLoading = true; + try + { + admins = await ChannelService.GetAdminsAsync(channel.CreatorAccountId, channel.TelegramId); + } + catch (Exception ex) + { + admins.Clear(); + Snackbar.Add($"加载管理员失败:{ex.Message}", Severity.Error); + } + finally + { + adminsLoading = false; + } + } + + private async Task KickUser() + { + if (channel == null) + return; + + kickLoading = true; + try + { + await ChannelService.KickUserAsync(channel.CreatorAccountId, channel.TelegramId, kickUsername, kickPermanent); + Snackbar.Add("已执行踢出操作", Severity.Success); + kickUsername = ""; + } + catch (Exception ex) + { + Snackbar.Add($"踢出失败:{ex.Message}", Severity.Error); + } + finally + { + kickLoading = false; + } + } + + private async Task OpenEdit() + { + if (channel == null) + return; + + var parameters = new DialogParameters { ["ChannelDbId"] = ChannelDbId }; + var options = new DialogOptions { CloseOnEscapeKey = true, MaxWidth = MaxWidth.Medium, FullWidth = true }; + var dialog = DialogService.Show("编辑频道", parameters, options); + var result = await dialog.Result; + if (!result.Canceled) + { + await LoadChannel(); + await LoadAdmins(); + } + } + + private void Close() + { + MudDialog.Close(); + } +} diff --git a/src/TelegramPanel.Web/Components/Dialogs/ChannelEditDialog.razor b/src/TelegramPanel.Web/Components/Dialogs/ChannelEditDialog.razor new file mode 100644 index 0000000..089bd1b --- /dev/null +++ b/src/TelegramPanel.Web/Components/Dialogs/ChannelEditDialog.razor @@ -0,0 +1,136 @@ +@namespace TelegramPanel.Web.Components.Dialogs +@inject ChannelManagementService ChannelManagement +@inject IChannelService ChannelService +@inject ISnackbar Snackbar +@using TelegramPanel.Data.Entities + + + + @if (loading) + { + + } + else if (channel == null) + { + 未找到频道数据 + } + else + { + + + + + + @if (isPublic) + { + + } + + + + } + + + 取消 + + @if (saving) + { + + 保存中... + } + else + { + 保存 + } + + + + +@code +{ + [CascadingParameter] private MudDialogInstance MudDialog { get; set; } = default!; + [Parameter] public int ChannelDbId { get; set; } + + private bool loading = true; + private bool saving; + private Channel? channel; + + private string title = ""; + private string? about; + private bool isPublic; + private string username = ""; + private bool forwardingAllowed = true; + + private bool CanSave => channel != null && !string.IsNullOrWhiteSpace(title) && (!isPublic || !string.IsNullOrWhiteSpace(username)); + + protected override async Task OnInitializedAsync() + { + await LoadChannel(); + } + + private async Task LoadChannel() + { + loading = true; + try + { + channel = await ChannelManagement.GetChannelAsync(ChannelDbId); + if (channel == null) + return; + + title = channel.Title; + about = channel.About; + isPublic = !string.IsNullOrWhiteSpace(channel.Username); + username = channel.Username ?? ""; + } + catch (Exception ex) + { + Snackbar.Add($"加载频道失败:{ex.Message}", Severity.Error); + } + finally + { + loading = false; + } + } + + private async Task Save() + { + if (channel == null) + return; + + saving = true; + try + { + var newTitle = title.Trim(); + var newAbout = string.IsNullOrWhiteSpace(about) ? null : about.Trim(); + var newUsername = string.IsNullOrWhiteSpace(username) ? null : username.Trim().TrimStart('@'); + + await ChannelService.UpdateChannelInfoAsync(channel.CreatorAccountId, channel.TelegramId, newTitle, newAbout); + await ChannelService.SetChannelVisibilityAsync(channel.CreatorAccountId, channel.TelegramId, isPublic, newUsername); + await ChannelService.SetForwardingAllowedAsync(channel.CreatorAccountId, channel.TelegramId, forwardingAllowed); + + channel.Title = newTitle; + channel.About = newAbout; + channel.Username = isPublic ? newUsername : null; + + await ChannelManagement.UpdateChannelAsync(channel); + + Snackbar.Add("保存成功", Severity.Success); + MudDialog.Close(DialogResult.Ok(true)); + } + catch (Exception ex) + { + Snackbar.Add($"保存失败:{ex.Message}", Severity.Error); + } + finally + { + saving = false; + } + } + + private void Cancel() + { + MudDialog.Cancel(); + } +} diff --git a/src/TelegramPanel.Web/Components/Pages/Channels.razor b/src/TelegramPanel.Web/Components/Pages/Channels.razor index 6fb3ca1..61bbda1 100644 --- a/src/TelegramPanel.Web/Components/Pages/Channels.razor +++ b/src/TelegramPanel.Web/Components/Pages/Channels.razor @@ -4,6 +4,7 @@ @inject ISnackbar Snackbar @inject IDialogService DialogService @inject NavigationManager Navigation +@using TelegramPanel.Web.Components.Dialogs @using TelegramPanel.Data.Entities 频道列表 - Telegram Panel @@ -82,8 +83,9 @@ @context.SyncedAt.ToString("yyyy-MM-dd HH:mm") - 查看详情 - 编辑频道 + 查看详情 + 编辑频道 + 踢人 邀请用户 复制链接 @@ -169,14 +171,28 @@ return false; } - private void ShowDetails(Channel channel) + private async Task ShowDetails(Channel channel) { - Snackbar.Add($"查看频道详情:{channel.Title}", Severity.Info); + var parameters = new DialogParameters { ["ChannelDbId"] = channel.Id }; + var options = new DialogOptions { CloseOnEscapeKey = true, MaxWidth = MaxWidth.Large, FullWidth = true }; + DialogService.Show("频道详情", parameters, options); + await Task.CompletedTask; } - private void EditChannel(Channel channel) + private async Task EditChannel(Channel channel) { - Snackbar.Add($"编辑频道:{channel.Title}", Severity.Info); + var parameters = new DialogParameters { ["ChannelDbId"] = channel.Id }; + var options = new DialogOptions { CloseOnEscapeKey = true, MaxWidth = MaxWidth.Medium, FullWidth = true }; + var dialog = DialogService.Show("编辑频道", parameters, options); + var result = await dialog.Result; + if (!result.Canceled) + await LoadChannels(); + } + + private async Task KickUser(Channel channel) + { + // 复用详情弹窗里的“踢人”能力,减少重复 UI + await ShowDetails(channel); } private void InviteUsers(Channel channel) diff --git a/src/TelegramPanel.Web/Components/Pages/Home.razor b/src/TelegramPanel.Web/Components/Pages/Home.razor index 91fd424..6724cf2 100644 --- a/src/TelegramPanel.Web/Components/Pages/Home.razor +++ b/src/TelegramPanel.Web/Components/Pages/Home.razor @@ -208,7 +208,8 @@ IsBroadcast = channelInfo.IsBroadcast, MemberCount = channelInfo.MemberCount, About = channelInfo.About, - CreatorAccountId = account.Id + CreatorAccountId = account.Id, + CreatedAt = channelInfo.CreatedAt }; await ChannelManagement.CreateOrUpdateChannelAsync(channel); totalChannelsSynced++; diff --git a/src/TelegramPanel.Web/Components/Pages/Settings.razor b/src/TelegramPanel.Web/Components/Pages/Settings.razor index 94c35b3..99d7b87 100644 --- a/src/TelegramPanel.Web/Components/Pages/Settings.razor +++ b/src/TelegramPanel.Web/Components/Pages/Settings.razor @@ -245,7 +245,8 @@ IsBroadcast = channelInfo.IsBroadcast, MemberCount = channelInfo.MemberCount, About = channelInfo.About, - CreatorAccountId = account.Id + CreatorAccountId = account.Id, + CreatedAt = channelInfo.CreatedAt }; await ChannelManagement.CreateOrUpdateChannelAsync(channel); totalChannelsSynced++;