From af21c31e6179c2091e8a880afcf0dc20b6f043a3 Mon Sep 17 00:00:00 2001 From: zhangyahui Date: Mon, 3 Nov 2025 13:24:42 +0800 Subject: [PATCH 1/4] =?UTF-8?q?style:=20=E9=A1=B6=E9=83=A8=E5=AF=BC?= =?UTF-8?q?=E8=88=AA=E6=A0=8F=E8=AE=BE=E7=BD=AE=E5=9B=BE=E6=A0=87=E9=A2=9C?= =?UTF-8?q?=E8=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/HeaderTitle.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/HeaderTitle.vue b/src/components/HeaderTitle.vue index 9af224f..6d44400 100644 --- a/src/components/HeaderTitle.vue +++ b/src/components/HeaderTitle.vue @@ -67,6 +67,7 @@ position: absolute; right: 3.2rem; display: inline-block; + color: var(--header-title-color, #000); } } From 5acd523d1b27476fb1e83883f903b045463402ba Mon Sep 17 00:00:00 2001 From: zhangyahui Date: Mon, 3 Nov 2025 15:46:16 +0800 Subject: [PATCH 2/4] =?UTF-8?q?bugfix:=20=20=E5=A4=84=E7=90=86=E6=B5=81?= =?UTF-8?q?=E5=BC=8F=E6=8E=A5=E5=8F=A3token=E8=BF=87=E6=9C=9F=E6=97=B6?= =?UTF-8?q?=E7=9A=84=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/asistant/index.vue | 47 ++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/src/views/asistant/index.vue b/src/views/asistant/index.vue index 50bbd83..1f3f9c1 100644 --- a/src/views/asistant/index.vue +++ b/src/views/asistant/index.vue @@ -84,7 +84,7 @@ const handleSendMessage = (message: string): void => { type: 'text', content: message, timestamp: new Date().toISOString(), - sessionId: (userInfoStore.state.userInfo as any).id, + sessionId: Math.floor(Date.now() / 1000).toString(), self: true } messageList.value.push(userMessage) @@ -95,9 +95,11 @@ const handleSendMessage = (message: string): void => { const abort = new AbortController() const handleFetchMessage = (message: string) => { + const sessionId = Math.floor(Date.now() / 1000).toString() + const params = { message: message, - sessionId: (userInfoStore.state.userInfo as any).id, + sessionId: sessionId, gender: 'male' } @@ -107,7 +109,7 @@ const handleFetchMessage = (message: string) => { type: 'text', content: '', timestamp: new Date().toISOString(), - sessionId: (userInfoStore.state.userInfo as any).id + sessionId: sessionId } // 添加到消息列表 @@ -136,16 +138,51 @@ const handleFetchMessage = (message: string) => { credentials: 'include' }) .then(async (response) => { - console.log('response',response) + // 检查响应内容类型,判断是否为流式响应 + const contentType = response.headers.get('content-type') || '' + const isStreamResponse = contentType.includes('text/event-stream') || contentType.includes('stream') + if (!response.ok) { + // 非流式错误响应,使用 text() 读取错误信息 + const errorText = await response.text() + console.error('请求错误:', errorText) showToast({ message: `failed to fetch: ${response.status}`, position: 'top', icon: 'none' }) - throw new Error(`发起对话错误--- ${response.status}`) + throw new Error(`发起对话错误--- ${response.status}: ${errorText}`) } + // 不是流式响应,使用 text()读取错误信息 + if (!isStreamResponse) { + const text = await response.text() + + try { + const errorData = JSON.parse(text) + if (errorData.message || errorData.error) { + showToast({ + message: errorData.message || errorData.error || '请求失败', + position: 'top', + icon: 'none' + }) + } + } catch (e) { + // 如果不是 JSON,直接显示文本内容 + showToast({ + message: text || '请求失败', + position: 'top', + icon: 'none' + }) + throw new Error(text || '请求失败') + } + + isStreaming.value = false + currentStreamingMessage.value = null + return + } + + // 流式响应处理 let contentBody = '' let buffer = '' const reader = response.body?.getReader() From fcacab93bfe0a98847d1c4871f52cce602e41654 Mon Sep 17 00:00:00 2001 From: zhangyahui Date: Mon, 3 Nov 2025 15:52:20 +0800 Subject: [PATCH 3/4] =?UTF-8?q?feat:=20=E5=AF=B9=E8=AF=9DsessionId?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/stores/modules/generate.ts | 39 +++++++++++++++++++--------------- src/views/asistant/index.vue | 23 ++++++++++++-------- 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/src/stores/modules/generate.ts b/src/stores/modules/generate.ts index 3cac53c..53ddc1c 100644 --- a/src/stores/modules/generate.ts +++ b/src/stores/modules/generate.ts @@ -1,7 +1,7 @@ // 每一个存储的模块,命名规则use开头,store结尾 import { defineStore } from 'pinia' import MyEvent from '@/utils/myEvent' -MyEvent.add('clear-generate-state', () => useGenerateStore().clearGenerateData()) +MyEvent.add('clear-generate-state', () => useGenerateStore().clearGenerateData()) export const useGenerateStore = defineStore({ id: 'generate', // 必须指明唯一的pinia仓库的id @@ -11,7 +11,7 @@ export const useGenerateStore = defineStore({ id: '', oldId: '' //表示从生成页面返回回来,需要调整的样式id }, - styleList: [{},{},{},{}], + styleList: [{}, {}, {}, {}], model: { id: '' }, @@ -32,9 +32,9 @@ export const useGenerateStore = defineStore({ /** AI魔改信息 */ customizeInfo: { inputText: '', - count: 0, - oldInputText: '', - oldTryOnId: '', + count: 0, + oldInputText: '', + oldTryOnId: '', tryOnId: '', tryOnUrl: '', @@ -45,7 +45,8 @@ export const useGenerateStore = defineStore({ customerInfo: { customerId: '', visitRecordId: '' - } + }, + sessionId: '' //会话id 秒级时间戳 } }, getters: { @@ -87,7 +88,7 @@ export const useGenerateStore = defineStore({ this.isGenerate = isGenerate }, clearProductData() { - this.styleList = [{},{},{},{}] + this.styleList = [{}, {}, {}, {}] this.style = { id: '', oldId: '' @@ -111,8 +112,8 @@ export const useGenerateStore = defineStore({ /** 清空 AI魔改信息 */ clearCustomizeInfo() { this.customizeInfo.inputText = '' - this.customizeInfo.count = 0 - this.customizeInfo.oldInputText = '' + this.customizeInfo.count = 0 + this.customizeInfo.oldInputText = '' this.customizeInfo.oldTryOnId = '' this.customizeInfo.tryOnId = '' this.customizeInfo.tryOnUrl = '' @@ -120,12 +121,12 @@ export const useGenerateStore = defineStore({ this.customizeInfo.isRegenerated = '' this.customizeInfo.isFavorite = false }, - uploadCustomizeInfo(data: object){ - for (const key in data) { - this.customizeInfo[key] = data[key] - } - }, - clearCustomerInfo(){ + uploadCustomizeInfo(data: object) { + for (const key in data) { + this.customizeInfo[key] = data[key] + } + }, + clearCustomerInfo() { this.customerInfo = { customerId: '', visitRecordId: '' @@ -137,9 +138,13 @@ export const useGenerateStore = defineStore({ this.updatePhotoInfo({}) this.clearCustomizeInfo() this.clearCustomerInfo() + this.setSessionId('') }, setCustomerInfo(data: any) { this.customerInfo = data - } + }, + setSessionId(data: string) { + this.sessionId = data + }, } -}) \ No newline at end of file +}) diff --git a/src/views/asistant/index.vue b/src/views/asistant/index.vue index 1f3f9c1..1852cb3 100644 --- a/src/views/asistant/index.vue +++ b/src/views/asistant/index.vue @@ -29,7 +29,7 @@ import HeaderTitle from '@/components/HeaderTitle.vue' import NoticeList from './components/NoticeList.vue' import InputArea from './components/InputArea.vue' import GenerateLoading from './components/GenerateLoading.vue' -import { ref, onUnmounted, onActivated } from 'vue' +import { ref, onMounted, onUnmounted, onActivated } from 'vue' import { useRouter } from 'vue-router' import { useUserInfoStore, useGenerateStore } from '@/stores' import { streamChatAddress } from '@/api/workshop' @@ -66,6 +66,12 @@ const messageList = ref([]) // 流式消息相关状态 const isStreaming = ref(false) const currentStreamingMessage = ref(null) +const sessionId = ref('') + +onMounted(() => { + sessionId.value = Math.floor(Date.now() / 1000).toString() + generateStore.setSessionId(sessionId.value) +}) onActivated(() => { noticeListRef.value?.scrollToBottom() @@ -84,7 +90,7 @@ const handleSendMessage = (message: string): void => { type: 'text', content: message, timestamp: new Date().toISOString(), - sessionId: Math.floor(Date.now() / 1000).toString(), + sessionId: sessionId.value, self: true } messageList.value.push(userMessage) @@ -95,11 +101,9 @@ const handleSendMessage = (message: string): void => { const abort = new AbortController() const handleFetchMessage = (message: string) => { - const sessionId = Math.floor(Date.now() / 1000).toString() - const params = { message: message, - sessionId: sessionId, + sessionId: sessionId.value, gender: 'male' } @@ -109,7 +113,7 @@ const handleFetchMessage = (message: string) => { type: 'text', content: '', timestamp: new Date().toISOString(), - sessionId: sessionId + sessionId: sessionId.value } // 添加到消息列表 @@ -140,7 +144,8 @@ const handleFetchMessage = (message: string) => { .then(async (response) => { // 检查响应内容类型,判断是否为流式响应 const contentType = response.headers.get('content-type') || '' - const isStreamResponse = contentType.includes('text/event-stream') || contentType.includes('stream') + const isStreamResponse = + contentType.includes('text/event-stream') || contentType.includes('stream') if (!response.ok) { // 非流式错误响应,使用 text() 读取错误信息 @@ -157,7 +162,7 @@ const handleFetchMessage = (message: string) => { // 不是流式响应,使用 text()读取错误信息 if (!isStreamResponse) { const text = await response.text() - + try { const errorData = JSON.parse(text) if (errorData.message || errorData.error) { @@ -176,7 +181,7 @@ const handleFetchMessage = (message: string) => { }) throw new Error(text || '请求失败') } - + isStreaming.value = false currentStreamingMessage.value = null return From ec2acb2044f04c274f97556dc8f273b16e587356 Mon Sep 17 00:00:00 2001 From: zhangyahui Date: Mon, 3 Nov 2025 15:53:18 +0800 Subject: [PATCH 4/4] feat: sessionId --- src/stores/modules/generate.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/stores/modules/generate.ts b/src/stores/modules/generate.ts index 53ddc1c..8a19620 100644 --- a/src/stores/modules/generate.ts +++ b/src/stores/modules/generate.ts @@ -61,7 +61,9 @@ export const useGenerateStore = defineStore({ /** 原始试穿id-优先AI魔改 */ originalTryOnId: (state) => state.customizeInfo.tryOnId || state.originalTryOn.id, /** 顾客照片id */ - customerPhotoId: (state) => state.photoInfo.id + customerPhotoId: (state) => state.photoInfo.id, + /** 会话id */ + sessionId: (state) => state.sessionId }, actions: { selectStyle(data: any) {