feat: 实现基础设施层
axios 请求封装及七个业务模块 API,Pinia 状态管理(auth/system/models/tools),Mock 适配器与数据,以及流式对话、轮询、倒计时组合式函数。
This commit is contained in:
80
frontend/src/api/modules/compare.ts
Normal file
80
frontend/src/api/modules/compare.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import { get, post, del } from '../request'
|
||||
import type { CompareTask, CompareModelRef } from '@/types'
|
||||
|
||||
/** 推理/对比任务列表 */
|
||||
export const getCompareList = () => get<CompareTask[]>('/model-compare')
|
||||
|
||||
/** 任务详情 */
|
||||
export const getCompare = (id: string | number) => get<CompareTask>(`/model-compare/${id}`)
|
||||
|
||||
/** 创建任务 */
|
||||
export const createCompare = (data: Partial<CompareTask>) =>
|
||||
post<{ id: string | number }>('/model-compare', data)
|
||||
|
||||
/** 删除任务 */
|
||||
export const deleteCompare = (id: string | number) => del(`/model-compare/${id}`)
|
||||
|
||||
/** 更新任务加载状态 */
|
||||
export const updateLoadStatus = (id: string | number, load_status: any) =>
|
||||
post(`/model-compare/${id}/load-status`, { load_status })
|
||||
|
||||
/** 查询任务加载状态 */
|
||||
export const getLoadStatus = (id: string | number) =>
|
||||
get<{ all_ready: boolean; loaded_models: any[] }>(`/model-compare/${id}/load-status`)
|
||||
|
||||
/** 停止所有旧模型服务 */
|
||||
export const stopAllModels = () => post('/model-compare/all/stop-all')
|
||||
|
||||
/** 启动单个模型服务 */
|
||||
export const startModel = (id: string | number, data: Partial<CompareModelRef>) =>
|
||||
post<{ pid: number; port: number }>(`/model-compare/${id}/start-model`, data)
|
||||
|
||||
/** 按 PID 停止模型进程 */
|
||||
export const stopModelByPid = (pid: number) =>
|
||||
post('/model-compare/stop-by-pid', { pid })
|
||||
|
||||
/** 加载任务 */
|
||||
export const loadCompare = (id: string | number) => post(`/model-compare/${id}/load`)
|
||||
|
||||
/** 卸载任务 */
|
||||
export const unloadCompare = (id: string | number) => post(`/model-compare/${id}/unload`)
|
||||
|
||||
/** 流式对话(mock 模式下返回非流式响应,调用方需兼容) */
|
||||
export const streamChat = async (data: any): Promise<any> => {
|
||||
// Mock 环境:返回非流式响应对象,调用方检测 content-type 决定如何处理
|
||||
const resp = await post<{ response: string }>('/model-compare/stream-chat', data)
|
||||
return {
|
||||
ok: true,
|
||||
body: {
|
||||
getReader: () => {
|
||||
// 模拟流式读取:把整个响应切成小块逐个返回
|
||||
const text = resp?.response || ''
|
||||
const encoder = new TextEncoder()
|
||||
const chunks = [text.slice(0, text.length / 3), text.slice(text.length / 3, 2 * text.length / 3), text.slice(2 * text.length / 3)]
|
||||
let i = 0
|
||||
return {
|
||||
read: async () => {
|
||||
if (i >= chunks.length) return { done: true, value: undefined }
|
||||
const value = encoder.encode(chunks[i++])
|
||||
return { done: false, value }
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/** 非流式对话(按端口代理) */
|
||||
export const chatWithPort = (data: any) => post('/model-compare/chat-with-port', data)
|
||||
|
||||
/** 批量对话(API 类型模型) */
|
||||
export const batchChat = (data: any) => post('/model-chat/batch', data)
|
||||
|
||||
/** 本地 transformers 模型对话 */
|
||||
export const localChat = (data: any) => post('/model-chat/local/chat', data)
|
||||
|
||||
/** 预加载本地模型 */
|
||||
export const preloadLocalModel = (data: any) => post('/model-chat/local/preload', data)
|
||||
|
||||
/** 预加载已训练模型 */
|
||||
export const preloadTrainedModel = (data: any) => post('/model-chat/trained/preload', data)
|
||||
40
frontend/src/api/modules/dataset.ts
Normal file
40
frontend/src/api/modules/dataset.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { get, post, put, del } from '../request'
|
||||
import type { DatasetItem } from '@/types'
|
||||
|
||||
/** 数据集列表 */
|
||||
export const getDatasetList = () => get<DatasetItem[]>('/dataset-manage')
|
||||
|
||||
/** 数据集详情 */
|
||||
export const getDataset = (id: string | number) => get<DatasetItem>(`/dataset-manage/${id}`)
|
||||
|
||||
/** 创建数据集 */
|
||||
export const createDataset = (data: Partial<DatasetItem>) =>
|
||||
post<{ id: string | number }>('/dataset-manage', data)
|
||||
|
||||
/** 更新数据集 */
|
||||
export const updateDataset = (id: string | number, data: Partial<DatasetItem>) =>
|
||||
put(`/dataset-manage/${id}`, data)
|
||||
|
||||
/** 删除数据集 */
|
||||
export const deleteDataset = (id: string | number) => del(`/dataset-manage/${id}`)
|
||||
|
||||
/** 上传数据集文件(multipart,字段名 files) */
|
||||
export const uploadDatasetFiles = (datasetId: string | number, files: File[]) => {
|
||||
const formData = new FormData()
|
||||
files.forEach((f) => formData.append('files', f))
|
||||
return post(`/dataset-manage/upload/${datasetId}`, formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
})
|
||||
}
|
||||
|
||||
/** 预览数据集文件内容 */
|
||||
export const previewDatasetFile = (fileId: string | number) =>
|
||||
get<{ content: string }>(`/dataset-manage/preview/${fileId}`)
|
||||
|
||||
/** 下载文件 URL */
|
||||
export const downloadFileUrl = (datasetId: string | number, fileId: string | number) =>
|
||||
`/api/dataset-manage/download/${datasetId}/${fileId}`
|
||||
|
||||
/** 打包下载数据集 URL */
|
||||
export const downloadDatasetUrl = (datasetId: string | number) =>
|
||||
`/api/dataset-manage/download/${datasetId}`
|
||||
27
frontend/src/api/modules/eval.ts
Normal file
27
frontend/src/api/modules/eval.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { get, post, put, del } from '../request'
|
||||
import type { EvalTask, Dimension } from '@/types'
|
||||
|
||||
/** 评测任务列表 */
|
||||
export const getEvalList = () => get<EvalTask[]>('/model-eval')
|
||||
|
||||
/** 删除评测任务 */
|
||||
export const deleteEval = (id: string | number) => del(`/model-eval/${id}`)
|
||||
|
||||
/** 启动评测 */
|
||||
export const startEval = (data: any) => post('/model-eval/start', data)
|
||||
|
||||
/** 评测维度列表 */
|
||||
export const getDimensionList = () => get<Dimension[]>('/dimension')
|
||||
|
||||
/** 评测维度详情 */
|
||||
export const getDimension = (id: string | number) => get<Dimension>(`/dimension/${id}`)
|
||||
|
||||
/** 创建维度 */
|
||||
export const createDimension = (data: Partial<Dimension>) => post('/dimension', data)
|
||||
|
||||
/** 编辑维度 */
|
||||
export const updateDimension = (id: string | number, data: Partial<Dimension>) =>
|
||||
put(`/dimension/${id}`, data)
|
||||
|
||||
/** 删除维度 */
|
||||
export const deleteDimension = (id: string | number) => del(`/dimension/${id}`)
|
||||
40
frontend/src/api/modules/fineTune.ts
Normal file
40
frontend/src/api/modules/fineTune.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { get, post, put, del } from '../request'
|
||||
import type { FineTuneTask, TrainingProgress } from '@/types'
|
||||
|
||||
/** 训练任务列表 */
|
||||
export const getFineTuneList = () => get<FineTuneTask[]>('/fine-tune')
|
||||
|
||||
/** 训练任务详情 */
|
||||
export const getFineTune = (id: string | number) => get<FineTuneTask>(`/fine-tune/${id}`)
|
||||
|
||||
/** 任务名查重 */
|
||||
export const checkFineTuneName = (name: string) =>
|
||||
get<{ exists: boolean }>('/fine-tune/check-name', { name })
|
||||
|
||||
/** 创建训练任务记录(第一步) */
|
||||
export const createFineTune = (data: Partial<FineTuneTask>) =>
|
||||
post<{ id: string | number }>('/fine-tune', data)
|
||||
|
||||
/** 启动训练(第二步) */
|
||||
export const startFineTune = (data: any) => post('/fine-tune/start', data)
|
||||
|
||||
/** 更新训练任务 */
|
||||
export const updateFineTune = (id: string | number, data: Partial<FineTuneTask>) =>
|
||||
put(`/fine-tune/${id}`, data)
|
||||
|
||||
/** 停止训练任务 */
|
||||
export const stopFineTune = (id: string | number) => post(`/fine-tune/stop/${id}`)
|
||||
|
||||
/** 删除训练任务 */
|
||||
export const deleteFineTune = (id: string | number) => del(`/fine-tune/${id}`)
|
||||
|
||||
/** 获取训练进度 */
|
||||
export const getFineTuneProgress = (id: string | number) =>
|
||||
get<TrainingProgress>(`/fine-tune/progress/${id}`)
|
||||
|
||||
/** 启动 TensorBoard */
|
||||
export const startTensorboard = () => post('/fine-tune/tensorboard/start')
|
||||
|
||||
/** 提交 Web 日志 */
|
||||
export const sendWebLog = (level: string, message: string, page: string) =>
|
||||
post('/web-log', { level, message, page, timestamp: new Date().toISOString() })
|
||||
18
frontend/src/api/modules/log.ts
Normal file
18
frontend/src/api/modules/log.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { get } from '../request'
|
||||
import type { LogFile, LogContent, TrainingLogFile } from '@/types'
|
||||
|
||||
/** 按日期获取系统日志文件列表 */
|
||||
export const getLogFiles = (date: string) =>
|
||||
get<LogFile[]>('/log-files', { date })
|
||||
|
||||
/** 获取系统日志内容 */
|
||||
export const getLogContent = (file: string) =>
|
||||
get<LogContent>('/log-content', { file })
|
||||
|
||||
/** 训练日志文件列表 */
|
||||
export const getTrainingLogFiles = () =>
|
||||
get<TrainingLogFile[]>('/training-log-files')
|
||||
|
||||
/** 训练日志内容 */
|
||||
export const getTrainingLogContent = (file: string) =>
|
||||
get<LogContent>('/training-log-content', { file })
|
||||
48
frontend/src/api/modules/model.ts
Normal file
48
frontend/src/api/modules/model.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { get, post, put, del } from '../request'
|
||||
import type { ModelItem, ModelForm, TrainedModel } from '@/types'
|
||||
|
||||
/** 模型列表 */
|
||||
export const getModelList = () => get<ModelItem[]>('/model-manage')
|
||||
|
||||
/** 模型详情 */
|
||||
export const getModel = (id: string | number) => get<ModelItem>(`/model-manage/${id}`)
|
||||
|
||||
/** 按名称查模型 */
|
||||
export const getModelByName = (name: string) => get<ModelItem>(`/model-manage/name/${name}`)
|
||||
|
||||
/** 本地模型路径列表 */
|
||||
export const getLocalModels = () =>
|
||||
get<{ models: { path: string; name: string }[] }>('/model-manage/local-models')
|
||||
|
||||
/** 已训练模型列表 */
|
||||
export const getTrainedModels = () =>
|
||||
get<{ models: TrainedModel[] }>('/model-manage/trained-models')
|
||||
|
||||
/** 创建模型 */
|
||||
export const createModel = (data: ModelForm) => post('/model-manage', data)
|
||||
|
||||
/** 编辑模型 */
|
||||
export const updateModel = (id: string | number, data: ModelForm) =>
|
||||
put(`/model-manage/${id}`, data)
|
||||
|
||||
/** 删除模型 */
|
||||
export const deleteModel = (id: string | number) => del(`/model-manage/${id}`)
|
||||
|
||||
/** 删除已训练模型(合并权重) */
|
||||
export const deleteTrainedModel = (id: string | number, type: 'merged' | 'lora' = 'merged') =>
|
||||
del(`/model-manage/trained-models/${id}`, { type })
|
||||
|
||||
/** 更新模型用途 */
|
||||
export const updateModelPurpose = (id: string | number, purpose: string) =>
|
||||
put(`/model-manage/${id}/purpose`, { purpose })
|
||||
|
||||
/** 合并 LoRA 权重 */
|
||||
export const mergeModel = (data: {
|
||||
model_name: string
|
||||
train_method: string
|
||||
base_model_path: string
|
||||
}) => post('/model-manage/merge', data)
|
||||
|
||||
/** 导出已训练模型权重 */
|
||||
export const exportModelUrl = (modelName: string) =>
|
||||
`/api/model-manage/trained-models/${encodeURIComponent(modelName)}/export`
|
||||
12
frontend/src/api/modules/system.ts
Normal file
12
frontend/src/api/modules/system.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { get, post } from '../request'
|
||||
import type { SystemInfo, HealthMetrics } from '@/types'
|
||||
|
||||
/** 系统信息(CPU/内存/磁盘/GPU/网络/系统) */
|
||||
export const getSystemInfo = () => get<SystemInfo>('/system-info')
|
||||
|
||||
/** 健康指标(顶部栏轻量指标) */
|
||||
export const getHealth = () => get<HealthMetrics>('/health')
|
||||
|
||||
/** 登录 */
|
||||
export const login = (username: string, password: string) =>
|
||||
post('/login', { username, password })
|
||||
Reference in New Issue
Block a user