From d02ee7be8b53e0c2ac7fee4a2c98fe20bcaabe57 Mon Sep 17 00:00:00 2001 From: Li-shi-ling <114913764+Li-shi-ling@users.noreply.github.com> Date: Sat, 21 Feb 2026 23:50:13 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=96=B0=E5=BB=BA?= =?UTF-8?q?=E5=AF=B9=E8=AF=9D=E6=97=B6=E5=9B=A0=E7=BC=BA=E5=B0=91=E4=BC=9A?= =?UTF-8?q?=E8=AF=9DID=E5=AF=BC=E8=87=B4=E9=85=8D=E7=BD=AE=E7=BB=91?= =?UTF-8?q?=E5=AE=9A=E5=A4=B1=E8=B4=A5=E7=9A=84=E9=97=AE=E9=A2=98=20(#5292?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix:尝试修改 * fix:添加详细日志 * fix:进行详细修改,并添加日志 * fix:删除所有日志 * fix: 增加安全访问函数 - 给 localStorage 访问加了 try/catch + 可用性判断:dashboard/src/utils/chatConfigBinding.ts:13 - 新增 getFromLocalStorage/setToLocalStorage(在受限存储/无痕模式下异常时回退/忽略) - getStoredDashboardUsername() / getStoredSelectedChatConfigId() 改为走安全读取:dashboard/src/utils/chatConfigBinding.ts:36 - 新增 setStoredSelectedChatConfigId(),写入失败静默忽略:dashboard/src/utils/chatConfigBinding.ts:44 - 把 ConfigSelector.vue 里直接 localStorage.getItem/setItem 全部替换为上述安全方法:dashboard/src/components/chat/ConfigSelector.vue:81 - 已重新跑过 pnpm run typecheck,通过。 * rm:删除个人用的文档文件 * Revert "rm:删除个人用的文档文件" This reverts commit 0fceee05434cfbcb11e45bb967a77d5fa93196bf. * rm:删除个人用的文档文件 * rm:删除个人用的文档文件 --- .../src/components/chat/ConfigSelector.vue | 17 +++--- .../src/components/chat/StandaloneChat.vue | 24 ++++++++ dashboard/src/composables/useSessions.ts | 16 +++++ dashboard/src/utils/chatConfigBinding.ts | 60 +++++++++++++++++++ 4 files changed, 110 insertions(+), 7 deletions(-) create mode 100644 dashboard/src/utils/chatConfigBinding.ts diff --git a/dashboard/src/components/chat/ConfigSelector.vue b/dashboard/src/components/chat/ConfigSelector.vue index d77e91072..d53e3ed77 100644 --- a/dashboard/src/components/chat/ConfigSelector.vue +++ b/dashboard/src/components/chat/ConfigSelector.vue @@ -77,6 +77,11 @@ import { computed, onMounted, ref, watch } from 'vue'; import axios from 'axios'; import { useToast } from '@/utils/toast'; import { useModuleI18n } from '@/i18n/composables'; +import { + getStoredDashboardUsername, + getStoredSelectedChatConfigId, + setStoredSelectedChatConfigId +} from '@/utils/chatConfigBinding'; interface ConfigInfo { id: string; @@ -88,8 +93,6 @@ interface ConfigChangedPayload { agentRunnerType: string; } -const STORAGE_KEY = 'chat.selectedConfigId'; - const props = withDefaults(defineProps<{ sessionId?: string | null; platformId?: string; @@ -128,7 +131,7 @@ const hasActiveSession = computed(() => !!normalizedSessionId.value); const messageType = computed(() => (props.isGroup ? 'GroupMessage' : 'FriendMessage')); -const username = computed(() => localStorage.getItem('user') || 'guest'); +const username = computed(() => getStoredDashboardUsername()); const sessionKey = computed(() => { if (!normalizedSessionId.value) { @@ -265,10 +268,10 @@ async function confirmSelection() { } const previousId = selectedConfigId.value; await setSelection(tempSelectedConfig.value); - localStorage.setItem(STORAGE_KEY, tempSelectedConfig.value); + setStoredSelectedChatConfigId(tempSelectedConfig.value); const applied = await applySelectionToBackend(tempSelectedConfig.value); if (!applied) { - localStorage.setItem(STORAGE_KEY, previousId); + setStoredSelectedChatConfigId(previousId); await setSelection(previousId); } dialog.value = false; @@ -287,7 +290,7 @@ async function syncSelectionForSession() { await fetchRoutingEntries(); const resolved = resolveConfigId(targetUmo.value); await setSelection(resolved); - localStorage.setItem(STORAGE_KEY, resolved); + setStoredSelectedChatConfigId(resolved); } watch( @@ -299,7 +302,7 @@ watch( onMounted(async () => { await fetchConfigList(); - const stored = props.initialConfigId || localStorage.getItem(STORAGE_KEY) || 'default'; + const stored = props.initialConfigId || getStoredSelectedChatConfigId(); selectedConfigId.value = stored; await setSelection(stored); await syncSelectionForSession(); diff --git a/dashboard/src/components/chat/StandaloneChat.vue b/dashboard/src/components/chat/StandaloneChat.vue index 25ca7faf9..db762dabf 100644 --- a/dashboard/src/components/chat/StandaloneChat.vue +++ b/dashboard/src/components/chat/StandaloneChat.vue @@ -70,6 +70,7 @@ import { useMessages } from '@/composables/useMessages'; import { useMediaHandling } from '@/composables/useMediaHandling'; import { useRecording } from '@/composables/useRecording'; import { useToast } from '@/utils/toast'; +import { buildWebchatUmoDetails } from '@/utils/chatConfigBinding'; interface Props { configId?: string | null; @@ -82,6 +83,7 @@ const props = withDefaults(defineProps(), { const { t } = useI18n(); const { error: showError } = useToast(); + // UI 状态 const imagePreviewDialog = ref(false); const previewImageUrl = ref(''); @@ -90,11 +92,33 @@ const previewImageUrl = ref(''); const currSessionId = ref(''); const getCurrentSession = computed(() => null); // 独立测试模式不需要会话信息 +async function bindConfigToSession(sessionId: string) { + const confId = (props.configId || '').trim(); + if (!confId || confId === 'default') { + return; + } + + const umoDetails = buildWebchatUmoDetails(sessionId, false); + + await axios.post('/api/config/umo_abconf_route/update', { + umo: umoDetails.umo, + conf_id: confId + }); +} + async function newSession() { try { const response = await axios.get('/api/chat/new_session'); const sessionId = response.data.data.session_id; + + try { + await bindConfigToSession(sessionId); + } catch (err) { + console.error('Failed to bind config to session', err); + } + currSessionId.value = sessionId; + return sessionId; } catch (err) { console.error(err); diff --git a/dashboard/src/composables/useSessions.ts b/dashboard/src/composables/useSessions.ts index 1cbe6284d..decde8d9e 100644 --- a/dashboard/src/composables/useSessions.ts +++ b/dashboard/src/composables/useSessions.ts @@ -1,6 +1,7 @@ import { ref, computed } from 'vue'; import axios from 'axios'; import { useRouter } from 'vue-router'; +import { buildWebchatUmoDetails, getStoredSelectedChatConfigId } from '@/utils/chatConfigBinding'; export interface Session { session_id: string; @@ -62,10 +63,25 @@ export function useSessions(chatboxMode: boolean = false) { async function newSession() { try { + const selectedConfigId = getStoredSelectedChatConfigId(); const response = await axios.get('/api/chat/new_session'); const sessionId = response.data.data.session_id; + const platformId = response.data.data.platform_id; + currSessionId.value = sessionId; + if (selectedConfigId && selectedConfigId !== 'default' && platformId === 'webchat') { + try { + const umoDetails = buildWebchatUmoDetails(sessionId, false); + await axios.post('/api/config/umo_abconf_route/update', { + umo: umoDetails.umo, + conf_id: selectedConfigId + }); + } catch (err) { + console.error('Failed to bind config to session', err); + } + } + // 更新 URL const basePath = chatboxMode ? '/chatbox' : '/chat'; router.push(`${basePath}/${sessionId}`); diff --git a/dashboard/src/utils/chatConfigBinding.ts b/dashboard/src/utils/chatConfigBinding.ts new file mode 100644 index 000000000..192f25d9c --- /dev/null +++ b/dashboard/src/utils/chatConfigBinding.ts @@ -0,0 +1,60 @@ +export const CHAT_SELECTED_CONFIG_STORAGE_KEY = 'chat.selectedConfigId'; + +export type ChatMessageType = 'FriendMessage' | 'GroupMessage'; + +export interface WebchatUmoDetails { + platformId: string; + messageType: ChatMessageType; + username: string; + sessionKey: string; + umo: string; +} + +function getFromLocalStorage(key: string, fallback: string): string { + try { + if (typeof localStorage === 'undefined') { + return fallback; + } + const value = localStorage.getItem(key); + return value == null ? fallback : value; + } catch { + return fallback; + } +} + +function setToLocalStorage(key: string, value: string): void { + try { + if (typeof localStorage === 'undefined') { + return; + } + localStorage.setItem(key, value); + } catch { + // Ignore storage errors (e.g. private mode / restricted storage). + } +} + +export function getStoredDashboardUsername(): string { + return getFromLocalStorage('user', '').trim() || 'guest'; +} + +export function getStoredSelectedChatConfigId(): string { + return getFromLocalStorage(CHAT_SELECTED_CONFIG_STORAGE_KEY, '').trim() || 'default'; +} + +export function setStoredSelectedChatConfigId(configId: string): void { + setToLocalStorage(CHAT_SELECTED_CONFIG_STORAGE_KEY, configId); +} + +export function buildWebchatUmoDetails(sessionId: string, isGroup = false): WebchatUmoDetails { + const platformId = 'webchat'; + const username = getStoredDashboardUsername(); + const messageType: ChatMessageType = isGroup ? 'GroupMessage' : 'FriendMessage'; + const sessionKey = `${platformId}!${username}!${sessionId}`; + return { + platformId, + messageType, + username, + sessionKey, + umo: `${platformId}:${messageType}:${sessionKey}` + }; +}