Files
xiaoxia-saas/apps/web/src/api/tts.ts
T
灵应 d1c83de698
CI/CD Pipeline / Deploy Staging (push) Has been skipped
CI/CD Pipeline / Staging E2E Tests (push) Has been skipped
CI/CD Pipeline / Build Production Runtime Images (push) Has been skipped
CI/CD Pipeline / Deploy Production (push) Has been skipped
CI/CD Pipeline / Production Browser E2E (push) Has been skipped
CI/CD Pipeline / Frontend Lint (push) Failing after 47h32m26s
CI/CD Pipeline / Validate Code Quality And Tests (push) Failing after 47h32m26s
feat: TTS 生成页加存为素材功能
- 合成完成后显示「存为素材」按钮,点击弹出保存弹窗
- 弹窗支持改名称、选标签(预设标签 + 自定义新增)
- 保存成功后提示「去素材库查看」可跳转配音素材库
- 新增 saveTtsToLibrary API 对接后端 POST /tts/jobs/{id}/save-to-library
2026-07-07 13:21:39 +08:00

143 lines
3.7 KiB
TypeScript

/**
* TTS 语音合成 API
* 对接后端 /api/v1/tts/* 端点
*
* 任务 3.14 新增
*/
import apiClient from "./client";
/* ── 类型定义 ──────────────────────────────────── */
/** TTS 合成请求参数 */
export interface TTSSynthesizeRequest {
text: string;
voice_id?: string;
output_name?: string;
language?: string;
speed?: number;
voice_model?: string;
voice_clone_profile_id?: string;
format?: string;
metadata?: Record<string, unknown>;
}
/** TTS 合成创建响应 */
export interface TTSSynthesizeResponse {
job_id: string;
status: string;
message: string;
}
/** TTS 任务详情 */
export interface TTSJob {
id: string;
user_id: string;
project_id: string | null;
text: string;
voice_id: string | null;
voice_model: string | null;
voice_clone_profile_id: string | null;
language: string;
speed: number;
output_name: string | null;
output_audio_url: string | null;
output_format: string;
duration_seconds: number | null;
file_size_bytes: number | null;
sample_rate: number | null;
status: string;
error_message: string | null;
retry_count: number;
max_retries: number;
metadata_: Record<string, unknown> | null;
created_at: string;
updated_at: string;
}
/** TTS 任务状态(轻量轮询用) */
export interface TTSJobStatus {
id: string;
status: string;
output_audio_url: string | null;
error_message: string | null;
duration_seconds: number | null;
retry_count: number;
}
/** TTS 任务列表响应 */
export interface TTSJobListResponse {
items: TTSJob[];
total: number;
skip: number;
limit: number;
}
/** TTS 任务列表查询参数 */
export interface TTSJobListParams {
status?: string;
skip?: number;
limit?: number;
}
/* ── API 函数 ──────────────────────────────────── */
/** 创建 TTS 合成任务 */
export const synthesizeSpeech = async (
data: TTSSynthesizeRequest,
): Promise<TTSSynthesizeResponse> => {
const response = await apiClient.post<TTSSynthesizeResponse>(
"/tts/synthesize",
data,
);
return response.data;
};
/** 获取 TTS 任务详情 */
export const getTTSJob = async (jobId: string): Promise<TTSJob> => {
const response = await apiClient.get<TTSJob>(`/tts/jobs/${jobId}`);
return response.data;
};
/** 获取 TTS 任务状态(轻量轮询) */
export const getTTSJobStatus = async (jobId: string): Promise<TTSJobStatus> => {
const response = await apiClient.get<TTSJobStatus>(
`/tts/jobs/${jobId}/status`,
);
return response.data;
};
/** 获取 TTS 任务列表 */
export const getTTSJobs = async (
params?: TTSJobListParams,
): Promise<TTSJobListResponse> => {
const searchParams = new URLSearchParams();
if (params?.status) searchParams.set("status", params.status);
if (params?.skip !== undefined) searchParams.set("skip", String(params.skip));
if (params?.limit !== undefined)
searchParams.set("limit", String(params.limit));
const qs = searchParams.toString();
const response = await apiClient.get<TTSJobListResponse>(
`/tts/jobs${qs ? `?${qs}` : ""}`,
);
return response.data;
};
/** 存为素材请求参数 */
export interface SaveTtsToLibraryRequest {
name?: string;
tag_ids?: string[];
}
/** 将 TTS 合成结果保存到配音素材库 */
export const saveTtsToLibrary = async (
jobId: string,
data?: SaveTtsToLibraryRequest,
): Promise<void> => {
await apiClient.post(`/tts/jobs/${jobId}/save-to-library`, data ?? {});
};
/** 删除 TTS 任务 */
export const deleteTTSJob = async (jobId: string): Promise<void> => {
await apiClient.delete(`/tts/jobs/${jobId}`);
};