Files
Telegram-Panel/src/TelegramPanel.Web/Components/Pages/Tasks.razor
T

221 lines
7.9 KiB
Plaintext

@page "/tasks"
@inject BatchTaskManagementService TaskManagement
@inject ISnackbar Snackbar
@inject IDialogService DialogService
@using TelegramPanel.Data.Entities
<PageTitle>任务中心 - Telegram Panel</PageTitle>
<MudText Typo="Typo.h4" Class="mb-4">任务中心</MudText>
<MudCard>
<MudCardContent>
<MudTable Items="@filteredTasks" Hover="true" Breakpoint="Breakpoint.Sm" Loading="@loading">
<ToolBarContent>
<MudText Typo="Typo.h6">任务列表 (@tasks.Count)</MudText>
<MudSpacer />
<MudSelect @bind-Value="filterStatus" Label="状态筛选" Variant="Variant.Outlined" Dense="true" Style="min-width: 120px;">
<MudSelectItem Value='@("all")'>全部</MudSelectItem>
<MudSelectItem Value='@("pending")'>待执行</MudSelectItem>
<MudSelectItem Value='@("running")'>执行中</MudSelectItem>
<MudSelectItem Value='@("completed")'>已完成</MudSelectItem>
<MudSelectItem Value='@("failed")'>失败</MudSelectItem>
</MudSelect>
</ToolBarContent>
<HeaderContent>
<MudTh>任务ID</MudTh>
<MudTh>任务类型</MudTh>
<MudTh>状态</MudTh>
<MudTh>进度</MudTh>
<MudTh>创建时间</MudTh>
<MudTh>完成时间</MudTh>
<MudTh>操作</MudTh>
</HeaderContent>
<RowTemplate>
<MudTd DataLabel="任务ID">@context.Id</MudTd>
<MudTd DataLabel="任务类型">
<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>
</MudTd>
<MudTd DataLabel="进度">
<MudProgressLinear Value="@GetProgress(context)" Color="@GetProgressColor(context.Status)" />
<MudText Typo="Typo.caption">@context.Completed / @context.Total (@context.Failed 失败)</MudText>
</MudTd>
<MudTd DataLabel="创建时间">@context.CreatedAt.ToString("yyyy-MM-dd HH:mm")</MudTd>
<MudTd DataLabel="完成时间">
@if (context.CompletedAt.HasValue)
{
@context.CompletedAt.Value.ToString("yyyy-MM-dd HH:mm")
}
else
{
<span>-</span>
}
</MudTd>
<MudTd DataLabel="操作">
<MudIconButton Icon="@Icons.Material.Filled.Info" Size="Size.Small" Color="Color.Info"
OnClick="@(() => ShowTaskDetails(context))" />
@if (context.Status == "pending" || context.Status == "running")
{
<MudIconButton Icon="@Icons.Material.Filled.Cancel" Size="Size.Small" Color="Color.Warning"
OnClick="@(() => CancelTask(context.Id))" />
}
@if (context.Status == "completed" || context.Status == "failed")
{
<MudIconButton Icon="@Icons.Material.Filled.Delete" Size="Size.Small" Color="Color.Error"
OnClick="@(() => DeleteTask(context.Id))" />
}
</MudTd>
</RowTemplate>
<NoRecordsContent>
<MudText>暂无任务</MudText>
</NoRecordsContent>
</MudTable>
</MudCardContent>
</MudCard>
@code {
private List<BatchTask> tasks = new();
private bool loading = true;
private string filterStatus = "all";
private IEnumerable<BatchTask> filteredTasks =>
filterStatus == "all" ? tasks : tasks.Where(t => t.Status == filterStatus);
protected override async Task OnInitializedAsync()
{
await LoadTasks();
}
private async Task LoadTasks()
{
loading = true;
try
{
var taskList = await TaskManagement.GetRecentTasksAsync(50);
tasks = taskList.OrderByDescending(t => t.CreatedAt).ToList();
}
catch (Exception ex)
{
Snackbar.Add($"加载失败:{ex.Message}", Severity.Error);
}
finally
{
loading = false;
}
}
private double GetProgress(BatchTask task)
{
if (task.Total == 0) return 0;
return (double)task.Completed / task.Total * 100;
}
private string GetTaskIcon(string type) => type switch
{
"invite" => Icons.Material.Filled.PersonAdd,
"set_admin" => Icons.Material.Filled.AdminPanelSettings,
_ => Icons.Material.Filled.Task
};
private string GetTaskTypeName(string type) => type switch
{
"invite" => "批量邀请",
"set_admin" => "设置管理员",
_ => type
};
private string GetStatusName(string status) => status switch
{
"pending" => "待执行",
"running" => "执行中",
"completed" => "已完成",
"failed" => "失败",
_ => status
};
private Color GetStatusColor(string status) => status switch
{
"completed" => Color.Success,
"running" => Color.Info,
"pending" => Color.Default,
"failed" => Color.Error,
_ => Color.Default
};
private Color GetProgressColor(string status) => status switch
{
"completed" => Color.Success,
"running" => Color.Primary,
"failed" => Color.Error,
_ => Color.Default
};
private void ShowTaskDetails(BatchTask task)
{
var details = $"任务类型: {GetTaskTypeName(task.TaskType)}\n" +
$"状态: {GetStatusName(task.Status)}\n" +
$"总数: {task.Total}\n" +
$"已完成: {task.Completed}\n" +
$"失败: {task.Failed}\n" +
$"创建时间: {task.CreatedAt:yyyy-MM-dd HH:mm}\n";
if (task.StartedAt.HasValue)
details += $"开始时间: {task.StartedAt.Value:yyyy-MM-dd HH:mm}\n";
if (task.CompletedAt.HasValue)
details += $"完成时间: {task.CompletedAt.Value:yyyy-MM-dd HH:mm}\n";
if (!string.IsNullOrEmpty(task.Config))
details += $"\n配置信息:\n{task.Config}";
DialogService.ShowMessageBox("任务详情", details);
}
private async Task CancelTask(int id)
{
bool? result = await DialogService.ShowMessageBox(
"确认取消",
"确定要取消这个任务吗?",
yesText: "取消任务", cancelText: "返回");
if (result == true)
{
try
{
await TaskManagement.CompleteTaskAsync(id, false);
await LoadTasks();
Snackbar.Add("任务已取消", Severity.Warning);
}
catch (Exception ex)
{
Snackbar.Add($"取消失败:{ex.Message}", Severity.Error);
}
}
}
private async Task DeleteTask(int id)
{
bool? result = await DialogService.ShowMessageBox(
"确认删除",
"确定要删除这个任务记录吗?此操作不可恢复。",
yesText: "删除", cancelText: "取消");
if (result == true)
{
try
{
await TaskManagement.DeleteTaskAsync(id);
tasks.RemoveAll(t => t.Id == id);
Snackbar.Add("任务已删除", Severity.Success);
}
catch (Exception ex)
{
Snackbar.Add($"删除失败:{ex.Message}", Severity.Error);
}
}
}
}