From 939a7f8e8f11ad774913bef19b633a655cfc0f64 Mon Sep 17 00:00:00 2001 From: caoxiaozhu Date: Sat, 25 Jul 2026 17:04:21 +0800 Subject: [PATCH] =?UTF-8?q?fix(frontend):=20=E5=B1=95=E7=A4=BA=E4=B8=89?= =?UTF-8?q?=E4=B8=AA=E7=8B=AC=E7=AB=8B=E5=8F=91=E5=B8=83=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E9=9B=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../regression-data-process-detail.mjs | 7 +- .../scripts/regression-dataset-preview.mjs | 9 +-- .../scripts/regression-dataset-task-tab.mjs | 4 +- frontend/src/types/dataProcess.ts | 11 +++ .../data-process/DataProcessDetailView.vue | 70 +++++++++---------- .../src/views/dataset/DatasetListView.vue | 34 ++------- .../src/views/dataset/DatasetPreviewView.vue | 15 ---- .../views/fine-tune/FineTuneCreateView.vue | 4 +- 8 files changed, 64 insertions(+), 90 deletions(-) diff --git a/frontend/scripts/regression-data-process-detail.mjs b/frontend/scripts/regression-data-process-detail.mjs index e16e45a..f2becb7 100644 --- a/frontend/scripts/regression-data-process-detail.mjs +++ b/frontend/scripts/regression-data-process-detail.mjs @@ -51,7 +51,12 @@ assert.match(detailSource, /v-model="statusFilter"/, '结果明细缺少状态 assert.match(detailSource, /updateDataProcessResult\(taskId\.value,[\s\S]*?expected_updated_at:/, '结果编辑没有携带并发版本时间') assert.match(detailSource, /restoreDataProcessResult\(taskId\.value,\s*result\.id\)/, '结果恢复没有调用真实 API') assert.match(detailSource, /publishDataProcess\(taskId\.value,/, '发布数据集没有调用真实 API') -assert.match(detailSource, /router\.push\(`\/dataset\/\$\{datasetId\}\/preview`\)/, '发布成功后未进入数据集预览') +assert.match(detailSource, /path: '\/dataset', query: \{ tab: 'task', task_id: taskId\.value \}/, '发布成功后未进入数据任务列表') +assert.match(detailSource, /published\.datasets \|\| published\.output_datasets/, '发布成功后未读取三个独立数据集') +assert.match(detailSource, /v-for="dataset in outputDatasets"/, '任务详情未展示三个输出数据集入口') +assert.match(detailSource, /将发布三个独立数据集/, '发布说明仍未明确生成三个独立数据集') +assert.match(detailSource, /outputDatasetBaseName\.value/, '重新同步时未使用单一基础名称') +assert.doesNotMatch(detailSource, /label="数据集类型"/, '发布三个数据集时不应再选择单一数据集类型') assert.match(detailSource, /无法加载数据处理任务/, '未知任务或加载失败缺少明确错误状态') assert.match(detailSource, /结果明细加载失败/, '结果加载失败缺少明确错误状态') assert.match(detailSource, /width:\s*100%/, '详情页没有铺满内容区域') diff --git a/frontend/scripts/regression-dataset-preview.mjs b/frontend/scripts/regression-dataset-preview.mjs index de14357..ec6b8e5 100644 --- a/frontend/scripts/regression-dataset-preview.mjs +++ b/frontend/scripts/regression-dataset-preview.mjs @@ -10,7 +10,6 @@ const previewComponentPaths = [ 'DatasetRecordTable.vue', 'DatasetRecordEditorDialog.vue', 'DatasetRawPreview.vue', - 'DatasetSplitNavigator.vue', ].map((name) => path.join(previewComponentsDir, name)) const apiPath = path.join(root, 'src/api/modules/dataset.ts') const adapterPath = path.join(root, 'src/mock/adapter.ts') @@ -51,16 +50,12 @@ function expect(condition, message) { } expect(previewLogicSource.split('\n').length < 520, 'DatasetPreviewView.vue 的逻辑与模板应保持在 520 行以内') -for (const componentName of ['DatasetVersionBar', 'DatasetRecordTable', 'DatasetRecordEditorDialog', 'DatasetRawPreview', 'DatasetSplitNavigator']) { +for (const componentName of ['DatasetVersionBar', 'DatasetRecordTable', 'DatasetRecordEditorDialog', 'DatasetRawPreview']) { expect(source.includes(`import ${componentName}`), `主页面未导入叶子组件:${componentName}`) expect(source.includes(`<${componentName}`), `主页面未挂载叶子组件:${componentName}`) } expect(source.includes('class="preview-workspace"'), '详情页应提供数据文件工作区') -expect(previewSurfaceSource.includes('class="split-file-tabs"'), '多切分数据集应提供训练/验证/测试文件切换') -expect(source.includes('@select="handleFileChange"'), '切换数据切分时应加载对应文件版本') -expect(previewSurfaceSource.includes('splitCounts.train'), '数据集概览应显示训练集数量') -expect(previewSurfaceSource.includes('splitCounts.validation'), '数据集概览应显示验证集数量') -expect(previewSurfaceSource.includes('splitCounts.test'), '数据集概览应显示测试集数量') +expect(!source.includes('DatasetSplitNavigator'), '独立数据集详情不应再混合展示三个切分') expect(previewSurfaceSource.includes('class="code-line"'), '内容查看器应提供逐行展示') expect(previewSurfaceSource.includes('class="line-number"'), '内容查看器应显示行号') expect(source.includes('previewLoading'), '切换文件时应提供独立加载状态') diff --git a/frontend/scripts/regression-dataset-task-tab.mjs b/frontend/scripts/regression-dataset-task-tab.mjs index 9a2a2f2..cdf199b 100644 --- a/frontend/scripts/regression-dataset-task-tab.mjs +++ b/frontend/scripts/regression-dataset-task-tab.mjs @@ -31,7 +31,9 @@ for (const name of [ assert.match(datasetLine, /source: 'task'/, `${name} 必须标记为数据任务来源`) } -assert.match(viewSource, /const activeTab = ref\('upload'\)/) +assert.match(viewSource, /route\.query\.tab === 'task' \? 'task' : 'upload'/) +assert.doesNotMatch(viewSource, /hasSplitCounts|splitLabels/) +assert.match(viewSource, /DATASET_TYPE_MAP\[String\(row\.type\)\.toLowerCase\(\)\]/) assert.match( viewSource, /if \(activeTab\.value === 'task'\) \{\s*return dataList\.value\.filter\(\(item\) => item\.source === 'task'\)\s*\}/, diff --git a/frontend/src/types/dataProcess.ts b/frontend/src/types/dataProcess.ts index 85dd096..3d7e46f 100644 --- a/frontend/src/types/dataProcess.ts +++ b/frontend/src/types/dataProcess.ts @@ -36,6 +36,7 @@ export interface DataProcessTask { output_dataset_id?: string | number | null output_dataset_name?: string | null output_dataset?: string | null + output_datasets?: DataProcessOutputDataset[] source_file_count?: number preview_count?: number input_count?: number @@ -58,6 +59,14 @@ export interface DataProcessTask { source_files?: DataProcessSourceFile[] } +export interface DataProcessOutputDataset { + id: string | number + name: string + type: 'train' | 'val' | 'test' | string + count?: number + dataset_split?: DataProcessSplit +} + export interface DataProcessTaskCreatePayload { name: string description?: string @@ -253,5 +262,7 @@ export interface DataProcessPublishResult { count?: number [key: string]: unknown } + datasets?: DataProcessOutputDataset[] + output_datasets?: DataProcessOutputDataset[] created?: boolean } diff --git a/frontend/src/views/data-process/DataProcessDetailView.vue b/frontend/src/views/data-process/DataProcessDetailView.vue index d881276..418a02e 100644 --- a/frontend/src/views/data-process/DataProcessDetailView.vue +++ b/frontend/src/views/data-process/DataProcessDetailView.vue @@ -149,9 +149,23 @@ const sourceDatasetName = computed(() => ( || detail.value?.source_files?.map((file) => file.name).join('、') || '源文件上传' )) +const outputDatasets = computed(() => { + const items = detail.value?.output_datasets || [] + if (items.length) return items + if (!detail.value?.output_dataset_id) return [] + return [{ + id: detail.value.output_dataset_id, + name: detail.value.output_dataset_name || detail.value.output_dataset || '训练集', + type: 'train', + }] +}) const outputDatasetName = computed(() => ( - detail.value?.output_dataset_name || detail.value?.output_dataset || '' + outputDatasets.value.map((item) => item.name).join('、') )) +const outputDatasetBaseName = computed(() => { + const name = String(outputDatasets.value[0]?.name || '').trim() + return name.replace(/-(?:训练集|验证集|测试集)$/, '') +}) const outputDatasetId = computed(() => detail.value?.output_dataset_id || null) const creatorName = computed(() => detail.value?.creator_name || detail.value?.creator || '-') const createTime = computed(() => detail.value?.create_time || detail.value?.created_at) @@ -410,7 +424,7 @@ function configuredSplit(): DataProcessDatasetSplit { function openPublishDialog() { if (!detail.value) return if (outputDatasetId.value) { - void router.push(`/dataset/${outputDatasetId.value}/preview`) + void router.push({ path: '/dataset', query: { tab: 'task', task_id: taskId.value } }) return } publishForm.dataset_name = `${detail.value.name}-数据集` @@ -431,16 +445,10 @@ async function publishDataset() { dataset_name: publishForm.dataset_name.trim(), split: { ...publishForm.split }, }) - const datasetId = published.dataset_id || published.output_dataset_id || published.dataset?.id - if (!datasetId) { - ElMessage.success('数据集发布成功') - publishDialogVisible.value = false - await loadTask(true) - return - } - ElMessage.success('数据集发布成功') + const datasets = published.datasets || published.output_datasets || [] + ElMessage.success(`已发布 ${datasets.length || 3} 个独立数据集`) publishDialogVisible.value = false - await router.push(`/dataset/${datasetId}/preview`) + await router.push({ path: '/dataset', query: { tab: 'task', task_id: taskId.value } }) } catch { // 统一请求层已展示后端返回的失败原因。 } finally { @@ -452,8 +460,8 @@ async function resyncPublishedDataset() { if (!detail.value || !outputDatasetId.value || publishing.value) return try { await ElMessageBox.confirm( - '将按当前 8:1:1 配置重新生成训练、验证、测试三个切分文件,数据集 ID 保持不变。', - '重新同步数据切分?', + '将按当前 8:1:1 配置同步为训练集、验证集、测试集三个独立数据集。', + '重新同步三个数据集?', { type: 'warning', confirmButtonText: '重新同步', cancelButtonText: '取消' }, ) } catch { @@ -464,12 +472,12 @@ async function resyncPublishedDataset() { try { const published = await publishDataProcess(taskId.value, { ...publishForm, - dataset_name: outputDatasetName.value || `${detail.value.name}-数据集`, + dataset_name: outputDatasetBaseName.value || `${detail.value.name}-数据集`, split: configuredSplit(), }) - ElMessage.success('训练集、验证集和测试集已重新同步') - const datasetId = published.dataset?.id || outputDatasetId.value - await router.push(`/dataset/${datasetId}/preview`) + const datasets = published.datasets || published.output_datasets || [] + ElMessage.success(`训练集、验证集和测试集已同步,共 ${datasets.length || 3} 个数据集`) + await router.push({ path: '/dataset', query: { tab: 'task', task_id: taskId.value } }) } finally { publishing.value = false } @@ -497,14 +505,14 @@ onBeforeUnmount(() => { @click="openPublishDialog" > - {{ outputDatasetId ? '查看输出数据集' : '发布为数据集' }} + {{ outputDatasetId ? '查看三个数据集' : '发布为三个数据集' }} - 重新同步切分 + 重新同步数据集

{{ detail.description || '暂无任务描述' }}

@@ -570,12 +578,13 @@ onBeforeUnmount(() => {
输出数据集
{{ outputDatasetName }} - {{ outputDatasetName || '尚未发布为数据集' }} + @click="router.push(`/dataset/${dataset.id}/preview`)" + >{{ dataset.name }}({{ dataset.count || 0 }} 条) + 尚未发布为数据集
@@ -721,21 +730,12 @@ onBeforeUnmount(() => { - +
- - - - - - - - - @@ -751,12 +751,12 @@ onBeforeUnmount(() => { diff --git a/frontend/src/views/dataset/DatasetListView.vue b/frontend/src/views/dataset/DatasetListView.vue index dd4ee29..34f27dc 100644 --- a/frontend/src/views/dataset/DatasetListView.vue +++ b/frontend/src/views/dataset/DatasetListView.vue @@ -1,6 +1,6 @@