From 6c526503d7b106e436393b4eac0a1c01ced0fe60 Mon Sep 17 00:00:00 2001 From: YM <479443481@qq.com> Date: 星期三, 23 四月 2025 19:49:39 +0800 Subject: [PATCH] Merge branch 'master' of http://182.92.203.7:2001/r/LibraryAgent --- src/views/Start.vue | 988 ++++++++++++++++++++++++++++++++++++--------------------- 1 files changed, 621 insertions(+), 367 deletions(-) diff --git a/src/views/Start.vue b/src/views/Start.vue index c4f1818..ec86788 100644 --- a/src/views/Start.vue +++ b/src/views/Start.vue @@ -1,6 +1,6 @@ <template> <div class="chat-box"> - <div class="chat-box-content"> + <div class="chat-box-content" ref="messagesContainer"> <div class="chat-date">03/15 13:10:00</div> <div class="chat-back-info"> <div class="back-avator"> @@ -46,33 +46,63 @@ <span>鎹竴鎹�</span> </div> </div> - <div class="chat-footer"> - <div class="icon-list"> - <img src="../assets/images/liebiao1.png" alt="" /> - <img src="../assets/images/tianjia2.png" alt="" /> + <div + v-for="(item, index) in message" + :key="index" + :class="['message', item.type === 'user' ? 'user-message' : 'assistant-message']" + > + <el-avatar + style="min-width: 40px" + :size="screenWidth > 375 ? 60 : 40" + v-if="item.type != 'user'" + :src="assistantAvatar" + /> + <div :class="['message-content', item.type === 'user' ? 'user-message-content' : '']"> + <div class="message-text" v-html="item.content"></div> + <div class="message-footer" v-if="item.type != 'user'"> + <span class="message-time">{{ item.time }}</span> + </div> </div> - <div class="chat-text"> - <el-input type="textarea" :autosize="{ minRows: 2, maxRows: 10 }" placeholder="璇疯緭鍏ユ偍鐨勯棶棰�" - v-model="inputValue" /> - </div> - <div class="select"> - <div class="select-left"> - <div class="select-item"> - <img src="../assets/images/sikao.png" alt="" /> - <span>娣卞害鎬濊�冿紙R1)</span> - </div> - <div class="select-item"> - <img src="../assets/images/lianwang.png" alt="" /> - <span>鑱旂綉鎼滅储</span> + <div v-if="loading" class="message assistant-message loading-message"> + <el-avatar :size="40" :src="assistantAvatar" /> + <div :class="['message-content', item.type === 'user' ? 'user-message-content' : '']"> + <div class="message-text"> + <span class="dot-loading">鎬濊�冧腑</span> </div> </div> - <div class="select-right"> - <div class="select-item"> - <img src="../assets/images/fujian1.png" alt="" /> - </div> - <div class="select-item"> - <img @click="sendMsg()" src="../assets/images/shangchuan2.png" alt="" /> - </div> + </div> + </div> + </div> + <div class="chat-footer"> + <div class="icon-list"> + <img src="../assets/images/liebiao1.png" alt="" /> + <img src="../assets/images/tianjia2.png" alt="" /> + </div> + <div class="chat-text"> + <el-input + type="textarea" + :autosize="{ minRows: 2, maxRows: 10 }" + placeholder="璇疯緭鍏ユ偍鐨勯棶棰�" + v-model="inputValue" + /> + </div> + <div class="select"> + <div class="select-left"> + <div class="select-item"> + <img src="../assets/images/sikao.png" alt="" /> + <span>娣卞害鎬濊�冿紙R1)</span> + </div> + <div class="select-item"> + <img src="../assets/images/lianwang.png" alt="" /> + <span>鑱旂綉鎼滅储</span> + </div> + </div> + <div class="select-right"> + <div class="select-item"> + <img src="../assets/images/fujian1.png" alt="" /> + </div> + <div class="select-item"> + <img @click="sendMsg()" src="../assets/images/shangchuan2.png" alt="" /> </div> </div> </div> @@ -80,389 +110,613 @@ </div> </template> <script lang="ts" setup> - import { ref } from 'vue' - const inputValue = ref('') +import { nextTick, onMounted, ref, watch } from 'vue' +import defaultImg from '../assets/images/image2.png' +const inputValue = ref('') +const message = ref<any>([]) +const loading = ref(false) +const autoScroll = ref(true) +const messagesContainer = ref<HTMLElement | null>(null) +const assistantAvatar = defaultImg +const screenWidth = ref(window.innerWidth) - const sendMsg = () => { - +const scrollToBottom = async () => { + if (!autoScroll.value) return + await nextTick() + if (messagesContainer.value) { + messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight } -// import { ref } from 'vue' -// import { useRouter } from 'vue-router' +} +const formatMessage = (content: string) => { + return content.replace(/\n/g, '<br>') +} -// const router = useRouter() -// const inputValue = ref('') +interface ChatMessage { + content: string + type: 'user' | 'assistant' + time: string +} +const sendMsg = async () => { + if (!inputValue.value.trim() || loading.value) return -// const handleChat = () => { -// router.push('/chat') -// } + const userMessage: ChatMessage = { + content: inputValue.value, + type: 'user', + time: new Date().toLocaleTimeString(), + } + message.value.push(userMessage) + + const messageToSend = inputValue.value + inputValue.value = '' + loading.value = true + + try { + setTimeout(() => { + const assistantMessage: ChatMessage = { + content: + '浣犲ソ,鍗佸ぇ鏉�涓ぇ鍌荤摐澶у帵鎻愰珮鍏氬憳婀垮湴鍏洯澶у垰鍒氭拻鍙嶅鍝堟寕鍙疯垂鍝�浼ょ殑姝岃繑鍥炵粰娉曟拻鏃︾瓑鍝堢殑鍦版柟鍙戠敓鑿插ぇ浣块鐨勬拻', + type: 'assistant', + time: new Date().toLocaleTimeString(), + } + message.value.push(assistantMessage) + loading.value = false + console.log(message, 'dasdas') + }, 1000) + // 淇濆瓨娑堟伅鍒版湰鍦板瓨鍌� + localStorage.setItem('chatMessages', JSON.stringify(message.value)) + } catch (error) { + console.error('鍙戦�佹秷鎭け璐�', error) + } finally { + loading.value = false + } +} + +// 鐩戝惉娑堟伅鍙樺寲锛岃嚜鍔ㄦ粴鍔� +watch(message.value, () => { + scrollToBottom() +}) + +// 浠庢湰鍦板瓨鍌ㄥ姞杞芥秷鎭� +onMounted(() => { + const savedMessages = localStorage.getItem('chatMessages') + if (savedMessages) { + message.value = JSON.parse(savedMessages) + } + scrollToBottom() + screenWidth.value = window.innerWidth +}) </script> <style lang="less" scoped> - @media screen and (max-width: 750px) { - .chat-box { - width: 100%; - height: auto; - background-image: url('@/assets/images/beijing2.png'); - background-position: center; - background-size: cover; +@media screen and (max-width: 750px) { + .chat-box { + width: 100%; + height: 100%; + background-image: url('@/assets/images/beijing2.png'); + background-position: center; + background-size: cover; - .chat-box-content { + .chat-box-content { + width: 100%; + height: calc(100vh - 170px); + display: flex; + flex-direction: column; + overflow: auto; + justify-content: flex-start; + align-items: flex-start; + + .chat-date { + width: 100%; + text-align: center; + margin-bottom: 30px; + } + + .chat-send { width: 100%; display: flex; - flex-direction: column; - justify-content: flex-start; - align-items: flex-start; + justify-content: flex-end; + margin-bottom: 20px; - .chat-date { - width: 100%; - text-align: center; - margin-bottom: 30px; - } - - .chat-send { - width: 100%; - display: flex; - justify-content: flex-end; - margin-bottom: 20px; - - .chat-send-info { - width: 263px; - height: 40px; - background: #af8b56; - border-radius: 20px; - line-height: 40px; - padding: 0 20px; - color: #fff; - } - } - - .chat-back-info { - margin-bottom: 20px; - display: flex; - justify-content: flex-start; - - .back-avator { - margin-right: 10px; - - img { - width: 40px; - } - } - - .base-book-box { - width: 300px; - padding: 20px; - box-sizing: border-box; - background-color: #fff; - border-radius: 20px; - } - } - - .back-item { - width: 300px; - background: #ffffff; + .chat-send-info { + width: 263px; + height: 40px; + background: #af8b56; border-radius: 20px; - margin-left: 50px; - margin-bottom: 20px; - - .back-item-title { - width: 80%; - height: 60px; - display: flex; - align-items: center; - padding: 0 10px; - margin: auto; - border-bottom: 1px solid #e9d8bf; - } - - img { - margin-right: 10px; - } - - ul { - padding: 0 25px; - - li { - list-style: none; - margin: 10px 0 10px 0; - display: flex; - justify-content: flex-start; - align-items: center; - } - } - - .chat-change { - display: flex; - justify-content: flex-end; - align-items: center; - padding: 10px 20px; - color: #d2a25b; - - img { - cursor: pointer; - } - } - } - - .chat-footer { - width: 300px; - background-color: #fff; - border-radius: 20px; - padding: 20px; - box-sizing: border-box; - margin-left: 50px; - margin-bottom: 20px; - - .icon-list img { - margin-right: 10px; - cursor: pointer; - } - - ::v-deep(.chat-text) { - margin-bottom: 10px; - - .el-textarea__inner { - border: none !important; - outline: none !important; - box-shadow: none !important; - background-color: transparent !important; - resize: none !important; - } - } - - .select { - width: 100%; - display: flex; - align-items: center; - justify-content: space-between; - - .select-left, - .select-right { - display: flex; - align-items: center; - justify-content: flex-start; - - .select-item { - display: flex; - align-items: center; - box-sizing: border-box; - border: 1px solid #e9d8bf; - border-radius: 15px; - font-size: 12px; - font-family: - Microsoft YaHei, - Microsoft YaHei-Regular; - font-weight: 400; - color: #e1c49a; - - img { - margin-right: 5px; - cursor: pointer; - } - } - } - - .select-left { - .select-item { - min-width: 70px; - padding: 5px 8px; - } - } - - .select-right { - display: flex; - align-items: center; - justify-content: flex-end; - - .select-item { - border: 0; - } - } - } + line-height: 40px; + padding: 0 20px; + color: #fff; } } - } - } - @media screen and (min-width: 750px) { - .chat-box { - width: 100%; - height: 100%; - background-image: url('@/assets/images/beijing2.png'); - background-size: 100% 100%; - background-position: center; - background-repeat: no-repeat; - display: flex; - justify-content: center; - align-items: center; - - .chat-box-content { - width: 1200px; + .chat-back-info { + margin-bottom: 20px; display: flex; - flex-direction: column; justify-content: flex-start; - align-items: flex-start; - .chat-date { - width: 100%; - text-align: center; - margin-bottom: 30px; - } - - .chat-send { - width: 100%; - display: flex; - justify-content: flex-end; - margin-bottom: 20px; - - .chat-send-info { - width: 263px; - height: 40px; - background: #af8b56; - border-radius: 20px; - line-height: 40px; - padding: 0 20px; - color: #fff; - } - } - - .chat-back-info { - margin-bottom: 20px; - display: flex; - justify-content: flex-start; - - .back-avator { - margin-right: 37px; - - img { - width: 60px; - } - } - - .base-book-box { - width: 800px; - padding: 20px 47px; - box-sizing: border-box; - background-color: #fff; - border-radius: 20px; - } - } - - .back-item { - width: 349px; - height: 391px; - background: #ffffff; - border-radius: 20px; - margin-left: 100px; - margin-bottom: 20px; - - .back-item-title { - width: 80%; - height: 60px; - display: flex; - align-items: center; - padding: 0 10px; - margin: auto; - border-bottom: 1px solid #e9d8bf; - } + .back-avator { + margin-right: 10px; img { - margin-right: 10px; + width: 40px; } + } - ul li { + .base-book-box { + width: 80%; + padding: 15px; + box-sizing: border-box; + background-color: #fff; + border-radius: 20px; + font-size: 14px; + } + } + + .back-item { + max-width: 80%; + background: #ffffff; + border-radius: 20px; + margin-left: 50px; + margin-bottom: 20px; + font-size: 14px; + + .back-item-title { + width: 80%; + height: 60px; + display: flex; + align-items: center; + padding: 0 10px; + margin: auto; + border-bottom: 1px solid #e9d8bf; + } + + img { + margin-right: 10px; + } + + ul { + padding: 0 25px; + + li { list-style: none; - margin: 20px 0 20px 0; + margin: 10px 0 10px 0; display: flex; justify-content: flex-start; align-items: center; } + } - .chat-change { + .chat-change { + display: flex; + justify-content: flex-end; + align-items: center; + padding: 10px 20px; + color: #d2a25b; + + img { + cursor: pointer; + } + } + } + } + .chat-footer { + width: 90%; + margin: auto; + background-color: #fff; + border-radius: 20px; + padding: 10px; + box-sizing: border-box; + margin-bottom: 20px; + + .icon-list img { + margin-right: 10px; + cursor: pointer; + } + + ::v-deep(.chat-text) { + margin-bottom: 10px; + + .el-textarea__inner { + border: none !important; + outline: none !important; + box-shadow: none !important; + background-color: transparent !important; + resize: none !important; + } + } + + .select { + width: 100%; + display: flex; + align-items: center; + justify-content: space-between; + + .select-left, + .select-right { + display: flex; + align-items: center; + justify-content: flex-start; + + .select-item { display: flex; - justify-content: flex-end; align-items: center; - padding: 0 20px; - color: #d2a25b; + box-sizing: border-box; + border: 1px solid #e9d8bf; + border-radius: 15px; + font-size: 12px; + font-family: + Microsoft YaHei, + Microsoft YaHei-Regular; + font-weight: 400; + color: #e1c49a; img { + margin-right: 5px; cursor: pointer; } } } - .chat-footer { - width: 800px; - height: 170px; - background-color: #fff; - border-radius: 20px; - padding: 20px; - box-sizing: border-box; - margin-left: 103px; - - .icon-list img { - margin-right: 10px; - cursor: pointer; + .select-left { + .select-item { + min-width: 70px; + padding: 5px 8px; + margin-left: 2px; } + } - ::v-deep(.chat-text) { - margin-bottom: 10px; + .select-right { + display: flex; + align-items: center; + justify-content: flex-end; - .el-textarea__inner { - border: none !important; - outline: none !important; - box-shadow: none !important; - background-color: transparent !important; - resize: none !important; - } - } - - .select { - width: 100%; - display: flex; - align-items: center; - justify-content: space-between; - - .select-left, - .select-right { - flex: 1; - display: flex; - align-items: center; - justify-content: flex-start; - - .select-item { - display: flex; - align-items: center; - padding: 2px 10px; - box-sizing: border-box; - border: 1px solid #e9d8bf; - border-radius: 15px; - margin-right: 10px; - font-size: 14px; - font-family: - Microsoft YaHei, - Microsoft YaHei-Regular; - font-weight: 400; - color: #e1c49a; - - img { - margin-right: 10px; - cursor: pointer; - } - } - } - - .select-right { - display: flex; - align-items: center; - justify-content: flex-end; - - .select-item { - border: 0; - } - } + .select-item { + border: 0; + margin-left: 2px; } } } } + .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; + padding-left: 3px; + } + + .message-content { + background: #fff; + margin-left: 10px; + border-radius: 20px; + min-width: 200px; + padding: 5px; + } + + .message-text { + padding: 12px 16px; + 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; + } + + .user-message { + flex-direction: row-reverse; + margin-left: auto; + } + + .user-message .message-text { + color: #8b6e47; + } + + .message-footer { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 8px; + padding: 0 4px; + color: #999; + } + + .message-time { + font-size: 0.85rem; + color: #999; + margin-left: 10px; + } } -</style> \ No newline at end of file +} + +@media screen and (min-width: 750px) { + .chat-box { + width: 100%; + height: 100%; + background-image: url('@/assets/images/beijing2.png'); + background-size: 100% 100%; + background-position: center; + background-repeat: no-repeat; + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: center; + padding-bottom: 10px; + + .chat-box-content { + width: 1200px; + height: calc(100vh - 180px); + display: flex; + flex-direction: column; + justify-content: flex-start; + overflow: auto; + align-items: flex-start; + + .chat-send { + width: 100%; + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: flex-end; + margin-bottom: 20px; + + .chat-send-info { + width: 263px; + height: 40px; + background: #af8b56; + border-radius: 20px; + line-height: 40px; + padding: 0 20px; + color: #fff; + } + + .chat-message { + width: 263px; + height: 40px; + background: #fff; + border-radius: 20px; + line-height: 40px; + padding: 0 20px; + color: #000; + } + } + + .chat-date { + width: 100%; + text-align: center; + margin-bottom: 30px; + } + + .chat-send { + width: 100%; + display: flex; + justify-content: flex-end; + margin-bottom: 20px; + + .chat-send-info { + width: 263px; + height: 40px; + background: #af8b56; + border-radius: 20px; + line-height: 40px; + padding: 0 20px; + color: #fff; + } + } + + .chat-back-info { + margin-bottom: 20px; + display: flex; + justify-content: flex-start; + + .back-avator { + margin-right: 37px; + + img { + width: 60px; + } + } + + .base-book-box { + width: 800px; + padding: 20px 47px; + box-sizing: border-box; + background-color: #fff; + border-radius: 20px; + } + } + + .back-item { + width: 349px; + height: 391px; + background: #ffffff; + border-radius: 20px; + margin-left: 100px; + margin-bottom: 20px; + + .back-item-title { + width: 80%; + height: 60px; + display: flex; + align-items: center; + padding: 0 10px; + margin: auto; + border-bottom: 1px solid #e9d8bf; + } + + img { + margin-right: 10px; + } + + ul li { + list-style: none; + margin: 20px 0 20px 0; + display: flex; + justify-content: flex-start; + align-items: center; + } + + .chat-change { + display: flex; + justify-content: flex-end; + align-items: center; + padding: 0 20px; + color: #d2a25b; + + img { + cursor: pointer; + } + } + } + } + + .chat-box-content::-webkit-scrollbar { + width: 1px; + } + + /* 闅愯棌姘村钩婊氬姩鏉� */ + .chat-box-content::-webkit-scrollbar { + height: 0; + } + + .chat-footer { + width: 1200px; + height: 170px; + background-color: #fff; + border-radius: 20px; + padding: 20px; + box-sizing: border-box; + + .icon-list img { + margin-right: 10px; + cursor: pointer; + } + + ::v-deep(.chat-text) { + margin-bottom: 10px; + + .el-textarea__inner { + border: none !important; + outline: none !important; + box-shadow: none !important; + background-color: transparent !important; + resize: none !important; + } + } + + .select { + width: 100%; + display: flex; + align-items: center; + justify-content: space-between; + + .select-left, + .select-right { + flex: 1; + display: flex; + align-items: center; + justify-content: flex-start; + + .select-item { + display: flex; + align-items: center; + padding: 2px 10px; + box-sizing: border-box; + border: 1px solid #e9d8bf; + border-radius: 15px; + margin-right: 10px; + font-size: 14px; + font-family: + Microsoft YaHei, + Microsoft YaHei-Regular; + font-weight: 400; + color: #e1c49a; + + img { + margin-right: 10px; + cursor: pointer; + } + } + } + + .select-right { + display: flex; + align-items: center; + justify-content: flex-end; + + .select-item { + border: 0; + } + } + } + } + + .message { + display: flex; + margin-bottom: 24px; + align-items: flex-start; + animation: slideIn 0.3s ease; + animation-fill-mode: forwards; + max-width: 95%; + border-radius: 12px; + // box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); + padding: 16px; + } + + .message-content { + background: #fff; + margin-left: 20px; + border-radius: 20px; + min-width: 200px; + padding: 5px; + } + + .message-text { + padding: 12px 16px; + 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; + } + + .user-message { + flex-direction: row-reverse; + margin-left: auto; + } + + .user-message .message-text { + color: #8b6e47; + } + + .message-footer { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 8px; + padding: 0 4px; + color: #999; + } + + .message-time { + font-size: 0.85rem; + color: #999; + margin-left: 10px; + } + } +} + +.user-message-content { + background: #af8b56 !important; + .message-text { + color: #fff !important; + padding: 5px 10px; + } +} +</style> -- Gitblit v1.9.1