Add pagination to admin management tabs (cases/categories/sources/orgs)

This commit is contained in:
Yuzhiran Dev
2026-05-18 19:18:09 +08:00
parent 7169ddb678
commit a09e7e6671
14 changed files with 455 additions and 340 deletions
+18 -4
View File
@@ -75,15 +75,19 @@
<div class="schedule-info">
<div class="schedule-name">{{ job.name }}</div>
<div class="schedule-time"><el-icon style="vertical-align:-2px;"><IconClock /></el-icon> 每日 {{ job.time }}</div>
<div style="font-size:11px;color:#c0c4cc;margin-top:1px;">{{ job.id }}</div>
</div>
<div class="schedule-next">
<span class="schedule-badge" :class="job.active ? 'active' : 'inactive'"></span>
<span>{{ job.active ? '运行中' : '等待中' }}</span>
<span v-if="job.next_run" style="margin-left: 8px; color: #909399;">下次: {{ job.next_run }}</span>
</div>
</div>
<div v-if="totalTasks > pageSize" style="display:flex;justify-content:center;margin-top:16px;">
<el-pagination background layout="prev, pager, next" :total="totalTasks" :page-size="pageSize" :current-page="currentPage" @current-change="p => { currentPage = p; loadTasks(); }"></el-pagination>
</div>
</div>
</div>
</div>
<div class="card page-fade">
<div class="page-header">
@@ -109,7 +113,8 @@
<div v-for="task in tasks" :key="task.task_id" class="task-card">
<div class="task-header">
<div style="display: flex; align-items: center; gap: 12px; flex-wrap: wrap;">
<span class="task-id">#{{ task.task_id }}</span>
<span class="task-id" title="任务ID">{{ task.task_id.slice(0,16) }}</span>
<span style="font-weight:600;color:#303133;font-size:14px;">{{ task.topic_title || task.topic_id || '通用任务' }}</span>
<span class="status-badge" :class="'status-' + task.status">{{ getStatusLabel(task.status) }}</span>
<span class="task-stage" :class="'stage-' + task.stage">{{ getStageLabel(task.stage) }}</span>
</div>
@@ -126,6 +131,7 @@
</div>
</div>
<div class="task-meta">
<span>ID: {{ task.task_id }}</span>
<span>创建: {{ formatDate(task.created_at) }}</span>
<span v-if="task.started_at">开始: {{ formatDate(task.started_at) }}</span>
<span v-if="task.finished_at">完成: {{ formatDate(task.finished_at) }}</span>
@@ -166,15 +172,21 @@
const TasksApp = {
data() {
const SCHEDULER_JOBS = {
'scheduled_collect': { icon: 'IconRefresh', name: '内容采集', defaultTime: '01:30' },
'scheduled_sync': { icon: 'IconRefresh', name: '数据同步', defaultTime: '02:30' },
'scheduled_generate': { icon: 'IconDocument', name: '内容创作', defaultTime: '03:30' },
'scheduled_optimize': { icon: 'IconSearch', name: '合规审查', defaultTime: '04:30' },
'scheduled_optimize_sources': { icon: 'IconSetting', name: '信息源优化', defaultTime: '05:00' },
'scheduled_metrics_sync': { icon: 'IconDashboard', name: '指标同步', defaultTime: '06:00' },
};
const STAGE_NAMES = { 'creator': '创作', 'optimize': '审查', 'review': '审查', 'publish': '发布' };
const STATUS_NAMES = { 'pending': '等待中', 'running': '进行中', 'completed': '已完成', 'failed': '失败', 'cancelled': '已取消' };
return {
currentUser: { username: '' }, isAdmin: false, isLoggedIn: false,
tasks: [], loading: false, filterStatus: '',
showDetailDialog: false, detailTask: null,
schedulerJobs: [], schedulerLoading: false,
totalTasks: 0, currentPage: 1, pageSize: 20,
SCHEDULER_JOBS,
}
},
@@ -227,9 +239,11 @@ const TasksApp = {
async loadTasks() {
this.loading = true;
try {
let url = '/api/tasks?limit=50';
let url = `/api/tasks?limit=${this.pageSize}&offset=${(this.currentPage - 1) * this.pageSize}`;
if (this.filterStatus) url += '&status=' + this.filterStatus;
this.tasks = await this.api(url) || [];
const data = await this.api(url) || [];
this.tasks = data;
this.totalTasks = data.length < this.pageSize ? (this.currentPage - 1) * this.pageSize + data.length : this.currentPage * this.pageSize + 1;
} catch (e) { console.error(e); this.$message.error('加载任务列表失败: ' + e.message); }
finally { this.loading = false; }
},