fix(dataset): 展示训练任务名称
This commit is contained in:
@@ -1151,12 +1151,25 @@ class PlatformStore:
|
|||||||
|
|
||||||
def datasets(self) -> list[dict[str, Any]]:
|
def datasets(self) -> list[dict[str, Any]]:
|
||||||
with self.connect() as conn:
|
with self.connect() as conn:
|
||||||
rows = conn.execute("SELECT * FROM datasets ORDER BY create_time DESC").fetchall()
|
rows = conn.execute(
|
||||||
|
"""SELECT dataset.*, task.name AS task_name
|
||||||
|
FROM datasets dataset
|
||||||
|
LEFT JOIN data_process_tasks task
|
||||||
|
ON task.id=COALESCE(dataset.source_task_id, dataset.task_id)
|
||||||
|
ORDER BY dataset.create_time DESC"""
|
||||||
|
).fetchall()
|
||||||
return [self._dataset(conn, row) for row in rows]
|
return [self._dataset(conn, row) for row in rows]
|
||||||
|
|
||||||
def dataset(self, dataset_id: str) -> dict[str, Any]:
|
def dataset(self, dataset_id: str) -> dict[str, Any]:
|
||||||
with self.connect() as conn:
|
with self.connect() as conn:
|
||||||
row = conn.execute("SELECT * FROM datasets WHERE id=?", (dataset_id,)).fetchone()
|
row = conn.execute(
|
||||||
|
"""SELECT dataset.*, task.name AS task_name
|
||||||
|
FROM datasets dataset
|
||||||
|
LEFT JOIN data_process_tasks task
|
||||||
|
ON task.id=COALESCE(dataset.source_task_id, dataset.task_id)
|
||||||
|
WHERE dataset.id=?""",
|
||||||
|
(dataset_id,),
|
||||||
|
).fetchone()
|
||||||
if not row:
|
if not row:
|
||||||
raise KeyError(dataset_id)
|
raise KeyError(dataset_id)
|
||||||
return self._dataset(conn, row)
|
return self._dataset(conn, row)
|
||||||
|
|||||||
@@ -1,6 +1,46 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from app.db.platform_store import dataset_file_version_summary, parse_size_bytes
|
from contextlib import contextmanager
|
||||||
|
from typing import Any, Iterator
|
||||||
|
|
||||||
|
from app.db.platform_store import PlatformStore, dataset_file_version_summary, parse_size_bytes
|
||||||
|
|
||||||
|
|
||||||
|
class _DatasetCursor:
|
||||||
|
def __init__(self, rows: list[dict[str, Any]]) -> None:
|
||||||
|
self.rows = rows
|
||||||
|
|
||||||
|
def fetchall(self) -> list[dict[str, Any]]:
|
||||||
|
return self.rows
|
||||||
|
|
||||||
|
|
||||||
|
class _DatasetConnection:
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self.queries: list[str] = []
|
||||||
|
|
||||||
|
def execute(self, sql: str, params: tuple[Any, ...] | None = None) -> _DatasetCursor:
|
||||||
|
self.queries.append(sql)
|
||||||
|
if "FROM datasets dataset" in sql:
|
||||||
|
return _DatasetCursor(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "dataset-train",
|
||||||
|
"name": "cash-数据集-训练集",
|
||||||
|
"type": "train",
|
||||||
|
"storage_type": "local",
|
||||||
|
"source": "task",
|
||||||
|
"task_id": "task-cash",
|
||||||
|
"source_task_id": "task-cash",
|
||||||
|
"task_name": "cash",
|
||||||
|
"size": "0 B",
|
||||||
|
"size_bytes": 0,
|
||||||
|
"metadata": "{}",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
if "FROM dataset_files" in sql or "FROM dataset_records" in sql:
|
||||||
|
return _DatasetCursor([])
|
||||||
|
raise AssertionError(f"unexpected query: {sql}")
|
||||||
|
|
||||||
|
|
||||||
def test_parse_size_bytes_supports_legacy_units() -> None:
|
def test_parse_size_bytes_supports_legacy_units() -> None:
|
||||||
@@ -44,3 +84,20 @@ def test_dataset_file_version_summary_uses_normalized_version_number_as_fallback
|
|||||||
|
|
||||||
assert summary["current_version_no"] == 1
|
assert summary["current_version_no"] == 1
|
||||||
assert summary["version_count"] == 0
|
assert summary["version_count"] == 0
|
||||||
|
|
||||||
|
|
||||||
|
def test_dataset_list_exposes_source_task_name() -> None:
|
||||||
|
store = PlatformStore.__new__(PlatformStore)
|
||||||
|
conn = _DatasetConnection()
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def connect() -> Iterator[_DatasetConnection]:
|
||||||
|
yield conn
|
||||||
|
|
||||||
|
store.connect = connect # type: ignore[method-assign]
|
||||||
|
|
||||||
|
[dataset] = store.datasets()
|
||||||
|
|
||||||
|
assert dataset["task_name"] == "cash"
|
||||||
|
assert dataset["name"] == "cash-数据集-训练集"
|
||||||
|
assert any("task.name AS task_name" in query for query in conn.queries)
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ const [typesSource, dataSource, viewSource, tablePageSource] = await Promise.all
|
|||||||
|
|
||||||
assert.match(typesSource, /export type DatasetSource = 'upload' \| 'task'/)
|
assert.match(typesSource, /export type DatasetSource = 'upload' \| 'task'/)
|
||||||
assert.match(typesSource, /source\?: DatasetSource/)
|
assert.match(typesSource, /source\?: DatasetSource/)
|
||||||
|
assert.match(typesSource, /task_name\?: string/)
|
||||||
|
|
||||||
assert.equal((dataSource.match(/source: 'upload'/g) || []).length, 6)
|
assert.equal((dataSource.match(/source: 'upload'/g) || []).length, 6)
|
||||||
assert.equal((dataSource.match(/source: 'task'/g) || []).length, 4)
|
assert.equal((dataSource.match(/source: 'task'/g) || []).length, 4)
|
||||||
@@ -31,6 +32,7 @@ for (const name of [
|
|||||||
const datasetLine = dataSource.split('\n').find((line) => line.includes(`name: '${name}'`))
|
const datasetLine = dataSource.split('\n').find((line) => line.includes(`name: '${name}'`))
|
||||||
assert.ok(datasetLine, `缺少数据任务 Mock:${name}`)
|
assert.ok(datasetLine, `缺少数据任务 Mock:${name}`)
|
||||||
assert.match(datasetLine, /source: 'task'/, `${name} 必须标记为数据任务来源`)
|
assert.match(datasetLine, /source: 'task'/, `${name} 必须标记为数据任务来源`)
|
||||||
|
assert.match(datasetLine, /task_name: '/, `${name} 必须提供来源任务名称`)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.match(viewSource, /route\.query\.tab === 'task' \? 'task' : 'upload'/)
|
assert.match(viewSource, /route\.query\.tab === 'task' \? 'task' : 'upload'/)
|
||||||
@@ -42,7 +44,9 @@ assert.match(
|
|||||||
)
|
)
|
||||||
assert.match(viewSource, /return dataList\.value\.filter\(\(item\) => item\.source !== 'task'\)/)
|
assert.match(viewSource, /return dataList\.value\.filter\(\(item\) => item\.source !== 'task'\)/)
|
||||||
assert.doesNotMatch(viewSource, /数据任务产生的数据集[\s\S]*?return \[\]/)
|
assert.doesNotMatch(viewSource, /数据任务产生的数据集[\s\S]*?return \[\]/)
|
||||||
assert.match(viewSource, /:search-fields="\['task_id', 'name'\]"/, '数据任务搜索应支持任务 ID')
|
assert.match(viewSource, /:search-fields="activeTab === 'task' \? \['task_id', 'task_name'\] : \['name'\]"/, '搜索字段应与当前页签展示的名称一致')
|
||||||
|
assert.match(viewSource, /activeTab === 'task' \? '训练任务名称' : '数据集名称'/, '数据任务页应展示训练任务名称表头')
|
||||||
|
assert.match(viewSource, /activeTab === 'task' \? \(row\.task_name \|\| '-'\) : row\.name/, '数据任务页应展示接口返回的来源任务名称')
|
||||||
assert.match(viewSource, /formatMegabytes\(row\.size_bytes, row\.size\)/, '数据集大小应统一转换为 MB')
|
assert.match(viewSource, /formatMegabytes\(row\.size_bytes, row\.size\)/, '数据集大小应统一转换为 MB')
|
||||||
assert.match(viewSource, /<el-table-column label="版本"/, '描述列应替换为真实版本列')
|
assert.match(viewSource, /<el-table-column label="版本"/, '描述列应替换为真实版本列')
|
||||||
assert.doesNotMatch(viewSource, /<el-table-column label="描述"/, '列表不应继续显示描述列')
|
assert.doesNotMatch(viewSource, /<el-table-column label="描述"/, '列表不应继续显示描述列')
|
||||||
|
|||||||
@@ -272,10 +272,10 @@ export const mockDatasets: DatasetItem[] = ([
|
|||||||
{ id: 4, name: '金融评测集', type: 'eval', storage_type: 'local', source: 'upload', size: '32 MB', count: 1200, description: '金融领域评测', create_time: '2026-01-10T09:15:00Z' },
|
{ id: 4, name: '金融评测集', type: 'eval', storage_type: 'local', source: 'upload', size: '32 MB', count: 1200, description: '金融领域评测', create_time: '2026-01-10T09:15:00Z' },
|
||||||
{ id: 5, name: '通用能力评测', type: 'eval', storage_type: 'local', source: 'upload', size: '64 MB', count: 3500, description: '通用能力评测数据集', create_time: '2026-01-12T11:30:00Z' },
|
{ id: 5, name: '通用能力评测', type: 'eval', storage_type: 'local', source: 'upload', size: '64 MB', count: 3500, description: '通用能力评测数据集', create_time: '2026-01-12T11:30:00Z' },
|
||||||
{ id: 6, name: '医疗问答-训练集', type: 'train', storage_type: 'local', source: 'upload', size: '180 MB', count: 9800, description: '医疗问答对', create_time: '2026-02-01T15:00:00Z' },
|
{ id: 6, name: '医疗问答-训练集', type: 'train', storage_type: 'local', source: 'upload', size: '180 MB', count: 9800, description: '医疗问答对', create_time: '2026-02-01T15:00:00Z' },
|
||||||
{ id: 7, name: '客服对话清洗集', type: 'train', storage_type: 'minio', source: 'task', task_id: 183921, size: '96 MB', count: 18240, description: '由客服问答数据清洗任务生成', create_time: '2026-07-08T06:28:00Z' },
|
{ id: 7, name: '客服对话清洗集', type: 'train', storage_type: 'minio', source: 'task', task_id: 183921, task_name: '客服问答数据清洗任务', size: '96 MB', count: 18240, description: '由客服问答数据清洗任务生成', create_time: '2026-07-08T06:28:00Z' },
|
||||||
{ id: 8, name: '通用指令构造集', type: 'train', storage_type: 'local', source: 'task', task_id: 492015, size: '148 MB', count: 12600, description: '由指令微调数据构造任务生成', create_time: '2026-07-09T01:42:00Z' },
|
{ id: 8, name: '通用指令构造集', type: 'train', storage_type: 'local', source: 'task', task_id: 492015, task_name: '指令微调数据构造任务', size: '148 MB', count: 12600, description: '由指令微调数据构造任务生成', create_time: '2026-07-09T01:42:00Z' },
|
||||||
{ id: 9, name: '用户反馈脱敏集', type: 'test', storage_type: 'minio', source: 'task', task_id: 731948, size: '72 MB', count: 9340, description: '由敏感信息脱敏任务生成', create_time: '2026-07-09T09:18:00Z' },
|
{ id: 9, name: '用户反馈脱敏集', type: 'test', storage_type: 'minio', source: 'task', task_id: 731948, task_name: '敏感信息脱敏任务', size: '72 MB', count: 9340, description: '由敏感信息脱敏任务生成', create_time: '2026-07-09T09:18:00Z' },
|
||||||
{ id: 10, name: '多轮对话增强集', type: 'eval', storage_type: 'local', source: 'task', task_id: 582012, size: '41 MB', count: 2780, description: '由多轮对话拼接任务生成', create_time: '2026-07-10T02:06:00Z' },
|
{ id: 10, name: '多轮对话增强集', type: 'eval', storage_type: 'local', source: 'task', task_id: 582012, task_name: '多轮对话拼接任务', size: '41 MB', count: 2780, description: '由多轮对话拼接任务生成', create_time: '2026-07-10T02:06:00Z' },
|
||||||
] satisfies DatasetItem[]).map((dataset) => ({
|
] satisfies DatasetItem[]).map((dataset) => ({
|
||||||
...dataset,
|
...dataset,
|
||||||
files: dataset.files?.length
|
files: dataset.files?.length
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ export interface DatasetItem {
|
|||||||
storage_type: DatasetStorage | string
|
storage_type: DatasetStorage | string
|
||||||
source?: DatasetSource
|
source?: DatasetSource
|
||||||
task_id?: string | number
|
task_id?: string | number
|
||||||
|
task_name?: string
|
||||||
size?: string | number
|
size?: string | number
|
||||||
size_bytes?: number
|
size_bytes?: number
|
||||||
count?: number
|
count?: number
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ onMounted(loadData)
|
|||||||
:data="filteredDataList"
|
:data="filteredDataList"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
searchable
|
searchable
|
||||||
:search-fields="['task_id', 'name']"
|
:search-fields="activeTab === 'task' ? ['task_id', 'task_name'] : ['name']"
|
||||||
:multi-select="activeTab === 'task' && batchMode"
|
:multi-select="activeTab === 'task' && batchMode"
|
||||||
:show-batch-bar="false"
|
:show-batch-bar="false"
|
||||||
:create-text="activeTab === 'upload' ? '上传数据集' : ''"
|
:create-text="activeTab === 'upload' ? '上传数据集' : ''"
|
||||||
@@ -199,7 +199,15 @@ onMounted(loadData)
|
|||||||
|
|
||||||
<template #columns>
|
<template #columns>
|
||||||
<el-table-column v-if="activeTab === 'task'" label="任务ID" prop="task_id" align="center" width="100" />
|
<el-table-column v-if="activeTab === 'task'" label="任务ID" prop="task_id" align="center" width="100" />
|
||||||
<el-table-column label="数据集名称" prop="name" align="center" />
|
<el-table-column
|
||||||
|
:label="activeTab === 'task' ? '训练任务名称' : '数据集名称'"
|
||||||
|
align="center"
|
||||||
|
show-overflow-tooltip
|
||||||
|
>
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ activeTab === 'task' ? (row.task_name || '-') : row.name }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="数据类型" align="center" width="110">
|
<el-table-column label="数据类型" align="center" width="110">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-tag type="primary" size="small">{{ DATASET_TYPE_MAP[String(row.type).toLowerCase()] || row.type || '-' }}</el-tag>
|
<el-tag type="primary" size="small">{{ DATASET_TYPE_MAP[String(row.type).toLowerCase()] || row.type || '-' }}</el-tag>
|
||||||
|
|||||||
Reference in New Issue
Block a user