fix: 修复新建对话时因缺少会话ID导致配置绑定失败的问题 (#5292)
* 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 0fceee0543.
* rm:删除个人用的文档文件
* rm:删除个人用的文档文件
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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<Props>(), {
|
||||
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);
|
||||
|
||||
@@ -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}`);
|
||||
|
||||
@@ -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}`
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user