liuQiang 1 jaar geleden
bovenliggende
commit
ca5eb05756

+ 19 - 0
src/api/chatglm/chatglm.js

@@ -0,0 +1,19 @@
+import request from '@/utils/request'
+export function chat(data) {
+    return request({
+        url: '/chat-glm3',
+        method: 'post',
+        data: data,
+        timeout: 1000*60*5,
+        headers: {
+            'Content-Type': 'application/json'
+        }
+    })
+}
+export function canChat(data) {
+    return request({
+        url: '/chat-glm3',
+        method: 'get',
+        data: data
+    })
+}

BIN
src/assets/images/newIndex/aiBot.png


+ 214 - 0
src/layout/components/AIPage/AIPage.vue

@@ -0,0 +1,214 @@
+<template>
+  <div class="AIPage">
+    <div class="main">
+      <div class="chatBox" :style="{ height: chatBoxHeight }">
+        <div class="oneChat" v-for="item in msg" :key="item">
+          <template v-if="item.role != 'system'">
+            <div class="top">
+              <img
+                v-if="item.role == 'assistant'"
+                src="@/assets/images/newIndex/aiBot.png"
+                alt=""
+              />
+              <img v-else-if="userInfo.avatar" :src="userInfo.avatar" alt="" />
+              <span v-if="item.role == 'assistant'">智聚AI</span>
+              <span v-else>{{ userInfo.name }}</span>
+            </div>
+            <div class="chat" :class="{ botChat: item.role == 'assistant' }">
+              <span>{{ item.content }}</span>
+            </div>
+          </template>
+        </div>
+      </div>
+      <div class="btnBox">
+        <el-input
+          v-model="iptText"
+          style="width: 100%"
+          :autosize="{ minRows: 2, maxRows: 5 }"
+          type="textarea"
+          placeholder="请在此输入关键词"
+        />
+        <div class="chatBtn">
+          <img :src="send" class="send-info" @click="enterChat" />
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref, computed, watch, onMounted } from "vue";
+import { chat } from "@/api/chatglm/chatglm.js";
+import useUserStore from "@/store/modules/user";
+import send from "@/assets/images/send.png";
+import { getToken } from "@/utils/auth";
+const wangzhi = import.meta.env.VITE_APP_BASE_API;
+const iptText = ref("");
+const chatBoxHeight = ref();
+const userInfo = ref({});
+const resultData = ref("");
+const disabled = ref(false);
+const msg = ref([
+  {
+    role: "system",
+    content: "你是智聚AI, 一个大语言模型,用于提供适当的答复和支持。",
+  },
+  {
+    role: "assistant",
+    content: "你好,我是智聚AI, 一个大语言模型,用于提供适当的答复和支持。",
+  },
+]);
+
+// el-input的最小高度为52px(2行),每增加一行高度增加21px,最大为115px(5行)
+// 这里的数值可能需要根据实际的CSS调整
+const baseInputHeight = 52;
+const maxInputHeight = 115;
+const enterChat = () => {
+  if (disabled.value) return;
+  disabled.value = true;
+  const newUser = {
+    role: "user",
+    content: iptText.value,
+  };
+  msg.value.push(newUser); // 添加用户输入
+  resultData.value = ""; // 清空
+  iptText.value = ""; // 清空
+  // 设置传输的上下文
+  let query;
+  if (msg.value.length <= 12) {
+    query = msg.value;
+  } else {
+    const longArr = msg.value.slice(msg.value.length - 11, msg.value.length);
+    query = [msg.value[0], ...longArr];
+  }
+  fetch(`${wangzhi}/chat-glm3`, {
+    method: "post",
+    body: JSON.stringify(query),
+    headers: {
+      "Content-Type": "application/json",
+      Authorization: "Bearer " + getToken(),
+    },
+  })
+    .then((response) => {
+      const newAssistant = {
+        role: "assistant",
+        content: "",
+      }; // 添加智聚AI回复
+      msg.value.push(newAssistant); // 添加智聚AI回复
+      const reader = response.body.getReader();
+      const decoder = new TextDecoder();
+      function processText({ done, value }) {
+        if (done) {
+          disabled.value = false;
+        //   console.log("Stream finished");
+          return;
+        }
+        const message = decoder.decode(value);
+        // console.log("原:", message);
+        let newMsg = message
+          .replace("data:", "")
+          .replace("\n", "")
+          .replace("\n", "")
+          .replace("data:", "")
+          .replace("\n", "")
+          .replace("data:", "");
+        // console.log("改:", newMsg);
+        let v = resultData.value.replace("\n", "") + newMsg.replace("\n", "");
+        resultData.value = v;
+        msg.value[msg.value.length - 1].content = resultData.value;
+        return reader.read().then(processText);
+      }
+      return reader.read().then(processText);
+    })
+    .catch(console.error);
+};
+// 获取用户信息
+const getUserInfo = async () => {
+  const userStore = useUserStore();
+  userInfo.value = userStore;
+};
+// 监听iptText变化,动态调整chatBox和el-input的高度
+watch(
+  iptText,
+  (newValue, oldValue) => {
+    // 计算input高度(根据el-input实际高度调整)
+    const ipt = document.getElementsByClassName("el-textarea__inner")[0];
+    let inputHeight = ipt?.style.height.split("px")[0] || 52;
+    if(newValue == "")inputHeight = 52
+    inputHeight = Math.min(inputHeight, maxInputHeight); // 限制最大高度
+    chatBoxHeight.value = "calc(100% - " + inputHeight + "px - 5px)";
+  },
+  {
+    immediate: true,
+    deep: true,
+  }
+);
+onMounted(() => {
+  getUserInfo();
+});
+</script>
+
+<style lang="scss" scoped>
+.AIPage {
+  width: 100%;
+  height: 100%;
+  background-color: #eaf1f9;
+}
+.main {
+  width: 565px;
+  height: 100%;
+  padding: 24px 0 16px 0;
+  margin: 0 auto;
+  //   border: 1px solid #000;
+  .chatBox {
+    width: 100%;
+    background-color: #eaf1f9;
+    overflow-y: auto;
+  }
+}
+.oneChat {
+  width: 100%;
+  margin-bottom: 16px;
+  .top {
+    width: 100%;
+    height: 28px;
+    display: flex;
+    align-items: center;
+    img {
+      width: 28px;
+      height: 28px;
+    }
+    span {
+      margin-left: 8px;
+      font-weight: 500;
+      font-size: 15px;
+      color: #0d0f39;
+    }
+  }
+  .chat {
+    margin-left: 32px;
+    padding: 16px;
+    background-color: #dbe4ef;
+    border-radius: 12px 12px 12px 12px;
+    color: #0d0f39;
+    font-size: 15px;
+    font-weight: 400;
+  }
+  .botChat {
+    background-color: #fff !important;
+  }
+}
+.btnBox {
+  position: relative;
+  .chatBtn {
+    position: absolute;
+    top: calc(50% - 20px);
+    right: 20px;
+  }
+  .send-info {
+    width: 40px;
+    height: 40px;
+    border-radius: 16px;
+  }
+}
+</style>

+ 24 - 11
src/layout/components/DefaultPage/DefaultPage.vue

@@ -276,8 +276,8 @@ const allLoading = ref(false);
 const highLoading = ref(false);
 const highPage = ref(1);
 const allPage = ref(1);
-const highEnd = ref(false)
-const allEnd = ref(false)
+const highEnd = ref(false);
+const allEnd = ref(false);
 
 const emit = defineEmits([
   "openMaxmin",
@@ -373,15 +373,14 @@ const toFile = async (row) => {
 // 高级搜索触底加载
 const setScroll = async () => {
   if (highEnd.value) return;
-    highPage.value++;
-    emit("highSearch", highPage.value);
+  highPage.value++;
+  emit("highSearch", highPage.value);
 };
 // all搜索触底加载
 const allScroll = async () => {
-  if (allEnd.value) 
-    return;
-    allPage.value++;
-    emit("allSearch", allPage.value);
+  if (allEnd.value) return;
+  allPage.value++;
+  emit("allSearch", allPage.value);
 };
 // 设置icon
 const setImg = (type) => {
@@ -462,12 +461,26 @@ function sureUpload() {
               message: "上传文件成功",
               type: "success",
             });
-            // getAllTop()
-            refreshFile();
-            uploadModal.value = false;
             loadingUpload.value = false;
             fileArr.value = [];
             fileBig.value = 0;
+            const storage = sessionStorage.getItem("tagList");
+            if (storage) {
+              const oldStorage = JSON.parse(storage);
+              // 判断是否存在myfile
+              const myfileTag = oldStorage.find((item) =>
+                item.path.includes("myfile")
+              );
+              if (myfileTag.id) {
+                const tagIfarme = document.querySelector(
+                  `#${myfileTag.id} iframe`
+                );
+                const iframeWindow = tagIfarme.contentWindow.window;
+                iframeWindow.$refreshFile();
+              } else {
+                return;
+              }
+            }
           }
         })
         .catch((err) => {

+ 9 - 2
src/layout/components/TopMenu/TopMenu.vue

@@ -29,7 +29,7 @@
       </div>
     </div>
     <div class="user">
-      <div class="AIBot hand" v-if="false">
+      <div class="AIBot hand" v-if="showAi" @click="openTab('智聚AI', '/aipage')">
         <img src="@/assets/images/newIndex/bot.png" alt="" />
         <span>智聚AI</span>
       </div>
@@ -134,6 +134,7 @@ import {
   watchEffect,
   watch,
 } from "vue";
+import { canChat } from "@/api/chatglm/chatglm.js";
 import bebumen from "@/assets/images/bebumen.png";
 import common from "@/assets/images/becommon.png";
 import manyBody from "@/assets/images/manyBodyFalse.png";
@@ -188,6 +189,7 @@ const openScanMove = ref(false);
 const openScan = ref(false); //控制扫描文档显示
 const scanFileArr = ref([]); //认领的扫描文件数组
 const hasNewMessage = ref(false);
+const showAi = ref(false);
 const emit = defineEmits(["openMaxmin", "goIndex"]);
 // 鼠标移入 显示更多菜单
 const showMoreMenu = () => {
@@ -223,7 +225,11 @@ const openTab = (title, path) => {
 const toIndex = () => {
   emit("goIndex");
 };
-
+// 判断是否可以使用ai
+const canChatFn = async () => {
+  const res = await canChat();
+  showAi.value = res;
+};
 //退出
 function logout() {
   setTimeout(() => {
@@ -287,6 +293,7 @@ const closeOpenScanMove = () => {
 };
 let lisetenMessageTime = null;
 onMounted(() => {
+  canChatFn()
   document.addEventListener("click", (e) => {
     if (e.target.className !== "oneMenu finger") {
       hideMoreMenu();

+ 7 - 0
src/router/index.js

@@ -376,6 +376,13 @@ export const constantRoutes = [{
 	}
 },
 {
+	path: "/aipage",
+	component: () => import("@/layout/components/AIPage/AIPage.vue"),
+	name: "aipage",
+	hidden: true,
+
+},
+{
 	path: "/department",
 	component: () => import("@/views/department/MyFile"),
 	name: "department",

+ 1 - 1
src/views/myfile/MyFile.vue

@@ -407,7 +407,7 @@
 
                 </div>
             </div>
-            <div class="setCli" id="setCli" v-if="cliCC" :style="{ left: xz + 'px', top: yz - 160 + 'px' }">
+            <div class="setCli" id="setCli" v-if="cliCC" :style="{ left: xz + 'px', top: yz - 150 + 'px' }">
                 <template v-for="(item, index) in filterMouseCli()" :key="index">
                     <p @click="chooseSet(item, index, 1)" :class="{'hasLine':item.name == '删除' ||item.name == '文字识别','btmLine':(item.name == '收藏' && !noHis)||item.name == '下载'}" class="chooseSet">
                         <img :src="item.img" alt="">