fix(aihr): recover stalled media processing
This commit is contained in:
@@ -149,6 +149,20 @@
|
||||
</el-table-column>
|
||||
<el-table-column prop="summary" label="AI摘要" min-width="230" show-overflow-tooltip />
|
||||
<el-table-column prop="updatedAt" label="更新时间" width="138" />
|
||||
<el-table-column label="操作" width="86" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
v-if="canRetryProcessingTask(row)"
|
||||
link
|
||||
type="danger"
|
||||
:loading="taskRetryingId === row.id"
|
||||
@click="retryTask(row)"
|
||||
>
|
||||
重试
|
||||
</el-button>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<footer class="table-footer">
|
||||
@@ -210,7 +224,7 @@
|
||||
</div>
|
||||
<div v-if="displayOverview.rules.failedTasks > 0" class="risk-tip">
|
||||
<el-icon><WarningFilled /></el-icon>
|
||||
<span>失败任务 {{ displayOverview.rules.failedTasks }} 个,建议先重试网络/格式异常文件</span>
|
||||
<span>需处理任务 {{ displayOverview.rules.failedTasks }} 个,可从原文件重试图片/视频解析</span>
|
||||
</div>
|
||||
</section>
|
||||
</aside>
|
||||
@@ -260,7 +274,7 @@
|
||||
import { CircleCheck, Document, Files, Operation, Refresh, Search, Upload, WarningFilled } from '@element-plus/icons-vue';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue';
|
||||
import { getProcessingOverview, type ProcessingOverview, type ProcessingTask } from '@/api/aihr/processing';
|
||||
import { getProcessingOverview, retryProcessingTask, type ProcessingOverview, type ProcessingTask } from '@/api/aihr/processing';
|
||||
import { uploadKnowledgeDocAsync, listUploadItems, retryUploadItem, type UploadItem } from '@/api/aihr/sop';
|
||||
import { listKnowledgeSpaces, type KnowledgeSpace } from '@/api/aihr/space';
|
||||
import { listPersonalPublishRequests, reviewPersonalPublishRequest, type PersonalPublishRequestRow } from '@/api/aihr/personal';
|
||||
@@ -294,9 +308,10 @@ const uploadBatch = ref<UploadItem[]>([]);
|
||||
const uploadBatchId = ref('');
|
||||
const enqueueFailures = ref<string[]>([]);
|
||||
const retryingId = ref<number | null>(null);
|
||||
const taskRetryingId = ref<number | null>(null);
|
||||
let batchPollTimer: number | undefined;
|
||||
|
||||
const statusTabs = ['全部', '等待解析', '解析中', '已完成', '失败'];
|
||||
const statusTabs = ['全部', '待重试', '解析中', '已完成', '失败'];
|
||||
const fileTypes = ['全部', 'Word', 'PDF', 'PPT', 'Excel', '图片', '视频'];
|
||||
|
||||
const seedOverview: ProcessingOverview = {
|
||||
@@ -304,7 +319,7 @@ const seedOverview: ProcessingOverview = {
|
||||
{ key: 'total', label: '资料总量', value: '3.2 GB', note: '已接入 1,286 个文件', type: 'danger' },
|
||||
{ key: 'completed', label: '已完成', value: '1,148', note: '较昨日 ↑128 (12.6%)', type: 'success' },
|
||||
{ key: 'processing', label: '处理中', value: '36', note: '进行中任务', type: 'primary' },
|
||||
{ key: 'failed', label: '失败', value: '7', note: '较昨日 ↑2 (22.2%)', type: 'warning' }
|
||||
{ key: 'failed', label: '需处理', value: '7', note: '可从任务列表重试', type: 'warning' }
|
||||
],
|
||||
categories: [
|
||||
{ name: '住宅 SOP', files: 368, size: '2.1 GB', icon: 'folder', type: 'danger' },
|
||||
@@ -331,7 +346,7 @@ const seedOverview: ProcessingOverview = {
|
||||
''
|
||||
),
|
||||
task(2, '住宅 SOP', '物业收费催缴流程.pdf', 'PDF', '8.1MB', '解析中', 'primary', 62, 0, '待向量化', 'warning', '2026-07-02 14:28', '查看', ''),
|
||||
task(3, '培训课件', '巡检标准培训课件.pptx', 'PPT', '42MB', '等待解析', 'warning', 0, 0, '待处理', 'warning', '2026-07-02 14:25', '开始', ''),
|
||||
task(3, '培训课件', '巡检标准培训课件.pptx', 'PPT', '42MB', '待重试', 'warning', 0, 0, '失败原因', 'danger', '2026-07-02 14:25', '重试', ''),
|
||||
task(4, '图片素材', '工单照片归档.zip', '图片', '286MB', 'OCR排队', 'primary', 0, 0, '待处理', 'warning', '2026-07-02 14:20', '查看', ''),
|
||||
task(
|
||||
5,
|
||||
@@ -401,7 +416,7 @@ const emptyOverview: ProcessingOverview = {
|
||||
{ key: 'total', label: '资料总量', value: '0', note: '暂无导入文件', type: 'danger' },
|
||||
{ key: 'completed', label: '已完成', value: '0', note: '等待真实上传', type: 'success' },
|
||||
{ key: 'processing', label: '处理中', value: '0', note: '暂无任务', type: 'primary' },
|
||||
{ key: 'failed', label: '失败', value: '0', note: '暂无失败', type: 'warning' }
|
||||
{ key: 'failed', label: '需处理', value: '0', note: '暂无异常', type: 'warning' }
|
||||
],
|
||||
categories: [],
|
||||
tasks: [],
|
||||
@@ -605,6 +620,23 @@ async function retryBatchItem(item: UploadItem) {
|
||||
}
|
||||
}
|
||||
|
||||
function canRetryProcessingTask(task: ProcessingTask) {
|
||||
return task.action === '重试' && ['图片', '视频'].includes(task.fileType);
|
||||
}
|
||||
|
||||
async function retryTask(task: ProcessingTask) {
|
||||
taskRetryingId.value = task.id;
|
||||
try {
|
||||
await retryProcessingTask(task.id);
|
||||
ElMessage.success(`已从原文件重新排队:${task.fileName}`);
|
||||
await loadOverview();
|
||||
} catch (error) {
|
||||
ElMessage.error(uploadFailureMessage(error));
|
||||
} finally {
|
||||
taskRetryingId.value = null;
|
||||
}
|
||||
}
|
||||
|
||||
const batchCounts = computed(() => ({
|
||||
queued: uploadBatch.value.filter((item) => item.status === 0).length,
|
||||
processing: uploadBatch.value.filter((item) => item.status === 1).length,
|
||||
@@ -635,7 +667,7 @@ function uploadFailureMessage(error: unknown) {
|
||||
|
||||
function matchStatus(status: string) {
|
||||
if (activeStatus.value === '全部') return true;
|
||||
if (activeStatus.value === '等待解析') return ['等待解析', 'OCR排队'].includes(status);
|
||||
if (activeStatus.value === '待重试') return ['待重试', '等待解析', 'OCR排队'].includes(status);
|
||||
return status === activeStatus.value;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user