فهرست منبع

首页bug修复,红点,搜索列表,发送消息滚动到底部,重连web--没太行

“yueshang” 2 سال پیش
والد
کامیت
a5f63d336a

+ 1 - 1
src/api/chat/msg.js

@@ -129,7 +129,7 @@ export function fileDownload(data){
       method:"get"
   })
 }
-//测试
+//测试进度条
 export function uploadFileMany(data) {
   return request({
       url: `/biz/info/uploadFiles`,

+ 0 - 1
src/components/FileTreeChoice/index.vue

@@ -71,7 +71,6 @@ const treeData = reactive({ data: [] });
 watchEffect(() => {
   treeData.data[0]=props.fileUserTreeData
   toRaw(treeData.data);
-  console.log('toRaw(treeData.data);', toRaw(treeData.data))
 });
 
 //树

+ 0 - 1
src/components/PicTree/PicTree.vue

@@ -71,7 +71,6 @@ const treeData = reactive({ data: [] });
 watchEffect(() => {
   treeData.data[0]=props.fileUserTreeData
   toRaw(treeData.data);
-  console.log('toRaw(treeData.data);', toRaw(treeData.data))
 });
 
 //树

+ 15 - 3
src/layout/indexCommon.vue

@@ -53,8 +53,9 @@
               :to="item.path"
               v-for="(item, index) in menuList.data"
               :key="index"
-              @click="clickPath(index)"
+              @click="clickPath(index,item)"
               ><div
+              style="position: relative;"
                 :class="
                   $route.path == item.path
                     ? 'acitve-img-style img-style'
@@ -67,6 +68,7 @@
                 <div class="text-style" v-if="$route.path != item.path">
                   {{ item.label }}
                 </div>
+                <span class="yuandian" v-if="websoctStore.messOne?.fromId&&item.path == '/index'&& $route.path != item.path"></span>
               </div> </router-link
             ><br />
           </div>
@@ -107,6 +109,8 @@ import behighsearch from "@/assets/images/behighsearch.png";
 import { AppMain, Navbar, Settings, TagsView } from "./components";
 import { flieSearch } from "@/api/search/search.js";
 import { useRouter, useRoute } from "vue-router";
+import useWebsoctStore from "@/store/modules/websocket";
+const websoctStore = useWebsoctStore();
 const router = useRouter(); //注册路由
 const route = useRoute();
 const appStore = useAppStore();
@@ -264,8 +268,7 @@ const menuList = reactive({
     },
   ],
 });
-
-const clickPath = (index) => {
+const clickPath = (index,items) => {
   clickId.value = index;
 };
 </script>
@@ -391,4 +394,13 @@ const clickPath = (index) => {
     color: #fff !important;
   }
 }
+.yuandian {
+  width: 8px;
+  height: 8px;
+  position: absolute;
+  right: 8px;
+  top: 6px;
+  background: #fa5151;
+  border-radius: 4px;
+}
 </style>

+ 30 - 5
src/store/modules/websocket.js

@@ -14,16 +14,23 @@ const useWebsoctStore = defineStore('websoct', {
   }),
   actions: {
     connect() {
-      const useUser=useUserStore()
+      const url=`${window.location.origin.replace("http", "ws")}/websocket/message/${useUserStore().uid}`
+      let lockReconnect = false; //避免socket重复连接
+      if (!window.WebSocket) {
+        return ElMessage({ message: "您的浏览器不支持WebSocket,无法获取数据", type: "error" });
+      }
       if (window.WebSocket) {
-      this.socket = new WebSocket(`${window.location.origin.replace("http", "ws")}/websocket/message/${useUserStore().uid}`);
+      this.socket = new WebSocket(url);
       }
       this.socket.addEventListener("open", () => {
         // console.log("WebSocket连接已打开")
+        setInterval(() => {
+          this.sendHeartbeat();
+        }, 5000); // 每隔5秒发送一次心跳消息
       })
 
       this.socket.addEventListener("message", (event) => {
-        console.log('event发送消息', event)
+        // console.log('event发送消息', event)
         const message=event.data!='连接成功'?JSON.parse(JSON.stringify(event.data)):''
         this.messOne=event.data!='连接成功'?JSON.parse(event.data):{}
         this.messages.push(message)
@@ -32,11 +39,13 @@ const useWebsoctStore = defineStore('websoct', {
 
       this.socket.addEventListener("close", () => {
         // console.log("WebSocket连接已关闭")
-        ElMessage({ message: "WebSocket连接已关闭", type: "error" });
+        ElMessage({ message: "WebSocket重连失败,请尝试刷新界面", type: "error" });
+        reconnect(url);  //尝试重新连接
       })
 
       this.socket.addEventListener("error", (error) => {
-        console.error("WebSocket连接错误:", error)
+        ElMessage({ message: "WebSocket连接错误", type: "error" });
+        reconnect(url);  //尝试重新连接
       })
     },
     sendMessage(message) {
@@ -55,6 +64,22 @@ const useWebsoctStore = defineStore('websoct', {
     //     this.socket.send(JSON.stringify(message))
     //   }
     },
+    
+    // 重新连接
+    reconnect(url) {
+      if (lockReconnect) return ElMessage({ message: "WebSocket重连失败,请尝试刷新界面", type: "error" });
+      lockReconnect = true;
+      setTimeout(function () { //没连接上会一直重连,设置延迟避免请求过多
+          this.socket = new WebSocket(url);
+          lockReconnect = false;
+      }, 2000);
+    },
+    sendHeartbeat() {
+      if (this.socket && this.socket.readyState === WebSocket.OPEN) {
+        // 发送心跳消息,可以是一个特定的字符串,表示心跳消息
+        this.socket.send("heartbeat");
+      }
+    },
     handleMessage(event) {
         console.log('event', event)
       // 处理接收到的消息

+ 2 - 76
src/utils/progress.js

@@ -30,7 +30,7 @@ export function multiUpload() {
     }
   })
   if (readFileList.length > 0) {
-    multiRun(upload, readFileList.slice(0, upload.processNumber), uploadAsync)
+    multiRun(upload, readFileList.slice(0, upload.processNumber))
   }
 }
 
@@ -47,7 +47,7 @@ function multiRun(upload, keyList, func) {
   for (let j = 0; j < keyList.length; j += processNumber) {
     for (let i = 0; i < processNumber; i++) {
       if (i + j < keyList.length) {
-        promise[(j + i) % processNumber] = promise[(j + i) % processNumber].then(() => func(keyList[i + j]))
+        // promise[(j + i) % processNumber] = promise[(j + i) % processNumber].then(() => func(keyList[i + j]))
         // .catch(({fileInfo,err}) => {
         //   if (fileInfo?.status === 3) {
         //     console.log(fileInfo.file.name, '取消上传')
@@ -67,78 +67,6 @@ function multiRun(upload, keyList, func) {
     }
   }
 }
-
-function uploadAsync(fileInfo) {
-  const progress = fileInfo.progress
-  const file = fileInfo.file
-  return new Promise((resolve, reject) => {
-    progress.file_name = file.name
-    progress.file_size = file.size
-    if (fileInfo.status === 0) {
-      fileInfo.status = 1
-    } else {
-      return resolve()
-    }
-    progress.progress = 10
-    // getUploadSid().then(async res => {
-    //   progress.speed = '文件读取中'
-    //   let hash = await PreHash(file, progress)
-    //   let fileHashInfo = {
-    //     sid: res.data.sid,
-    //     file_name: progress.file_name,
-    //     file_size: progress.file_size,
-    //     pre_hash: hash
-    //   }
-    //   progress.progress = 20
-    //   checkPreHash(fileHashInfo).then(async pRes => {
-    //     if (pRes.data.check_status === true) {
-    //       progress.progress = 30
-    //       const md5Code = pRes.data.md5_token
-    //       progress.speed = '文件校验中'
-    //       let hash = await ContentHash(file, md5Code, progress)
-    //       fileHashInfo.proof_code = hash.proofCode
-    //       fileHashInfo.content_hash = hash.conHash
-    //       checkContentHash(fileHashInfo).then(async cRes => {
-    //         if (cRes.data.check_status === true) {
-    //           progress.progress = 100
-    //           progress.upload_size = progress.file_size
-    //           progress.speed = '秒传成功'
-    //           fileInfo.status = 2
-    //           fileInfo.upload_time = new Date()
-    //           multiUpload()
-    //           resolve()
-    //         } else {
-    //           return await ChunkedUpload(fileInfo, fileHashInfo, cRes.data.upload_extra, cRes.data.part_info_list, () => {
-    //             fileInfo.status = 2
-    //             fileInfo.upload_time = new Date()
-    //             multiUpload()
-    //             resolve()
-    //           }, (err) => {
-    //             reject({fileInfo, err})
-    //           })
-    //         }
-    //       }).catch((err) => {
-    //         reject({fileInfo, err})
-    //       })
-    //     } else {
-    //       return await ChunkedUpload(fileInfo, fileHashInfo, pRes.data.upload_extra, pRes.data.part_info_list, () => {
-    //         fileInfo.status = 2
-    //         fileInfo.upload_time = new Date()
-    //         multiUpload()
-    //         resolve()
-    //       }, (err) => {
-    //         reject({fileInfo, err})
-    //       })
-    //     }
-    //   }).catch((err) => {
-    //     reject({fileInfo, err})
-    //   })
-    // }).catch((err) => {
-    //   reject({fileInfo, err})
-    // })
-
-    // Update this part of the code based on your project's API for uploading files
-    console.log('file=========', file,)
     uploadFileMany({spaceId:useUserStoreId.spaceIdCommon,dirId:17,files:''}).then((res) => {
       progress.progress = 100
       progress.upload_size = progress.file_size
@@ -161,5 +89,3 @@ function uploadAsync(fileInfo) {
       }
       reject({fileInfo, err})
     })
-  })
-}

+ 41 - 16
src/views/liveChat/index.vue

@@ -61,15 +61,7 @@ const sendCont = reactive({
 });
 const searchText = ref(""); //搜
 const searchData = ref([]);
-const SearchChat = () => {
-  if (searchText.value) {
-    searchData.value = personList.data.filter((i) => {
-      return i.toName == searchText.value;
-    });
-  } else {
-    searchData.value = personList.data;
-  }
-}; //搜索的点击事件
+
 //聊天列表数据模拟
 const personList = reactive({ data: [] });
 //获取好友列表
@@ -79,7 +71,15 @@ const getMsgList = async () => {
   // .filter(
   //   (item) => item.toId !== useUserStore().uid
   // );
+
   searchData.value = personList.data;
+    //圆点======
+    searchData.value.map((i) => {
+       if(i.fromId==websoctStore.messOne?.fromId){i.showCircel=true}else{
+        i.showCircel=false
+       }
+    });
+  //圆点======
   sendCont.data.toId =
     personList.data[0]?.toId == userIds.uid
       ? personList.data[0].fromId
@@ -103,7 +103,6 @@ const msgRecordEvent = async (toIdValue) => {
   resMsgData.rows.map((i) => (i.isForward = false));
   chatRecords.data = resMsgData.rows.reverse();
   const nowtime = parseTime(new Date().getTime(), "{y}-{m}-{d}");
-  console.log("firstnowtime", nowtime);
   chatRecords.data.map((i) => {
     if (nowtime == i.createTime.substr(0, 10))
       i.createTime = i.createTime.substring(11);
@@ -134,6 +133,10 @@ const clickPerson = (index, item) => {
     : item.toName;
   noMes.value = false;
   clickPersonIndex.value = index;
+  //点击某个人就不显示红点
+  searchData.value.map((i) => {
+       if(i.fromId==websoctStore.messOne?.fromId){i.showCircel=false}
+    });
   msgRecordEvent(sendCont.data.toId);
 };
 //删除聊天
@@ -153,6 +156,7 @@ const delClick = (msgId) => {
 const changeMsg = async (val) => {
   const resInfo = await userInfo(val.id);
   if (searchData.value.length > 0) {
+    //判断是否有相同的聊天人
     const filerData = searchData.value.filter(
       (vPerson) =>
         (vPerson.toId && vPerson.toId == resInfo.userId) ||
@@ -174,6 +178,10 @@ const changeMsg = async (val) => {
 
 //发送聊天
 const msgSendClick = () => {
+  noMes.value = false;
+  if (messageText.value.trim() == "") {
+    return ElMessage({ message: "不能发送空白消息", type: "error" });
+  }
   const message = {
     content: messageText.value,
     msgType: "2",
@@ -181,6 +189,12 @@ const msgSendClick = () => {
     toId: sendCont.data.toId,
   };
   websoctStore.sendMessage(message);
+  //发送消息后滚动到最底部显示最新消息
+  const chatContainer = document.querySelector(".right-container");
+  // 计算滚动的目标位置
+  const targetScrollTop = chatContainer.scrollHeight;
+  // 设置滚动位置
+  chatContainer.scrollTop = targetScrollTop;
   messageText.value = "";
 };
 //发送文件确认按钮
@@ -206,14 +220,14 @@ const sendFileClick = async () => {
 const handleNewMessage = async () => {
   if (websoctStore.newMessage) {
     msgRecordEvent(sendCont.data.toId); //获取用户的聊天记录
-    getMsgList()
+    getMsgList();
     websoctStore.newMessage = false; // 重置新消息标记
   }
 };
 watchEffect(() => {
   if (websoctStore.messOne?.fromId) {
     msgRecordEvent(websoctStore.messOne.fromId);
-    getMsgList()
+    getMsgList();
   }
 });
 // 滚动翻页========
@@ -237,7 +251,6 @@ const loadPreviousPage = async () => {
     pageNum: currentPageNum,
     pageSize: 10,
   };
-
   const resMsgData = await msgRecord(sendCont.data.toId, queryParams);
   const previousPageData = resMsgData.rows.reverse();
   chatRecords.data = [...previousPageData, ...chatRecords.data];
@@ -281,9 +294,18 @@ const forwardClick = async (indexs, docIds) => {
 const forwardChangeMsg = async (val) => {};
 //点击下载
 const downClick = async (fileId) => {
-  // location.href=await fileDownload(fileId)
   location.href = `${import.meta.env.VITE_APP_BASE_API}/api/download/${fileId}`;
 };
+//搜索的点击事件
+const SearchChat = () => {
+  if (searchText.value) {
+    searchData.value = personList.data.filter((i) => {
+      return i.toName == searchText.value;
+    });
+  } else {
+    getMsgList();
+  }
+};
 // 滚动翻页========
 onMounted(() => {
   getMsgList();
@@ -357,7 +379,10 @@ onMounted(() => {
             {{ item.file?.fileName ? item.file?.fileName : item.content }}</span
           >
         </div>
-        <!-- <span class="yuandian" v-if="showCircel==item.fromId&&$route.path=='/index'"></span> -->
+        <span
+          class="yuandian"
+          v-if="item.showCircel&& $route.path == '/index'"
+        ></span>
       </div>
     </div>
     <!-- 右侧聊天 -->
@@ -491,7 +516,7 @@ onMounted(() => {
               clearable
               size="small"
               placeholder="请输入聊天内容"
-              maxlength="450"
+              maxlength="800"
               @keydown.enter="msgSendClick"
             />
             <!-- 发送按钮 -->

+ 86 - 30
src/views/transFile/index.vue

@@ -1,40 +1,96 @@
-<script>
-export default {
-  name: "ttansFile",
-};
-</script>
-<script setup>
-import { ref, reactive } from "vue";
-import { addUploadFile } from "@/utils/progress";
-const beforeUpload=(raw)=>{
-    addUploadFile(raw)
-  return false
-}
-</script>
-
 <template>
   <div>
-    <!-- before-upload限制上传的格式和大小  action请求url  drag拖拽上传 multiple多文件-->
     <el-upload
+      ref="upload"
+      :action="uploadFileUrl"
+      :multiple="true"
+      accept=".pdf, .doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.html"
       :before-upload="beforeUpload"
-      action="#"
-      class="upload"
-      drag
-      multiple
+      :on-success="upload"
     >
-      <el-icon class="el-icon--upload">
-        <upload-filled />
-      </el-icon>
-      <div class="el-upload__text">拖拽或 <em>点击上传</em></div>
-      <!-- 提示说明文字 -->
-      <template #tip>
-        <div class="el-upload__tip">
-          请上传文件,仅支持上传文件,不支持文件夹
-        </div>
-      </template>
+      <!-- <el-button type="primary">Select Files</el-button> -->
+      <el-button type="success">Upload</el-button>
     </el-upload>
+    <div v-for="file in fileList" :key="file.id">
+        <div>{{file.name}}</div>
+      <el-progress
+        :percentage="file.progress"
+        :text-inside="true"
+        :stroke-width="18"
+        color="#409EFF"
+        type="line"
+        status="success"
+      />
+    </div>
   </div>
 </template>
+  <script>
+export default {
+  name: "transfile",
+};
+</script>
+  <script setup>
+import { ref } from "vue";
+import axios from "axios";
+import useUserStore from "@/store/modules/user";
+import { getToken } from "@/utils/auth";
+import { ElUpload, ElButton, ElProgress } from "element-plus";
+const useUserStoreId = useUserStore();
+const uploadFileUrl = ref(
+  import.meta.env.VITE_APP_BASE_API + "/biz/info/uploadFiles"
+); // 上传文件服务器地址
+const fileList = ref([]);
+const beforeUpload = (file) => {
+  fileList.value.push({
+    id: Date.now(),
+    file,
+    progress: 0,
+  });
+  return true; // 防止文件自动上传
+};
+const upload = async () => {
+  console.log(" fileList.value", fileList.value);
+  const uploadPromises = fileList.value.map((fileObj) => {
+    console.log("first", fileObj);
+    uploadFile(fileObj.file, fileObj);
+  });
+  await Promise.all(uploadPromises);
+};
+
+const uploadFile = async (file, fileObj) => {
+  console.log("14444444444431", file, fileObj);
+  const formData = new FormData();
+  formData.append("files", file);
+  formData.append("spaceId", useUserStoreId.spaceIdCommon);
+  formData.append("dirId", 122);
+  const config = {
+    headers: {
+      "Content-Type": "multipart/form-data",
+      Authorization: getToken(),
+    },
+    onUploadProgress: (progressEvent) => {
+        console.log('progressEvent', progressEvent.loaded,progressEvent.total)
+      const progressPercent = Math.round(
+        (progressEvent.loaded / progressEvent.total) * 100 || 0
+      );
+      fileObj.progress = progressPercent;
+    },
+  };
 
-<style scoped>
+  try {
+      const response = await axios.post(uploadFileUrl.value, formData, config);
+    console.log("response", response);
+    // 处理成功响应
+  } catch (error) {
+    // 处理上传错误
+    console.error(error);
+  }
+};
+</script>
+  
+  <style lang="scss" scoped>
+.el-progress {
+  margin-bottom: 10px;
+
+}
 </style>