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

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

@@ -35,11 +35,46 @@ export function updateMsg(data) {
   })
 }
 
-// 删除聊天消息管理;
+// 获得聊天消息管理;
 export function msgFriend(msgId) {
   return request({
     url: '/chat/msg/friend',
     method: 'get'
   })
 }
+// 删除聊天消息管理;
+export function delMsg(msgId) {
+  return request({
+    url: '/chat/msg',
+    method: 'delete'
+  })
+}
+//树获取用户信息
+export function userTree() {
+  return request({
+    url: '/system/user/tree',
+    method: 'get'
+  })
+}
+//选择树时得到用户个人的详细信息,包含头像等
+export function userInfo(data) {
+  return request({
+    url: '/system/user/info/'+data,
+    method: 'get'
+  })
+}
+//发送消息
+export function msgSend(data) {
+  return request({
+      url: "/chat/msg/send",
+      method: "post",
+      data
+  })
+}
+export function msgRecord(data) {
+  return request({
+    url: '/chat/msg/record/'+data,
+    method: 'get'
+  })
+}
 

+ 11 - 0
src/assets/styles/my-common.scss

@@ -121,6 +121,17 @@
         font-size: 14px;
       }
     }
+    .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;
+    }
   }
   //点击时列表的背景色
   .activ-left-container {

+ 86 - 11
src/components/AddPerson/index.vue

@@ -1,59 +1,134 @@
 <template>
   <el-dialog
     v-model="isOpen"
-    title="新建聊天"
     append-to-body
-    width="512"
+    width="342"
   >
+  <template #header>
+      <div class="my-header">
+        <div class="title">新建聊天</div>
+      </div>
+    </template>
   <div class="main-cont">
-    <div class="main-cont-left"></div>
-    <div class="main-cont-right"></div>
+    <div class="main-cont-left">
+        <div class="main-cont-item">  <el-input
+          v-model="searchText"
+          class="w-50 m-2"
+          size="default"
+          placeholder="搜索人员"
+          suffix-icon="Search"
+          @change="SearchPerson"
+        /></div>
+        <el-tree-v2 ref="treeRef" :data="treeData.data" :show-checkbox="false" :height="283" 
+        :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="dialogFormVisible = false">取消</el-button>
-        <el-button type="primary" @click="dialogFormVisible = false">
+        <el-button @click="isOpen = false">取消</el-button>
+        <el-button type="primary" @click="confirm">
           确认
         </el-button>
       </span>
     </template>
   </el-dialog>
+
 </template>
 <script setup>
+import { reactive,ref,toRaw,toRefs,watch} from "vue";
+import {  ElMessage} from 'element-plus'
+import { defineEmits } from "vue";
 const opent = ref(true);
 const props = defineProps({
   open: {
-    typeof: Boolean,
+    type: Boolean,
     default: false,
   },
+  userTreeData:{
+    type: Object,
+    default: ()=>{},
+  }
 });
 const isOpen = ref(props.open);
-watch(
-  () => props.open,
+watch(() => props.open,
   (newValue) => {
     isOpen.value = newValue;
   }
 );
+
+const treeData = reactive({data:[]
+})
+watchEffect(()=>{
+  treeData.data[0]=props.userTreeData
+  toRaw(treeData.data)
+})
+
+const searchText=ref('')
+const treeRef = ref()
+const SearchPerson=(query)=>{
+  treeRef.value?.filter(query)
+}
+const filterMethod = (query, node) => {
+  return node.label?.includes(query)
+}
+//树
+const clickData=ref({})
+const handleNodeClick = (data,node) => {
+    clickData.value=data
+}
+
+const defaultProps = {
+  children: 'children',
+  label: 'label',
+  value:'id'
+}
+//确定按钮
+const emit = defineEmits(["changeMsg"]);
+const confirm=()=>{
+  if(!clickData.value.id)return ElMessage({ message: '请选择人员', type: 'error' })
+  const {disabled,label}=toRefs(clickData.value)
+  if(disabled.value){
+    return ElMessage({ message: '当前选中的非人员,请重新选择', type: 'error' })
+  }
+    emit("changeMsg",  clickData.value);
+    isOpen.value  = false
+}
 onMounted(() => {
-  console.log("props.open", props.opens);
 });
+
 </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: 50%;
+      width: 100%;
       height: 100%;
     }
     .main-cont-right{
         border-left: 1px solid #C1CCE3;
     }
 }
+.w-50{
+    width: 94%;
+    margin: 8px;
+}
 </style>

+ 5 - 3
src/layout/indexCommon.vue

@@ -25,7 +25,7 @@
             >
               <div class="avatar-wrapper">
                 <img src="@/assets/images/profile.jpg" class="head-img" /><span
-                  >Cat container</span
+                  >{{ logingName }}</span
                 >
               </div>
               <template #dropdown>
@@ -68,12 +68,12 @@
 </template>
 
 <script setup>
-import { onMounted } from 'vue'
+import { onMounted, ref } from 'vue'
 import { ElMessageBox } from 'element-plus'
 import useAppStore from '@/store/modules/app'
 import useUserStore from '@/store/modules/user'
 import useSettingsStore from '@/store/modules/settings'
-
+import Cookies from "js-cookie";
 import chat from "@/assets/images/chat.png";
 import bechat from "@/assets/images/bechat.png";
 import zuijin from "@/assets/images/zuijin.png";
@@ -99,7 +99,9 @@ const searchText = ref('') //搜索ipt的值
 function toggleSideBar() {
   appStore.toggleSideBar()
 }
+const logingName=ref('')
 onMounted(() => {
+  logingName.value=Cookies.get('username')
   // console.log('router',router)
 })
 function handleCommand(command) {

+ 156 - 63
src/views/liveChat/index.vue

@@ -4,67 +4,159 @@ export default {
 };
 </script>
 <script setup>
-import { ref, reactive } from "vue";
+import { ref, reactive, toRaw } from "vue";
+import useUserStore from "@/store/modules/user";
 import chat from "@/assets/images/profile.jpg";
 import cebian from "@/assets/images/cebian.png";
 import send from "@/assets/images/send.png";
 import sendFile from "@/assets/images/send-file.png";
 import store from "@/store";
-import { msgFriend } from "@/api/chat/msg";
+import {
+  msgFriend,
+  userTree,
+  userInfo,
+  msgSend,
+  msgRecord,
+  delMsg
+} from "@/api/chat/msg";
 import Addperson from "@/components/AddPerson/index.vue"; //添加人员的弹框
 //websocket连接====
 import useWebsoctStore from "@/store/modules/websocket";
+import { ElMessage } from "element-plus";
 const websoctStore = useWebsoctStore();
 //====
-
+const { proxy } = getCurrentInstance();
+const userIds= useUserStore()
 const height = ref(document.documentElement.clientHeight - 74 + "px;");
-const searchText = ref(""); //搜
 const messageText = ref(""); //发送的内容
-const SearchChat = () => {}; //搜索的点击事件
-//聊天列表数据模拟
-const personList = reactive({
-  data: [
-    {
-      imgs: chat,
-      name: "Kathry Murl",
-      cont: "comment inside the import() call to suppress this",
-    },
-    {
-      imgs: chat,
-      name: "Mathry Murl",
-      cont: "comment inside o suppress this",
-    },
-  ],
+const headerName = ref("");
+const chatRecords = reactive(
+  { data: [] }
+  // { sender: "friend", content: "Hello" },
+  // { sender: "me", content: "Hi" },
+  // { sender: "me", content: "How are you?" },
+  // { sender: "friend", content: "I am fine, thanks!" },
+);
+const sendCont = reactive({
+  //发送聊天内容数据组装
+  data: {
+    content: "",
+    fileList: [],
+    toId: 0,
+    msgType: "",
+  },
 });
+const searchText = ref(""); //搜
+const searchData = ref([]);
+const SearchChat = () => {
+  if (searchText.value) {
+    searchData.value = personList.data.filter((i) => {
+      console.log('i.nickName', i)
+      return i.toName == searchText.value;
+    });
+  } else {
+    searchData.value =personList.data;
+  }
+}; //搜索的点击事件
+//聊天列表数据模拟
+const personList = reactive({ data: [] });
 // const personList =reactive({data: []})
 //获取好友列表
-function getMsgList() {
-  msgFriend().then((res) => {
-    // personList.data=res.rows
-  });
-}
-const chatRecords = reactive([
-  { sender: "friend", content: "Hello" },
-  { sender: "me", content: "Hi" },
-  { sender: "me", content: "How are you?" },
-  { sender: "friend", content: "I am fine, thanks!" },
-]);
+const getMsgList = async () => {
+  const resFriend = await msgFriend();
+  personList.data = resFriend.rows.filter(
+    (item) => item.toId !== useUserStore().uid
+  );
+  searchData.value=personList.data
+  sendCont.data.toId = personList.data[0]?.toId;
+  headerName.value = personList.data[0]?.toName;
+  if (personList.data[0]?.toId) {
+    //调用聊天记录
+    msgRecordEvent(personList.data[0]?.toId);
+  }
+};
+// const rightMySend=reactive({data:[]})
+// const leftFriendSend=reactive({data:[]})
+//获取用户的聊天记录
+const msgRecordEvent = async (toIdValue) => {
+  const resMsgData = await msgRecord(toIdValue);
+  chatRecords.data=resMsgData.rows
+  // rightMySend.data=resMsgData.rows.filter(
+  //   (item) => item.toId !== useUserStore().uid
+  // );
+  // leftFriendSend.data=resMsgData.rows.filter(
+  //   (item) => item.toId === useUserStore().uid
+  // );
+  console.log("resMsgData", resMsgData);
+};
 //点击左侧新建聊天
 const open = ref(false);
-const clickNewPerson = () => {
+const userTreeData = reactive({ data: [] });
+const clickNewPerson = async () => {
+  const res = await userTree();
+  userTreeData.data = res;
+  toRaw(userTreeData.data);
   open.value = true;
-  console.log("1111", 1111);
 };
 //点击左侧聊天列表
 const clickPersonIndex = ref("");
-const clickPerson = (index) => {
+const clickPerson = (index, item) => {
+  sendCont.data.toId = item.userId ? item.userId : item.toId;
+  headerName.value = item.nickName ? item.nickName : item.fromName;
   clickPersonIndex.value = index;
+  msgRecordEvent(sendCont.data.toId);
+  console.log("first", clickPersonIndex.value);
 };
+//删除聊天
+const delClick=(msgId)=>{
+  proxy.$modal.confirm('删除后,将清空该聊天的消息记录').then(function() {
+    return delMsg(msgId);
+  }).then(() => {
+    getMsgList();
+    proxy.$modal.msgSuccess("删除成功");
+  })
+}
 //发送聊天点击事件
-const messageChat = () => {
-  const message = { text: messageText.value };
-  websoctStore.send(message);
+// const messageChat = () => {
+//   const message = { text: messageText.value };
+//   websoctStore.send(message);
+//   messageText.value = "";
+// };
+//树选中的人传过来的选中人的信息,push进入列表中
+const changeMsg = async (val) => {
+  const resInfo = await userInfo(val.id);
+  // if (personList.data.length > 0) {
+  //   personList.data.map((vPerson) => {
+  //     if (vPerson.userId != resInfo.userId) {
+  //       personList.data.push(resInfo);
+  //     } else {
+  //       return ElMessage({ message: "该聊天已存在", type: "error" });
+  //     }
+  //   });
+  // } else {
+  //   personList.data.push(resInfo);
+  // }
+  if (searchData.value.length > 0) {
+    searchData.value.map((vPerson) => {
+      if (vPerson.userId != resInfo.userId) {
+        searchData.value.push(resInfo);
+      } else {
+        return ElMessage({ message: "该聊天已存在", type: "error" });
+      }
+    });
+  } else {
+    searchData.value.push(resInfo);
+  }
+  sendCont.data.toId = resInfo.userId;
+  headerName.value = resInfo.nickName;
+};
+//登录账号发送聊天
+const msgSendClick = async () => {
+  sendCont.data.content = messageText.value;
+  sendCont.data.msgType = "2";
+  const mysendmsg = await msgSend(sendCont.data);
   messageText.value = "";
+  console.log("mysendmsg", mysendmsg, sendCont.data);
 };
 onMounted(() => {
   try {
@@ -91,18 +183,12 @@ onMounted(() => {
         <el-icon size="24" color="#505870" @click="clickNewPerson"
           ><Plus
         /></el-icon>
-        <Addperson :open="open" @close="open = false"></Addperson>
-        <!-- <el-dialog
-          title="新建聊天"
-          append-to-body
-          v-model="open"
-          style="
-            width: 512px;
-            height: 428px;
-          "
-        >
-        <Addperson></Addperson>
-        </el-dialog> -->
+        <Addperson
+          :open="open"
+          @close="open = false"
+          :userTreeData="userTreeData.data"
+          @changeMsg="changeMsg"
+        ></Addperson>
       </div>
       <div
         :class="
@@ -110,15 +196,23 @@ onMounted(() => {
             ? 'activ-left-container left-container'
             : 'left-container'
         "
-        v-for="(item, index) in personList.data"
+        v-for="(item, index) in searchData"
         :key="index"
-        @click="clickPerson(index)"
+        @click="clickPerson(index, item)"
       >
+
         <img :src="cebian" class="cebian" v-if="clickPersonIndex == index" />
-        <div><img :src="item.imgs" class="head-sculpture" /></div>
+        <button class="del-chat" v-if="clickPersonIndex == index" @click="delClick(item.msgId)">删除聊天</button>
         <div>
-          <span class="person-name">{{ item.name }}</span
-          ><span class="person-cont spill"> {{ item.cont }}</span>
+          <img :src="item.avatar ? item.avatar : chat" class="head-sculpture" />
+        </div>
+        <div>
+          <span class="person-name">{{
+            item.nickName ? item.nickName : item.toName
+          }}</span
+          ><span class="person-cont spill">
+            {{ item.cont ? item.cont : item.content }}</span
+          >
         </div>
       </div>
     </div>
@@ -129,23 +223,23 @@ onMounted(() => {
         style="display: flex; flex-direction: column; height: 100vh"
       >
         <el-container>
-          <el-header height="64px" class="right-header flex-buju"
-            >Header</el-header
-          >
+          <el-header height="64px" class="right-header flex-buju">{{
+            headerName
+          }}</el-header>
           <!-- 聊天 -->
           <el-main class="right-container">
             <div
               class="message-container"
-              v-for="(record, index) in chatRecords"
+              v-for="(record, index) in chatRecords.data"
               :class="{
-                'message-left': record.sender !== 'me',
-                'message-right': record.sender === 'me',
+                'message-left': useUserStore().uid== record.toId,
+                'message-right':  useUserStore().uid !== record.toId,
               }"
               :key="index"
             >
-              <span v-if="record.sender == 'me'">{{ record.content }}</span>
+            <span v-if=" useUserStore().uid!== record.toId">{{ record.content }}</span>
               <img :src="chat" class="head-sculpture" />
-              <span v-if="record.sender !== 'me'">{{ record.content }}</span>
+              <span v-if=" useUserStore().uid == record.toId">{{ record.content }}</span>
             </div>
             <!-- <div class="chat-message">
               <div class="chat-item"  :class="{'chat-item-out':item.sender=='out'}" v-for="(item,index) in chatRecords"  :key="index">
@@ -166,9 +260,8 @@ onMounted(() => {
               class="w-50 m-2"
               size="small"
               placeholder="请输入聊天内容"
-              @change="messageChat"
             />
-            <img :src="send" class="send-info" />
+            <img :src="send" class="send-info" @click="msgSendClick" />
           </el-footer>
         </el-container>
       </div>

+ 4 - 2
vite.config.js

@@ -39,13 +39,15 @@ export default defineConfig(({
 			proxy: {
 				// https://cn.vitejs.dev/config/#server-proxy
 				'/dev-api': {
-					target: 'http://192.168.1.28:8080/',
+					// target: 'http://192.168.1.28:8080/',
+					target:'http://8.142.173.95:19527/',
 					changeOrigin: true,
 					rewrite: (p) => p.replace(/^\/dev-api/, '')
 				},
 				//websocket代理
 				'/websocket': {
-					target: 'ws://192.168.1.28:8080/websocket',
+					// target: 'ws://192.168.1.28:8080/websocket',
+					target:'ws://8.142.173.95:19527/websocket',
 					changeOrigin: true,
 					rewrite: (p) => p.replace(/^\/websocket/, '')
 				}