baozhengrui

导航

对话框模式

<template>
    <div class="content" :style="{ right: visible ? '10px' : '-100%' }">
        <el-row style="width:100%;height:100%;">
            
            <el-col :span="24" style="height:100%;padding: 20px;">
                <!-- 聊天界面 -->
                <div style="width: 100%; display: flex; flex-direction: column;height: 100%;" @click="closeHistory">
                    <!-- 打开历史记录按钮 -->
                    <!-- <div
                        style="text-align: left; height:80%; padding: 10px; position: absolute; top: 10px; right: 10px; display: none;">
                        <div class="historyBtn" @click="toggleDrawer" @click.stop :style="{
                            color: drawerVisible ? '#409EFF' : '#45a268'
                        }">
                            {{ drawerVisible ? '隐藏历史记录' : '显示历史记录' }}
                        </div>
                    </div> -->

                    <!-- 聊天列表 -->
                    <div :class="historyShow=== false?'chat-container':'chat-container-act'" style="flex: 1; height:77%; overflow-y: auto;">
                        <template v-if="chatMessages.length > 0">
                            <div class="answer-box-item" v-for="(item, index) in chatMessages" :key="index">
                                <div v-if="item.isUser" class="notes-item" style="justify-content: flex-end">
                                    <div>
                                        <p style="text-align: right;">{{ item.content }}</p>
                                    </div>
                                    <img :src="zhiNengAnswer" alt="">
                                </div>
                                <div v-else class="notes-item">
                                    <img class="xiaozhi-icon" :src="imgXiaoZhi" alt="">
                                    <div>
                                        <div>
                                            <p v-loading="item.loading" element-loading-spinner="el-icon-loading"
                                                element-loading-background="rgba(0, 0, 0, 0.3)"
                                                style="text-align: left;">
                                                {{ item.content }}
                                            </p>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </template>
                    </div>
                    
                    <!-- 输入框和发送按钮 -->
                    
                </div>
            </el-col>
        </el-row>
            
    </div>
</template>
<script>
import { getAction, postAction } from '@/api/manage' // 引入api

export default {
    props: {

        visible: {
            type: Boolean,
            default: false
        }
    },
    data() {
        return {
            tipList: this.type === 'airForce' 
                ? ['11111111111?', '2222222222222222?', '3333333333333333'] 
                : ['11111111111111111', '22222222222', '33333333333333'],
            activeTab: 'files',  // 当前激活的 Tab
            tabLoading: false, // tab切换加载中
            files: [],  // 文件列表
            pointList: [], // 要点列表
            question: '',  // 当前输入框内容
            sendDisabled: false, // 发送按钮是否禁用
            historyShow: false,
            minSpeed: 50,         // 最小打字速度
            maxSpeed: 100,
            chatId: '', // 当前对话的id
            chatMessages: [{ isUser: false, content: '' },], // 聊天内容列表
            history: [{ id: 1, title: '历史对话1' }, { id: 2, title: '历史对话2' }],  // 历史聊天记录
            drawerVisible: false,  // 控制历史记录显示或隐藏,
            zhiNengAnswer: require('@/views/ykzmdmxDir/qbzh/img/zhinenghuida.png'), // 智能体图
            imgXiaoZhi: require('@/views/ykzmdmxDir/imgs/xiaozhi.png'), // 小智图
            uploadParams: { // 上传文件参数
                action: '/navy/big-api/file/fileInfo/multifileListUpload?kbId=e2e67764ad2f11efb1300242ac120002',
                name: 'files',
                accept: '.doc,.docx,.txt,.pdf',
                headers: {
                    'Content-Type': 'multipart/form-data',  // 设置请求头
                },
            },
        }
    },
    mounted() {
        
        
    },
    watch: {
        visible(newVal) {
            if (newVal) {
                if(this.sendDisabled) return;
                this.chatMessages = [{ isUser: false, content: '' },]   // 清空聊天记录
                this.sendDisabled = true; // 发送按钮可用
                this.typeEffect(
                    this.chatMessages.length - 1,
                    'eiuroieuroiueoiru需要显示的内容'
                );
            }
        },
        type(newVal) {
            this.tipList = newVal === 'airForce' 
                ? ['2323333?', '12343444?', '23423749'] 
                : ['34234234444', '2222222222', '33333333333'];
        }
    },
    computed: {
       
    },
    methods: {
        // 气泡点击发送
        tipHandle(item){
            if (this.sendDisabled) return this.$message.info('正在回答中');
            this.question = item
            this.sendQue()
        },
        // 新建会话
        handelCreatNewChat() {
            this.creatNewChat() // 创建新会话
        },
        // 新建对话
        creatNewChat(callback) {
            this.chatMessages = [{ isUser: false, content: '有关于的问题,可以向我提问' }] // 清空消息列表
            this.sendDisabled = false;
            this.historyShow = false;
            postAction('/navy/dbct-catalog/ManagementModel/knowledgeChat/newChat').then(result => {
                if (result.data.code == 200) {
                    this.chatId = result.data.data // 聊天ID
                    if (callback) {
                        callback() // 回调
                    }
                }
            })
        },
        // 删除会话
        deleteHistory(packet) {
            postAction('/navy/dbct-catalog/ManagementModel/knowledgeChat/deleteGroup', { packet }).then(result => {
                this.getHistoryList()
            })
        },
        // 关闭历史记录
        closeHistory() {
            this.drawerVisible = false; // 关闭
        },
        // 获取历史记录
        getHistoryList() {
            postAction('/navy/dbct-catalog/ManagementModel/knowledgeChat/historyByGroup', {}).then(result => {
                if (result.data.code == 200) {
                    this.history = result.data.data
                }
            })
        },
        // 选择历史记录
        selectHistory(id) {
            this.chatId = id; // 聊天记录id
            this.chatMessages = [] // 清空聊天记录
            this.sendDisabled = true;
            this.historyShow = true;
            postAction('/navy/dbct-catalog/ManagementModel/knowledgeChat/multiFileHistoryChatByGroup', { packet: id }).then(result => {
                if (result.status == 200) {
                    this.chatMessages = result.data.data.map(item => {
                        return {
                            ...item,
                            loading: false,
                            isUser: item.role == 'user'
                        }
                    }) // 聊天记录

                }

            })
        },
        // 控制历史记录的显示与隐藏
        toggleDrawer() {
            this.drawerVisible = !this.drawerVisible; // 切换显示与隐藏
            if (this.drawerVisible) {
                this.getHistoryList()
            }
        },
        // 发送消息
        sendQue() {
            if (this.question.trim()) { // 判断输入框是否为空
                this.sendDisabled = true;
                this.chatMessages.push({ content: this.question, isUser: true }); // 发送消息
                this.replyFromModel(this.question);  // 模拟大模型的回复
                this.question = '';  // 清空输入框
            } else {
                if (this.sendDisabled) return this.$message.info('正在回答中');
                this.$message.info('请输入问题');
            }
        },
        // 大模型的回复
        replyFromModel(query) {
            this.chatMessages.push({ content: '', isUser: false, loading: true }); // 发送消息
            let params = {
                packet: this.chatId,
                question: query,
            }
            const fileId = this.type === 'airForce' ? 1008 : 1010;
            getAction(`/navy/dbct-catalog/ManagementModel/getFileData4/${fileId}`, params).then(result => {
                console.log(result)
                
                    if (result.data.answer) {
                        this.typeEffect(this.chatMessages.length - 1, result.data.answer)
                    } else {
                        this.chatMessages[this.chatMessages.length - 1].content = '暂无回答';
                    }
                    this.chatMessages[this.chatMessages.length - 1].loading = false;                
            })
        },
        // 模拟打字
        typeEffect(arrindex, text) {

            let index = 0;
            const typeNextChar = () => {
                if (index < text.length) {

                    // 每次增加一个字符
                    if (this.chatMessages[arrindex]) {
                        this.chatMessages[arrindex].content += text[index];
                        index++;
                        // 随机生成下一个字符的打字速度
                        const randomSpeed = this.getRandomSpeed(this.minSpeed, this.maxSpeed);
                        // 动态定时调用下一个字符输出
                        setTimeout(typeNextChar, randomSpeed);
                    } else {

                        // 输出完毕,显示发送按钮
                        return this.sendDisabled = false
                    }
                } else {
                    this.sendDisabled = false
                }
            };
            typeNextChar();
        },
        // 生成随机速度
        getRandomSpeed(min, max) {
            // 生成范围[min, max]内的随机数
            return Math.floor(Math.random() * (max - min + 1)) + min;
        },
    }
}
</script>
<style scoped>
.content {
    width: 810px;
    height: 35vh;
    color:#fff;
    position:absolute;
    top: 50%;
    /* right:-100%; */
    transition: all 0.3s ease;
    transform: translateY( -50%);
    border: 1px solid #45a268;
    background: rgba(28, 82, 51, 1);
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    border-radius: 20px;
}
.tip{
    height:7%;
    width:100%;
    margin-bottom:5px;
    display: flex;
    cursor: pointer;
}
.tip >span{
    border: 1px solid #45a268;
    background: rgba(28, 82, 51, 1);
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    border-radius: 5px;
    padding:5px;
    margin-right:5px;
}
.chat-container {
    border: 1px solid #45a268;
    overflow-y: auto;
    border-radius: 10px;
    padding: 20px 20px 0;
    margin-bottom: 10px;
}
.chat-container-act {
    border: 1px solid #45a268;
    overflow-y: auto;
    border-radius: 10px;
    padding: 20px 20px 0;
}
.notes-item {
    display: flex;
    align-items: flex-start;
    margin-bottom: 20px;
}

.notes-item .xiaozhi-icon {
    width: 38px;
    height: 33px;
    vertical-align: text-top;
}

.notes-item img {
    width: 30px;
    vertical-align: middle;
    /*height: 42px;*/
}

.notes-item p {
    display: inline-block;
    vertical-align: text-top;
    margin-left: 14px;
    margin-right: 14px;
    background: linear-gradient(360deg, #063428 0%, #377540 100%);
    color: #ffffff;
    padding: 7px 12px;
    line-height: 21px;
    white-space: pre-wrap;
    /*margin-top: 4px;*/
    border-radius: 5px;
}

.notes-item span {
    display: inline-block;
    margin-left: 14px;
    color: #ffffff;
    padding: 11px 0;
}
.right-bottom {
    background: url("@/views/ykzmdmxDir/zszx/image/bg-4.png") no-repeat;
    background-size: 100% 100%;
    height: 100%;
    /* margin-top: 16px; */
    padding: 12px 12px;
    text-align: left;
    color: #fff;
    width: 100%;
    position: relative;
    box-sizing: border-box;
}
.qbzh-transparent-input {
    width: 100%;
    height: 100%;
    background-color: transparent;
    /* 透明背景 */
    border: none;
    /* 移除边框 */
    color: white;
    /* 继承父元素的文本颜色 */
    outline: none;
    /* 移除聚焦时的外边框 */
}
.bottom-btn {
    background: url("@/views/ykzmdmxDir/zszx/image/icon-2.png") 100% 100% no-repeat;
    background-size: 100% 100%;
    height: 32px;
    width: 62px;
    display: inline-block;
    position: absolute;
    right: 10px;
    bottom: 10px;
    cursor: pointer;
}
.qbzh-transparent-input::placeholder {
    color: white;
    /* 占位符颜色设置为白色 */
    opacity: 0.7;
    /* 占位符透明度(可选,根据需要调整) */
}
.historyBtn {
    cursor: pointer;
    color: #45a268;
    user-select: none;
}

.title {
    background-size: auto 100%;
    color: #ffffff;
    background-image: url("@/views/ykzmdmxDir/imgs/descTittleBox.png");
    font-size: 0.55rem;
    font-family: YouSheBiaoTiHei;
    width: 100%;
    text-align: center;
    margin-bottom: 20px;
}

.titleBtn {
    color: #ffffff;
    background: url("@/assets/image/btn-bg-green.png") center no-repeat;
    width: 105px;
    height: 35px;
    background-size: 100% 100%;
    line-height: 30px;
    cursor: pointer;
    position: relative;
    left: 50%;
    transform: translateX(-50%);
    margin-bottom: 10px;
}
.warp-radio-item {
    background: linear-gradient(360deg, #063428 0%, #377540 100%);
    margin-bottom: 10px;
    padding: 10px 20px 10px 10px;
    display: flex;
    justify-content: space-between;
}

.warp-radio-item-active {
    /*background: url("@/assets/image/radio-bg.png") center center no-repeat;*/
    /*background-size: 100% 100%;*/
    border: 1px solid #3d9c6c;
}
</style>

posted on 2025-04-25 16:21  芮艺  阅读(42)  评论(0)    收藏  举报