From 8c6fbc506e9a2c8cde56a794d8319cc55f4be666 Mon Sep 17 00:00:00 2001 From: wujingjing <gersonwu@qq.com> Date: 星期二, 11 二月 2025 15:56:48 +0800 Subject: [PATCH] 修复问题 --- src/components/chat/smallChat/index.vue | 136 ++++++++++++++++++++++++++++++++++++++------ 1 files changed, 116 insertions(+), 20 deletions(-) diff --git a/src/components/chat/smallChat/index.vue b/src/components/chat/smallChat/index.vue index 18f0698..6e1a57f 100644 --- a/src/components/chat/smallChat/index.vue +++ b/src/components/chat/smallChat/index.vue @@ -1,6 +1,6 @@ <template> <div ref="chatContainerRef" :style="chatContainerStyle" class="opacity-90 small-chat-container" @mousedown="startDrag"> - <div class="bg-white rounded-lg shadow-lg flex flex-col w-[370px] max-h-[600px] absolute bottom-4 right-4"> + <div class="bg-white rounded-lg shadow-lg flex flex-col w-[370px] max-h-[540px] absolute bottom-4 right-4"> <!-- 澶撮儴 --> <div ref="chatHeaderRef" @@ -8,7 +8,7 @@ class="small-chat-header h-12 flex items-center justify-between px-4" style="border-bottom: 1px solid #e0e0e0" > - <div class="text-lg font-bold">WI姘村姟鏅鸿兘鍔╂墜</div> + <div class="text-lg font-bold py-2">WI姘村姟鏅鸿兘鍔╂墜</div> <div class="flex items-center gap-2"> <!-- <el-icon class="cursor-pointer text-gray-400 hover:text-gray-600"> <Refresh /> @@ -73,19 +73,50 @@ </div> --> </div> </div> - <div v-else class="flex flex-col gap-4"> + <div v-else class="flex flex-col gap-1.5"> <!-- 瀵硅瘽鍐呭 --> - <div class="flex flex-col gap-4" v-for="item in historyMessages" :key="item.id"> + <div class="flex flex-col gap-4" v-for="(item, index) in historyMessages" :key="item.id"> <!-- 鐢ㄦ埛鎻愰棶 --> - <div class="flex gap-3" v-if="item.role === 'user'"> + <div class="flex gap-3 items-center" v-if="item.role === 'user'"> <img :src="userPic" class="w-10 h-10" alt="鐢ㄦ埛澶村儚" /> - <div class="flex-1 bg-blue-100"> - <div class="p-4 rounded-lg">{{ item.content.value }}</div> + <div class="flex-1 bg-blue-100 rounded-lg"> + <div class="p-3 flex items-center"> + <span> + {{ item.content.value }} + </span> + + <!-- #region ====================== 鍥炲鍙嶉 ======================--> + <el-icon v-if="(historyMessages[index+1].content as AssistantContent).isLoading" class="ml-2 animate-spin" + ><Loading + /></el-icon> + <template v-else> + <span + v-if="(historyMessages[index+1].content as AssistantContent).isError" + class="flex items-center text-nowrap ml-4 text-danger before:content-['('] after:content-[')']" + > + {{ (historyMessages[index + 1].content as AssistantContent).value }} + <el-tooltip + v-if="(historyMessages[index + 1].content as AssistantContent).reason" + :content="(historyMessages[index + 1].content as AssistantContent).reason" + placement="top" + > + <el-icon class="flex-center cursor-pointer ml-1"> + <question-filled /> + </el-icon> + </el-tooltip> + </span> + <span v-else class="ml-4 text-success text-nowrap before:content-['('] after:content-[')']"> + {{ (historyMessages[index + 1].content as AssistantContent).value }} + </span> + </template> + + <!-- #endregion --> + </div> </div> </div> <!-- AI鍥炵瓟 --> - <div class="flex gap-3" v-else-if="item.role === 'assistant'"> + <!-- <div class="flex gap-3" v-else-if="item.role === 'assistant'"> <img :src="assistantPic" class="w-10 h-10" alt="AI澶村儚" /> <div class="flex-1 bg-gray-100"> <div v-if="(item.content as AssistantContent)?.isLoading" class="p-4 rounded-lg flex items-center"> @@ -96,7 +127,7 @@ {{ item.content.value }} </div> </div> - </div> + </div> --> </div> </div> </div> @@ -106,6 +137,9 @@ <ChatInput v-model="inputText" @sendClick="sendClick" @toggleHistory="toggleHistory" :showHistory="showHistory" /> </div> </div> + <Teleport to="body"> + <WorkOrderDlg v-model="optDlgIsShow" :item="optDlgMapRow" @insert="submitDlg" @cancelSubmit="cancelSubmit"></WorkOrderDlg> + </Teleport> </div> </template> @@ -120,7 +154,8 @@ import assistantPic from '/static/images/role/assistant-200x192.png'; import userPic from '/static/images/role/user-200x206.png'; import { useDrag } from '/@/hooks/useDrag'; - +import { cloneDeep, defaults } from 'lodash-es'; +import WorkOrderDlg from './WorkOrderDlg.vue'; const props = defineProps<{ olMap?: OLMap; }>(); @@ -141,8 +176,16 @@ handleStyle, } = useDrag({ handle: chatHeaderRef, + startPos: { + x: 200, + }, }); - +const cancelSubmit = (reason) => { + refreshAssistantMessage({ reason: reason }); +}; +const submitDlg = () => { + refreshAssistantMessage({ value: `鎴愬姛`, isError: false }); +}; const historyMessages = ref<ChatMessage[]>([]); const isInit = computed(() => historyMessages.value.length === 0); const initQuestionList = ref([ @@ -150,6 +193,7 @@ { title: '鍦板浘缂╂斁', question: '鏀惧ぇ' }, { title: '璁惧鏄鹃殣', question: '闅愯棌璁惧' }, { title: '璁惧鑱氱劍', question: '鑱氱劍璁惧' }, + { title: '鍒涘缓宸ュ崟', question: '鏉剧澶ч亾DN800鏉惧矖鑱旈�氱洃娴嬭澶囨病鏈夋暟鎹紝鍒涘缓涓�涓澶囩淮淇伐鍗曪紝璇峰強鏃舵淳浜虹淮淇��' }, ]); const chatContentRef = ref<HTMLDivElement>(null); @@ -158,6 +202,18 @@ const result = last.role === 'assistant' ? last : null; return result as ChatMessage<AssistantContent>; }; + +//#region ====================== 娣诲姞宸ュ崟 ====================== +const optDlgIsShow = ref(false); +const optDlgMapRow = ref(null); + +const openOptDlg = (row?: any) => { + optDlgMapRow.value = row; + optDlgIsShow.value = true; +}; + +const submit = () => {}; +//#endregion const mockCommand = (question: string) => { if (question === `鍒囨崲${gaoDeSourceTypeMap[GaoDeSourceType.Vector]}`) { @@ -181,10 +237,20 @@ } }; +const handleCreateWorkOrder = (formData: any) => { + openOptDlg(formData ?? {}); +}; + const startStream = (question: string) => { if (lastIsInit) { showHistory.value = false; } + // if (question === '鏉剧澶ч亾DN800鏉惧矖鑱旈�氱洃娴嬭澶囨病鏈夋暟鎹紝鍒涘缓涓�涓澶囩淮淇伐鍗曪紝璇峰強鏃舵淳浜虹淮淇��') { + // setTimeout(() => { + // openOptDlg(); + // }, 400); + // return; + // } // mockCommand(question); // return; @@ -203,30 +269,48 @@ const jsonData = JSON.parse(chunkRes.value); handleMapCommand(jsonData); } + } else if (chunkRes.mode === 'create_work_order') { + haveMapOperate = true; + if(chunkRes.type==='string'){ + const jsonData = JSON.parse(chunkRes.value); + handleCreateWorkOrder(jsonData) + } } if (chunkRes.mode === 'finish') { if (!haveMapOperate) { - refreshAssistantMessage({ value: `鏈瘑鍒埌鎿嶄綔锛�${question}`, isError: true }); + refreshAssistantMessage({ reason: `鏈瘑鍒埌鎿嶄綔锛�"${question}"` }); } } } ).catch((error) => { Logger.error('agent stream error锛歕n\n' + error); - refreshAssistantMessage(); + refreshAssistantMessage({ reason: 'AI鍥炵瓟澶辫触' }); }); }; -const refreshAssistantMessage = (content: Partial<AssistantContent> = { value: 'AI鍥炵瓟澶辫触', isError: true }) => { +const refreshAssistantMessage = ( + content: Partial<AssistantContent> = { value: '澶辫触', isError: true, reason: '', isLoading: false } +) => { + const cloneContent = cloneDeep(content); const last = getLastAssistantMessage(); + content = defaults(cloneContent, { + value: '澶辫触', + isError: true, + reason: '', + isLoading: false, + }); if (last) { - last.content.value = content.value; - last.content.isLoading = content.isLoading; - last.content.isError = content.isError ?? false; + for (const key in content) { + if (Object.prototype.hasOwnProperty.call(content, key)) { + last.content[key] = content[key]; + } + } } }; const handleMapCommand = (command: any) => { if (!command) return; + // openOptDlg(); switch (command.operate) { case '鏀惧ぇ': props.olMap.zoomIn(); @@ -247,16 +331,28 @@ break; case '鏄剧ず璁惧': - props.olMap.toggleMarkerOverlayVisible(true); + const equipOverlay = props.olMap.getEquipOverlay(); + if (equipOverlay) { + equipOverlay.isVisible = true; + // 寮哄埗瑙﹀彂鏇存柊 + props.olMap.layerInfo.value = props.olMap.layerInfo.value.concat([]); + // props.olMap.toggleMarkerOverlayVisible(true); + } break; case '闅愯棌璁惧': - props.olMap.toggleMarkerOverlayVisible(false); + const equipOverlay1 = props.olMap.getEquipOverlay(); + if (equipOverlay1) { + equipOverlay1.isVisible = false; + // 寮哄埗瑙﹀彂鏇存柊 + props.olMap.layerInfo.value = props.olMap.layerInfo.value.concat([]); + // props.olMap.toggleMarkerOverlayVisible(false); + } break; case '鑱氱劍璁惧': props.olMap.adjustViewToMarkers(); break; } - refreshAssistantMessage({ value: `${command.operate}鎴愬姛` }); + refreshAssistantMessage({ value: `鎴愬姛`, isError: false }); }; const scrollToBottom = () => { -- Gitblit v1.9.3