fix(tasks): 简化Bot管理员任务详情并修正完成状态展示

This commit is contained in:
meoacgx committed 2026-03-04 22:20:36 +08:00
1 parent 4121572a8d
commit a7929b1eed
2 files changed
+85 -10

No files matched your search

@@ -6,6 +6,8 @@
@inject IDialogService DialogService
@using TelegramPanel.Data.Entities
@using TelegramPanel.Core.BatchTasks
@using System.Text.Json
@using TelegramPanel.Web.Services
@implements IDisposable
<PageTitle>任务中心 - Telegram Panel</PageTitle>
@@ -62,10 +64,10 @@
<MudChip T="string" Size="Size.Small" Icon="@GetTaskIcon(context.TaskType)">@GetTaskTypeName(context.TaskType)</MudChip>
</MudTd>
<MudTd DataLabel="状态">
<MudChip T="string" Size="Size.Small" Color="@GetStatusColor(context.Status)">@GetStatusName(context.Status)</MudChip>
<MudChip T="string" Size="Size.Small" Color="@GetStatusColor(GetDisplayStatus(context))">@GetStatusName(GetDisplayStatus(context))</MudChip>
</MudTd>
<MudTd DataLabel="进度">
<MudProgressLinear Value="@GetProgress(context)" Color="@GetProgressColor(context.Status)" />
<MudProgressLinear Value="@GetProgress(context)" Color="@GetProgressColor(GetDisplayStatus(context))" />
<MudText Typo="Typo.caption">@context.Completed / @context.Total (@context.Failed 失败)</MudText>
</MudTd>
<MudTd DataLabel="创建时间"><PanelTime Value="context.CreatedAt" /></MudTd>
@@ -82,12 +84,12 @@
<MudTd DataLabel="操作">
<MudIconButton Icon="@Icons.Material.Filled.Info" Size="Size.Small" Color="Color.Info"
OnClick="@(() => ShowTaskDetails(context))" />
@if (context.Status == "pending" || context.Status == "running")
@if (GetDisplayStatus(context) == "pending" || GetDisplayStatus(context) == "running")
{
<MudIconButton Icon="@Icons.Material.Filled.Cancel" Size="Size.Small" Color="Color.Warning"
OnClick="@(() => CancelTask(context.Id))" />
}
@if (context.Status == "completed" || context.Status == "failed")
@if (GetDisplayStatus(context) == "completed" || GetDisplayStatus(context) == "failed")
{
<MudIconButton Icon="@Icons.Material.Filled.Delete" Size="Size.Small" Color="Color.Error"
OnClick="@(() => DeleteTask(context.Id))" />
@@ -112,7 +114,7 @@
private IEnumerable<BatchTask> filteredTasks =>
tasks.Where(t =>
(filterStatus == "all" || t.Status == filterStatus) &&
(filterStatus == "all" || GetDisplayStatus(t) == filterStatus) &&
(filterCategory == "all" || GetCategory(t.TaskType) == filterCategory));
private IEnumerable<string> AvailableCategories =>
@@ -277,11 +279,20 @@
_ => Color.Default
};
private static string GetDisplayStatus(BatchTask task)
{
if (task.Status == "failed" && task.CompletedAt.HasValue && task.Total > 0 && task.Completed >= task.Total)
return "completed";
return task.Status;
}
private void ShowTaskDetails(BatchTask task)
{
var createdAt = TimeZone.Format(task.CreatedAt, "yyyy-MM-dd HH:mm");
var displayStatus = GetDisplayStatus(task);
var details = $"任务类型: {GetTaskTypeName(task.TaskType)}\n" +
$"状态: {GetStatusName(task.Status)}\n" +
$"状态: {GetStatusName(displayStatus)}\n" +
$"总数: {task.Total}\n" +
$"已完成: {task.Completed}\n" +
$"失败: {task.Failed}\n" +
@@ -293,7 +304,10 @@
if (task.CompletedAt.HasValue)
details += $"完成时间: {TimeZone.Format(task.CompletedAt.Value, "yyyy-MM-dd HH:mm")}\n";
if (!string.IsNullOrEmpty(task.Config))
var failureLines = ExtractBotAdminFailureLines(task);
if (failureLines.Count > 0)
details += $"\n失败频道:\n{string.Join('\n', failureLines)}";
else if (!IsBotAdminTask(task.TaskType) && !string.IsNullOrEmpty(task.Config))
details += $"\n配置信息:\n{task.Config}";
var html = System.Net.WebUtility.HtmlEncode(details)
@@ -302,6 +316,67 @@
DialogService.ShowMessageBox("任务详情", (MarkupString)html);
}
private static bool IsBotAdminTask(string taskType) =>
taskType is BatchTaskTypes.BotChannelSetAdminsByAccount or BatchTaskTypes.BotSetAdmins;
private static List<string> ExtractBotAdminFailureLines(BatchTask task)
{
var lines = new List<string>();
if (!IsBotAdminTask(task.TaskType) || string.IsNullOrWhiteSpace(task.Config) || task.Failed <= 0)
return lines;
try
{
using var doc = JsonDocument.Parse(task.Config);
var root = doc.RootElement;
if (root.TryGetProperty("FailureLines", out var failureLinesElement)
&& failureLinesElement.ValueKind == JsonValueKind.Array)
{
foreach (var lineElement in failureLinesElement.EnumerateArray())
{
var line = (lineElement.GetString() ?? string.Empty).Trim();
if (line.Length > 0)
lines.Add(line);
}
if (lines.Count > 0)
return lines;
}
if (root.TryGetProperty("Failures", out var failuresElement)
&& failuresElement.ValueKind == JsonValueKind.Array)
{
var failures = new List<BotAdminTaskFailureItem>();
foreach (var item in failuresElement.EnumerateArray())
{
if (item.ValueKind != JsonValueKind.Object)
continue;
var failure = new BotAdminTaskFailureItem
{
ChannelTelegramId = item.TryGetProperty("ChannelTelegramId", out var channelId) && channelId.TryGetInt64(out var id) ? id : 0,
ChannelTitle = item.TryGetProperty("ChannelTitle", out var channelTitle) ? channelTitle.GetString() ?? string.Empty : string.Empty,
Username = item.TryGetProperty("Username", out var username) ? username.GetString() : null,
UserId = item.TryGetProperty("UserId", out var userId) && userId.TryGetInt64(out var uid) ? uid : null,
Reason = item.TryGetProperty("Reason", out var reason) ? reason.GetString() ?? string.Empty : string.Empty
};
failures.Add(failure);
}
if (failures.Count > 0)
lines = BotAdminTaskFailureFormatter.BuildLines(failures);
}
}
catch
{
// 配置异常时回退到默认展示,不中断详情弹窗。
}
return lines;
}
private async Task CancelTask(int id)
{
bool? result = await DialogService.ShowMessageBox(
@@ -160,9 +160,9 @@ public sealed class BatchTaskBackgroundService : BackgroundService
if (latest != null && latest.Status != "running")
return;
await taskManagement.CompleteTaskAsync(pending.Id, success: failed == 0);
_logger.LogInformation("Batch task completed: {TaskId} {TaskType} (ok={Ok}, completed={Completed}, failed={Failed})",
pending.Id, pending.TaskType, failed == 0, completed, failed);
await taskManagement.CompleteTaskAsync(pending.Id, success: true);
_logger.LogInformation("Batch task completed: {TaskId} {TaskType} (completed={Completed}, failed={Failed})",
pending.Id, pending.TaskType, completed, failed);
}
catch (Exception ex)
{