refactor: 数据集预览组件化

拆分 DatasetVersionBar、DatasetRecordTable、DatasetRawPreview、DatasetRecordEditorDialog 子组件,DatasetPreviewView 聚焦编排,预览类型独立到 preview/types.ts,回归脚本适配。
This commit is contained in:
caoxiaozhu
2026-07-13 15:30:11 +08:00
parent e212de1693
commit 3fabd0c0eb
7 changed files with 821 additions and 518 deletions

View File

@@ -4,12 +4,24 @@ import ts from 'typescript'
const root = process.cwd()
const previewPath = path.join(root, 'src/views/dataset/DatasetPreviewView.vue')
const previewComponentsDir = path.join(root, 'src/views/dataset/preview')
const previewComponentPaths = [
'DatasetVersionBar.vue',
'DatasetRecordTable.vue',
'DatasetRecordEditorDialog.vue',
'DatasetRawPreview.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')
const mockPath = path.join(root, 'src/mock/data.ts')
const recordsPath = path.join(root, 'src/views/dataset/datasetRecords.ts')
const versionsPath = path.join(root, 'src/mock/datasetVersions.ts')
const source = fs.readFileSync(previewPath, 'utf8')
const previewComponentSources = previewComponentPaths.map((componentPath) => {
expect(fs.existsSync(componentPath), `缺少数据集预览叶子组件:${path.basename(componentPath)}`)
return fs.readFileSync(componentPath, 'utf8')
})
const previewSurfaceSource = [source, ...previewComponentSources].join('\n')
const apiSource = fs.readFileSync(apiPath, 'utf8')
const adapterSource = fs.readFileSync(adapterPath, 'utf8')
const mockSource = fs.readFileSync(mockPath, 'utf8')
@@ -35,33 +47,55 @@ function expect(condition, message) {
if (!condition) throw new Error(message)
}
expect(source.split('\n').length < 800, 'DatasetPreviewView.vue 应拆分到 800 行以内')
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(!source.includes('class="file-pane"'), '单文件数据集详情不应展示文件选择侧栏')
expect(source.includes('class="code-line"'), '内容查看器应提供逐行展示')
expect(source.includes('class="line-number"'), '内容查看器应显示行号')
expect(previewSurfaceSource.includes('class="code-line"'), '内容查看器应提供逐行展示')
expect(previewSurfaceSource.includes('class="line-number"'), '内容查看器应显示行号')
expect(source.includes('previewLoading'), '切换文件时应提供独立加载状态')
expect(source.includes('previewError'), '内容加载失败时应提供错误状态')
expect(source.includes('class="records-viewer"'), '详情页应将结构化文件展示为样本列表')
expect(source.includes('class="record-table"'), '样本数据应使用企业级表格展示')
expect(source.includes('fixed="right"'), '逐条编辑操作列应固定在表格右侧')
expect(source.includes('v-for="fieldKey in tableFieldKeys"'), '企业表格应根据数据结构动态生成字段列')
expect(source.includes('openRecordEditor(asDatasetRecord(row))'), '每条样本应提供独立编辑入口')
expect(source.includes('暂存修改'), '单条编辑应先暂存到当前页面')
expect(previewSurfaceSource.includes('class="records-viewer"'), '详情页应将结构化文件展示为样本列表')
expect(previewSurfaceSource.includes('class="record-table"'), '样本数据应使用企业级表格展示')
expect(previewSurfaceSource.includes('fixed="right"'), '逐条编辑操作列应固定在表格右侧')
expect(previewSurfaceSource.includes('v-for="fieldKey in tableFieldKeys"'), '企业表格应根据数据结构动态生成字段列')
expect(previewSurfaceSource.includes("emit('edit', asDatasetRecord(row))"), '每条样本应向主页面发送编辑事件')
expect(previewSurfaceSource.includes('暂存修改'), '单条编辑应先暂存到当前页面')
expect(source.includes('hasPendingVersionChanges && isViewingActiveVersion'), '存在暂存修改时才应显示保存版本按钮')
expect(source.includes('保存版本'), '文件工具栏应提供保存版本按钮')
expect(source.includes('baseVersionContent'), '页面应区分已保存版本与待保存工作副本')
expect(source.includes('class="version-control-bar"'), '详情页应提供独立版本控制区')
expect(source.includes('设为当前版本'), '历史版本应支持显式切换为当前版本')
expect(source.includes('历史版本(只读)'), '历史版本应明确展示只读状态')
expect(previewSurfaceSource.includes('class="version-control-bar"'), '详情页应提供独立版本控制区')
expect(previewSurfaceSource.includes('设为当前版本'), '历史版本应支持显式切换为当前版本')
expect(previewSurfaceSource.includes('历史版本(只读)'), '历史版本应明确展示只读状态')
expect(source.includes('loadedVersionId.value'), '下载和展示应绑定正在查看的具体版本')
expect(source.includes('versionRequestId'), '快速切换历史版本时应防止旧响应覆盖新内容')
expect(source.includes('v-model:current-page="currentPage"'), '样本列表应支持分页浏览')
expect(previewSurfaceSource.includes('v-model:current-page="currentPage"'), '样本列表应支持分页浏览')
expect(!source.includes('class="content-editor"'), '详情页不应继续提供整文件编辑器')
expect(source.includes('saveRecord'), '逐条编辑器应提供单条保存动作')
expect(source.includes('hasUnsavedChanges'), '在线编辑器应跟踪未保存修改')
expect(source.includes('onBeforeRouteLeave'), '离开页面时应保护未保存修改')
expect(source.includes("event.key.toLowerCase() === 's'"), '在线编辑器应支持快捷键保存')
expect(previewSurfaceSource.includes("event.key.toLowerCase() === 's'"), '在线编辑器应支持快捷键保存')
expect(source.includes('loadVersions(selectedFile)'), '版本内容加载失败后应支持重新加载')
expect(source.includes('function resetRecordEditor()'), '主页面应提供统一的编辑器状态清理函数')
const resetEditorStart = source.indexOf('function resetRecordEditor()')
const updateFieldStart = source.indexOf('function updateEditField', resetEditorStart)
const resetEditorSource = source.slice(resetEditorStart, updateFieldStart)
for (const marker of [
'editorVisible.value = false',
'editingRecord.value = null',
'editFields.value = []',
"rawDraft.value = ''",
"originalDraft.value = ''",
]) {
expect(resetEditorSource.includes(marker), `编辑器状态清理不完整:${marker}`)
}
const versionChangeStart = source.indexOf('async function handleViewedVersionChange')
const activateVersionStart = source.indexOf('async function activateViewedVersion', versionChangeStart)
const versionChangeSource = source.slice(versionChangeStart, activateVersionStart)
expect(versionChangeSource.includes('resetRecordEditor()'), '成功切换版本后必须关闭并清空旧编辑器状态')
expect(!source.includes('handleDownloadAll'), '页面不应保留整包下载逻辑')
expect(!source.includes('handleDelete'), '页面不应保留删除逻辑')
expect(!source.includes('router.back()'), '页面不应保留页头返回逻辑')