Преглед изворни кода

首页聊天的转发,未开发完

“yueshang” пре 2 година
родитељ
комит
bb830fd5cf

BIN
src/assets/images/down-file.png


BIN
src/assets/images/forward-file.png


BIN
src/assets/images/word2.png


+ 209 - 156
src/assets/styles/my-common.scss

@@ -1,182 +1,235 @@
-.spill{
-    display: -webkit-box; /*弹性伸缩盒子模型显示*/
-    -webkit-box-orient: vertical; /*排列方式*/
-    -webkit-line-clamp: 1; /*显示文本行数*/
-    overflow: hidden; /*溢出隐藏*/
+.spill {
+  display: -webkit-box;
+  /*弹性伸缩盒子模型显示*/
+  -webkit-box-orient: vertical;
+  /*排列方式*/
+  -webkit-line-clamp: 1;
+  /*显示文本行数*/
+  overflow: hidden;
+  /*溢出隐藏*/
 }
-.flex-buju{
-    display: flex;
-    align-items: center;
-    justify-content: center;
+
+.flex-buju {
+  display: flex;
+  align-items: center;
+  justify-content: center;
 }
 
 .main {
-    overflow: hidden;
+  overflow: hidden;
+  display: flex;
+  justify-content: space-between;
+
+  .left-main,
+  .right-main {
+    background: #fff;
+    border-radius: 4px;
+  }
+
+  //左侧板块
+  .left-main {
+    // width: 312px;
+    width: 20.1%;
+    margin-right: 8px;
+
+    .left-top {
+      display: flex;
+      justify-content: space-around;
+      align-items: center;
+      height: 48px;
+      background: #ebeff6;
+      border-top-right-radius: 4px;
+      border-top-left-radius: 4px;
+    }
+  }
+
+  //右侧板块
+  .right-main {
+    width: 100%;
+    flex-grow: 1;
     display: flex;
-    justify-content: space-between;
-    .left-main,
-    .right-main {
-      background: #fff;
-      border-radius: 4px;
+    flex-direction: column;
+
+    .right-header {
+      background-color: #ebeff6;
+      border-top-right-radius: 4px;
+      border-top-left-radius: 4px;
     }
-    //左侧板块
-    .left-main {
-      // width: 312px;
-      width: 20.1%;
-      margin-right: 8px;
-      .left-top {
-        display: flex;
-        justify-content: space-around;
-        align-items: center;
-        height: 48px;
-        background: #ebeff6;
-        border-top-right-radius: 4px;
-        border-top-left-radius: 4px;
-      }
+
+    .right-container {
+      // flex: 1;
+      height: 300px !important;
+      overflow: auto;
+      border-bottom: 1px solid #c1cce3;
     }
-    //右侧板块
-    .right-main {
-      width: 100%;
-      flex-grow: 1;
+
+    .right-footer {
       display: flex;
-      flex-direction: column;
-      .right-header {
-        background-color: #ebeff6;
-        border-top-right-radius: 4px;
-        border-top-left-radius: 4px;
+      align-items: center;
+
+      :deep .el-input__wrapper {
+        background: #f5f7f9 !important;
+        border-radius: 16px;
+      }
+
+      .w-50 {
+        margin: 0 16px;
+        flex: 1;
       }
-      .right-container {
-        // flex: 1;
-        height: 300px !important;
-        overflow: auto;
-        border-bottom: 1px solid #c1cce3;
+
+      .send-info {
+        width: 40px;
+        height: 40px;
+        border-radius: 16px;
       }
-      .right-footer {
-        display: flex;
-        align-items: center;
-        :deep .el-input__wrapper {
-          background: #f5f7f9 !important;
-          border-radius: 16px;
-        }
-        .w-50 {
-          margin: 0 16px;
-          flex: 1;
-        }
-        .send-info {
-          width: 40px;
-          height: 40px;
-          border-radius: 16px;
-        }
-        .send-info-file {
-          width: 28px;
-          height: 28px;
-        }
-        :deep .el-input {
-          width: 80%;
-          height: 40px;
-          border-radius: 16px;
-          --el-input-border-color: #c9d2e6;
-        }
+
+      .send-info-file {
+        width: 28px;
+        height: 28px;
+      }
+
+      :deep .el-input {
+        width: 80%;
+        height: 40px;
+        border-radius: 16px;
+        --el-input-border-color: #c9d2e6;
       }
     }
   }
-  //搜索
-  .search {
-    .w-50,
-    :deep .el-input {
-      width: 80%;
-      height: 32px;
-      border-radius: 4px;
-      --el-input-border-color: #c9d2e6;
-    }
+}
+
+//搜索
+.search {
+
+  .w-50,
+  :deep .el-input {
+    width: 80%;
+    height: 32px;
+    border-radius: 4px;
+    --el-input-border-color: #c9d2e6;
   }
-  //聊天头像
-  .head-sculpture {
-      width: 40px;
-      height: 40px;
-      border-radius: 20px;
-      margin: 0 8px 0 12px;
-      vertical-align: middle;
-    }
-  
-  //左侧聊天列表展示
-  .left-container {
-    height: 80px;
+}
+
+//聊天头像
+.head-sculpture {
+  width: 40px;
+  height: 40px;
+  border-radius: 20px;
+  margin: 8px 12px;
+  vertical-align: middle;
+}
+
+//左侧聊天列表展示
+.left-container {
+  height: 80px;
+  display: flex;
+  align-items: center;
+  border-bottom: 1px solid #c1cce3;
+  position: relative;
+
+  &>div:last-child {
+    vertical-align: middle;
+    margin-right: 10px;
     display: flex;
-    align-items: center;
-    border-bottom: 1px solid #c1cce3;
-    position: relative;
-    & > div:last-child {
-      vertical-align: middle;
-      margin-right: 10px;
-      display: flex;
-      height: 40px;
-      justify-content: space-between;
-      flex-direction: column;
-      .person-name {
-        font-family: "Inter-Medium";
-        color: #000;
-        font-size: 16px;
-      }
-      .person-cont {
-        color: #505870;
-        font-size: 14px;
+    height: 40px;
+    justify-content: space-between;
+    flex-direction: column;
 
-      }
+    .person-name {
+      font-family: "Inter-Medium";
+      color: #000;
+      font-size: 16px;
     }
-    .del-chat{
-      position: absolute;
-      right: 8px;
-      bottom: -8px;
-      width: 88px;
-      height: 38px;
-      box-shadow: 0px 2px 8px 1px rgba(199,203,216,0.5);
-      background: rgba(255,255,255,0.9);
-      border-radius: 4px;
-      border: none;
+
+    .person-cont {
+      color: #505870;
+      font-size: 14px;
+
     }
   }
-  //点击时列表的背景色
-  .activ-left-container {
-    background: #f5f7f9;
-  }
-  .cebian {
-    height: 100%;
-    width: 4px;
+
+  .del-chat {
     position: absolute;
-    left: 0;
+    right: 8px;
+    bottom: -8px;
+    width: 88px;
+    height: 38px;
+    box-shadow: 0px 2px 8px 1px rgba(199, 203, 216, 0.5);
+    background: rgba(255, 255, 255, 0.9);
+    border-radius: 4px;
+    border: none;
   }
-  //聊天
-  .message-container {
-    display: flex;
-    align-items: flex-start;
-    margin-bottom: 20px;
+}
 
-  }
-  
-  .message-left {
-    margin-right: 40%;   
-    justify-content: flex-start;
-    .left-back{
-      background: #EBEFF6;
-    border-radius: 20px 20px 20px 0px;
-    padding: 8px 16px;
-    }
+//点击时列表的背景色
+.activ-left-container {
+  background: #f5f7f9;
+}
+
+.cebian {
+  height: 100%;
+  width: 4px;
+  position: absolute;
+  left: 0;
+}
 
+//聊天
+.message-container {
+  display: flex;
+  align-items: flex-start;
+  margin-bottom: 20px;
+  font-size: 14px;
+}
+
+.message-left {
+  margin-right: 40%;
+  justify-content: flex-start;
+
+  .left-back {
+    background: #EBEFF6;
+    border-radius: 20px 20px 20px 0px;
+    padding-right: 13px;
   }
-  
-  .message-right {
-    // width: 80%;
-    margin-left: 40%;
-    justify-content: flex-end;
-    .right-back{
-      padding: 8px 16px;
-      background: #2E6BC8;
+
+}
+
+.message-right {
+  // width: 80%;
+  margin-left: 40%;
+  justify-content: flex-end;
+
+  .right-back {
+    display: flex;
+    background: #2E6BC8;
+    color: #fff;
+
     border-radius: 20px 20px 0px 20px;
-    }
   }
-  .time-text{
-    display: flex;
-    flex-direction: column;
-    align-items: flex-end;
-  }
+}
+
+.time-text {
+  display: flex;
+  flex-direction: column;
+  // align-items: flex-end;
+  align-items: center;
+}
+.file-msg{
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+}
+.clip-path{
+  margin: 8px 15px 8px 15px;
+}
+.clip-path-right{
+
+  padding-right: 13px;
+}
+//转发下载图片的大小
+.zhuanfa{
+  width: 22px;
+  height: 22px;
+}
+.forwd{
+margin:0 16px;
+}

+ 35 - 0
src/assets/styles/tree-common.scss

@@ -0,0 +1,35 @@
+:deep(.el-dialog__header) {
+    --el-dialog-bg-color: #0b4ab7 !important;
+  }
+  .my-header {
+    margin: -20px -36px -20px -20px;
+    .title {
+      background: #ebeff6;
+      padding: 15px;
+    }
+  }
+  
+  .main-cont {
+    height: 348px;
+    border: 1px solid #c1cce3;
+    display: flex;
+  
+    .main-cont-left,
+    .main-cont-right {
+      width: 99%;
+      height: 100%;
+    }
+    .main-cont-right {
+      border-left: 1px solid #c1cce3;
+    }
+  }
+  .w-50 {
+    width: 94%;
+    margin: 8px;
+  }
+  .cancel-button {
+    border: 1px solid #c1cce3;
+  }
+  .sure-button {
+    background-color: #2e6bc8;
+  }

+ 1 - 38
src/components/AddPerson/index.vue

@@ -23,11 +23,7 @@
         :filter-method="filterMethod"
         :props="defaultProps"  @node-click="handleNodeClick" />
     </div>
-    <!-- <div class="main-cont-right">
-        <div class="main-cont-item">{{ clickData.label }}</div>
-    </div> -->
   </div>
-    <!-- <el-transfer :titles="['显示', '隐藏']"></el-transfer> -->
     <template #footer>
       <span class="dialog-footer">
         <el-button @click="isOpen = false" class="cancel-button">取消</el-button>
@@ -105,38 +101,5 @@ onMounted(() => {
 });
 </script>
 <style lang="scss" scoped>
-:deep(.el-dialog__header) {
-    --el-dialog-bg-color: #0b4ab7 !important;
-}
-.my-header{
-    margin: -20px -36px -20px -20px;
-    .title{
-        background: #EBEFF6;
-        padding: 15px;
-    }
-}
-
-.main-cont{
-    height: 348px;
-    border: 1px solid #C1CCE3;
-    display: flex;
-
-    .main-cont-left, .main-cont-right{
-      width: 100%;
-      height: 100%;
-    }
-    .main-cont-right{
-        border-left: 1px solid #C1CCE3;
-    }
-}
-.w-50{
-    width: 94%;
-    margin: 8px;
-}
-.cancel-button{
-  border: 1px solid #C1CCE3;
-}
-.sure-button{
-  background-color: #2E6BC8;
-}
+@import "@/assets/styles/tree-common.scss";
 </style>

+ 3 - 40
src/components/FileTreeChoice/index.vue

@@ -67,7 +67,6 @@ watch(
     isOpen.value = newValue;
   }
 );
-
 const treeData = reactive({ data: [] });
 watchEffect(() => {
   treeData.data[0]=props.fileUserTreeData
@@ -79,7 +78,6 @@ const clickData = ref({});
 const handleNodeClick = (data) => {
   clickData.value = data;
 };
-
 //确定按钮
   const emit = defineEmits(["fileChangeMsg"]);
 const confirm = () => {
@@ -87,45 +85,10 @@ const confirm = () => {
   if(disabled.value){
     return ElMessage({ message: '当前选中为目录,请重新选择文件', type: 'error' })
   }
-    emit("fileChangeMsg",  clickData.value);
+    emit("fileChangeMsg", clickData.value);
     isOpen.value  = false
 };
-onMounted(() => {});
 </script>
-  <style lang="scss" scoped>
-:deep(.el-dialog__header) {
-  --el-dialog-bg-color: #0b4ab7 !important;
-}
-.my-header {
-  margin: -20px -36px -20px -20px;
-  .title {
-    background: #ebeff6;
-    padding: 15px;
-  }
-}
-
-.main-cont {
-  height: 348px;
-  border: 1px solid #c1cce3;
-  display: flex;
-
-  .main-cont-left,
-  .main-cont-right {
-    width: 99%;
-    height: 100%;
-  }
-  .main-cont-right {
-    border-left: 1px solid #c1cce3;
-  }
-}
-.w-50 {
-  width: 94%;
-  margin: 8px;
-}
-.cancel-button {
-  border: 1px solid #c1cce3;
-}
-.sure-button {
-  background-color: #2e6bc8;
-}
+<style lang="scss" scoped>
+@import "@/assets/styles/tree-common.scss";
 </style>

+ 95 - 0
src/components/forwordTree/index.vue

@@ -0,0 +1,95 @@
+<template>
+    <el-dialog v-model="isOpen" append-to-body width="700">
+      <template #header>
+        <div class="my-header">
+          <div class="title">选择文件</div>
+        </div>
+      </template>
+      <div class="main-cont">
+        <div class="main-cont-left">
+          <el-tree-v2
+            ref="treeRef"
+            :data="treeData.data"
+            :show-checkbox="false"
+            :height="280"
+            :props="defaultProps"
+            @node-click="handleNodeClick"
+          >
+            <template #default="{ node }">
+              <span style="display: flex;align-items: center;">
+                <img :src="fileImg" alt="" style="width: 20px;height: 20px;margin-right: 5px;"/>
+                <!-- 放置图片 -->
+                <span>{{ node.label }}</span>
+                <!-- 显示节点标签 -->
+              </span>
+            </template>
+          </el-tree-v2>
+        </div>
+      </div>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="isOpen = false" class="cancel-button"
+            >取消</el-button
+          >
+          <el-button type="primary" @click="confirm" class="sure-button">
+            确认
+          </el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </template>
+    <script setup>
+  import { reactive, ref, toRaw, toRefs, watch } from "vue";
+  import { ElMessage } from "element-plus";
+  import fileImg from "@/assets/images/file-img.png";
+  import useUserStore from "@/store/modules/user";
+  import { defineEmits } from "vue";
+  const opent = ref(true);
+  const props = defineProps({
+    openForwardFile: {
+      type: Boolean,
+      default: false,
+    },
+    forwardTreeData: {
+      type: Object,
+      default: () => {},
+    },
+  });
+  const defaultProps = {
+    children: "children",
+    label: "label",
+    value: "id",
+  };
+  const isOpen = ref(props.openForwardFile);
+  watch(
+    () => props.openForwardFile,
+    (newValue) => {
+      isOpen.value = newValue;
+    }
+  );
+  const treeData = reactive({ data: [] });
+  watchEffect(() => {
+    treeData.data[0]=props.forwardTreeData
+    console.log(treeData.data,'treeData.data')
+    toRaw(treeData.data);
+  });
+  
+  //树
+  const clickData = ref({});
+  const handleNodeClick = (data) => {
+    clickData.value = data;
+  };
+  //确定按钮
+    const emit = defineEmits(["forwardChangeMsg"]);
+  const confirm = () => {
+    const {disabled,label}=toRefs(clickData.value)
+    if(disabled.value){
+      return ElMessage({ message: '当前选中为目录,请重新选择文件', type: 'error' })
+    }
+      emit("forwardChangeMsg", clickData.value);
+      isOpen.value  = false
+  };
+  </script>
+  <style lang="scss" scoped>
+  @import "@/assets/styles/tree-common.scss";
+  </style>

+ 1 - 1
src/layout/indexCommon.vue

@@ -231,7 +231,7 @@ const clickPath = (index) => {
 //整体布局css
 .common-layout,
 .el-container {
-  height: 100vh;
+  height: 94vh;
 }
 :deep .el-main {
   --el-main-padding: 8px !important;

+ 68 - 34
src/views/liveChat/index.vue

@@ -6,10 +6,12 @@ export default {
 <script setup>
 import { ref, reactive, toRaw, toRefs } from "vue";
 import useUserStore from "@/store/modules/user";
-import word from "@/assets/images/word.png";
+import word from "@/assets/images/word2.png";
 import chat from "@/assets/images/profile.jpg";
 import cebian from "@/assets/images/cebian.png";
 import send from "@/assets/images/send.png";
+import downFile from "@/assets/images/down-file.png";
+import forwardFile from "@/assets/images/forward-file.png";
 import sendFile from "@/assets/images/send-file.png";
 import store from "@/store";
 import {
@@ -21,10 +23,10 @@ import {
   delMsg,
   dirTree,
   fileTree,
-  getConfigKeys,
 } from "@/api/chat/msg";
 import Addperson from "@/components/AddPerson/index.vue"; //添加人员的弹框
 import FileTreeChoice from "@/components/FileTreeChoice/index.vue"; //选择文件发送的列表
+import forwordTree from "@/components/forwordTree/index.vue"; //选择文件发送的列表
 //websocket连接====
 import useWebsoctStore from "@/store/modules/websocket";
 import { ElMessage } from "element-plus";
@@ -37,7 +39,9 @@ const messageText = ref(""); //发送的内容
 const headerName = ref("");
 const total = ref(0);
 const sendId = ref(""); //选择发送的文件id
+const isForward=ref(false)
 const openFile = ref(false); //文件目录
+const openForwardFile = ref(false); //转发目录
 const chatRecords = reactive({ data: [] });
 const sendCont = reactive({
   //发送聊天内容数据组装
@@ -90,26 +94,9 @@ const msgRecordEvent = async (toIdValue) => {
     pageSize: 10,
   };
   const resMsgData = await msgRecord(toIdValue, queryParams);
+  resMsgData.rows.map(i=>i.isForward=false)
   chatRecords.data = resMsgData.rows.reverse();
   total.value = resMsgData.total;
-  console.log('sendId.value',sendId.value)
-  if (sendId.value) {
-    //转换文件名称
-    const res = await getConfigKeys(sendId.value);
- 
-    chatRecords.data.forEach((i) => {
-      console.log('i.content', i.content,res.docId)
-      if (i.content == res.docId) {
-        console.log("res.docId======", res.docId);
-        i.content = res.fileName;
-        i.fileType = res.fileType;
-        i.dirId = res.dirId;
-        i.fileSize = res.fileSize;
-      }
-    });
-    sendId.value = "";
-  }
-
 };
 //点击左侧新建聊天
 const open = ref(false);
@@ -139,7 +126,6 @@ const clickPerson = (index, item) => {
 };
 //删除聊天
 const delClick = (msgId) => {
-  console.log("msgId", msgId);
   proxy.$modal
     .confirm("删除后,将清空该聊天的消息记录")
     .then(function () {
@@ -169,7 +155,6 @@ const changeMsg = async (val) => {
     //为空数组的时候无需判断
     searchData.value.unshift(resInfo);
   }
-  console.log("first", searchData.value);
   sendCont.data.toId = resInfo.userId;
   msgRecordEvent(sendCont.data.toId);
   headerName.value = resInfo.nickName;
@@ -182,22 +167,20 @@ const msgSendClick = () => {
     msgType: "2",
     fileList: [],
     toId: sendCont.data.toId,
-  }
+  };
   websoctStore.sendMessage(message);
   messageText.value = "";
 };
 //发送文件确认按钮
 const fileChangeMsg = async (val) => {
-  const ids=toRefs(val)
   const message = {
-    content: ids.value,
+    content: val.id,
     msgType: "1",
     fileList: [],
     toId: sendCont.data.toId,
   };
-  sendId.value =ids.value;
+  sendId.value = val.id;
   websoctStore.sendMessage(message);
-  console.log('sendId.value',sendId.value)
 };
 //点击发送文件图标
 const fileUserTreeData = reactive({ data: {} });
@@ -215,7 +198,6 @@ const handleNewMessage = () => {
   }
 };
 watchEffect(() => {
-  console.log("first", websoctStore.messOne);
   if (websoctStore.messOne?.fromId) {
     msgRecordEvent(websoctStore.messOne.fromId);
   }
@@ -244,6 +226,30 @@ const loadPreviousPage = async () => {
   // 将加载的上一页聊天记录插入到 chatRecords.data 的前面
   chatRecords.data = [...previousPageData, ...chatRecords.data];
 };
+const transferFiles=(forwardVal,msgIds)=>{
+  chatRecords.data.map(i=>{
+    if(i.msgId==msgIds&&i.msgType=='1'){
+      i.isForward=true
+    }else{
+      i.isForward=false
+    }
+  })
+}
+// 点击转发
+const forwardTreeData = reactive({ data: {} });
+const forwardClick=async ()=>{
+  const resDir = await dirTree(3);
+  forwardTreeData.data = resDir;
+  toRaw(forwardTreeData.data);
+  openFile.value = true;
+}
+const forwardChangeMsg = async (val) => {
+
+};
+//点击下载
+const downClick=()=>{
+
+}
 // 滚动翻页========
 onMounted(() => {
   getMsgList();
@@ -340,16 +346,44 @@ onMounted(() => {
             >
               <div
                 v-if="useUserStore().uid !== record.toId"
-                class="time-text right-back"
+                :class="record.msgType == '1'?'file-msg right-back':'time-text right-back'"
               >
-                <div>{{ record.createTime }}</div>
-                <span>{{ record.content }}</span>
+                <img :src="word"  v-if="record.msgType == '1'" class="head-sculpture" />
+                <div :class="record.msgType == '2'?'clip-path':'clip-path-right'">
+                  <div>{{ record.createTime }}</div>
+                  <span v-if="record.msgType == '1'">{{
+                    record.file?.fileName
+                  }}</span>
+                  <span v-else-if="record.msgType == '2'">{{
+                    record.content
+                  }}</span>
+                </div>
               </div>
               <img :src="chat" class="head-sculpture" />
-              <div v-if="useUserStore().uid == record.toId" class="left-back">
-                <div>{{ record.createTime }}</div>
-                <span>{{ record.content }}</span>
+              <div style="display: flex;align-items: center;">
+              <div v-if="useUserStore().uid == record.toId"  :class="record.msgType == '1'?'file-msg left-back':'left-back'" @click="transferFiles(record.msgType,record.msgId)">
+                <img
+                  v-if="record.msgType == '1'"
+                  :src="word"
+                  class="head-sculpture"
+                />
+                <div :class="record.msgType == '2'?'clip-path':'clip-path-left'">
+                  <div>{{ record.createTime }}</div>
+                  <span v-if="record.msgType == '1'">{{
+                    record.file?.fileName
+                  }}</span>
+                  <span  v-else-if="record.msgType == '2'">{{ record.content }}</span>
+                </div>
               </div>
+                  <img :src="forwardFile" class="zhuanfa forwd" alt="转存" v-if="record.isForward" @click="forwardClick">
+                  <img :src="downFile" class="zhuanfa downf" alt="下载" v-if="record.isForward" @click="downClick">
+                    <forwordTree
+                    :openForwardFile="openForwardFile"
+                    @close="openForwardFile = false"
+                    :forwardTreeData="forwardTreeData.data"
+                    @forwardChangeMsg="forwardChangeMsg"
+                  ></forwordTree>
+                </div>
             </div>
           </el-main>
           <!-- 底部 -->