This commit is contained in:
fengchuanhn@gmail.com
2026-05-18 10:09:55 +08:00
parent fb1c3c55d6
commit beb5eaeb42
7 changed files with 605 additions and 1 deletions

View File

@@ -0,0 +1,103 @@
/** 克隆音色本地存储(对齐 Electron be.list/add/update/delete SoundPrompt */
import { findSystemVoice } from "../data/systemVoices.js";
const STORAGE_KEY = "aiclient_sound_prompts";
/**
* @typedef {{ id: string, title: string, content: { url?: string, promptText?: string, aliyunVoiceId?: string } }} SoundPromptRecord
*/
/** @returns {SoundPromptRecord[]} */
export function listCloneVoices() {
try {
const raw = localStorage.getItem(STORAGE_KEY);
if (!raw) return [];
const data = JSON.parse(raw);
return Array.isArray(data) ? data : [];
} catch {
return [];
}
}
/** @param {SoundPromptRecord[]} list */
function saveCloneVoices(list) {
localStorage.setItem(STORAGE_KEY, JSON.stringify(list));
}
/**
* @param {{ title: string, content?: SoundPromptRecord['content'] }} payload
* @returns {SoundPromptRecord}
*/
export function addCloneVoice(payload) {
const list = listCloneVoices();
const record = {
id: `clone_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
title: String(payload.title || "").trim(),
content: {
url: payload.content?.url || "",
promptText: payload.content?.promptText || "",
aliyunVoiceId: payload.content?.aliyunVoiceId || "",
},
};
list.unshift(record);
saveCloneVoices(list);
return record;
}
/**
* @param {string} id
* @param {{ title: string, content?: SoundPromptRecord['content'] }} payload
*/
export function updateCloneVoice(id, payload) {
const list = listCloneVoices();
const idx = list.findIndex((item) => item.id === id);
if (idx < 0) return null;
list[idx] = {
...list[idx],
title: String(payload.title || "").trim(),
content: {
...list[idx].content,
...payload.content,
},
};
saveCloneVoices(list);
return list[idx];
}
/** @param {string} id */
export function deleteCloneVoice(id) {
const list = listCloneVoices().filter((item) => item.id !== id);
saveCloneVoices(list);
}
/** @param {string} id */
export function getCloneVoice(id) {
return listCloneVoices().find((item) => item.id === id) ?? null;
}
/** @param {string} title */
export function cloneVoiceTitleExists(title, excludeId = null) {
const t = String(title || "").trim();
return listCloneVoices().some(
(item) => item.title === t && item.id !== excludeId,
);
}
/**
* 解析选中音色对应的阿里云 voiceId
* @param {string} selectedVoiceId
* @param {SoundPromptRecord[]} [clones]
*/
export function resolveAliyunVoiceId(selectedVoiceId, clones = listCloneVoices()) {
if (!selectedVoiceId) return "Cherry";
if (selectedVoiceId.startsWith("sys_")) {
return findSystemVoiceFromId(selectedVoiceId);
}
const clone = clones.find((c) => c.id === selectedVoiceId);
return String(clone?.content?.aliyunVoiceId || "").trim() || "Cherry";
}
function findSystemVoiceFromId(id) {
return findSystemVoice(id)?.aliyunVoiceId || "Cherry";
}