核工业西南物理研究院知识库AI客户端
xiangpei
2025-03-28 4b2f79bd2833ef99aa0c3825b03074be3f2f7196
src/components/AiChat.vue
@@ -1,18 +1,36 @@
<template>
  <div>
  <div style="position: relative;height:calc(100vh - 20px);width: 100%;display: flex;justify-content: center">
    <!-- 聊天消息列表 -->
    <div class="chat-messages">
      <div
          v-for="(message, index) in messages"
          :key="index"
          :key="message + index"
          :class="['message', message.role]"
          @mouseover="handleMouseEnter(message)"
      >
        <div class="avatar">
          <img :src="getAvatar(message.role)" alt="avatar" />
        </div>
        <div class="content">
<!--          <div class="name">{{ getRoleName(message.role) }}</div>-->
          <div class="text">{{ message.content }}</div>
          <div class="text" :ref="'msg' + index">{{ message.content }}</div>
          <div v-if="message.role === 'assistant'">
            <div v-show="msgIndex === message" class="msg-op-list">
              <el-button class="copy" v-show="false"/>
              <el-tooltip class="item" effect="dark" content="复制" placement="top">
                <i class="el-icon-copy-document msg-op msg-copy" @click="copyText(message.content)"/>
              </el-tooltip>
              <el-tooltip class="item" effect="dark" content="重新生成" placement="top">
                <i class="el-icon-refresh msg-op msg-re" @click="reAnswer"/>
              </el-tooltip>
            </div>
          </div>
        </div>
        <div v-if="message.role === 'user'">
          <div v-show="msgIndex === message" style="display: flex">
            <el-tooltip class="item" effect="dark" content="复制" placement="top">
              <i class="el-icon-copy-document msg-op msg-copy" @click="copyText(message.content)"/>
            </el-tooltip>
          </div>
        </div>
      </div>
    </div>
@@ -36,7 +54,9 @@
</template>
<script>
import ClipboardJS from 'clipboard';
import {sendKbMsg} from "@/api/chat";
import {Message} from "element-ui";
export default {
  name: 'AiChat',
@@ -45,6 +65,10 @@
      messages: [
        {
          role: 'assistant',
          content: '你好!我是你的 AI 助手,有什么可以帮你的吗?',
        },
        {
          role: 'user',
          content: '你好!我是你的 AI 助手,有什么可以帮你的吗?',
        },
      ],
@@ -71,10 +95,33 @@
        max_tokens: 0,
        prompt_name: "default",
        return_direct: false
      }
      },
      msgIndex: null,
      msgRole: null
    };
  },
  methods: {
    handleMouseEnter(msgIndex) {
      console.log("鼠标移入", msgIndex)
      this.msgIndex = msgIndex
    },
    handleMouseLeave() {
      console.log("鼠标移除")
      this.msgIndex = null
    },
    // 重新生成
    reAnswer() {
    },
    // 复制内容
    copyText(content) {
      const clipboard = new ClipboardJS('.copy', {
        text: () => content
      });
      // 触发复制(需要一个隐藏的按钮)
      document.querySelector('.copy').click();
      clipboard.destroy();
      Message.success("复制成功")
    },
    // 获取角色头像
    getAvatar(role) {
      const avatars = {
@@ -139,17 +186,21 @@
}
.chat-messages {
  flex: 1;
  padding: 16px;
  margin-top: 14px;
  overflow-y: auto;
  width: 800px;
  height: 680px;
}
.message {
  display: flex;
  margin-bottom: 16px;
  margin-bottom: 18px;
  min-height: 75px;
}
.message.user {
  align-items: center;
  flex-direction: row-reverse;
}
@@ -165,7 +216,7 @@
  padding: 8px 12px;
  border-radius: 8px;
  background-color: #fff;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  /*box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);*/
}
.message.user .content {
@@ -196,8 +247,25 @@
  justify-content: center;
  align-items: center;
  position: absolute;
  bottom: 70px;
  bottom: 50px;
  left: 50%; /* 将 div 的左边移动到父容器的 50% 位置 */
  transform: translateX(-50%); /* 将 div 向左移动自身宽度的 50% */
}
.msg-op-list {
  margin-top: 15px;
}
.msg-copy {
  font-size: 18px;
}
.msg-re {
  font-size: 20px;
}
.msg-op {
  color: gray;
  margin-right: 5px;
}
.msg-op:hover {
  cursor: pointer;
}
</style>