refactor: 训练日志组件化与 Mock 数据增强

拆分 TrainingTaskOverview 组件与 trainingLogModel 状态模型,TrainingLogView 大幅瘦身;Mock 新增按文件路由的训练日志内容与更真实的 GPU 进程占用数据,adapter 类型收敛为 AxiosAdapter,配套新增 mock 内容回归脚本。
This commit is contained in:
caoxiaozhu
2026-07-13 15:29:49 +08:00
parent e580ec4791
commit e212de1693
7 changed files with 1473 additions and 914 deletions

View File

@@ -3,7 +3,7 @@
* 拦截所有 API 请求并返回 mock 数据
* 通过 URL + method 路由到对应的 mock 响应
*/
import type { AxiosInstance, AxiosRequestConfig } from 'axios'
import type { AxiosAdapter, AxiosInstance, AxiosRequestConfig } from 'axios'
import {
mockLoginOk,
mockHealth,
@@ -21,6 +21,7 @@ import {
mockLogFiles,
mockTrainingLogFiles,
mockLogContent,
mockTrainingLogContents,
} from './data'
import {
activateDatasetVersion,
@@ -164,7 +165,8 @@ async function handleMock(config: AxiosRequestConfig) {
}
m = url.match(/^\/dataset-manage\/([^/]+)$/)
if (m && method === 'get') {
const found = mockDatasets.find((x) => String(x.id) === m[1])
const datasetId = m[1]
const found = mockDatasets.find((x) => String(x.id) === datasetId)
return found ? ok(found) : fail('数据集不存在', 404)
}
if (m && (method === 'put' || method === 'delete')) {
@@ -261,7 +263,8 @@ async function handleMock(config: AxiosRequestConfig) {
}
m = url.match(/^\/fine-tune\/progress\/([^/]+)$/)
if (m && method === 'get') {
const task = mockFineTuneList.find((t) => String(t.id) === m[1])
const taskId = m[1]
const task = mockFineTuneList.find((t) => String(t.id) === taskId)
if (!task) return fail('任务不存在', 404)
if (task.status === 'running') {
return ok({
@@ -276,7 +279,8 @@ async function handleMock(config: AxiosRequestConfig) {
}
m = url.match(/^\/fine-tune\/([^/]+)$/)
if (m && method === 'get') {
const found = mockFineTuneList.find((x) => String(x.id) === m[1])
const taskId = m[1]
const found = mockFineTuneList.find((x) => String(x.id) === taskId)
return found ? ok(found) : fail('任务不存在', 404)
}
m = url.match(/^\/fine-tune\/stop\/([^/]+)$/)
@@ -296,7 +300,8 @@ async function handleMock(config: AxiosRequestConfig) {
}
m = url.match(/^\/model-compare\/([^/]+)$/)
if (m && method === 'get') {
const found = mockCompareList.find((x) => String(x.id) === m[1])
const compareId = m[1]
const found = mockCompareList.find((x) => String(x.id) === compareId)
return found ? ok(found) : fail('任务不存在', 404)
}
if (m && method === 'delete') return ok({ deleted: m[1] })
@@ -363,7 +368,14 @@ async function handleMock(config: AxiosRequestConfig) {
if (url === '/log-files' && method === 'get') return ok(mockLogFiles)
if (url === '/log-content' && method === 'get') return ok(mockLogContent)
if (url === '/training-log-files' && method === 'get') return ok(mockTrainingLogFiles)
if (url === '/training-log-content' && method === 'get') return ok(mockLogContent)
if (url === '/training-log-content' && method === 'get') {
const file = String(params.file || '')
return ok(mockTrainingLogContents[file] || {
file,
size: '0 KB',
content: `[Mock] 未找到训练日志内容:${file}`,
})
}
// 未匹配的请求 → 兜底返回空成功(避免阻断 UI
console.warn('[Mock] 未匹配路由:', method.toUpperCase(), url, params)
@@ -380,12 +392,13 @@ function safeJSON(str: string) {
/** 给 axios instance 安装 mock adapter */
export function installMockAdapter(instance: AxiosInstance) {
instance.defaults.adapter = async (config: AxiosRequestConfig) => {
const adapter = async (config: AxiosRequestConfig) => {
try {
const response = await handleMock(config)
return response
} catch (e: any) {
return fail(e.message || 'Mock 错误', 500, config)
} catch (error: unknown) {
return fail(error instanceof Error ? error.message : 'Mock 错误', 500, config)
}
}
instance.defaults.adapter = adapter as AxiosAdapter
}