From 401ed176c9f1bdd97ccdf827d9454b11a3891f79 Mon Sep 17 00:00:00 2001 From: zhongshujie <2862698242@qq.com> Date: 星期五, 08 八月 2025 23:10:50 +0800 Subject: [PATCH] 8.8 初始版本 --- src/views/ai/aiDetails.vue | 283 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 266 insertions(+), 17 deletions(-) diff --git a/src/views/ai/aiDetails.vue b/src/views/ai/aiDetails.vue index 9c76460..ba83455 100644 --- a/src/views/ai/aiDetails.vue +++ b/src/views/ai/aiDetails.vue @@ -29,7 +29,7 @@ </div> </div> <!-- 娑堟伅鍒楄〃 --> - <div v-for="(item, index) in pageData.message" :key="index" class="chat-box-content-item"> + <div v-for="(item, index) in message" :key="index" class="chat-box-content-item"> <div v-if="item.type === 'user'" class="chat-date">{{ item.time }}</div> <div :class="['message', item.type === 'user' ? 'user-message' : 'assistant-message']"> <!-- 鍔╂墜澶村儚 --> @@ -43,18 +43,13 @@ <div :class="['message-text', 'requestText' + index].join(' ')" v-if="item.type != 'user' && item.txtType == 'txt'"> <p class="message-text-title"> - AI鏅鸿兘鍔╂墜涓烘偍鎵惧埌浠ヤ笅{{ pageData.inputValue }}鐨勪俊鎭唴瀹瑰涓�: + AI鏅鸿兘鍔╂墜涓烘偍鎵惧埌浠ヤ笅鐨勪俊鎭唴瀹瑰涓�: </p> <iframe class="message-text-iframe" ref="iframeRef" v-if="item.iframeSrc != ''" :src="item.iframeSrc" frameborder="0"></iframe> <div v-html="item.content"></div> <p class="message-text-titleOne">浠ヤ笂鍐呭鐢盇I鐢熸垚锛屼粎渚涘弬鑰冦��</p> </div> - <!-- AI 鏂囨湰娑堟伅 --> - <!-- <div :class="['Ai-message-text', 'requestText' + index].join(' ')" - v-if="item.type != 'user' && item.txtType == 'txt'"> - <div v-html="item.content"></div> - </div> --> <!-- 娑堟伅搴曢儴鏃堕棿 --> <div class="message-footer" v-if="item.type != 'user'"> <span class="message-time">{{ item.time }}</span> @@ -78,8 +73,8 @@ <div class="chat-footer"> <!-- 杈撳叆妗� --> <div class="chat-text"> - <el-input type="textarea" :autosize="{ minRows: 3, maxRows: 3 }" placeholder="" - v-model="pageData.inputValue" @keyup.enter="handleEnter($event)" /> + <el-input type="textarea" :autosize="{ minRows: 3, maxRows: 3 }" placeholder="" v-model="inputValue" + @keyup.enter="handleEnter($event)" /> </div> <!-- 鍔熻兘閫夋嫨鍖哄煙 --> <div class="select"> @@ -100,12 +95,18 @@ </template> <script lang="ts" setup> -import { ref, reactive, computed } from 'vue' +import { ref, reactive, nextTick, computed, onMounted } from 'vue' import type { aiDetails } from '@/types/aiDetails' import current from '@/assets/images/ai/current.png' import noCurrent from '@/assets/images/ai/noCurrent.png' import dayjs from 'dayjs' import Header from '@/layout/components/headerPage.vue' +import defaultImg from '../../assets/images/home/AI_logo.png' +import userIcon from '../../assets/images/ai/userImg.png' +import request from '@/plugin/axios/index' +const screenWidth = ref(window.innerWidth) +const assistantAvatar = defaultImg +const userProfilePicture = userIcon const pageData = reactive<aiDetails>({ historylist: [ { @@ -121,20 +122,170 @@ content: "What are the quarterly strata fees?", }, ], - inputValue: "", - message: "", }) +const inputValue = ref('') +const message = ref<any>([]) +const loading = ref(false) +const autoScroll = ref(true) +const messagesContainer = ref<HTMLElement | null>(null) const currentTime = ref(dayjs(new Date()).format('MM/DD HH:mm:ss')) const currentImage = computed(() => { - return pageData.inputValue.trim() === '' ? noCurrent : current; + return inputValue.value.trim() === '' ? noCurrent : current; }); +// 浠庢湰鍦板瓨鍌ㄥ姞杞芥秷鎭� +onMounted(() => { + // getCommonQyestuion() + // 鍒犻櫎鏈湴缂撳瓨 + localStorage.removeItem('chatMessages') + const savedMessages = localStorage.getItem('chatMessages') + if (savedMessages) { + message.value = JSON.parse(savedMessages) + } + scrollToBottom() + screenWidth.value = window.innerWidth -const goAi = (e: any) => { - pageData.inputValue = e.content; -}; + window.addEventListener('message', function (event) { + console.log(event, "event"); + if (event.data.type == 'toggleFullScreen') { + window.open(event.data.data) + } else if (event.data.type == 'download') { + const link = document.createElement('a') + link.href = event.data.data + link.download = event.data.data + document.body.appendChild(link) + link.click() + document.body.removeChild(link) + } + }) +}) + +const scrollToBottom = async () => { + if (!autoScroll.value) return + await nextTick() + if (messagesContainer.value) { + const dom1 = document.querySelector('.dot-loading') + const dom = document.querySelector('.requestText' + (message.value.length - 1)) + dom1?.scrollIntoView({ behavior: 'smooth', block: 'center' }) + dom?.scrollIntoView({ behavior: 'smooth', block: 'start' }) + } +} +interface ChatMessage { + content: string + type: 'user' | 'assistant' + time: string + txtType: 'txt' | 'List' + currentContentIndex: 0 + isEnd: boolean + iframeSrc: string +} + +const handleEnter = (event: any) => { + event.preventDefault() + inputValue.value = inputValue.value.replace(/\n/g, '') + // 璋冪敤鍙戦�佹秷鎭殑鏂规硶 + sendMsg() +} +const sendMsg = async () => { + if (!inputValue.value.trim() || loading.value) return + const userMessage: ChatMessage = { + content: inputValue.value, + type: 'user', + time: new Date().toLocaleTimeString(), + txtType: 'txt', + currentContentIndex: 0, + isEnd: false, + iframeSrc: '', + } + + message.value.push(userMessage) + const messageToSend = inputValue.value + inputValue.value = '' + try { + await getData(messageToSend) // 浣跨敤 await 绛夊緟 getData 瀹屾垚 + console.log(message, "message"); + + } catch (error) { + console.error('鍙戦�佹秷鎭け璐�', error) + } +} + + +// 鑾峰彇鏁版嵁 +const getData = async (messageToSend: any) => { + loading.value = true + try { + const response = await request({ + url: '/v1/workflows/run', + method: 'post', + data: { + inputs: { + question: messageToSend, + }, + parent_message_id: null, + response_mode: 'blocking', + conversation_id: '', + user: 'abc-123', + files: [], + }, + }) + try { + const answerAgain = JSON.parse((response as any).data.outputs.text) + answerAgain.msg = answerAgain.msg.replace(/\n/g, '<br>') + console.log(answerAgain, 'answerAgain'); + answerAgain.iframeSrc = ''; + if (answerAgain.model && answerAgain.model[0].name == 'Conformer3D_COMPOUND_CID_2244') { + answerAgain.iframeSrc = 'http://182.92.203.7:3007/showModel/?name=' + answerAgain.model[0].name; + } + if (answerAgain.code == 1) { + const assistantMessage: ChatMessage = { + content: answerAgain.data, + type: 'assistant', + time: new Date().toLocaleTimeString(), + txtType: 'List', + currentContentIndex: 0, + isEnd: false, + iframeSrc: answerAgain.iframeSrc, + } + message.value.push(assistantMessage) + } else if (answerAgain.code == 2 || answerAgain.code == 3) { + const assistantMessage: ChatMessage = { + content: answerAgain.msg, + type: 'assistant', + time: new Date().toLocaleTimeString(), + txtType: 'txt', + currentContentIndex: 0, + isEnd: false, + iframeSrc: answerAgain.iframeSrc, + } + console.log(assistantMessage); + message.value.push(assistantMessage) + loading.value = false + // 淇濆瓨娑堟伅鍒版湰鍦板瓨鍌� + localStorage.setItem('chatMessages', JSON.stringify(message.value)) + } + console.log(message, "message"); + } catch (error) { + console.log(error) + } + } catch (error) { + const assistantMessage: ChatMessage = { + content: '褰撳墠鎿嶄綔閬囧埌涓�浜涢棶棰橈紝璇风◢鍚庡啀璇曘��', + type: 'assistant', + time: new Date().toLocaleTimeString(), + txtType: 'txt', + currentContentIndex: 0, + isEnd: false, + iframeSrc: "", + } + message.value.push(assistantMessage) + console.error('鍙戦�佹秷鎭け璐�', error) + } finally { + loading.value = false + } +} @@ -187,6 +338,35 @@ } } +.message { + display: flex; + margin-bottom: 24px; + align-items: flex-start; + animation: slideIn 0.3s ease; + animation-fill-mode: forwards; + max-width: 85%; + border-radius: 12px; + // box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); + padding: 16px; +} + +.assistant-avatar { + width: 32px; + height: auto; +} + +.user-message { + flex-direction: row-reverse; + margin-left: auto; +} + +.assistant-message { + background-color: #f7fffc; +} + + + + .chat-box-right { width: 86%; margin: 0 auto; @@ -198,7 +378,8 @@ .chat-box-content { - width: 100%; + width: 62%; + margin: 0 auto; height: calc(100vh - 150px); display: flex; flex-direction: column; @@ -282,6 +463,7 @@ box-sizing: border-box; background-color: #f7fffc; border-radius: 20px; + line-height: 1.5em; } } @@ -353,8 +535,74 @@ } + .message-content { + display: inline-block; + max-width: 80%; + background: #DEDEDE; + margin-left: 10px; + border-radius: 10px 0px 10px 10px; + padding: 14px 12px; + margin-top: 5px; + margin-right: 10px; + } + .user-message-text { + font-weight: 400; + font-size: 14px; + color: #000000; + line-height: 1.5em; + } + .message-text { + min-width: 600px; + padding: 0px 40px; + border-radius: 12px; + word-wrap: break-word; + line-height: 1.6; + font-size: 0.95rem; + transition: all 0.3s ease; + white-space: pre-wrap; + color: #333; + + .message-text-title { + font-size: 16px; + color: #999; + line-height: 35px; + padding: 0px 0 10px 0; + } + + .message-text-iframe { + width: 100%; + height: 400px; + margin-bottom: 10px; + } + + .message-text-titleOne { + text-align: right; + color: #fe7313; + font-size: 10px; + padding-bottom: 5px; + border-bottom: 1px solid #e9d8bf; + } + + .message-text-changeOne { + display: flex; + align-items: center; + justify-content: flex-end; + padding: 10px 0 0 0; + + span { + font-size: 14px; + font-family: + Microsoft YaHei, + Microsoft YaHei-Regular; + font-weight: 400; + text-align: left; + color: #d2a25b; + line-height: 35px; + } + } + } .chat-footer { width: 62%; @@ -364,6 +612,7 @@ padding: 9px 13px; box-sizing: border-box; margin-bottom: 10px; + margin-top: 14px; } ::v-deep(.chat-text) { -- Gitblit v1.9.1