fix(frontend): 展示三个独立发布数据集
This commit is contained in:
@@ -51,7 +51,12 @@ assert.match(detailSource, /v-model="statusFilter"/, '结果明细缺少状态
|
|||||||
assert.match(detailSource, /updateDataProcessResult\(taskId\.value,[\s\S]*?expected_updated_at:/, '结果编辑没有携带并发版本时间')
|
assert.match(detailSource, /updateDataProcessResult\(taskId\.value,[\s\S]*?expected_updated_at:/, '结果编辑没有携带并发版本时间')
|
||||||
assert.match(detailSource, /restoreDataProcessResult\(taskId\.value,\s*result\.id\)/, '结果恢复没有调用真实 API')
|
assert.match(detailSource, /restoreDataProcessResult\(taskId\.value,\s*result\.id\)/, '结果恢复没有调用真实 API')
|
||||||
assert.match(detailSource, /publishDataProcess\(taskId\.value,/, '发布数据集没有调用真实 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, /结果明细加载失败/, '结果加载失败缺少明确错误状态')
|
assert.match(detailSource, /结果明细加载失败/, '结果加载失败缺少明确错误状态')
|
||||||
assert.match(detailSource, /width:\s*100%/, '详情页没有铺满内容区域')
|
assert.match(detailSource, /width:\s*100%/, '详情页没有铺满内容区域')
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ const previewComponentPaths = [
|
|||||||
'DatasetRecordTable.vue',
|
'DatasetRecordTable.vue',
|
||||||
'DatasetRecordEditorDialog.vue',
|
'DatasetRecordEditorDialog.vue',
|
||||||
'DatasetRawPreview.vue',
|
'DatasetRawPreview.vue',
|
||||||
'DatasetSplitNavigator.vue',
|
|
||||||
].map((name) => path.join(previewComponentsDir, name))
|
].map((name) => path.join(previewComponentsDir, name))
|
||||||
const apiPath = path.join(root, 'src/api/modules/dataset.ts')
|
const apiPath = path.join(root, 'src/api/modules/dataset.ts')
|
||||||
const adapterPath = path.join(root, 'src/mock/adapter.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 行以内')
|
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(`import ${componentName}`), `主页面未导入叶子组件:${componentName}`)
|
||||||
expect(source.includes(`<${componentName}`), `主页面未挂载叶子组件:${componentName}`)
|
expect(source.includes(`<${componentName}`), `主页面未挂载叶子组件:${componentName}`)
|
||||||
}
|
}
|
||||||
expect(source.includes('class="preview-workspace"'), '详情页应提供数据文件工作区')
|
expect(source.includes('class="preview-workspace"'), '详情页应提供数据文件工作区')
|
||||||
expect(previewSurfaceSource.includes('class="split-file-tabs"'), '多切分数据集应提供训练/验证/测试文件切换')
|
expect(!source.includes('DatasetSplitNavigator'), '独立数据集详情不应再混合展示三个切分')
|
||||||
expect(source.includes('@select="handleFileChange"'), '切换数据切分时应加载对应文件版本')
|
|
||||||
expect(previewSurfaceSource.includes('splitCounts.train'), '数据集概览应显示训练集数量')
|
|
||||||
expect(previewSurfaceSource.includes('splitCounts.validation'), '数据集概览应显示验证集数量')
|
|
||||||
expect(previewSurfaceSource.includes('splitCounts.test'), '数据集概览应显示测试集数量')
|
|
||||||
expect(previewSurfaceSource.includes('class="code-line"'), '内容查看器应提供逐行展示')
|
expect(previewSurfaceSource.includes('class="code-line"'), '内容查看器应提供逐行展示')
|
||||||
expect(previewSurfaceSource.includes('class="line-number"'), '内容查看器应显示行号')
|
expect(previewSurfaceSource.includes('class="line-number"'), '内容查看器应显示行号')
|
||||||
expect(source.includes('previewLoading'), '切换文件时应提供独立加载状态')
|
expect(source.includes('previewLoading'), '切换文件时应提供独立加载状态')
|
||||||
|
|||||||
@@ -31,7 +31,9 @@ for (const name of [
|
|||||||
assert.match(datasetLine, /source: 'task'/, `${name} 必须标记为数据任务来源`)
|
assert.match(datasetLine, /source: 'task'/, `${name} 必须标记为数据任务来源`)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.match(viewSource, /const activeTab = ref<DatasetSource>\('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(
|
assert.match(
|
||||||
viewSource,
|
viewSource,
|
||||||
/if \(activeTab\.value === 'task'\) \{\s*return dataList\.value\.filter\(\(item\) => item\.source === 'task'\)\s*\}/,
|
/if \(activeTab\.value === 'task'\) \{\s*return dataList\.value\.filter\(\(item\) => item\.source === 'task'\)\s*\}/,
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ export interface DataProcessTask {
|
|||||||
output_dataset_id?: string | number | null
|
output_dataset_id?: string | number | null
|
||||||
output_dataset_name?: string | null
|
output_dataset_name?: string | null
|
||||||
output_dataset?: string | null
|
output_dataset?: string | null
|
||||||
|
output_datasets?: DataProcessOutputDataset[]
|
||||||
source_file_count?: number
|
source_file_count?: number
|
||||||
preview_count?: number
|
preview_count?: number
|
||||||
input_count?: number
|
input_count?: number
|
||||||
@@ -58,6 +59,14 @@ export interface DataProcessTask {
|
|||||||
source_files?: DataProcessSourceFile[]
|
source_files?: DataProcessSourceFile[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DataProcessOutputDataset {
|
||||||
|
id: string | number
|
||||||
|
name: string
|
||||||
|
type: 'train' | 'val' | 'test' | string
|
||||||
|
count?: number
|
||||||
|
dataset_split?: DataProcessSplit
|
||||||
|
}
|
||||||
|
|
||||||
export interface DataProcessTaskCreatePayload {
|
export interface DataProcessTaskCreatePayload {
|
||||||
name: string
|
name: string
|
||||||
description?: string
|
description?: string
|
||||||
@@ -253,5 +262,7 @@ export interface DataProcessPublishResult {
|
|||||||
count?: number
|
count?: number
|
||||||
[key: string]: unknown
|
[key: string]: unknown
|
||||||
}
|
}
|
||||||
|
datasets?: DataProcessOutputDataset[]
|
||||||
|
output_datasets?: DataProcessOutputDataset[]
|
||||||
created?: boolean
|
created?: boolean
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,9 +149,23 @@ const sourceDatasetName = computed(() => (
|
|||||||
|| detail.value?.source_files?.map((file) => file.name).join('、')
|
|| 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(() => (
|
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 outputDatasetId = computed(() => detail.value?.output_dataset_id || null)
|
||||||
const creatorName = computed(() => detail.value?.creator_name || detail.value?.creator || '-')
|
const creatorName = computed(() => detail.value?.creator_name || detail.value?.creator || '-')
|
||||||
const createTime = computed(() => detail.value?.create_time || detail.value?.created_at)
|
const createTime = computed(() => detail.value?.create_time || detail.value?.created_at)
|
||||||
@@ -410,7 +424,7 @@ function configuredSplit(): DataProcessDatasetSplit {
|
|||||||
function openPublishDialog() {
|
function openPublishDialog() {
|
||||||
if (!detail.value) return
|
if (!detail.value) return
|
||||||
if (outputDatasetId.value) {
|
if (outputDatasetId.value) {
|
||||||
void router.push(`/dataset/${outputDatasetId.value}/preview`)
|
void router.push({ path: '/dataset', query: { tab: 'task', task_id: taskId.value } })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
publishForm.dataset_name = `${detail.value.name}-数据集`
|
publishForm.dataset_name = `${detail.value.name}-数据集`
|
||||||
@@ -431,16 +445,10 @@ async function publishDataset() {
|
|||||||
dataset_name: publishForm.dataset_name.trim(),
|
dataset_name: publishForm.dataset_name.trim(),
|
||||||
split: { ...publishForm.split },
|
split: { ...publishForm.split },
|
||||||
})
|
})
|
||||||
const datasetId = published.dataset_id || published.output_dataset_id || published.dataset?.id
|
const datasets = published.datasets || published.output_datasets || []
|
||||||
if (!datasetId) {
|
ElMessage.success(`已发布 ${datasets.length || 3} 个独立数据集`)
|
||||||
ElMessage.success('数据集发布成功')
|
|
||||||
publishDialogVisible.value = false
|
|
||||||
await loadTask(true)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ElMessage.success('数据集发布成功')
|
|
||||||
publishDialogVisible.value = false
|
publishDialogVisible.value = false
|
||||||
await router.push(`/dataset/${datasetId}/preview`)
|
await router.push({ path: '/dataset', query: { tab: 'task', task_id: taskId.value } })
|
||||||
} catch {
|
} catch {
|
||||||
// 统一请求层已展示后端返回的失败原因。
|
// 统一请求层已展示后端返回的失败原因。
|
||||||
} finally {
|
} finally {
|
||||||
@@ -452,8 +460,8 @@ async function resyncPublishedDataset() {
|
|||||||
if (!detail.value || !outputDatasetId.value || publishing.value) return
|
if (!detail.value || !outputDatasetId.value || publishing.value) return
|
||||||
try {
|
try {
|
||||||
await ElMessageBox.confirm(
|
await ElMessageBox.confirm(
|
||||||
'将按当前 8:1:1 配置重新生成训练、验证、测试三个切分文件,数据集 ID 保持不变。',
|
'将按当前 8:1:1 配置同步为训练集、验证集、测试集三个独立数据集。',
|
||||||
'重新同步数据切分?',
|
'重新同步三个数据集?',
|
||||||
{ type: 'warning', confirmButtonText: '重新同步', cancelButtonText: '取消' },
|
{ type: 'warning', confirmButtonText: '重新同步', cancelButtonText: '取消' },
|
||||||
)
|
)
|
||||||
} catch {
|
} catch {
|
||||||
@@ -464,12 +472,12 @@ async function resyncPublishedDataset() {
|
|||||||
try {
|
try {
|
||||||
const published = await publishDataProcess(taskId.value, {
|
const published = await publishDataProcess(taskId.value, {
|
||||||
...publishForm,
|
...publishForm,
|
||||||
dataset_name: outputDatasetName.value || `${detail.value.name}-数据集`,
|
dataset_name: outputDatasetBaseName.value || `${detail.value.name}-数据集`,
|
||||||
split: configuredSplit(),
|
split: configuredSplit(),
|
||||||
})
|
})
|
||||||
ElMessage.success('训练集、验证集和测试集已重新同步')
|
const datasets = published.datasets || published.output_datasets || []
|
||||||
const datasetId = published.dataset?.id || outputDatasetId.value
|
ElMessage.success(`训练集、验证集和测试集已同步,共 ${datasets.length || 3} 个数据集`)
|
||||||
await router.push(`/dataset/${datasetId}/preview`)
|
await router.push({ path: '/dataset', query: { tab: 'task', task_id: taskId.value } })
|
||||||
} finally {
|
} finally {
|
||||||
publishing.value = false
|
publishing.value = false
|
||||||
}
|
}
|
||||||
@@ -497,14 +505,14 @@ onBeforeUnmount(() => {
|
|||||||
@click="openPublishDialog"
|
@click="openPublishDialog"
|
||||||
>
|
>
|
||||||
<i class="fa" :class="outputDatasetId ? 'fa-external-link' : 'fa-database'" />
|
<i class="fa" :class="outputDatasetId ? 'fa-external-link' : 'fa-database'" />
|
||||||
{{ outputDatasetId ? '查看输出数据集' : '发布为数据集' }}
|
{{ outputDatasetId ? '查看三个数据集' : '发布为三个数据集' }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
v-if="detail.status === 'completed' && outputDatasetId"
|
v-if="detail.status === 'completed' && outputDatasetId"
|
||||||
:loading="publishing"
|
:loading="publishing"
|
||||||
@click="resyncPublishedDataset"
|
@click="resyncPublishedDataset"
|
||||||
>
|
>
|
||||||
<i class="fa fa-refresh" />重新同步切分
|
<i class="fa fa-refresh" />重新同步数据集
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
<p>{{ detail.description || '暂无任务描述' }}</p>
|
<p>{{ detail.description || '暂无任务描述' }}</p>
|
||||||
@@ -570,12 +578,13 @@ onBeforeUnmount(() => {
|
|||||||
<dt>输出数据集</dt>
|
<dt>输出数据集</dt>
|
||||||
<dd>
|
<dd>
|
||||||
<el-button
|
<el-button
|
||||||
v-if="outputDatasetId && outputDatasetName"
|
v-for="dataset in outputDatasets"
|
||||||
|
:key="String(dataset.id)"
|
||||||
type="primary"
|
type="primary"
|
||||||
link
|
link
|
||||||
@click="router.push(`/dataset/${outputDatasetId}/preview`)"
|
@click="router.push(`/dataset/${dataset.id}/preview`)"
|
||||||
>{{ outputDatasetName }} <i class="fa fa-external-link" /></el-button>
|
>{{ dataset.name }}({{ dataset.count || 0 }} 条)<i class="fa fa-external-link" /></el-button>
|
||||||
<span v-else>{{ outputDatasetName || '尚未发布为数据集' }}</span>
|
<span v-if="!outputDatasets.length">尚未发布为数据集</span>
|
||||||
</dd>
|
</dd>
|
||||||
</div>
|
</div>
|
||||||
</dl>
|
</dl>
|
||||||
@@ -721,21 +730,12 @@ onBeforeUnmount(() => {
|
|||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<el-dialog v-model="publishDialogVisible" title="发布为数据集" width="560px" destroy-on-close>
|
<el-dialog v-model="publishDialogVisible" title="发布为三个数据集" width="560px" destroy-on-close>
|
||||||
<el-form label-position="top">
|
<el-form label-position="top">
|
||||||
<el-form-item label="数据集名称" required>
|
<el-form-item label="数据集名称" required>
|
||||||
<el-input v-model="publishForm.dataset_name" maxlength="150" show-word-limit />
|
<el-input v-model="publishForm.dataset_name" maxlength="150" show-word-limit />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<div class="publish-form-grid">
|
<div class="publish-form-grid">
|
||||||
<el-form-item label="数据集类型">
|
|
||||||
<el-select v-model="publishForm.dataset_type">
|
|
||||||
<el-option label="训练数据" value="train" />
|
|
||||||
<el-option label="测试数据" value="test" />
|
|
||||||
<el-option label="评测数据" value="eval" />
|
|
||||||
<el-option label="验证数据" value="val" />
|
|
||||||
<el-option label="其他" value="other" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="存储位置">
|
<el-form-item label="存储位置">
|
||||||
<el-select v-model="publishForm.storage_type">
|
<el-select v-model="publishForm.storage_type">
|
||||||
<el-option label="平台本地存储" value="local" />
|
<el-option label="平台本地存储" value="local" />
|
||||||
@@ -751,12 +751,12 @@ onBeforeUnmount(() => {
|
|||||||
<el-alert
|
<el-alert
|
||||||
type="info"
|
type="info"
|
||||||
:closable="false"
|
:closable="false"
|
||||||
:title="`将生成三个独立文件:训练集 ${publishForm.split.train}% / 验证集 ${publishForm.split.validation}% / 测试集 ${publishForm.split.test}%`"
|
:title="`将发布三个独立数据集:训练集 ${publishForm.split.train}% / 验证集 ${publishForm.split.validation}% / 测试集 ${publishForm.split.test}%`"
|
||||||
/>
|
/>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button @click="publishDialogVisible = false">取消</el-button>
|
<el-button @click="publishDialogVisible = false">取消</el-button>
|
||||||
<el-button type="primary" :loading="publishing" @click="publishDataset">发布并查看</el-button>
|
<el-button type="primary" :loading="publishing" @click="publishDataset">发布三个数据集</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, computed } from 'vue'
|
import { ref, onMounted, computed } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import DataTablePage from '@/components/DataTablePage.vue'
|
import DataTablePage from '@/components/DataTablePage.vue'
|
||||||
import { getDatasetList, deleteDataset, downloadDatasetUrl } from '@/api/modules/dataset'
|
import { getDatasetList, deleteDataset, downloadDatasetUrl } from '@/api/modules/dataset'
|
||||||
@@ -8,10 +8,11 @@ import { DATASET_TYPE_MAP, STORAGE_MAP } from '@/constants'
|
|||||||
import type { DatasetItem, DatasetSource } from '@/types'
|
import type { DatasetItem, DatasetSource } from '@/types'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const dataList = ref<DatasetItem[]>([])
|
const dataList = ref<DatasetItem[]>([])
|
||||||
const activeTab = ref<DatasetSource>('upload')
|
const activeTab = ref<DatasetSource>(route.query.tab === 'task' ? 'task' : 'upload')
|
||||||
|
|
||||||
const filteredDataList = computed(() => {
|
const filteredDataList = computed(() => {
|
||||||
if (activeTab.value === 'task') {
|
if (activeTab.value === 'task') {
|
||||||
@@ -21,17 +22,6 @@ const filteredDataList = computed(() => {
|
|||||||
return dataList.value.filter((item) => item.source !== 'task')
|
return dataList.value.filter((item) => item.source !== 'task')
|
||||||
})
|
})
|
||||||
|
|
||||||
const splitLabels = [
|
|
||||||
{ key: 'train', label: '训练', type: 'primary' },
|
|
||||||
{ key: 'validation', label: '验证', type: 'warning' },
|
|
||||||
{ key: 'test', label: '测试', type: 'success' },
|
|
||||||
] as const
|
|
||||||
|
|
||||||
function hasSplitCounts(row: Partial<DatasetItem>) {
|
|
||||||
return row.source === 'task'
|
|
||||||
&& Object.values(row.split_counts || {}).some((value) => Number(value) > 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function loadData() {
|
async function loadData() {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
@@ -98,17 +88,7 @@ onMounted(loadData)
|
|||||||
<el-table-column label="数据集名称" prop="name" align="center" />
|
<el-table-column label="数据集名称" prop="name" align="center" />
|
||||||
<el-table-column label="数据类型" align="center" width="110">
|
<el-table-column label="数据类型" align="center" width="110">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<div v-if="hasSplitCounts(row)" class="split-tags">
|
<el-tag type="primary" size="small">{{ DATASET_TYPE_MAP[String(row.type).toLowerCase()] || row.type || '-' }}</el-tag>
|
||||||
<el-tag
|
|
||||||
v-for="item in splitLabels"
|
|
||||||
:key="item.key"
|
|
||||||
:type="item.type"
|
|
||||||
size="small"
|
|
||||||
>
|
|
||||||
{{ item.label }} {{ row.split_counts?.[item.key] || 0 }}
|
|
||||||
</el-tag>
|
|
||||||
</div>
|
|
||||||
<el-tag v-else type="primary" size="small">{{ DATASET_TYPE_MAP[String(row.type).toLowerCase()] || row.type || '-' }}</el-tag>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="存储位置" align="center" width="110">
|
<el-table-column label="存储位置" align="center" width="110">
|
||||||
@@ -187,10 +167,4 @@ onMounted(loadData)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.split-tags {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 4px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import DatasetVersionBar from './preview/DatasetVersionBar.vue'
|
|||||||
import DatasetRecordTable from './preview/DatasetRecordTable.vue'
|
import DatasetRecordTable from './preview/DatasetRecordTable.vue'
|
||||||
import DatasetRecordEditorDialog from './preview/DatasetRecordEditorDialog.vue'
|
import DatasetRecordEditorDialog from './preview/DatasetRecordEditorDialog.vue'
|
||||||
import DatasetRawPreview from './preview/DatasetRawPreview.vue'
|
import DatasetRawPreview from './preview/DatasetRawPreview.vue'
|
||||||
import DatasetSplitNavigator from './preview/DatasetSplitNavigator.vue'
|
|
||||||
import type { EditField } from './preview/types'
|
import type { EditField } from './preview/types'
|
||||||
import type { DatasetFile, DatasetItem, DatasetVersion } from '@/types'
|
import type { DatasetFile, DatasetItem, DatasetVersion } from '@/types'
|
||||||
|
|
||||||
@@ -54,7 +53,6 @@ let versionRequestId = 0
|
|||||||
|
|
||||||
const files = computed<DatasetFile[]>(() => dataset.value?.files || [])
|
const files = computed<DatasetFile[]>(() => dataset.value?.files || [])
|
||||||
const selectedFile = computed(() => files.value.find((file) => fileKey(file) === selectedFileId.value))
|
const selectedFile = computed(() => files.value.find((file) => fileKey(file) === selectedFileId.value))
|
||||||
const splitCounts = computed(() => dataset.value?.split_counts || { train: 0, validation: 0, test: 0 })
|
|
||||||
const totalLines = computed(() => previewContent.value ? previewContent.value.split('\n').length : 0)
|
const totalLines = computed(() => previewContent.value ? previewContent.value.split('\n').length : 0)
|
||||||
const recordResult = computed(() => parseDatasetRecords(previewContent.value, selectedFile.value?.name || ''))
|
const recordResult = computed(() => parseDatasetRecords(previewContent.value, selectedFile.value?.name || ''))
|
||||||
const isRecordFile = computed(() => recordResult.value.supported)
|
const isRecordFile = computed(() => recordResult.value.supported)
|
||||||
@@ -83,13 +81,6 @@ function fileKey(file: DatasetFile) {
|
|||||||
return String(file.id || file.name)
|
return String(file.id || file.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleFileChange(file: DatasetFile) {
|
|
||||||
if (fileKey(file) === selectedFileId.value) return
|
|
||||||
if (!await confirmDiscardChanges('切换数据切分后,当前样本的未保存修改将丢失。')) return
|
|
||||||
selectedFileId.value = fileKey(file)
|
|
||||||
await loadVersions(file)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function loadDataset() {
|
async function loadDataset() {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
@@ -409,12 +400,6 @@ onBeforeUnmount(() => window.removeEventListener('beforeunload', handleBeforeUnl
|
|||||||
<div class="overview-item overview-item-wide"><span>创建时间</span><strong>{{ createdAt }}</strong></div>
|
<div class="overview-item overview-item-wide"><span>创建时间</span><strong>{{ createdAt }}</strong></div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<DatasetSplitNavigator
|
|
||||||
v-if="Object.values(splitCounts).some((value) => value > 0)"
|
|
||||||
:files="files" :selected-file-id="selectedFileId" :split-counts="splitCounts"
|
|
||||||
@select="handleFileChange"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<DatasetVersionBar
|
<DatasetVersionBar
|
||||||
v-model="selectedVersionId"
|
v-model="selectedVersionId"
|
||||||
:versions="versions"
|
:versions="versions"
|
||||||
|
|||||||
@@ -154,7 +154,9 @@ async function loadModels() {
|
|||||||
|
|
||||||
async function loadDatasets() {
|
async function loadDatasets() {
|
||||||
try {
|
try {
|
||||||
datasets.value = (await getDatasetList()) || []
|
datasets.value = ((await getDatasetList()) || []).filter(
|
||||||
|
(dataset) => String(dataset.type).toLowerCase() === 'train',
|
||||||
|
)
|
||||||
} catch {
|
} catch {
|
||||||
datasets.value = []
|
datasets.value = []
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user