Files
YG_FT/frontend/src/views/data-process/DataProcessListView.vue

180 lines
5.8 KiB
Vue
Raw Normal View History

<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import DataTablePage from '@/components/DataTablePage.vue'
import { deleteDataProcessTask, getDataProcessTasks } from '@/api/modules/dataProcess'
import { usePolling } from '@/composables/usePolling'
import type { DataProcessTask, DataProcessType } from '@/types/dataProcess'
import { dataProcessDisplayStatus } from '@/utils/dataProcessStatus.js'
const processTypeMap: Record<DataProcessType, string> = {
structured: '结构化数据',
unstructured: '非结构化数据',
external: '外来数据源拉取',
}
const router = useRouter()
const dataList = ref<DataProcessTask[]>([])
const loading = ref(false)
const deletingId = ref<string | number | null>(null)
const loadError = ref('')
async function loadData(silent = false) {
if (!silent) loading.value = true
loadError.value = ''
try {
const response = await getDataProcessTasks({ page: 1, page_size: 200 })
dataList.value = response.items
if (dataList.value.some((item) => (
item.status === 'running'
|| item.preview_status === 'running'
|| item.preview_status === 'queued'
))) startPolling()
else stopPolling()
} catch {
loadError.value = '数据处理任务加载失败,请稍后重试。'
} finally {
if (!silent) loading.value = false
}
}
/** 查看任务详情 */
function viewDetail(row: unknown) {
const task = row as DataProcessTask
const routeName = task.status === 'completed' && task.results_confirmed !== false
? 'data-process-detail'
: 'data-process-workflow'
router.push({ name: routeName, params: { id: task.id } })
}
/** 删除由后端再次校验任务状态以及发布锁。 */
async function handleDelete(row: DataProcessTask) {
try {
await ElMessageBox.confirm(
`确定删除数据处理任务“${row.name}”吗?删除后无法恢复。`,
'确认删除',
{
type: 'warning',
confirmButtonText: '删除',
cancelButtonText: '取消',
confirmButtonClass: 'el-button--danger',
},
)
} catch {
return
}
deletingId.value = row.id
try {
await deleteDataProcessTask(row.id)
dataList.value = dataList.value.filter((item) => item.id !== row.id)
ElMessage.success('数据处理任务已删除')
} catch {
// 统一请求层已展示后端返回的失败原因。
} finally {
deletingId.value = null
}
}
function formatDateTime(value?: string) {
if (!value) return '-'
const date = new Date(value)
return Number.isNaN(date.getTime()) ? value : date.toLocaleString('zh-CN', { hour12: false })
}
function safeCount(value: unknown) {
const count = Number(value)
return Number.isFinite(count) ? Math.max(0, Math.trunc(count)) : 0
}
function documentCountLabel(task: DataProcessTask) {
return `${safeCount(task.source_file_count)}`
}
function generatedCountLabel(task: DataProcessTask) {
return `${safeCount(task.output_count)}`
}
const { start: startPolling, stop: stopPolling } = usePolling(
() => loadData(true),
3000,
{ immediate: false },
)
onMounted(() => void loadData())
</script>
<template>
<div class="data-process-page" style="height: 100%;">
<DataTablePage
title=""
:data="dataList"
:loading="loading"
searchable
:search-fields="['name']"
create-text="新建数据处理"
create-to="/data-process/create"
row-key="id"
:page-size="10"
:empty-text="loadError || '暂无数据处理任务'"
>
<template #columns>
<el-table-column label="任务ID" prop="id" align="center" width="100" />
<el-table-column label="任务名称" prop="name" align="center" show-overflow-tooltip />
<el-table-column label="任务状态" align="center" width="110">
<template #default="{ row }">
<el-tag
:type="dataProcessDisplayStatus(row as DataProcessTask).type"
size="small"
effect="light"
>{{ dataProcessDisplayStatus(row as DataProcessTask).label }}</el-tag>
</template>
</el-table-column>
<el-table-column label="处理类型" align="center" width="140">
<template #default="{ row }">
<el-tag v-if="row.process_type" size="small" type="info" effect="plain">
{{ processTypeMap[row.process_type as DataProcessType] || row.process_type }}
</el-tag>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="文档数量" align="center" width="120">
<template #default="{ row }">{{ documentCountLabel(row as DataProcessTask) }}</template>
</el-table-column>
<el-table-column label="生成个数" align="center" width="120">
<template #default="{ row }">{{ generatedCountLabel(row as DataProcessTask) }}</template>
</el-table-column>
<el-table-column label="创建时间" align="center" width="190">
<template #default="{ row }">{{ formatDateTime(row.create_time || row.created_at) }}</template>
</el-table-column>
</template>
<template #actions="{ row }">
<div class="action-buttons">
<el-button type="primary" link size="small" @click="viewDetail(row)">
<i class="fa fa-file-text-o" style="margin-right: 4px" />详情
</el-button>
<el-button
type="danger"
link
size="small"
:loading="deletingId === row.id"
@click="handleDelete(row as DataProcessTask)"
>
<i class="fa fa-trash-o" style="margin-right: 4px" />删除
</el-button>
</div>
</template>
</DataTablePage>
</div>
</template>
<style scoped lang="scss">
.action-buttons {
display: flex;
justify-content: center;
gap: 8px;
}
</style>