调整频道同步:仅同步创建者频道,频道页分离全部/单账号同步

This commit is contained in:
meoacgx committed 2025-12-19 17:39:07 +08:00
1 parent fc64e3e8e6
commit 04bbdaa4fb
4 files changed
+102 -33

No files matched your search

@@ -33,16 +33,14 @@ public class ChannelManagementService
}
/// <summary>
/// 用于列表展示:可选按账号筛选,并可选是否包含“仅管理员(非本系统创建)”频道
/// 用于列表展示:可选按账号筛选(仅展示“本系统创建/创建者为该账号”的频道)
/// </summary>
public async Task<IEnumerable<Channel>> 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<IEnumerable<Channel>> GetChannelsByCreatorAsync(int accountId)
@@ -32,10 +32,59 @@ public class ChannelService : IChannelService
public async Task<List<ChannelInfo>> 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<ChannelInfo>();
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<List<ChannelInfo>> GetAdminedChannelsAsync(int accountId)
@@ -18,8 +18,6 @@
<ToolBarContent>
<MudText Typo="Typo.h6">频道 (@channels.Count)</MudText>
<MudSpacer />
<MudSwitch @bind-Value="showAllChannels" @bind-Value:after="LoadChannels" Color="Color.Primary" Class="mr-2"
Label="显示全部(含仅管理员)" />
<MudSelect @bind-Value="filterAccount" @bind-Value:after="LoadChannels" Label="筛选账号" Variant="Variant.Outlined" Dense="true" Class="mr-2" Style="min-width: 220px;">
<MudSelectItem Value="0">全部账号</MudSelectItem>
@foreach (var account in accounts)
@@ -33,8 +31,12 @@
<MudSelectItem Value='@("private")'>私密</MudSelectItem>
</MudSelect>
<MudButton Variant="Variant.Outlined" Color="Color.Info" StartIcon="@Icons.Material.Filled.Sync" Class="mr-2"
Disabled="@loading" OnClick="SyncChannels">
同步频道
Disabled="@(loading || filterAccount <= 0)" OnClick="SyncCurrentAccountChannels">
同步当前账号
</MudButton>
<MudButton Variant="Variant.Outlined" Color="Color.Info" StartIcon="@Icons.Material.Filled.Sync" Class="mr-2"
Disabled="@loading" OnClick="SyncAllAccountsChannels">
同步全部账号
</MudButton>
<MudTextField @bind-Value="searchString" Placeholder="搜索频道..." Adornment="Adornment.Start"
AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0" />
@@ -88,7 +90,7 @@
}
else
{
<MudChip T="string" Size="Size.Small" Color="Color.Default">仅管理员</MudChip>
<span>-</span>
}
</MudTd>
<MudTd DataLabel="最后同步">@context.SyncedAt.ToString("yyyy-MM-dd HH:mm")</MudTd>
@@ -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);
@@ -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<int>(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();
}
}