功能:通过分页和任务控制功能增强任务管理

-为创建任务引入分页功能,以提
升用户体验。
-新增暂停、继续和删除任务的功能。
-更新了任务状态处理,包括'已暂停'状态及其相应的UI更新。
This commit is contained in:
2026-04-29 09:52:56 +08:00
parent f137ae591e
commit 2ae927a851

View File

@@ -147,7 +147,7 @@
<el-dialog v-model="taskDialogVisible" title="创作任务" width="680px" append-to-body class="task-dialog"> <el-dialog v-model="taskDialogVisible" title="创作任务" width="680px" append-to-body class="task-dialog">
<div class="task-list"> <div class="task-list">
<el-empty v-if="creationTasks.length === 0" description="暂无创作任务" /> <el-empty v-if="creationTasks.length === 0" description="暂无创作任务" />
<div v-for="task in creationTasks" :key="task.id" class="task-item"> <div v-for="task in pagedCreationTasks" :key="task.id" class="task-item">
<div class="task-item-header"> <div class="task-item-header">
<div class="task-name">{{ task.title }}</div> <div class="task-name">{{ task.title }}</div>
<el-tag :type="getTaskTagType(task.status)" effect="light">{{ getTaskStatusText(task.status) }}</el-tag> <el-tag :type="getTaskTagType(task.status)" effect="light">{{ getTaskStatusText(task.status) }}</el-tag>
@@ -158,10 +158,23 @@
</div> </div>
<div v-if="task.error" class="task-error">{{ task.error }}</div> <div v-if="task.error" class="task-error">{{ task.error }}</div>
<div class="task-actions-row"> <div class="task-actions-row">
<el-button v-if="task.status === 'running'" type="warning" link @click="pauseTask(task)">暂停</el-button>
<el-button v-if="task.status === 'paused'" type="primary" link :loading="submitLoading" @click="continueTask(task)">继续</el-button>
<el-button v-if="task.status === 'failed'" type="primary" link :loading="submitLoading" @click="retryTask(task)">重新执行</el-button> <el-button v-if="task.status === 'failed'" type="primary" link :loading="submitLoading" @click="retryTask(task)">重新执行</el-button>
<el-button type="danger" link @click="deleteTask(task.id)">删除</el-button>
</div> </div>
</div> </div>
</div> </div>
<div v-if="creationTasks.length > taskPageSize" class="task-pagination" :style="{ marginTop: '20px' }">
<el-pagination
background
layout="prev, pager, next"
:current-page="taskPage"
:page-size="taskPageSize"
:total="creationTasks.length"
@current-change="handleTaskPageChange"
/>
</div>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
@@ -196,7 +209,7 @@ interface PreviewState {
nodeType: 'html' | 'image'; nodeType: 'html' | 'image';
} }
const formRef = ref<FormInstance>(); const formRef = ref<FormInstance>();
type CreationTaskStatus = 'running' | 'success' | 'failed'; type CreationTaskStatus = 'running' | 'success' | 'failed' | 'paused';
interface CreationTask { interface CreationTask {
id: number; id: number;
title: string; title: string;
@@ -215,6 +228,8 @@ const treeNodes = ref<TreeNode[]>([]);
const selectedPreview = ref<PreviewState | null>(null); const selectedPreview = ref<PreviewState | null>(null);
const descriptionFiles = ref<UploadUserFile[]>([]); const descriptionFiles = ref<UploadUserFile[]>([]);
const taskDialogVisible = ref(false); const taskDialogVisible = ref(false);
const taskPage = ref(1);
const taskPageSize = ref(3);
const mockCreationParams: CreationSubmitParams = { const mockCreationParams: CreationSubmitParams = {
mode: '混合模式(文案 + 图片)', mode: '混合模式(文案 + 图片)',
content_type: '穿搭分享', content_type: '穿搭分享',
@@ -292,13 +307,27 @@ const styleOptions = [
]; ];
const imageRatioOptions = ['3:4 — 小红书', '1:1 — 方图', '16:9 — 横版']; const imageRatioOptions = ['3:4 — 小红书', '1:1 — 方图', '16:9 — 横版'];
const taskBadgeCount = computed(() => creationTasks.value.filter((task) => task.status !== 'success').length); const taskBadgeCount = computed(() => creationTasks.value.filter((task) => task.status !== 'success').length);
const pagedCreationTasks = computed(() => {
const start = (taskPage.value - 1) * taskPageSize.value;
return creationTasks.value.slice(start, start + taskPageSize.value);
});
watch(
() => creationTasks.value.length,
(total) => {
const maxPage = Math.max(1, Math.ceil(total / taskPageSize.value));
if (taskPage.value > maxPage) taskPage.value = maxPage;
}
);
const handleTaskPageChange = (page: number) => {
taskPage.value = page;
};
const formatTaskTime = () => { const formatTaskTime = () => {
const date = new Date(); const date = new Date();
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}:${String(date.getSeconds()).padStart(2, '0')}`; return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}:${String(date.getSeconds()).padStart(2, '0')}`;
}; };
const getTaskStatusText = (status: CreationTaskStatus) => ({ running: '执行中', success: '已完成', failed: '失败' })[status]; const getTaskStatusText = (status: CreationTaskStatus) => ({ running: '执行中', success: '已完成', failed: '失败', paused: '已暂停' })[status];
const getTaskTagType = (status: CreationTaskStatus) => const getTaskTagType = (status: CreationTaskStatus) =>
({ running: 'warning', success: 'success', failed: 'danger' })[status] as 'warning' | 'success' | 'danger'; ({ running: 'warning', success: 'success', failed: 'danger', paused: 'info' })[status] as 'warning' | 'success' | 'danger' | 'info';
const buildTaskSummary = (params: CreationSubmitParams) => const buildTaskSummary = (params: CreationSubmitParams) =>
`${params.content_type} / ${params.theme || '未填写主题'} / ${params.title || '未填写标题'}`; `${params.content_type} / ${params.theme || '未填写主题'} / ${params.title || '未填写标题'}`;
watch( watch(
@@ -509,6 +538,18 @@ const retryTask = async (task: CreationTask) => {
if (submitLoading.value) return; if (submitLoading.value) return;
await runCreationTask(task); await runCreationTask(task);
}; };
const deleteTask = (taskId: number) => {
creationTasks.value = creationTasks.value.filter((task) => task.id !== taskId);
};
const pauseTask = (task: CreationTask) => {
if (task.status !== 'running') return;
task.status = 'paused';
task.updatedAt = formatTaskTime();
};
const continueTask = async (task: CreationTask) => {
if (task.status !== 'paused' || submitLoading.value) return;
await runCreationTask(task);
};
const handleSubmit = async () => { const handleSubmit = async () => {
if (!formRef.value || submitLoading.value) return; if (!formRef.value || submitLoading.value) return;
try { try {