feat: upload local music directories

This commit is contained in:
2026-07-21 19:25:20 +08:00
parent b21a5d0ed1
commit 59cf2ea67c
15 changed files with 1024 additions and 29 deletions
+17
View File
@@ -1,4 +1,5 @@
import request from './request';
import type { AxiosRequestConfig } from 'axios';
export interface IngestResponse {
taskId: string;
@@ -59,3 +60,19 @@ export function getIngestCurrentStatus(): Promise<IngestStatusResponse> {
export function getIngestStatus(taskId: string): Promise<IngestStatusResponse> {
return request.get(`/api/ingest/status/${taskId}`);
}
export interface UploadFileResponse {
status: 'uploaded' | 'skipped';
relativePath: string;
size: number;
}
/**
* 上传文件到输入目录
*/
export function uploadFile(file: File, relativePath: string, config?: AxiosRequestConfig): Promise<UploadFileResponse> {
const formData = new FormData();
formData.append('file', file);
formData.append('relativePath', relativePath);
return request.post('/api/ingest/upload', formData, config);
}
+11 -5
View File
@@ -1,12 +1,18 @@
import axios from 'axios';
import { ElMessage } from 'element-plus';
export class BusinessError extends Error {
code: number;
constructor(message: string, code: number) {
super(message);
this.code = code;
this.name = 'BusinessError';
}
}
const request = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL ?? 'http://localhost:8080',
timeout: 30000,
headers: {
'Content-Type': 'application/json'
}
timeout: 30000
});
// 响应拦截器:统一处理 Result<T> 格式
@@ -21,7 +27,7 @@ request.interceptors.response.use(
} else {
// 失败,显示错误信息并 reject
ElMessage.error(result.message || '请求失败');
return Promise.reject(new Error(result.message || '请求失败'));
return Promise.reject(new BusinessError(result.message || '请求失败', result.code));
}
}
// 如果不是 Result 格式,直接返回