diff --git a/src/TelegramPanel.Core/Interfaces/IChannelService.cs b/src/TelegramPanel.Core/Interfaces/IChannelService.cs index 0564cba..2694fd0 100644 --- a/src/TelegramPanel.Core/Interfaces/IChannelService.cs +++ b/src/TelegramPanel.Core/Interfaces/IChannelService.cs @@ -52,6 +52,11 @@ public interface IChannelService /// Task SetForwardingAllowedAsync(int accountId, long channelId, bool allowed); + /// + /// 导出频道加入链接:公开频道返回 t.me 链接;私密频道导出邀请链接(需要权限)。 + /// + Task ExportJoinLinkAsync(int accountId, long channelId); + /// /// 获取频道管理员列表 /// diff --git a/src/TelegramPanel.Core/Services/Telegram/ChannelService.cs b/src/TelegramPanel.Core/Services/Telegram/ChannelService.cs index 9794512..a054be1 100644 --- a/src/TelegramPanel.Core/Services/Telegram/ChannelService.cs +++ b/src/TelegramPanel.Core/Services/Telegram/ChannelService.cs @@ -431,6 +431,28 @@ public class ChannelService : IChannelService return true; } + public async Task ExportJoinLinkAsync(int accountId, long channelId) + { + var client = await GetOrCreateConnectedClientAsync(accountId); + var channel = await GetChannelByIdAsync(client, channelId) + ?? throw new InvalidOperationException($"Channel {channelId} not found"); + + if (!string.IsNullOrWhiteSpace(channel.MainUsername)) + return $"https://t.me/{channel.MainUsername}"; + + var invite = await client.Messages_ExportChatInvite(channel); + var link = invite switch + { + ChatInviteExported e => e.link, + _ => null + }; + + if (string.IsNullOrWhiteSpace(link)) + throw new InvalidOperationException("无法导出邀请链接(可能无权限)"); + + return link; + } + public async Task> GetAdminsAsync(int accountId, long channelId) { var client = await GetOrCreateConnectedClientAsync(accountId); diff --git a/src/TelegramPanel.Web/Components/Pages/Channels.razor b/src/TelegramPanel.Web/Components/Pages/Channels.razor index 5cd4fde..f86cd87 100644 --- a/src/TelegramPanel.Web/Components/Pages/Channels.razor +++ b/src/TelegramPanel.Web/Components/Pages/Channels.razor @@ -2,9 +2,11 @@ @inject ChannelManagementService ChannelManagement @inject AccountManagementService AccountManagement @inject TelegramPanel.Web.Services.DataSyncService DataSync +@inject IChannelService ChannelService @inject ISnackbar Snackbar @inject IDialogService DialogService @inject NavigationManager Navigation +@inject IJSRuntime JS @using TelegramPanel.Web.Components.Dialogs @using TelegramPanel.Data.Entities @@ -100,7 +102,8 @@ 编辑频道 踢人 邀请用户 - 复制链接 + 复制链接 + 复制邀请链接 删除频道 @@ -281,12 +284,47 @@ Navigation.NavigateTo($"/batch/invite?channelId={channel.Id}"); } - private void CopyLink(Channel channel) + private async Task CopyLinkAsync(Channel channel) { - var link = string.IsNullOrEmpty(channel.Username) - ? $"私密频道(邀请链接待实现)" - : $"https://t.me/{channel.Username}"; - Snackbar.Add($"链接:{link}", Severity.Info); + try + { + var executeAccountId = channel.CreatorAccountId ?? filterAccount; + if (executeAccountId <= 0) + { + Snackbar.Add("无法导出链接:请先选择账号或确保频道有创建账号", Severity.Warning); + return; + } + + var link = await ChannelService.ExportJoinLinkAsync(executeAccountId, channel.TelegramId); + + await JS.InvokeVoidAsync("telegramPanel.copyText", link); + Snackbar.Add("已复制链接", Severity.Success); + } + catch (Exception ex) + { + Snackbar.Add($"复制失败:{ex.Message}", Severity.Error); + } + } + + private async Task CopyInviteAsync(Channel channel) + { + try + { + var executeAccountId = channel.CreatorAccountId ?? filterAccount; + if (executeAccountId <= 0) + { + Snackbar.Add("无法导出邀请链接:请先选择账号或确保频道有创建账号", Severity.Warning); + return; + } + + var link = await ChannelService.ExportJoinLinkAsync(executeAccountId, channel.TelegramId); + await JS.InvokeVoidAsync("telegramPanel.copyText", link); + Snackbar.Add("已复制邀请链接", Severity.Success); + } + catch (Exception ex) + { + Snackbar.Add($"获取邀请失败:{ex.Message}", Severity.Error); + } } private async Task DeleteChannel(int id)