1
This commit is contained in:
75
src/stores/avatar.js
Normal file
75
src/stores/avatar.js
Normal file
@@ -0,0 +1,75 @@
|
||||
import { defineStore, acceptHMRUpdate } from "pinia";
|
||||
import {
|
||||
listAvatars,
|
||||
insertAvatar,
|
||||
updateAvatarName,
|
||||
deleteAvatar,
|
||||
avatarNameExists,
|
||||
migrateLegacyAvatarsIfNeeded,
|
||||
} from "../services/avatarDb.js";
|
||||
|
||||
export const useAvatarStore = defineStore("avatar", {
|
||||
state: () => ({
|
||||
templates: [],
|
||||
loading: false,
|
||||
}),
|
||||
|
||||
getters: {
|
||||
selectOptions: (state) => [
|
||||
{ label: "请选择形象", value: null },
|
||||
...state.templates.map((t) => ({
|
||||
label: t.name,
|
||||
value: t.id,
|
||||
})),
|
||||
],
|
||||
},
|
||||
|
||||
actions: {
|
||||
async refresh() {
|
||||
this.loading = true;
|
||||
try {
|
||||
await migrateLegacyAvatarsIfNeeded();
|
||||
this.templates = await listAvatars();
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {{ name: string, filePath: string }} payload
|
||||
*/
|
||||
async addTemplate(payload) {
|
||||
const record = await insertAvatar(payload.name, payload.filePath);
|
||||
this.templates = await listAvatars();
|
||||
return record;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {number} id
|
||||
* @param {string} name
|
||||
*/
|
||||
async renameTemplate(id, name) {
|
||||
const exists = await avatarNameExists(name, id);
|
||||
if (exists) {
|
||||
return { ok: false, message: "名称重复" };
|
||||
}
|
||||
try {
|
||||
await updateAvatarName(id, name);
|
||||
this.templates = await listAvatars();
|
||||
return { ok: true };
|
||||
} catch (err) {
|
||||
const msg = err instanceof Error ? err.message : String(err);
|
||||
return { ok: false, message: msg || "重命名失败" };
|
||||
}
|
||||
},
|
||||
|
||||
async removeTemplate(item) {
|
||||
await deleteAvatar(item.id);
|
||||
this.templates = await listAvatars();
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (import.meta.hot) {
|
||||
import.meta.hot.accept(acceptHMRUpdate(useAvatarStore, import.meta.hot));
|
||||
}
|
||||
@@ -21,6 +21,8 @@ import {
|
||||
executeGenerateSpeech,
|
||||
selectAudioHistory,
|
||||
} from "../services/voiceGenerate.js";
|
||||
import { listGeneratedAudios } from "../services/audioDb.js";
|
||||
import { localAudioToPlayableUrl } from "../services/localAudio.js";
|
||||
|
||||
|
||||
|
||||
@@ -165,7 +167,7 @@ export const useWorkflowStore = defineStore("workflow", {
|
||||
|
||||
currentAudioId: null,
|
||||
|
||||
/** @type {Array<{ id: string, label: string, audioPath: string, audioSrc: string, createdAt: number }>} */
|
||||
/** @type {Array<{ id: number, name: string, filePath: string, createdAt: string, audioSrc?: string }>} */
|
||||
audioHistory: [],
|
||||
|
||||
|
||||
@@ -451,10 +453,27 @@ export const useWorkflowStore = defineStore("workflow", {
|
||||
|
||||
},
|
||||
|
||||
pickAudioHistory(audioId) {
|
||||
|
||||
selectAudioHistory(this, audioId);
|
||||
async refreshAudioHistory() {
|
||||
try {
|
||||
const rows = await listGeneratedAudios();
|
||||
this.audioHistory = await Promise.all(
|
||||
rows.map(async (row) => {
|
||||
let audioSrc = "";
|
||||
try {
|
||||
audioSrc = await localAudioToPlayableUrl(row.filePath);
|
||||
} catch {
|
||||
audioSrc = "";
|
||||
}
|
||||
return { ...row, audioSrc };
|
||||
}),
|
||||
);
|
||||
} catch {
|
||||
this.audioHistory = [];
|
||||
}
|
||||
},
|
||||
|
||||
async pickAudioHistory(audioId) {
|
||||
await selectAudioHistory(this, audioId);
|
||||
},
|
||||
|
||||
resetAll() {
|
||||
|
||||
Reference in New Issue
Block a user