zhongshujie
2025-08-08 401ed176c9f1bdd97ccdf827d9454b11a3891f79
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">以上内容由AI生成,仅供参考。</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) {