From 04bbdaa4fb25693ec622d223620b2c8cb816b894 Mon Sep 17 00:00:00 2001 From: meoacgx Date: Fri, 19 Dec 2025 17:39:07 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E9=A2=91=E9=81=93=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=EF=BC=9A=E4=BB=85=E5=90=8C=E6=AD=A5=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E8=80=85=E9=A2=91=E9=81=93=EF=BC=8C=E9=A2=91=E9=81=93=E9=A1=B5?= =?UTF-8?q?=E5=88=86=E7=A6=BB=E5=85=A8=E9=83=A8/=E5=8D=95=E8=B4=A6?= =?UTF-8?q?=E5=8F=B7=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/ChannelManagementService.cs | 8 +-- .../Services/Telegram/ChannelService.cs | 57 +++++++++++++++++-- .../Components/Pages/Channels.razor | 54 ++++++++++++++---- .../Services/DataSyncService.cs | 16 +----- 4 files changed, 102 insertions(+), 33 deletions(-) diff --git a/src/TelegramPanel.Core/Services/ChannelManagementService.cs b/src/TelegramPanel.Core/Services/ChannelManagementService.cs index 196bcb7..e48a5e8 100644 --- a/src/TelegramPanel.Core/Services/ChannelManagementService.cs +++ b/src/TelegramPanel.Core/Services/ChannelManagementService.cs @@ -33,16 +33,14 @@ public class ChannelManagementService } /// - /// 用于列表展示:可选按账号筛选,并可选是否包含“仅管理员(非本系统创建)”频道 + /// 用于列表展示:可选按账号筛选(仅展示“本系统创建/创建者为该账号”的频道) /// public async Task> GetChannelsForViewAsync(int accountId, bool includeNonCreator) { if (accountId <= 0) - return includeNonCreator ? await _channelRepository.GetAllAsync() : await _channelRepository.GetCreatedAsync(); + return await _channelRepository.GetCreatedAsync(); - return includeNonCreator - ? await _channelRepository.GetForAccountAsync(accountId, includeNonCreator: true) - : await _channelRepository.GetForAccountAsync(accountId, includeNonCreator: false); + return await _channelRepository.GetByCreatorAccountAsync(accountId); } public async Task> GetChannelsByCreatorAsync(int accountId) diff --git a/src/TelegramPanel.Core/Services/Telegram/ChannelService.cs b/src/TelegramPanel.Core/Services/Telegram/ChannelService.cs index 43a9203..befb04a 100644 --- a/src/TelegramPanel.Core/Services/Telegram/ChannelService.cs +++ b/src/TelegramPanel.Core/Services/Telegram/ChannelService.cs @@ -32,10 +32,59 @@ public class ChannelService : IChannelService public async Task> GetOwnedChannelsAsync(int accountId) { - var all = await GetAdminedChannelsAsync(accountId); - var owned = all.Where(c => c.IsCreator).ToList(); - _logger.LogInformation("Found {Count} owned channels for account {AccountId}", owned.Count, accountId); - return owned; + var client = await GetOrCreateConnectedClientAsync(accountId); + + var channels = new List(); + var dialogs = await client.Messages_GetAllDialogs(); + + foreach (var (_, chat) in dialogs.chats) + { + if (chat is not Channel channel || !channel.IsActive) + continue; + + try + { + var isCreator = ReadBool(channel, "creator", "Creator", "is_creator", "IsCreator"); + if (!isCreator) + continue; + + var memberCount = ReadInt(channel, 0, "participants_count", "ParticipantsCount", "participantsCount", "memberCount", "MemberCount"); + string? about = null; + try + { + var fullChannel = await client.Channels_GetFullChannel(channel); + memberCount = fullChannel.full_chat.ParticipantsCount; + about = (fullChannel.full_chat as ChannelFull)?.about; + } + catch (Exception ex) + { + _logger.LogDebug(ex, "Failed to get full channel info for {ChannelId}", channel.id); + } + + channels.Add(new ChannelInfo + { + TelegramId = channel.id, + AccessHash = channel.access_hash, + Title = channel.title, + Username = channel.MainUsername, + IsBroadcast = channel.IsChannel, + MemberCount = memberCount, + About = about, + CreatorAccountId = accountId, + IsCreator = true, + IsAdmin = true, + CreatedAt = channel.date, + SyncedAt = DateTime.UtcNow + }); + } + catch (Exception ex) + { + _logger.LogWarning(ex, "Failed to get owned channel info for {ChannelId}", channel.id); + } + } + + _logger.LogInformation("Found {Count} owned channels for account {AccountId}", channels.Count, accountId); + return channels; } public async Task> GetAdminedChannelsAsync(int accountId) diff --git a/src/TelegramPanel.Web/Components/Pages/Channels.razor b/src/TelegramPanel.Web/Components/Pages/Channels.razor index 533e830..5cd4fde 100644 --- a/src/TelegramPanel.Web/Components/Pages/Channels.razor +++ b/src/TelegramPanel.Web/Components/Pages/Channels.razor @@ -18,8 +18,6 @@ 频道 (@channels.Count) - 全部账号 @foreach (var account in accounts) @@ -33,8 +31,12 @@ 私密 - 同步频道 + Disabled="@(loading || filterAccount <= 0)" OnClick="SyncCurrentAccountChannels"> + 同步当前账号 + + + 同步全部账号 @@ -88,7 +90,7 @@ } else { - 仅管理员 + - } @context.SyncedAt.ToString("yyyy-MM-dd HH:mm") @@ -121,7 +123,6 @@ private string searchString = ""; private int filterAccount = 0; private string filterType = "all"; - private bool showAllChannels; protected override async Task OnInitializedAsync() { @@ -147,7 +148,7 @@ loading = true; try { - var channelList = await ChannelManagement.GetChannelsForViewAsync(filterAccount, showAllChannels); + var channelList = await ChannelManagement.GetChannelsForViewAsync(filterAccount, includeNonCreator: false); channels = channelList.ToList(); } catch (Exception ex) @@ -191,7 +192,40 @@ return namePart; } - private async Task SyncChannels() + private async Task SyncCurrentAccountChannels() + { + if (loading) + return; + + if (filterAccount <= 0) + { + Snackbar.Add("请先选择一个账号再同步", Severity.Info); + return; + } + + loading = true; + try + { + var summary = await DataSync.SyncAccountAsync(filterAccount, CancellationToken.None); + + foreach (var failure in summary.AccountFailures) + Snackbar.Add($"账号 {failure.Phone} 同步失败:{failure.Error}", Severity.Warning); + + Snackbar.Add($"同步完成:{summary.TotalChannelsSynced} 个频道,{summary.TotalGroupsSynced} 个群组", summary.AccountFailures.Count == 0 ? Severity.Success : Severity.Warning); + + await LoadChannels(); + } + catch (Exception ex) + { + Snackbar.Add($"同步失败:{ex.Message}", Severity.Error); + } + finally + { + loading = false; + } + } + + private async Task SyncAllAccountsChannels() { if (loading) return; @@ -199,9 +233,7 @@ loading = true; try { - var summary = filterAccount > 0 - ? await DataSync.SyncAccountAsync(filterAccount, CancellationToken.None) - : await DataSync.SyncAllActiveAccountsAsync(CancellationToken.None); + var summary = await DataSync.SyncAllActiveAccountsAsync(CancellationToken.None); foreach (var failure in summary.AccountFailures) Snackbar.Add($"账号 {failure.Phone} 同步失败:{failure.Error}", Severity.Warning); diff --git a/src/TelegramPanel.Web/Services/DataSyncService.cs b/src/TelegramPanel.Web/Services/DataSyncService.cs index a1da15e..b1db5ef 100644 --- a/src/TelegramPanel.Web/Services/DataSyncService.cs +++ b/src/TelegramPanel.Web/Services/DataSyncService.cs @@ -57,8 +57,8 @@ public class DataSyncService try { - // 同步频道:包含“非本系统创建但账号为管理员”的频道 - var channelInfos = await _channelService.GetAdminedChannelsAsync(account.Id); + // 同步频道:仅同步“频道创建人=本账号”的频道 + var channelInfos = await _channelService.GetOwnedChannelsAsync(account.Id); var keepChannelIds = new List(capacity: channelInfos.Count); foreach (var channelInfo in channelInfos) @@ -74,25 +74,16 @@ public class DataSyncService IsBroadcast = channelInfo.IsBroadcast, MemberCount = channelInfo.MemberCount, About = channelInfo.About, - CreatorAccountId = channelInfo.IsCreator ? account.Id : null, + CreatorAccountId = account.Id, CreatedAt = channelInfo.CreatedAt }; var saved = await _channelManagement.CreateOrUpdateChannelAsync(channel); keepChannelIds.Add(saved.Id); - await _channelManagement.UpsertAccountChannelAsync( - accountId: account.Id, - channelId: saved.Id, - isCreator: channelInfo.IsCreator, - isAdmin: channelInfo.IsAdmin, - syncedAtUtc: DateTime.UtcNow); - summary.TotalChannelsSynced++; } - await _channelManagement.DeleteStaleAccountChannelsAsync(account.Id, keepChannelIds); - // 同步群组:保持原逻辑(仅创建的群组) var groups = await _groupService.GetOwnedGroupsAsync(account.Id); foreach (var groupInfo in groups) @@ -133,4 +124,3 @@ public class DataSyncService public List<(int AccountId, string Phone, string Error)> AccountFailures { get; } = new(); } } -