feat: 完成数据处理接口与前端接入

This commit is contained in:
caoxiaozhu
2026-07-23 15:10:13 +08:00
parent f453234057
commit f04dc479bb
29 changed files with 7126 additions and 1144 deletions

View File

@@ -1,71 +1,35 @@
<script setup lang="ts">
import { ref } from 'vue'
import { onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus'
import DataTablePage from '@/components/DataTablePage.vue'
import ModelStatusTag from '@/components/ModelStatusTag.vue'
import { deleteDataProcessTask, getDataProcessTasks } from '@/api/modules/dataProcess'
import type { DataProcessTask, DataProcessType } from '@/types/dataProcess'
import type { ProcessType } from './create/types'
/** 数据处理任务类型 */
interface DataProcessTask {
id: number | string
name: string
status: string
process_type: ProcessType
source_dataset: string
output_dataset?: string
create_time?: string
}
const processTypeMap: Record<ProcessType, string> = {
const processTypeMap: Record<DataProcessType, string> = {
structured: '结构化数据',
unstructured: '非结构化数据',
external: '外来数据源拉取',
}
// TODO: 接入真实接口前,先用本地 mock 数据
const router = useRouter()
const dataList = ref<DataProcessTask[]>([
{
id: 183921,
name: '客服问答数据清洗',
status: 'completed',
process_type: 'structured',
source_dataset: '客服对话原始集',
output_dataset: '客服对话清洗集',
create_time: '2026-07-08 14:23:00',
},
{
id: 492015,
name: '指令微调数据构造',
status: 'running',
process_type: 'unstructured',
source_dataset: '通用语料库',
output_dataset: 'SFT 指令集',
create_time: '2026-07-09 09:10:00',
},
{
id: 731948,
name: '敏感信息脱敏处理',
status: 'pending',
process_type: 'structured',
source_dataset: '用户反馈数据',
create_time: '2026-07-09 16:45:00',
},
{
id: 582012,
name: '多轮对话拼接',
status: 'failed',
process_type: 'structured',
source_dataset: '单轮问答集',
create_time: '2026-07-10 08:30:00',
},
])
const dataList = ref<DataProcessTask[]>([])
const loading = ref(false)
const deletingId = ref<string | number | null>(null)
const loadError = ref('')
/** 新建数据处理任务 */
function handleCreate() {
router.push('/data-process/create')
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
} catch {
loadError.value = '数据处理任务加载失败,请稍后重试。'
} finally {
if (!silent) loading.value = false
}
}
/** 查看任务详情 */
@@ -74,15 +38,50 @@ function viewDetail(row: unknown) {
router.push({ name: 'data-process-detail', params: { id: taskId } })
}
/** 删除任务(功能开发中) */
function handleDelete(_row: unknown) {
ElMessage.info('删除功能开发中...')
/** 删除由后端再次校验任务状态以及发布锁。 */
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 '-'
return new Date(value).toLocaleString('zh-CN', { hour12: false })
const date = new Date(value)
return Number.isNaN(date.getTime()) ? value : date.toLocaleString('zh-CN', { hour12: false })
}
function sourceDatasetName(task: DataProcessTask) {
return task.source_dataset_name || task.source_dataset || '-'
}
function outputDatasetName(task: DataProcessTask) {
return task.output_dataset_name || task.output_dataset || '-'
}
onMounted(loadData)
</script>
<template>
@@ -90,12 +89,14 @@ function formatDateTime(value?: string) {
<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" />
@@ -108,19 +109,19 @@ function formatDateTime(value?: string) {
<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 ProcessType] || row.process_type }}
{{ 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" show-overflow-tooltip>
<template #default="{ row }">{{ row.source_dataset || '-' }}</template>
<template #default="{ row }">{{ sourceDatasetName(row as DataProcessTask) }}</template>
</el-table-column>
<el-table-column label="输出数据集" align="center" show-overflow-tooltip>
<template #default="{ row }">{{ row.output_dataset || '-' }}</template>
<template #default="{ row }">{{ outputDatasetName(row as DataProcessTask) }}</template>
</el-table-column>
<el-table-column label="创建时间" align="center" width="190">
<template #default="{ row }">{{ formatDateTime(row.create_time) }}</template>
<template #default="{ row }">{{ formatDateTime(row.create_time || row.created_at) }}</template>
</el-table-column>
</template>
@@ -129,7 +130,13 @@ function formatDateTime(value?: string) {
<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" @click="handleDelete(row)">
<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>