Files
xiaoxia-saas/apps/web/src/api/voices.ts
T
灵应 8935196fcd
Deploy / Staging E2E Tests (push) Has been skipped
Deploy / Build Production Runtime Images (push) Has been skipped
Deploy / Deploy Production (push) Has been skipped
Deploy / Production Browser E2E (push) Has been skipped
Deploy / Deploy Staging (push) Failing after 138h4m33s
CI/CD Pipeline / Frontend Lint (push) Failing after 138h4m39s
CI/CD Pipeline / Validate Code Quality And Tests (push) Failing after 138h4m39s
style: 后端代码black格式化
2026-07-03 18:49:54 +08:00

152 lines
4.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 配音相关 API
* Phase 1 新增:全局配音库
*
* 任务 3.11:新增统一音色 API(对接后端 3.04),保留旧接口向后兼容
*/
import apiClient from "./client";
/* ── 统一音色 API(后端 3.04) ─────────────────────────── */
/** 统一音色条目(preset + clone 混合) */
export interface UnifiedVoiceItem {
id: string;
type: "preset" | "clone";
name: string;
description: string;
gender: string;
language: string;
voice_id: string;
voice_provider: string;
audio_url: string | null;
preview_url: string | null;
duration: number | null;
file_size: number | null;
status: string;
tags: string[];
user_id: string | null;
project_id: string | null;
voice_clone_profile_id: string | null;
created_at: string | null;
updated_at: string | null;
}
/** 统一音色列表响应 */
export interface UnifiedVoiceListResponse {
items: UnifiedVoiceItem[];
total: number;
preset_count: number;
clone_count: number;
}
/** 预设音色条目 */
export interface PresetVoiceItem {
voice_id: string;
name: string;
description: string;
gender: string;
language: string;
preview_url: string | null;
tags: string[];
}
/** 预设音色列表响应 */
export interface PresetVoiceListResponse {
items: PresetVoiceItem[];
total: number;
}
/** 统一列表查询参数 */
export interface UnifiedVoiceListParams {
type?: "preset" | "clone";
status?: string;
skip?: number;
limit?: number;
}
/** 获取统一音色列表(推荐) */
export const fetchVoices = async (
params?: UnifiedVoiceListParams,
): Promise<UnifiedVoiceListResponse> => {
const searchParams = new URLSearchParams();
if (params?.type) searchParams.set("type", params.type);
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<UnifiedVoiceListResponse>(
`/voices${qs ? `?${qs}` : ""}`,
);
return response.data;
};
/** 获取预设音色列表(无需鉴权) */
export const fetchPresetVoices = async (): Promise<PresetVoiceListResponse> => {
const response =
await apiClient.get<PresetVoiceListResponse>("/voices/presets");
return response.data;
};
/* ── 向后兼容(旧接口) ────────────────────────────────── */
/** 配音条目(旧) */
export interface VoiceItem {
id: string;
name: string;
text: string;
voice_type?: string;
duration_seconds?: number;
storage_key?: string;
audio_url?: string;
status?: string;
is_favorite?: boolean;
created_at?: string;
updated_at?: string;
}
/** 创建配音请求(旧) */
export interface CreateVoiceRequest {
name: string;
text: string;
voice_type?: string;
}
/** 获取当前用户的所有配音(旧 → /voices/legacy */
export const getVoices = async (): Promise<VoiceItem[]> => {
const response = await apiClient.get("/voices/legacy");
return response.data.items || response.data || [];
};
/** 创建配音 */
export const createVoice = async (
data: CreateVoiceRequest,
): Promise<VoiceItem> => {
const response = await apiClient.post("/voices", data);
return response.data;
};
/** 更新配音 */
export const updateVoice = async (
voiceId: string,
data: Partial<CreateVoiceRequest>,
): Promise<VoiceItem> => {
const response = await apiClient.put(`/voices/${voiceId}`, data);
return response.data;
};
/** 删除配音 */
export const deleteVoice = async (voiceId: string): Promise<void> => {
await apiClient.delete(`/voices/${voiceId}`);
};
/** AI 生成配音 */
export const generateAIVoice = async (data: {
text: string;
voice_type?: string;
speed?: number;
}): Promise<VoiceItem> => {
const response = await apiClient.post("/voices/generate", data);
return response.data;
};