Fix pagination: all pages default to 10 per page, add total counts, fix tasks pagination position and use client-side slicing

This commit is contained in:
Yuzhiran Dev
2026-05-18 22:59:03 +08:00
parent 894e53caef
commit 7b4e52743b
3 changed files with 30 additions and 19 deletions
+20 -12
View File
@@ -82,9 +82,6 @@
<span>{{ job.active ? '运行中' : '等待中' }}</span>
<span v-if="job.next_run" style="margin-left: 8px; color: #909399;">下次: {{ job.next_run }}</span>
</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>
@@ -104,13 +101,13 @@
</div>
</div>
<div v-if="loading" style="text-align: center; padding: 40px; color: #909399;">加载中...</div>
<div v-else-if="tasks.length === 0" style="text-align: center; padding: 60px 20px; color: #909399;">
<div v-else-if="allTasks.length === 0" style="text-align: center; padding: 60px 20px; color: #909399;">
<el-icon style="font-size:56px;margin-bottom:16px;color:#c0c4cc;"><IconTopic /></el-icon>
<div style="font-size: 16px;">暂无任务</div>
<div style="margin-top: 12px; font-size: 14px;">前往 <a href="/topics.html" style="color: #409eff;">选题管理</a> 创建新任务</div>
</div>
<div v-else>
<div v-for="task in tasks" :key="task.task_id" class="task-card">
<div v-for="task in paginatedTasks" :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" title="任务ID">{{ task.task_id.slice(0,16) }}</span>
@@ -140,6 +137,10 @@
</div>
<div v-if="task.error_msg" class="error-box">错误: {{ task.error_msg }}</div>
</div>
<div v-if="paginatedTasks.length > 0 && allTasks.length > pageSize" style="display:flex;justify-content:center;align-items:center;margin-top:16px;gap:16px;">
<span style="font-size:13px;color:#909399;">共 {{ allTasks.length }} 条</span>
<el-pagination background layout="prev, pager, next" :total="allTasks.length" :page-size="pageSize" :current-page="currentPage" @current-change="p => { currentPage = p; }"></el-pagination>
</div>
</div>
</div>
</main>
@@ -183,14 +184,20 @@ const TasksApp = {
const STATUS_NAMES = { 'pending': '等待中', 'running': '进行中', 'completed': '已完成', 'failed': '失败', 'cancelled': '已取消' };
return {
currentUser: { username: '' }, isAdmin: false, isLoggedIn: false,
tasks: [], loading: false, filterStatus: '',
allTasks: [], tasks: [], loading: false, filterStatus: '',
showDetailDialog: false, detailTask: null,
schedulerJobs: [], schedulerLoading: false,
totalTasks: 0, currentPage: 1, pageSize: 20,
currentPage: 1, pageSize: 10,
pollTimer: null,
SCHEDULER_JOBS,
}
},
computed: {
paginatedTasks() {
const start = (this.currentPage - 1) * this.pageSize;
return this.allTasks.slice(start, start + this.pageSize);
}
},
methods: {
getToken() { return localStorage.getItem('authToken'); },
async api(url, opts = {}) {
@@ -239,19 +246,20 @@ const TasksApp = {
},
startPolling() {
this.stopPolling();
this.pollTimer = setInterval(() => this.loadTasks(), 5000);
this.pollTimer = setInterval(() => this.loadTasks(false), 5000);
},
stopPolling() {
if (this.pollTimer) { clearInterval(this.pollTimer); this.pollTimer = null; }
},
async loadTasks() {
async loadTasks(resetPage = true) {
this.loading = true;
try {
let url = `/api/tasks?limit=${this.pageSize}&offset=${(this.currentPage - 1) * this.pageSize}`;
let url = '/api/tasks?limit=200';
if (this.filterStatus) url += '&status=' + this.filterStatus;
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;
const oldId = this.allTasks.length > 0 && this.allTasks[0] ? this.allTasks[0].task_id : null;
this.allTasks = data;
if (resetPage) this.currentPage = 1;
const hasRunning = data.some(t => t.status === 'running');
if (hasRunning) { this.startPolling(); } else { this.stopPolling(); }
} catch (e) { console.error(e); this.$message.error('加载任务列表失败: ' + e.message); }