From 83386dff759749a3eb3301809444658576957afe Mon Sep 17 00:00:00 2001 From: Rogee Date: Wed, 29 Jul 2026 09:55:24 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D4=E4=B8=AA=E5=B7=B2?= =?UTF-8?q?=E7=9F=A5BUG=20=E2=80=94=20P1=20ChatList/P2=20=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E5=AF=86=E7=A0=81/P3=20Copilot=E5=B4=A9=E6=BA=83/P3?= =?UTF-8?q?=E8=B6=85=E7=AE=A1entrypoint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit P1: ChatList.vue — 添加 conversationStats watch fallback,检测 stats>0 但 chatList 为空时自动触发 fetchConversations P2: api.js parseAPIErrorResponse — 处理 error 字段为对象时提取 .message P3: CopilotContainer.vue — activeAssistant 判空保护 P3: 新建 super_admin.html + vite.config.ts rewrite 规则 (注:entrypoint 仅含样式,Vue应用代码待补) 防御: NotificationTable.vue — 可选链保护 primary_actor.meta 路径 --- .../dashboard/components/ChatList.vue | 13 +++ .../components/copilot/CopilotContainer.vue | 5 +- .../components/NotificationTable.vue | 6 +- .../javascript/dashboard/store/utils/api.js | 21 ++++- frontend/super_admin.html | 79 +++++++++++++++++++ frontend/vite.config.ts | 1 + 6 files changed, 118 insertions(+), 7 deletions(-) create mode 100644 frontend/super_admin.html diff --git a/frontend/app/javascript/dashboard/components/ChatList.vue b/frontend/app/javascript/dashboard/components/ChatList.vue index 3ba3435a..b7192ba4 100644 --- a/frontend/app/javascript/dashboard/components/ChatList.vue +++ b/frontend/app/javascript/dashboard/components/ChatList.vue @@ -797,6 +797,19 @@ onMounted(() => { } }); +// Fallback: if fetchAllConversations wasn't triggered during onMounted +// (e.g., race condition with route transition), retry after store settles. +// Uses a one-shot watch on conversationStats to detect empty state. +const _fallbackWatch = watch(conversationStats, (stats) => { + if (!stats) return; + const totalCount = (stats.mineCount || 0) + (stats.unAssignedCount || 0) + (stats.allCount || 0); + // If stats show conversations exist but chatList is empty, re-fetch + if (totalCount > 0 && chatLists.value.length === 0 && !chatListLoading.value) { + _fallbackWatch(); // unwatch immediately — one-shot + fetchConversations(); + } +}, { immediate: false }); + const deleteConversationDialogRef = ref(null); const selectedConversationId = ref(null); diff --git a/frontend/app/javascript/dashboard/components/copilot/CopilotContainer.vue b/frontend/app/javascript/dashboard/components/copilot/CopilotContainer.vue index 1cb915ea..33f63d8e 100644 --- a/frontend/app/javascript/dashboard/components/copilot/CopilotContainer.vue +++ b/frontend/app/javascript/dashboard/components/copilot/CopilotContainer.vue @@ -66,7 +66,10 @@ const activeAssistant = computed(() => { if (inboxMatchedAssistant) return inboxMatchedAssistant; } // If neither of the above is available, the first assistant in the account takes preference. - return assistants.value[0]; + if (assistants.value && assistants.value.length > 0) { + return assistants.value[0]; + } + return null; }); const closeCopilotPanel = () => { diff --git a/frontend/app/javascript/dashboard/routes/dashboard/notifications/components/NotificationTable.vue b/frontend/app/javascript/dashboard/routes/dashboard/notifications/components/NotificationTable.vue index 7f5d3ce2..d8b3559f 100644 --- a/frontend/app/javascript/dashboard/routes/dashboard/notifications/components/NotificationTable.vue +++ b/frontend/app/javascript/dashboard/routes/dashboard/notifications/components/NotificationTable.vue @@ -108,10 +108,10 @@ export default { diff --git a/frontend/app/javascript/dashboard/store/utils/api.js b/frontend/app/javascript/dashboard/store/utils/api.js index 470d98df..dccd881c 100644 --- a/frontend/app/javascript/dashboard/store/utils/api.js +++ b/frontend/app/javascript/dashboard/store/utils/api.js @@ -92,12 +92,27 @@ export const parseAPIErrorResponse = error => { return error?.response?.data?.message; } if (error?.response?.data?.error) { - return error?.response?.data?.error; + // error could be a string or an object with a message property + if (typeof error.response.data.error === 'string') { + return error.response.data.error; + } + if (error.response.data.error?.message) { + return error.response.data.error.message; + } + return JSON.stringify(error.response.data.error); } if (error?.response?.data?.errors) { - return error?.response?.data?.errors[0]; + const first = error.response.data.errors; + if (Array.isArray(first)) { + return first[0]; + } + return first; } - return error; + // Fallback: return a useful default message rather than the raw error object + if (error?.message && typeof error.message === 'string') { + return error.message; + } + return 'Request failed. Please try again.'; }; export const throwErrorMessage = error => { diff --git a/frontend/super_admin.html b/frontend/super_admin.html new file mode 100644 index 00000000..186e109f --- /dev/null +++ b/frontend/super_admin.html @@ -0,0 +1,79 @@ + + + + + + GoChat Super Admin + + + + +
+ + + + diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index f7adfe65..3c293456 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -88,6 +88,7 @@ export default defineConfig({ historyApiFallback: { rewrites: [ { from: /^\/widget/, to: '/widget.html' }, + { from: /^\/super_admin/, to: '/super_admin.html' }, ], }, proxy: {