feat: 添加全局人设与头像设置并优化对话及弹窗交互
This commit is contained in:
@@ -10,6 +10,7 @@ import {
|
||||
} from '@/services/chatService'
|
||||
import type { ChatMessage, Conversation } from '@/contracts'
|
||||
import type { SseClient } from '@/services/sseClient'
|
||||
import { useChatPreferences } from './chatPreferences'
|
||||
|
||||
vi.mock('@/services/chatService', () => ({
|
||||
createConversation: vi.fn(),
|
||||
@@ -63,6 +64,17 @@ it('sends persistent message ids and restores messages from the backend', async
|
||||
expect(store.messages[1]?.citations?.[0]?.heading_path).toBe('Heading')
|
||||
})
|
||||
|
||||
it('leaves global persona assembly to the backend', async () => {
|
||||
useChatPreferences().settings = {persona:'stale browser persona',presetDialogue:'old example',aiAvatar:'',userAvatar:''}
|
||||
const store = useChatStore()
|
||||
store.selectedProviderId = 'real'
|
||||
store.selectedModel = 'configured-model'
|
||||
await store.sendMessage('hello')
|
||||
const request = vi.mocked(streamChat).mock.calls[0]![0]
|
||||
expect(request).not.toHaveProperty('system')
|
||||
expect(request).not.toHaveProperty('aiAvatar')
|
||||
})
|
||||
|
||||
it('loads the newest persisted conversation on initialization', async () => {
|
||||
const conversation: Conversation = {
|
||||
conversation_id: 'persisted', title: 'Saved', created_at: '2026-01-01T00:00:00Z',
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
|
||||
export interface ChatPreferences { persona: string; presetDialogue: string; aiAvatar: string; userAvatar: string }
|
||||
const storageKey = 'chat-persona-preferences-v1'
|
||||
const empty = (): ChatPreferences => ({ persona: '', presetDialogue: '', aiAvatar: '', userAvatar: '' })
|
||||
export function validAvatar(value: unknown): value is string {
|
||||
return typeof value === 'string' && (value === '' || (value.length <= 710000 && /^data:image\/(png|jpeg|webp);base64,[A-Za-z0-9+/=]+$/.test(value)))
|
||||
}
|
||||
function validate(value: ChatPreferences) {
|
||||
if (typeof value.persona !== 'string' || typeof value.presetDialogue !== 'string' || value.persona.length > 16000 || value.presetDialogue.length > 32000 || !validAvatar(value.aiAvatar) || !validAvatar(value.userAvatar)) throw new Error('人设、预设对话或头像格式无效 / Invalid chat preferences')
|
||||
return {persona:value.persona, presetDialogue:value.presetDialogue, aiAvatar:value.aiAvatar, userAvatar:value.userAvatar}
|
||||
}
|
||||
export const useChatPreferences = defineStore('chatPreferences', () => {
|
||||
const settings = ref<ChatPreferences>(empty())
|
||||
try { const stored = localStorage.getItem(storageKey); if (stored) settings.value = validate(JSON.parse(stored)) } catch { /* Invalid or unavailable local settings use defaults. */ }
|
||||
function save(value: ChatPreferences) {
|
||||
const next = validate(value)
|
||||
localStorage.setItem(storageKey, JSON.stringify(next))
|
||||
settings.value = next
|
||||
}
|
||||
return { settings, save }
|
||||
})
|
||||
Reference in New Issue
Block a user