dev 分支暂存

This commit is contained in:
2026-05-16 08:26:56 +08:00
parent 58c8caa570
commit eb4129176c
71 changed files with 8474 additions and 214 deletions
+10 -34
View File
@@ -1,52 +1,28 @@
import { create } from 'zustand';
import type { Message } from '@/types/chat';
interface Message {
id: string;
role: 'user' | 'assistant' | 'system';
content: string;
audioUrl?: string;
segments?: { index: number; text: string; audioUrl?: string }[];
timestamp: number;
isStreaming?: boolean; // 是否还在流式输出中
}
interface ChatState {
interface ChatStore {
messages: Message[];
isTyping: boolean;
currentMode: 'text' | 'voice_msg' | 'voice_assistant';
// Actions
addMessage: (msg: Message) => void;
updateLastAssistantMessage: (content: string) => void;
addMessage: (message: Message) => void;
setMessages: (messages: Message[]) => void;
setTyping: (typing: boolean) => void;
setMode: (mode: 'text' | 'voice_msg' | 'voice_assistant') => void;
clearMessages: () => void;
}
export const useChatStore = create<ChatState>((set) => ({
export const useChatStore = create<ChatStore>((set) => ({
messages: [],
isTyping: false,
currentMode: 'text',
addMessage: (msg) =>
addMessage: (message) =>
set((state) => ({
messages: [...state.messages, msg],
messages: [...state.messages, message],
})),
updateLastAssistantMessage: (content) =>
set((state) => {
const messages = [...state.messages];
const lastIdx = messages.length - 1;
if (lastIdx >= 0 && messages[lastIdx].role === 'assistant') {
messages[lastIdx] = {
...messages[lastIdx],
content: messages[lastIdx].content + content,
};
}
return { messages };
}),
setMessages: (messages) => set({ messages }),
setTyping: (typing) => set({ isTyping: typing }),
setMode: (mode) => set({ currentMode: mode }),
clearMessages: () => set({ messages: [] }),
clearMessages: () => set({ messages: [], isTyping: false }),
}));
+54
View File
@@ -0,0 +1,54 @@
import { create } from 'zustand';
import type { CyreneForm, Mood } from '@/types/persona';
import { DEFAULT_PERSONA_STATE, MOOD_EMOJI } from '@/types/persona';
interface PersonaStore {
currentForm: CyreneForm;
mood: Mood;
affectionScore: number;
affectionLevel: number;
setForm: (form: CyreneForm) => void;
setMood: (mood: Mood) => void;
addAffectionScore: (score: number) => void;
resetPersona: () => void;
}
export const usePersonaStore = create<PersonaStore>((set) => ({
currentForm: DEFAULT_PERSONA_STATE.currentForm,
mood: DEFAULT_PERSONA_STATE.mood,
affectionScore: DEFAULT_PERSONA_STATE.affectionScore,
affectionLevel: DEFAULT_PERSONA_STATE.affectionLevel,
setForm: (form) => set({ currentForm: form }),
setMood: (mood) => set({ mood }),
addAffectionScore: (score) =>
set((state) => {
const newScore = state.affectionScore + score;
// 根据分数计算等级
let newLevel = 1;
for (const level of DEFAULT_PERSONA_STATE.affectionLevels) {
if (newScore >= level.threshold) {
newLevel = level.level;
}
}
return {
affectionScore: newScore,
affectionLevel: newLevel,
};
}),
resetPersona: () =>
set({
currentForm: DEFAULT_PERSONA_STATE.currentForm,
mood: DEFAULT_PERSONA_STATE.mood,
affectionScore: DEFAULT_PERSONA_STATE.affectionScore,
affectionLevel: DEFAULT_PERSONA_STATE.affectionLevel,
}),
}));
/** 获取心情对应的 Emoji */
export function getMoodEmoji(mood: Mood): string {
return MOOD_EMOJI[mood] || '🌸';
}
+31
View File
@@ -0,0 +1,31 @@
import { create } from 'zustand';
import type { Session } from '@/types/session';
interface SessionStore {
sessions: Session[];
currentSessionId: string | null;
loading: boolean;
setSessions: (sessions: Session[]) => void;
addSession: (session: Session) => void;
removeSession: (id: string) => void;
setCurrentSessionId: (id: string | null) => void;
setLoading: (loading: boolean) => void;
}
export const useSessionStore = create<SessionStore>((set) => ({
sessions: [],
currentSessionId: null,
loading: false,
setSessions: (sessions) => set({ sessions }),
addSession: (session) =>
set((state) => ({ sessions: [session, ...state.sessions] })),
removeSession: (id) =>
set((state) => ({
sessions: state.sessions.filter((s) => s.id !== id),
currentSessionId: state.currentSessionId === id ? null : state.currentSessionId,
})),
setCurrentSessionId: (id) => set({ currentSessionId: id }),
setLoading: (loading) => set({ loading }),
}));