ソースを参照

0.0.25

在线会话-通讯录开发完毕
Sean 5 ヶ月 前
コミット
541cca53ad

+ 132 - 7
src/api/chat.js

@@ -1,14 +1,139 @@
 import request from '@/utils/request'
 
-//1.在线会话 start ------------------------------------->
+//1.已有好友的情况 start ------------------------------------->
 
-//1.1 获取消息列表
-export function getTalkSessionList(params) {
+//1.1 获取消息列表 - 刘佳伟
+// export function getTalkSessionList(params) {
+//   return request({
+//     url: '/chat/getTalkSessionList',
+//     method: 'get',
+//     params
+//   })
+// }
+
+//1.1 添加好友
+export function addFriend(data) {
+  return request({
+    url: '/chat/addFriend',
+    method: 'post',
+    data
+  })
+}
+
+//1.2 好友列表
+export function getFriendsList(data) {
+  return request({
+    url: '/chat/getFriendsList',
+    method: 'post',
+    data
+  })
+}
+
+//1.3 删除好友
+export function delFriend(data) {
+  return request({
+    url: '/chat/delFriend',
+    method: 'post',
+    data
+  })
+}
+
+//1.4 编辑好友信息
+export function updateFriend(data) {
   return request({
-    url: '/chat/getTalkSessionList',
-    method: 'get',
-    params
+    url: '/chat/updateFriend',
+    method: 'post',
+    data
   })
 }
 
-//1.在线会话 end ------------------------------------->
+//1.5 搜索用户
+export function searchFriend(data) {
+  return request({
+    url: '/chat/searchFriend',
+    method: 'post',
+    data
+  })
+}
+
+//1.6 获取好友信息
+export function getFriendInfo(data) {
+  return request({
+    url: '/chat/getFriendInfo',
+    method: 'post',
+    data
+  })
+}
+//1.已有好友的情况 end ------------------------------------->
+
+
+//2.没有好友的情况 start ------------------------------------->
+//2.1 申请成为你好友的列表
+export function getFriendsApplyList(data) {
+  return request({
+    url: '/chat/getFriendsApplyList',
+    method: 'post',
+    data
+  })
+}
+
+//2.2 添加当前用户为好友
+export function applyFriend(data) {
+  return request({
+    url: '/chat/applyFriend',
+    method: 'post',
+    data
+  })
+}
+//2.没有好友的情况 end ------------------------------------->
+
+//3.搜索好友 start ------------------------------------->
+//3.1 判断当前用户是否为你的好友
+export function isFriend(data) {
+  return request({
+    url: '/chat/isFriend',
+    method: 'post',
+    data
+  })
+}
+//3.搜索好友 end ------------------------------------->
+
+//4.会话关系 start ------------------------------------->
+//4.1 你当前有几个会话
+export function getConversation(data) {
+  return request({
+    url: '/chat/getConversation',
+    method: 'post',
+    data
+  })
+}
+
+//4.2 查询会话下面的聊天记录
+export function getChatRecords(data) {
+  return request({
+    url: '/chat/getChatRecords',
+    method: 'post',
+    data
+  })
+}
+//4.会话关系 end ------------------------------------->
+
+//5.群聊 start ------------------------------------->
+//5.1 创建群聊
+export function addGroup(data) {
+  return request({
+    url: '/chat/addGroup',
+    method: 'post',
+    data
+  })
+}
+
+//5.2 群成员列表
+export function getGroupMembers(data) {
+  return request({
+    url: '/chat/getGroupMembers',
+    method: 'post',
+    data
+  })
+}
+//5.群聊 end ------------------------------------->

BIN
src/assets/chat/addcontacts.png


BIN
src/assets/chat/boy.png


BIN
src/assets/chat/girl.png


BIN
src/assets/chat/newcontacts.png


BIN
src/assets/chat/sendmessage.png


+ 49 - 1
src/router/index.js

@@ -292,7 +292,7 @@ export const constantRoutes = [
         path: '',
         component: () => import('@/views/chat/hall'),
         meta: {
-          title: '大厅',
+          title: '聊天',
           hidden: true,
           breadcrumb: true
         }
@@ -315,6 +315,54 @@ export const constantRoutes = [
       }
     ]
   },
+  {
+    path: '/contacts',
+    component: Layout,
+    children: [
+      {
+        name: '',
+        path: '',
+        component: () => import('@/views/chat/contacts'),
+        meta: {
+          title: '通讯录',
+          hidden: true,
+          breadcrumb: true
+        }
+      }
+    ]
+  },
+  {
+    path: '/topic',
+    component: Layout,
+    children: [
+      {
+        name: '',
+        path: '',
+        component: () => import('@/views/chat/topic'),
+        meta: {
+          title: '课题',
+          hidden: true,
+          breadcrumb: true
+        }
+      }
+    ]
+  },
+  {
+    path: '/creatTopic',
+    component: Layout,
+    children: [
+      {
+        name: '',
+        path: '',
+        component: () => import('@/views/chat/creatTopic'),
+        meta: {
+          title: '编辑课题',
+          hidden: true,
+          breadcrumb: true
+        }
+      }
+    ]
+  },
   // {
   //   path: '/documentation',
   //   component: Layout,

+ 144 - 5
src/store/modules/chat.js

@@ -1,4 +1,6 @@
-import {getTalkSessionList} from '@/api/chat'
+import {getTalkSessionList,addFriend,getFriendsList,delFriend,updateFriend,getFriendsApplyList,
+  applyFriend,isFriend,getConversation,getChatRecords,addGroup,getGroupMembers,searchFriend,getFriendInfo
+} from '@/api/chat'
 
 const state = {
 
@@ -9,17 +11,154 @@ const mutations = {
 }
 
 const actions = {
-  //在线会话 start ---------------------------------------->
-  getTalkSessionList({commit},data) {
+  //1.已有好友的情况 start ---------------------------------------->
+  //1.1 获取消息列表 - 刘佳伟
+  // getTalkSessionList({commit},data) {
+  //   return new Promise((resolve, reject) => {
+  //     getTalkSessionList(data).then(response => {
+  //       resolve(response)
+  //     }).catch(error => {
+  //       reject(error)
+  //     })
+  //   })
+  // },
+  //1.1 添加好友
+  addFriend({commit},data) {
     return new Promise((resolve, reject) => {
-      getTalkSessionList(data).then(response => {
+      addFriend(data).then(response => {
         resolve(response)
       }).catch(error => {
         reject(error)
       })
     })
   },
-  //在线会话 end ---------------------------------------->
+  //1.2 好友列表
+  getFriendsList({commit},data) {
+    return new Promise((resolve, reject) => {
+      getFriendsList(data).then(response => {
+        resolve(response)
+      }).catch(error => {
+        reject(error)
+      })
+    })
+  },
+  //1.3 删除好友
+  delFriend({commit},data) {
+    return new Promise((resolve, reject) => {
+      delFriend(data).then(response => {
+        resolve(response)
+      }).catch(error => {
+        reject(error)
+      })
+    })
+  },
+  //1.4 编辑好友信息
+  updateFriend({commit},data) {
+    return new Promise((resolve, reject) => {
+      updateFriend(data).then(response => {
+        resolve(response)
+      }).catch(error => {
+        reject(error)
+      })
+    })
+  },
+  //1.5 搜索用户
+  searchFriend({commit},data) {
+    return new Promise((resolve, reject) => {
+      searchFriend(data).then(response => {
+        resolve(response)
+      }).catch(error => {
+        reject(error)
+      })
+    })
+  },
+  //1.6 获取好友信息
+  getFriendInfo({commit},data) {
+    return new Promise((resolve, reject) => {
+      getFriendInfo(data).then(response => {
+        resolve(response)
+      }).catch(error => {
+        reject(error)
+      })
+    })
+  },
+  //1.已有好友的情况 end ---------------------------------------->
+
+  //2.没有好友的情况 start ---------------------------------------->
+  //2.1 编辑好友信息
+  getFriendsApplyList({commit},data) {
+    return new Promise((resolve, reject) => {
+      getFriendsApplyList(data).then(response => {
+        resolve(response)
+      }).catch(error => {
+        reject(error)
+      })
+    })
+  },
+  applyFriend({commit},data) {
+    return new Promise((resolve, reject) => {
+      applyFriend(data).then(response => {
+        resolve(response)
+      }).catch(error => {
+        reject(error)
+      })
+    })
+  },
+  //2.没有好友的情况 start ---------------------------------------->
+
+  //3.搜索好友 start ---------------------------------------->
+  isFriend({commit},data) {
+    return new Promise((resolve, reject) => {
+      isFriend(data).then(response => {
+        resolve(response)
+      }).catch(error => {
+        reject(error)
+      })
+    })
+  },
+  //3.搜索好友 end ---------------------------------------->
+
+  //4.会话关系 start ------------------------------------->
+  getConversation({commit},data) {
+    return new Promise((resolve, reject) => {
+      getConversation(data).then(response => {
+        resolve(response)
+      }).catch(error => {
+        reject(error)
+      })
+    })
+  },
+  getChatRecords({commit},data) {
+    return new Promise((resolve, reject) => {
+      getChatRecords(data).then(response => {
+        resolve(response)
+      }).catch(error => {
+        reject(error)
+      })
+    })
+  },
+  //4.会话关系 end ------------------------------------->
+
+  //5.会话关系 start ------------------------------------->
+  addGroup({commit},data) {
+    return new Promise((resolve, reject) => {
+      addGroup(data).then(response => {
+        resolve(response)
+      }).catch(error => {
+        reject(error)
+      })
+    })
+  },
+  getGroupMembers({commit},data) {
+    return new Promise((resolve, reject) => {
+      getGroupMembers(data).then(response => {
+        resolve(response)
+      }).catch(error => {
+        reject(error)
+      })
+    })
+  }
+  //5.会话关系 end ------------------------------------->
 }
 
 

+ 6 - 1
src/store/modules/user.js

@@ -7,7 +7,8 @@ const state = {
   name: '',
   avatar: '',
   introduction: '',
-  roles: []
+  roles: [],
+  userid:''
 }
 
 const mutations = {
@@ -26,6 +27,9 @@ const mutations = {
   SET_ROLES: (state, roles) => {
     state.roles = roles
   },
+  SET_USERID: (state, id) => {
+    state.userid = id
+  },
   // 退出登录逻辑直接放在 mutations 中
   LOGOUT(state) {
     state.token = ''
@@ -69,6 +73,7 @@ const actions = {
         //   reject('getInfo: roles must be a non-null array!')
         // }
         commit('SET_ROLES', roles)
+        commit('SET_USERID', data.id)
         commit('SET_NAME', real_name)
         commit('SET_AVATAR', avatar)
         commit('SET_INTRODUCTION', introduction)

+ 1 - 1
src/styles/sidebar.scss

@@ -40,7 +40,7 @@
 
     &.has-logo {
       .el-scrollbar {
-        height: calc(100% - 50px);
+        height: calc(100% - 100px);
       }
     }
 

+ 2 - 1
src/utils/baseUrl.js

@@ -1,5 +1,6 @@
 const URL = {
-  testUrl: 'http://192.168.1.201:9501',//老刘服务器
+  testUrl: 'http://192.168.1.201:9501',//刘佳伟的电脑
+  liuUrl: 'http://192.168.1.127:9501',//刘剑的电脑
   baseUrl: 'http://183.131.25.186:9501',//测试服务器
   servUrl: 'https://admin.bjzxtw.org.cn/zxtapi',//服务端
   WebsocketUrl: 'ws://192.168.1.201:9506',//老刘websocket地址

+ 3 - 2
src/utils/request.js

@@ -7,8 +7,9 @@ import URL from '@/utils/baseUrl';
 // create an axios instance
 const service = axios.create({
   //千万不能在这里使用绝对地址,这会导致webpack的devserve不生效
-  //baseURL: URL.testUrl, //老刘服务器
-  baseURL: URL.baseUrl, //测试服务器
+  //baseURL: URL.testUrl, //刘佳伟的电脑
+  baseURL: URL.liuUrl, //刘剑的电脑
+  //baseURL: URL.baseUrl, //测试服务器
   //baseURL: URL.servUrl, //正式服务器
   //baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
   //withCredentials: true, // send cookies when cross-domain requests

+ 80 - 0
src/views/chat/components/contactsTitle.vue

@@ -0,0 +1,80 @@
+<template>
+  <div class="tableTitle">
+    <div class="tableTitleBox">
+      <span class="tableFloatLine"></span>
+      <div>{{name}}</div>
+    </div>
+    <div class="addContacts">
+      <img src="@/assets/chat/addcontacts.png" @click="handleAddUser" v-if="iconStatus==1">
+      <i class="el-icon-close" @click="closeAddUser" v-else></i>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    name: {
+      type: String,
+      required: true,
+    },
+  },
+  data() {
+    return {
+      someData: '',
+      iconStatus: 1,//1=添加好友 2=关闭
+    };
+  },
+  methods: {
+    handleAddUser() {
+      this.iconStatus = 2;
+      this.$emit('addUser'); // Emit an event to notify the parent
+    },
+    closeAddUser(){
+      this.iconStatus = 1;
+      this.$emit('closeAddUser');
+    }
+  }
+};
+</script>
+
+<style scoped lang="less">
+  .tableTitle {
+    color:#333333;
+    position: relative;
+    padding-bottom: 20px;
+    padding-top: 37px;
+    padding-right: 22px;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    img {
+      cursor: pointer;
+    }
+    .tableFloatLine {
+      width: 3px;
+      height:16px;
+      background:#5570F1;
+      display: inline-block;
+    }
+    .tableTitleBox {
+      display: flex;
+      align-items: center;
+      font-size: 18px;
+      font-weight: bold;
+      span {
+        margin-right: 25px;
+      }
+    }
+    .addContacts {
+      width: 28px;
+      height: 28px;
+      background: #EFEFEF;
+      border-radius: 8px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      cursor: pointer;
+    }
+  }
+</style>

+ 61 - 0
src/views/chat/components/hallTitle.vue

@@ -0,0 +1,61 @@
+<template>
+  <div class="tableTitle">
+    <div class="tableTitleBox">
+      <span class="tableFloatLine"></span>
+      <div>{{name}}</div>
+    </div>
+    <img src="@/assets/chat/addUser.png" @click="handleAddUser">
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    name: {
+      type: String,
+      required: true,
+    },
+  },
+  data() {
+    return {
+      someData: '',
+    };
+  },
+  methods: {
+    handleAddUser() {
+      this.$emit('addUser'); // Emit an event to notify the parent
+    }
+  }
+};
+</script>
+
+<style scoped lang="less">
+  .tableTitle {
+    color:#333333;
+    position: relative;
+    padding-bottom: 20px;
+    padding-top: 37px;
+    padding-right: 22px;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    img {
+      cursor: pointer;
+    }
+    .tableFloatLine {
+      width: 3px;
+      height:16px;
+      background:#5570F1;
+      display: inline-block;
+    }
+    .tableTitleBox {
+      display: flex;
+      align-items: center;
+      font-size: 18px;
+      font-weight: bold;
+      span {
+        margin-right: 25px;
+      }
+    }
+  }
+</style>

+ 6 - 28
src/views/chat/components/tableTitle.vue

@@ -1,10 +1,7 @@
 <template>
   <div class="tableTitle">
-    <div class="tableTitleBox">
-      <span class="tableFloatLine"></span>
-      <div>{{name}}</div>
-    </div>
-    <img src="@/assets/chat/addUser.png" @click="handleAddUser">
+    <span class="tableFloatLine"></span>
+    {{name}}
   </div>
 </template>
 
@@ -21,11 +18,6 @@ export default {
       someData: '',
     };
   },
-  methods: {
-    handleAddUser() {
-      this.$emit('addUser'); // Emit an event to notify the parent
-    }
-  }
 };
 </script>
 
@@ -34,28 +26,14 @@ export default {
     color:#333333;
     position: relative;
     padding-bottom: 20px;
-    padding-top: 37px;
-    padding-right: 22px;
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-    img {
-      cursor: pointer;
-    }
     .tableFloatLine {
       width: 3px;
       height:16px;
       background:#5570F1;
-      display: inline-block;
-    }
-    .tableTitleBox {
-      display: flex;
-      align-items: center;
-      font-size: 18px;
-      font-weight: bold;
-      span {
-        margin-right: 25px;
-      }
+      display: block;
+      position: absolute;
+      left:-20px;
+      top:1px;
     }
   }
 </style>

+ 1613 - 0
src/views/chat/contacts.vue

@@ -0,0 +1,1613 @@
+<template>
+  <div class="mainBox">
+    <div class="hallBox">
+      <div class="hallLeft">
+        <!--添加好友 start------------------------------------------>
+        <contactsTitle :name="tableTitleName" @addUser="addUser" @closeAddUser="closeAddUser" />
+        <!--添加好友 end------------------------------------------>
+        <!--搜索 start------------------------------------------>
+        <div class="searchBox">
+          <el-input
+            placeholder="请输入内容"
+            prefix-icon="el-icon-search"
+            v-model="searchUserName"
+            @keyup.enter.native="searchFriend"
+            :disabled="pagestatus !== 4"
+          >
+          </el-input>
+        </div>
+        <!--搜索 end------------------------------------------>
+        <div class="newFriendBox">新的朋友</div>
+        <div class="newFriendImgBox" v-if="pagestatus==4">
+          <div class="newFriendImg">
+            <img src="@/assets/chat/newcontacts.png">
+          </div>
+          <div class="newFriendText">
+            搜索:{{searchUserName}}
+          </div>
+          <div class="searchFriendBox" v-if="searchWindowStatus==true">
+            <div class="searchFriendItem">
+              <div class="searchFriendAvatar">
+                <img src="@/assets/chat/user/user.png">
+              </div>
+              <div class="searchFriendInfo">
+                <div class="searchFriendName">
+                  <div class="searchFriendNameText" v-if="searchFriendList.remark!=null">{{searchFriendList.remark}}</div>
+                  <div class="searchFriendNameText" v-else>{{searchFriendList.user_name}}</div>
+                  <!--性别-->
+                  <!-- <div class="gender"><img src="@/assets/chat/girl.png"></div> -->
+                  <!--更多-->
+                  <!-- <img src="@/assets/chat/fi_more.png"> -->
+                </div>
+                <div class="searchFriendPhone">账号:{{searchFriendList.user_name}}</div>
+              </div>
+            </div>
+            <!-- <div v-if="searchFriendList.isfriend==0||searchFriendList.isfriend==null"></div>
+            <div class="searchFriendLineBox" v-else @click="openEditWindow">
+              <div class="searchFriendLineTitle">备注</div>
+              <div class="searchFriendLineContent">
+                <div class="searchFriendLineContentItem">
+                  <div>{{searchFriendList.remark}}</div>
+                  <div><i class="el-icon-edit"></i></div>
+                </div>
+              </div>
+            </div> -->
+            <!-- <div class="searchFriendLineBox">
+              <div class="searchFriendLineTitle">共同群聊</div>
+              <div class="searchFriendLineContent">0个</div>
+            </div>
+            <div class="searchFriendLineBox">
+              <div class="searchFriendLineTitle">添加方式</div>
+              <div class="searchFriendLineContent">通过账号添加</div>
+            </div> -->
+            <div class="searchFriendButton">
+              <el-button type="primary" v-if="searchFriendList.isfriend==0||searchFriendList.isfriend==null" @click="openAddWindow(searchFriendList.id)">添加到通讯录</el-button>
+              <el-button type="danger" v-else @click="deleteFriend(searchFriendList.id)">删除好友</el-button>
+            </div>
+            <!-- <div class="searchFriendButton">
+              <div class="searchFriendButtonItem">
+                <img src="@/assets/chat/sendmessage.png">
+                <div>发消息</div>
+              </div>
+            </div> -->
+          </div>
+        </div>
+        <div :class="['newFriendImgBox', pagestatus === 2 ? 'newFriendIActive' : '']" @click="tabPage(2)" v-else>
+          <div class="newFriendImg">
+            <img src="@/assets/chat/newcontacts.png">
+          </div>
+          <div class="newFriendText" v-if="pagestatus==4">
+            搜索:{{searchUserName}}
+          </div>
+          <div class="newFriendText" v-else>
+            新的朋友
+          </div>
+        </div>
+        <!--用户列表 start------------------------------------------>
+        <div class="userListBox" v-if="pagestatus==1||pagestatus==2||pagestatus==3">
+          <!-- <div class="userListTitle">A</div> -->
+          <div class="userItem" @click="changeUserItem(item.friend_id)" v-for="(item,index) in userFriendList" :key="index" :class="['userItem', { active: item.status == 1 }]">
+            <div class="userAvatar">
+              <img :src="item.avatar">
+            </div>
+            <div class="userInfo">
+              <div class="userName">
+                <div class="userNameText" v-if="item.remark!=null">{{item.user_name}}({{item.remark}})</div>
+                <div class="userNameText" v-else>{{item.user_name}}</div>
+              </div>
+            </div>
+          </div>
+        </div>
+        <!--用户列表 end------------------------------------------>
+      </div>
+      <div class="hallRight" v-if="pagestatus==1||pagestatus==4">
+        <div class="ifHallRigthNoMessage">恒星管理平台</div>
+      </div>
+      <div class="hallRight" v-if="pagestatus==2">
+        <div class="UserNameBox">
+          <div class="userName">新的朋友</div>
+        </div>
+        <div class="rightNewFriendBox" v-for="(item,index) in userApplyList" :key="index">
+          <div class="rightNewFriendItem">
+            <div class="rightNewFriendAvatar">
+              <img src="@/assets/chat/user/user.png">
+            </div>
+            <div class="rightNewFriendInfo">
+              <div class="rightNewFriendName">{{item.remark}}</div>
+              <div class="rightNewFriendPhone">{{item.nickname}}</div>
+            </div>
+          </div>
+          <div class="rightNewFriendStatus">
+            <div class="rightNewFriendStatus2">
+              <el-button type="primary" @click="openWindow(item.id)">接受</el-button>
+            </div>
+          </div>
+        </div>
+        <!-- <div class="rightNewFriendBox">
+          <div class="rightNewFriendItem">
+            <div class="rightNewFriendAvatar">
+              <img src="@/assets/chat/user/user.png">
+            </div>
+            <div class="rightNewFriendInfo">
+              <div class="rightNewFriendName">我是某某某</div>
+              <div class="rightNewFriendPhone">15210211200</div>
+            </div>
+          </div>
+          <div class="rightNewFriendStatus">
+            <div class="rightNewFriendStatus1">已接受</div>
+          </div>
+        </div>
+        <div class="rightNewFriendBox">
+          <div class="rightNewFriendItem">
+            <div class="rightNewFriendAvatar">
+              <img src="@/assets/chat/user/user.png">
+            </div>
+            <div class="rightNewFriendInfo">
+              <div class="rightNewFriendName">我是某某某</div>
+              <div class="rightNewFriendPhone">15210211200</div>
+            </div>
+          </div>
+          <div class="rightNewFriendStatus">
+            <div class="rightNewFriendStatus2">
+              <el-button type="primary" @click="friendWindowStatus=true">接受</el-button>
+            </div>
+          </div>
+        </div> -->
+      </div>
+      <div class="hallRight" v-if="pagestatus==3">
+        <div class="userInfoMainBox">
+          <div class="userInfoMainItem">
+            <div class="userInfoMainAvatar">
+              <img :src="friendInfo.avatar">
+            </div>
+            <div class="userInfoMainInfo">
+              <div class="userInfoMainName">
+                <div class="userInfoMainNameText">{{friendInfo.user_name}}</div>
+              </div>
+              <div class="userInfoMainPhone">账号:{{friendInfo.user_name}}</div>
+            </div>
+          </div>
+          <div class="userInfoMainLineBox">
+            <div class="userInfoMainLineTitle">备注</div>
+            <div class="userInfoMainLineContent">
+              <div class="userInfoMainLineContentItem" @click="openEditWindow">
+                <div v-if="friendInfo.remark!=null">{{friendInfo.remark}}</div>
+                <div v-else>暂无备注</div>
+                <div><i class="el-icon-edit"></i></div>
+              </div>
+            </div>
+          </div>
+          <!-- <div class="userInfoMainLineBox">
+            <div class="userInfoMainLineTitle">共同群聊</div>
+            <div class="userInfoMainLineContent">0个</div>
+          </div>
+          <div class="userInfoMainLineBox">
+            <div class="userInfoMainLineTitle">添加方式</div>
+            <div class="userInfoMainLineContent">通过账号添加</div>
+          </div> -->
+          <div class="userInfoMainButton">
+            <!-- <div class="userInfoMainButtonItem">
+              <img src="@/assets/chat/sendmessage.png">
+              <div>删除好友</div>
+            </div> -->
+            <el-button type="danger" icon="el-icon-delete" @click="deleteFriend">删除好友</el-button>
+          </div>
+        </div>
+      </div>
+    </div>
+    <!--发送好友申请弹出框 start------------------------------------------------------------>
+    <el-dialog :visible.sync="addFriendWindowStatus" title="朋友申请" :close-on-click-modal="false" width="420px">
+      <div>
+        <div>
+          <el-form :model="form" ref="form" autocomplete="off" label-position="left">
+            <div class="formDiv">
+              <el-form-item label="备注名" :label-width="formLabelWidth" class="custom-align-right">
+                <el-input v-model="addform.remark" autocomplete="off"  placeholder="请输入备注名.."></el-input>
+              </el-form-item>
+            </div> 
+          </el-form>
+        </div>
+        <div class="footerButtonBox">
+          <el-button type="info" @click="addFriendWindowStatus=false">取消</el-button>
+          <el-button type="primary" @click="addMyFriend">确定</el-button>
+        </div>
+      </div>
+    </el-dialog>
+    <!--发送好友申请弹出框 end------------------------------------------------------------>
+    <!--请求验证弹出框 start------------------------------------------------------------>
+    <el-dialog :visible.sync="friendWindowStatus" title="通过朋友验证" :close-on-click-modal="false" width="420px">
+      <div>
+        <div>
+          <el-form :model="form" ref="form" autocomplete="off" label-position="left">
+            <div class="formDiv">
+              <el-form-item label="备注名" :label-width="formLabelWidth" class="custom-align-right">
+                <el-input v-model="form.remark" autocomplete="off"  placeholder="请输入备注名.."></el-input>
+              </el-form-item>
+            </div> 
+          </el-form>
+        </div>
+        <div class="footerButtonBox">
+          <el-button type="info" @click="friendWindowStatus=false">取消</el-button>
+          <el-button type="primary" @click="addFriend">确定</el-button>
+        </div>
+      </div>
+    </el-dialog>
+    <!--请求验证弹出框 end------------------------------------------------------------>
+    <!--修改备注弹出框 start------------------------------------------------------------>
+    <el-dialog :visible.sync="editWindowStatus" title="修改备注" :close-on-click-modal="false" width="420px">
+      <div>
+        <div>
+          <el-form :model="form" ref="form" autocomplete="off" label-position="left">
+            <div class="formDiv">
+              <el-form-item label="备注名" :label-width="formLabelWidth" class="custom-align-right">
+                <el-input v-model="remark" autocomplete="off"  placeholder="请输入备注名.."></el-input>
+              </el-form-item>
+            </div> 
+          </el-form>
+        </div>
+        <div class="footerButtonBox">
+          <el-button type="info" @click="editWindowStatus=false">取消</el-button>
+          <el-button type="primary" @click="editFriend">确定</el-button>
+        </div>
+      </div>
+    </el-dialog>
+    <!--修改备注弹出框 end------------------------------------------------------------>
+  </div>
+</template>
+
+<script>
+//引入公用样式
+import '@/styles/global.less';
+//引入baseUrl
+import URL from '@/utils/baseUrl';
+//引入组件
+import contactsTitle from './components/contactsTitle.vue';
+import { status } from 'nprogress';
+import openWindow from '@/utils/open-window';
+
+export default {
+  components: {
+    contactsTitle
+  },
+  data() {
+    return {
+      //1.全局配置 start------------------------------------------------------------>
+      tableTitleName:'通讯录',
+      pagestatus:1,//1=没有选择任何联系人 2=申请列表 3=好友详情 4=搜索结果
+      formLabelWidth:"80px",//表单label宽度
+      searchUserName:"",//搜索框
+      friendId:"",//要添加的好友id
+      friendWindowStatus:false,//通过朋友申请弹出框
+      searchWindowStatus:false,//搜索窗口左侧弹出框
+      editWindowStatus:false,//修改备注弹出框
+      addFriendWindowStatus:false,//发送好友申请弹出框
+      editFriendId:"",//要编辑的好友
+      //1.全局配置 end------------------------------------------------------------>
+      //2.好友列表 start------------------------------------------------------------>
+      userFriendList:[],//好友列表
+      userApplyList:[],//好友申请列表
+      searchFriendList:"",//搜索好友列表
+      //2.好友列表 end------------------------------------------------------------>
+      //3.通过好友申请 start------------------------------------------------------------>
+      form:{
+        //好友id
+        id:"",
+        //好友申请
+        remark:"",
+        //状态
+        status:2
+      },
+      //3.通过好友申请 end------------------------------------------------------------>
+      //4.编辑好友 start------------------------------------------------------------>
+      friendInfo:{},//好友信息
+      remark:"",//修改的用户备注
+      //4.编辑好友 end------------------------------------------------------------>
+      //5.发送好友申请 start------------------------------------------------------------>
+      addform:{
+        //好友id
+        id:"",
+        //好友申请
+        remark:"",
+      },
+      //5.发送好友申请 end------------------------------------------------------------>
+    };
+  },
+  methods: {
+    //0.全局操作 start------------------------------------------------------------>
+    //0.1切换页面状态
+    tabPage(status){
+      this.pagestatus = status;
+      if(status==2){
+        //如果是2 好友列表状态还原
+        for(let item of this.userFriendList){
+          item.status = 0;
+        }
+      }
+    },
+    //0.全局操作 end------------------------------------------------------------>
+    //1.好友列表 start------------------------------------------------------------>
+    addUser(){
+      this.pagestatus = 4;
+    },
+    closeAddUser(){
+      this.pagestatus = 2;
+      this.searchWindowStatus = false;
+    },
+    //1.1获取联系人列表
+    getUserFriendList(){
+      //获取用户身份id
+      //const userId = this.$store.state.user.userid;
+      this.$store.dispatch('chat/getFriendsList',{}).then(res=> {
+        let data = res.data;
+        for(let item of data){
+          item.status = 0; //默认未选中
+        }
+        this.userFriendList = data;
+      }).catch(() => {
+        this.$message.error('获取好友列表失败!')
+      })
+    },
+    //1.2选择联系人
+    changeUserItem(id){
+      for(let item of this.userFriendList){
+        if(item.id == id){
+          item.status = 1;
+        }else{
+          item.status = 0;
+        }
+      }
+      //切换页面到用户列表
+      this.pagestatus = 3;
+      //把要编辑的好友的id存起来
+      this.editFriendId = id;
+
+      //获取好友身份信息详情
+      this.$store.dispatch('chat/getFriendInfo',{friend_id:this.editFriendId}).then(res=> {
+        console.log(res);
+        //保存好友信息
+        this.friendInfo = res.data;
+      }).catch(() => {
+        this.$message.error('获得好友身份详情失败!')
+      })
+
+    },
+    //1.3搜索联系人
+    searchFriend(){
+      //搜索联系人
+      this.$store.dispatch('chat/searchFriend',{keyword:this.searchUserName}).then(res=> {
+        //获取到好友
+        this.searchWindowStatus = false;
+        console.log(res);
+        if(res.code==200){
+          if(res.data.length>0){
+            this.searchWindowStatus = true;
+            this.searchFriendList = res.data[0];
+          }else{
+            this.$message.error('没有找到该联系人!')
+          }
+        }else{
+          this.$message.error('搜索关键字不能为空!')
+        }
+      }).catch(() => {
+        this.$message.error('网络错误!')
+      })
+    },
+    //1.好友列表 end------------------------------------------------------------>
+
+    //2.获得好友申请列表 start------------------------------------------------------------>
+    //2.1 好友申请列表
+    getFriendApplyList(){
+      const userId = this.$store.state.user.userid;
+      this.$store.dispatch('chat/getFriendsApplyList',{user_id:userId}).then(res=> {
+        this.userApplyList = res.data;
+      }).catch(() => {
+        this.$message.error('获取好友申请列表失败!')
+      })
+    },
+    
+    //2.2 接受好友申请
+    addFriend(){
+      console.log(this.form);
+      this.$store.dispatch('chat/applyFriend',this.form).then(res=> {
+        if(res.code==200){
+          this.$message.success('成功添加好友!')
+          this.friendWindowStatus = false;
+        }
+      })
+    },
+    //2.3 删除好友
+    deleteFriend(id){
+      if(id){
+        this.editFriendId = id;
+      }
+      this.$confirm('此操作将永久删除该联系人, 是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        console.log(this.editFriendId);
+        this.$store.dispatch('chat/delFriend',{id:editFriendId}).then(res=> {
+          this.$message.success('删除成功!')
+          //关闭用户详情显示
+          this.pagestatus = 1;
+          //重新装在用户列表
+          this.getUserFriendList();
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'warning',
+          message: '已取消删除'
+        });
+      });
+    },
+    //2.4 编辑好友
+    editFriend(){
+      let data = {
+        friend_id:this.editFriendId,
+        remark:this.remark
+      }
+      //this.editFriendId
+      this.$store.dispatch('chat/updateFriend',data).then(res=> {
+        this.$message.success('修改备注名成功!')
+        this.pagestatus = 1;
+        this.editWindowStatus = false;
+        this.getUserFriendList();
+        this.remark = "";
+      }).catch(() => {
+        this.$message.error('修改备注名失败!')
+      })
+    },
+    //2.5 发送好友申请
+    addMyFriend(){
+      console.log(this.addform);
+      this.$store.dispatch('chat/applyFriend',this.addform).then(res=> {
+        if(res.code==200){
+          this.$message.success('成功添加好友!')
+          this.friendWindowStatus = false;
+        }
+      })
+    },
+    //2.获得好友申请列表 end------------------------------------------------------------>
+
+    //3.操作弹出框 start------------------------------------------------------------>
+    //用户菜单操作
+    openWindow(id){
+      this.form.id = id;
+      //打开弹出框
+      this.friendWindowStatus = true;
+    },
+    openEditWindow(id){
+      //打开修改备注弹出框
+      this.editWindowStatus = true;
+    },
+    openAddWindow(id){
+      this.addform.id = id;
+      this.addFriendWindowStatus = true;
+    }
+    //3.操作弹出框 end------------------------------------------------------------>
+    
+  },
+  mounted() {
+    //1.获取联系人列表
+    this.getUserFriendList();
+    //2.获取好友申请列表
+    this.getFriendApplyList();
+  },
+  beforeDestroy() {
+    
+  }
+};
+</script>
+
+<style scoped lang="less">
+  .hallBox {
+    display: flex;
+    margin: 30px;
+    //左侧
+    .hallLeft {
+      width: 420px;
+      background: #fff;
+      border-radius: 20px;
+      margin-right: 20px;
+      .newFriendBox {
+        padding: 10px 25px 0 25px;
+        font-size: 18px;
+        color: #999;
+      }
+      .newFriendImgBox {
+        margin: 10px 0 10px 0;
+        padding: 20px 0 20px 25px;
+        display: flex;
+        align-items: center;
+        justify-content: flex-start;
+        cursor: pointer;
+        border-bottom: 1px solid #E9EDF7;
+        position: relative;
+        .newFriendImg {
+          width: 58px;
+          height: 58px;
+          border-radius: 8px;
+          background: #5570F1;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          margin-right: 20px;
+        }
+        .newFriendText {  
+          color: #333;
+          font-size: 18px;
+        }
+      }
+      .newFriendIActive {
+        border-right: 4px solid #5570F1 !important;
+        background: #F5F7FD
+      }
+      .searchFriendBox {
+        position: absolute;
+        width: 280px;
+        border-radius: 8px;
+        top: 0;
+        right: -300px;
+        background: #fff;
+        box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.1);
+        border-radius: 8px;
+        z-index: 100;
+        box-sizing: border-box;
+        padding: 30px 0;
+        .searchFriendItem {
+          display: flex;
+          align-items: center;
+          justify-content: flex-start;
+          border-bottom: 1px solid #E9EDF7;
+          padding: 0 20px 30px 20px;
+          .searchFriendAvatar {
+            img {
+              width: 66px;
+              height: 66px;
+              border-radius: 50%;
+            }
+            margin-right: 15px;
+          }
+          .searchFriendInfo {
+            flex: 1;
+            .searchFriendName {
+              display: flex;
+              align-items: center;
+              .gender {
+                img {
+                  width: 12px;
+                  height: 12px;
+                }
+              }
+              img {
+                width: 18px;
+                height: 18px;
+                cursor: pointer;
+              }
+              .searchFriendNameText {
+                font-size: 18px;
+                width: 120px;
+                height: 28px;
+                line-height: 28px;
+                white-space: nowrap; 
+                overflow: hidden; 
+                text-overflow: ellipsis;
+              }
+            }
+            .searchFriendPhone {
+              font-size: 14px;
+              color: #999;
+              margin-top: 10px;
+            }
+          }
+        }
+        .searchFriendLineBox {
+          display: flex;
+          align-items: center;
+          justify-content: flex-start;
+          padding: 20px;
+          border-bottom: 1px solid #E9EDF7;
+          .searchFriendLineTitle{
+            font-size: 16px;
+            color: #999999;
+            width: 90px;
+          }
+          .searchFriendLineContent{
+            font-size: 16px;
+            color: #333;
+            flex: 1;
+            .searchFriendLineContentItem{
+              display: flex;
+              align-items: center;
+              justify-content: space-between;
+            }
+          }
+        }
+        .searchFriendButton {
+          padding:40px 0 10px 0;
+          text-align: center;
+          .searchFriendButtonItem {
+            font-size: 14px;
+            color: #5570F1;
+            img {
+              width: 30px;
+              height: 30px;
+              margin-bottom: 5px;
+            }
+          }
+        }
+      }
+      .userListTitle {
+        padding: 15px 25px;
+        font-size: 18px;
+        color: #999;
+      }
+      .searchBox {
+        padding-left: 25px;
+        padding-right: 25px;
+        padding-bottom: 20px;
+      }
+      .userListBox {
+        padding: 15px 0;
+        .active {
+          background: #F5F7FD;
+          box-sizing: border-box;
+          border-right: 4px solid #5570F1 !important;
+        }
+        .userItem {
+          padding: 0 21px 0 25px;
+          display: flex;
+          align-items: center;
+          justify-content: space-between;
+          height: 90px;
+          box-sizing: border-box;
+          border-right: 4px solid #fff;
+          cursor: pointer;
+          .userAvatar {
+            img {
+              width: 58px;
+              height: 58px;
+              border-radius: 50%;
+            }
+          }
+          .userInfo {
+            flex: 1;
+            box-sizing: border-box;
+            padding-left: 15px;
+            .userName {
+              display: flex;
+              align-items: center;
+              justify-content: space-between;
+              .userNameText {
+                font-size: 18px;
+                font-weight: bold;
+                width: 240px;
+                white-space: nowrap;
+                overflow: hidden;
+                text-overflow: ellipsis;
+                color: #333;
+              }
+              .userMessageNum {
+                font-size: 12px;
+                color: #333;
+                width: 24px;
+                height: 24px;
+                line-height: 24px;
+                text-align: center;
+                border-radius: 50%;
+                background: #FFCC91;
+                font-weight: bold;
+              }
+            }
+            .userMessage {
+              display: flex;
+              align-items: center;
+              justify-content: space-between;
+              .userMessageText {
+                display: block;
+                width: 240px;
+                white-space: nowrap;
+                overflow: hidden;
+                text-overflow: ellipsis;
+                font-size: 14px;
+                color: #999999;
+              }
+              .userMessageTime {
+                font-size: 14px;
+                color: #999999;
+              }
+            }
+          }
+        }
+      }
+    }
+    //右侧
+    .hallRight {
+      flex: 1;
+      background: #fff;
+      border-radius: 20px;
+      position: relative;
+      height: 1184px;
+      .rightNewFriendBox {
+        height: 126px;
+        border-bottom: 1px solid #E9EDF7;
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        box-sizing: border-box;
+        padding: 30px 40px;
+        .rightNewFriendItem { 
+          display: flex;
+          align-items: center; 
+          .rightNewFriendAvatar {
+            margin-right: 15px;
+            img {
+              width: 66px;
+              height: 66px;
+              border-radius: 50%;
+            }
+          }
+          .rightNewFriendInfo {
+            .rightNewFriendName {
+              font-size: 18px; 
+              margin-bottom: 7px;
+            }
+            .rightNewFriendPhone {
+              font-size: 18px;
+              color: #999;
+            }
+          }
+        }
+        .rightNewFriendStatus {
+          .rightNewFriendStatus1 {
+            font-size: 16px;
+            color: #999;
+            width: 69px;
+            text-align: center;
+          }
+        }
+      }
+      .userInfoMainBox {
+        padding: 40px;
+        max-width: 900px;
+        margin: 100px auto 0 auto;
+        .userInfoMainItem {
+          display: flex;
+          align-items: center;
+          justify-content: flex-start;
+          border-bottom: 1px solid #E9EDF7;
+          padding: 0 20px 30px 20px;
+          .userInfoMainAvatar {
+            img {
+              width: 66px;
+              height: 66px;
+              border-radius: 50%;
+            }
+            margin-right: 15px;
+          }
+          .userInfoMainInfo {
+            flex: 1;
+            .userInfoMainName {
+              display: flex;
+              align-items: center;
+              justify-content: space-between;
+              img {
+                width: 18px;
+                height: 18px;
+                cursor: pointer;
+              }
+              .userInfoMainNameText {
+                font-size: 18px;
+                width: 240px;
+                height: 28px;
+                line-height: 28px;
+                white-space: nowrap; 
+                overflow: hidden; 
+                text-overflow: ellipsis;
+              }
+            }
+            .userInfoMainPhone {
+              font-size: 14px;
+              color: #999;
+              margin-top: 10px;
+            }
+          }
+        }
+        .userInfoMainLineBox {
+          display: flex;
+          align-items: center;
+          justify-content: flex-start;
+          padding: 20px;
+          border-bottom: 1px solid #E9EDF7;
+          .userInfoMainLineTitle{
+            font-size: 16px;
+            color: #999999;
+            width: 90px;
+          }
+          .userInfoMainLineContent{
+            font-size: 16px;
+            color: #333;
+            flex: 1;
+            .userInfoMainLineContentItem{
+              display: flex;
+              align-items: center;
+              justify-content: space-between;
+              cursor: pointer;
+            }
+          }
+        }
+        .userInfoMainButton {
+          padding:40px 0 10px 0;
+          text-align: center;
+          .userInfoMainButtonItem {
+            font-size: 14px;
+            color: #5570F1;
+            img {
+              width: 30px;
+              height: 30px;
+              margin-bottom: 5px;
+            }
+          }
+        }
+      }
+      .ifHallRigthNoMessage {
+        color: #CCCCCC;
+        font-size: 32px;
+        font-weight: bold;
+        text-align: center;
+        height: 1184px;
+        line-height: 1184px;
+      }
+      .userName {
+        font-size: 20px;
+        color: #333;
+        font-weight: bold;
+      }
+      .ifNotice {
+        padding-bottom: 60px !important;  
+      }
+      .UserNameBox {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        padding: 40px 30px 30px 30px;
+        border-bottom: 1px solid #E7E7E7;
+        position: relative;
+        .moreIcon {
+          cursor: pointer;
+        }
+        .groupNotice {
+          position: absolute;
+          height: 40px;
+          line-height: 40px;
+          font-size: 16px;
+          background:url('../../assets/chat/notice.png') no-repeat 10px center #F6F8FE;
+          left: 30px;
+          box-sizing: border-box;
+          padding-left: 40px;
+          bottom: 10px;
+          color: #999999;
+          border-radius: 10px;
+          padding-right: 10px;
+          width: 400px;
+          white-space: nowrap;
+          overflow: hidden;
+          text-overflow: ellipsis;
+        }
+      }
+      .rightPositionBox {
+        position: relative;
+        .rightUserMessageBox {
+          padding: 40px;
+          height: 760px;
+          box-sizing: border-box;
+          overflow-y: auto;
+          .timeBox {
+            width: 100%;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            padding:0 0 30px 0; 
+            span {
+              border-radius: 8px;
+              display: block;
+              width: 80px;
+              height: 30px;
+              line-height: 30px;
+              font-size: 14px;
+              text-align: center;
+              display: block;
+              background: #F4F5FA;
+              color: #999999;
+            }
+          }
+          .newUserStatus {
+            width: 100%;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            padding:0 0 30px 0;
+            .newUserStatusText {
+              display: flex;
+              align-items: center;
+              justify-content: center;
+              border-radius: 8px;
+              width: 200px;
+              height: 30px;
+              line-height: 30px;
+              font-size: 14px;
+              text-align: center;
+              background: #F4F5FA;
+              color: #999999;
+            }
+            span {
+              display: inline-block;
+              line-height: 30px;
+            }
+            .newUserStatusTextName {
+              display: inline-block;
+              width: 100px;
+              line-height: 30px;
+              overflow: hidden;
+              white-space: nowrap;
+              text-overflow: ellipsis;
+            }
+          }
+          //其他用户
+          .otherUserMessage {
+            display: flex;
+            align-items: flex-start;
+            margin-bottom: 30px;
+            .otherUserIcon {
+              margin-right: 20px;
+              img {
+                width: 58px;
+                height: 58px;
+                border-radius: 50%;
+              }
+            }
+            .otherUserMessageText {
+              border-radius: 16px;
+              padding:16px;
+              font-size: 16px;
+              color:#fff;
+              background: #5570F1;
+              position: relative;
+            }
+            .otherUserMessageText::before {
+              content: '';
+              position: absolute;
+              left: -8px;
+              top: 26px;
+              transform: translateY(-50%);
+              width: 0;
+              height: 0;
+              border-top: 8px solid transparent;
+              border-bottom: 8px solid transparent;
+              border-right: 8px solid #5570F1;
+            }
+          }
+          //我
+          .meUserMessage {
+            display: flex;
+            align-items: flex-start;
+            margin-bottom: 30px;
+            justify-content: flex-end; 
+            .meUserIcon {
+              margin-left: 20px;
+              img {
+                width: 58px;
+                height: 58px;
+                border-radius: 50%;
+              }
+            }
+            .meUserMessageText {
+              border-radius: 16px;
+              padding:16px;
+              font-size: 16px;
+              color:#333;
+              background: #FFEAD1;
+              position: relative;
+            }
+            .meUserMessageText::before {
+              content: '';
+              position: absolute;
+              right: -8px;
+              top: 26px;
+              transform: translateY(-50%);
+              width: 0;
+              height: 0;
+              border-top: 8px solid transparent;
+              border-bottom: 8px solid transparent; 
+              border-left: 8px solid #FFEAD1;
+            }
+          }
+        }
+      }
+      //消息框
+      .sendMessageBox {
+        padding: 20px 40px;
+        border-top: 1px solid #E7E7E7;
+        box-sizing: border-box;
+        height: 276px;
+        .sendMessageTools {
+          img {
+            width: 36px;
+            height: 36px;
+            margin-right: 30px;
+            cursor: pointer;
+          }
+        }
+        .sendMessageInput {
+          margin-top: 20px;
+        }
+        .sendMessageButton {
+          padding-top: 20px;
+          text-align: right;
+          button {
+            width: 120px;
+            height: 38px;
+          }
+        }
+      }
+      //右侧菜单
+      .rightSlideBox {
+        width: 420px;
+        position: absolute;
+        right: 0;
+        top: 0;
+        background: #fff;
+        height: 100%;
+        box-shadow: -4px 0px 4px 0px rgba(0, 0, 0, 0.1); 
+        .rightSlideSearch {
+          padding: 30px 25px 0 25px;
+        }
+        .rightSlideUserBox {
+          box-sizing: border-box;
+          padding: 40px 40px 10px 40px;
+          display: flex;
+          align-items: center;
+          flex-wrap: wrap;
+          //border-bottom: 1px solid #E9EDF7;
+          .rightSlideUserItem {
+            margin-bottom: 20px;
+            width: 25%;
+            .rightSlideUserItemIcon {
+              display: flex;
+              align-items: center;
+              justify-content: center;
+              border-radius: 50%;
+
+              img {
+                width: 58px;
+                height: 58px;
+                border-radius: 50%;
+              }
+              .addUserIcon {
+                width: 58px;
+                height: 58px;
+                line-height: 58px;
+                background: #F0F0F0;
+                border-radius: 50%;
+                text-align: center;
+              }
+            }
+            .rightSlideUserItemName {
+              font-size: 18px;
+              color: #333;
+              margin-top: 10px;
+              text-align: center
+            }
+          }
+        }
+        .rightLineBorder {
+          width: 100%;
+          border-bottom: 1px solid #E9EDF7;
+        }
+        .rightSlideMore {
+          padding: 30px 40px;
+          font-size: 18px;
+          color: #999;
+          text-align: center
+        }
+        //聊天记录
+        .rightSlideFunction {
+          .rightSlideFunctionItem {
+            height: 80px;
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            padding: 30px 40px;
+            border-bottom: 1px solid #E9EDF7;
+            .rightSlideFunctionItemText {
+              font-size: 18px;
+              color: #333;
+            }
+            .rightSlideFunctionItemIcon {
+              img {
+                width: 18px;
+                height: 18px;
+              }
+            }
+          }
+        }
+        //群聊设置
+        .groupSystem {
+          border-bottom: 1px solid #E9EDF7;
+          padding-bottom: 30px;
+          .groupChatSystem {
+            padding: 30px 40px 0 40px;
+            .groupChatTitle {
+              font-size: 18px;
+              color: #333;
+              margin-bottom: 15px;
+            }
+            .groupChatText {
+              font-size: 18px;
+              color: #999;
+            }
+          }
+        }
+        .rightSlideFooter {
+          font-size: 18px;
+          color: #CC5F5F;
+          padding: 30px 40px;
+          text-align: center;
+          cursor: pointer;
+          border-bottom: 1px solid #E9EDF7;
+        }
+      }
+    }
+  }
+  //不同的消息类型
+  //发送文件
+  .messageTypeFile {
+    width: 283px;
+    background: #fff;
+    border-radius: 16px;
+    border: 1px solid #E9EDF7;
+    .messageTypeFileTop{
+      border-bottom: 1px solid #E9EDF7;
+      .messageTypeFileSize {
+        padding: 10px 20px 10px 20px;
+      }
+      .messageTypeFileInfo {
+        display: flex;
+        align-items: center;
+        padding:20px 20px 0 20px;
+        .messageTypeFileTitle {
+          font-size: 16px;
+          color: #333;
+          height: auto; /* Allow height to adjust */
+          max-height: 48px; /* Maximum height for two lines (16px * 2) */
+          overflow: hidden; /* Hide overflow */
+          text-overflow: ellipsis; /* Show ellipsis for overflow text */
+          display: -webkit-box; /* Use flexbox for multi-line ellipsis */
+          -webkit-box-orient: vertical; /* Set box orientation to vertical */
+          -webkit-line-clamp: 2; /* Limit to 2 lines */
+          white-space: normal; /* Allow text wrapping */
+          width: 200px;
+        }
+        .messageTypeFileIcon {
+          img {
+            width: 42px;
+            height: 42px;
+          }
+        }
+      }
+    }
+    .messageTypeFileLogo {
+      padding:15px 20px;
+    }
+    .messageTypeFileSize {
+      font-size: 12px;
+      color: #999;
+    }
+    .messageTypeFileLogo {
+      font-size: 12px;
+      color: #999;
+    }
+  }
+  //发送名片
+  .messageTypeCard {
+    width: 321px;
+    background: #fff;
+    border-radius: 16px;
+    border: 1px solid #E9EDF7;
+    .messageTypeCardTop {
+      display: flex;
+      align-items: center;
+      padding: 20px 20px 24px 20px;
+      border-bottom: 1px solid #E9EDF7;
+      .messageTypeCardIcon {
+        margin-right: 15px;
+        img {
+          width: 58px;
+          height: 58px;
+          border-radius: 50%;
+        }
+      } 
+      .messageTypeCardName {
+        font-size: 16px;
+        color: #333;
+      }
+    }
+    .messageTypeCardText {
+      padding-top: 14px;
+      padding-left: 20px;
+      padding-bottom: 15px;
+      font-size: 12px;
+      color: #999999;
+    }
+  }
+  //发送图片
+  .messageTypeImage {
+    width: 200px;
+    height: 200px;
+    img {
+      max-width: 200px;
+      border-radius: 16px;
+      border: 1px solid #ECECEC;
+    }
+  }
+  //发送群聊
+  .messageGroupInvite {
+    background: #fff;
+    border-radius: 16px;
+    border: 1px solid #E9EDF7;
+    .messageGroupInviteTop {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 20px 20px 24px 20px;
+      .messageGroupInviteIcon {
+        margin-right: 15px;
+        img {
+          width: 58px;
+          height: 58px;
+          border-radius: 50%;
+        }
+      }
+      .messageGroupInfoText {
+        .messageGroupInfoTextTitle {
+          font-size: 16px;
+          color: #333;
+          margin-bottom: 5px;
+        }
+        .messageGroupInfoTextTxt {
+          font-size: 12px;
+          color: #999;
+          line-height: 18px;
+        }
+      }
+    }
+    .messageGroupInviteText {
+      padding-top: 14px;
+      padding-left: 20px;
+      padding-bottom: 15px;
+      font-size: 12px;
+      color: #999999;
+      border-top: 1px solid #E9EDF7;
+    }
+  }
+  //添加用户弹出框
+  .searchWindow {
+    display: flex;
+    .searchWindowLeft {
+      width: 330px;
+      box-sizing: border-box;
+      border-right: 1px solid #E9EDF7;
+      padding-right: 25px;
+      .searchUserBox {
+        .searchNameEnglish {
+          font-size: 18px;
+          color: #999;
+          padding: 30px 0 20px 0;
+        }
+        .searchUserItem {
+          display: flex;
+          align-items: center;
+          .searchUserName {
+            font-size: 18px;
+            font-weight: bold;
+            color: #333;
+          }
+          img {
+            width: 38px;
+            height: 38px;
+            border-radius: 50%;
+            margin: 0 20px;
+          }
+        }
+      }
+    }
+    .searchWindowRight {
+      width: 690px;
+      .searchWindowRightTop {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        padding: 0 30px 30px 30px;
+        .searchWindowRightTitle {
+          font-size: 18px;
+          color: #333;
+        }
+        .searchWindowRightNum {
+          font-size: 18px;
+          color: #999;
+        }
+      }
+      .searchWindowUserList {
+        padding: 0 30px;
+        display: flex;
+        flex-wrap: wrap;
+        .searchWindowUserItem {
+          width:20%;
+          text-align: center;
+          margin-bottom: 30px;
+          .searchWindowUserName {
+            font-size: 18px;
+            color: #333;
+            font-weight: bold;
+            width: 122px;
+            white-space: nowrap; /* 强制不换行 */
+            overflow: hidden; /* 超出宽度隐藏 */
+            text-overflow: ellipsis; /* 显示省略号 */
+          }
+          .searchWindowUserIcon {
+            width: 58px;
+            height: 58px;
+            position: relative;
+            margin: 0 auto 10px auto;
+            .searchWindowDeleteUser {
+              position: absolute;
+              width: 15px;
+              height: 15px;
+              background: rgba(0,0,0,0.3);
+              border-radius: 5px;
+              color: #fff;
+              right: -3px;
+              top: -3px;
+              cursor: pointer;
+            }
+            img {
+              width: 58px;
+              height: 58px;
+              border-radius: 50%;
+              margin-bottom: 10px;
+            }
+          }
+        }
+      }
+      .shareCardBox {
+        border-top: 1px solid #E9EDF7;
+        .shareCardTitle {
+          padding: 30px;
+        }
+        .shareCardInput {
+          padding: 0 30px 0 30px;
+        }
+      }
+      .searchWindowFooter {
+        text-align: center;
+        padding-top: 30px;
+      }
+    }
+  }
+  //聊天记录弹出框
+  .fileWindow {
+    .fileWindowHeader {
+      margin-bottom: 20px;
+    }
+    .fileWindowMessageTime {
+      width: 100px;
+      height: 37px;
+      line-height: 37px;
+      text-align: center;
+      background: #F4F5FA;
+      border-radius: 8px;
+      font-size: 14px;
+      color: #999999;
+      margin-top: 30px;
+    }
+    .fileWindowMessageItemBox {
+      display: flex;
+      align-items: flex-start;
+      padding: 30px 0 20px 0;
+      border-bottom: 1px solid #E9EDF7;
+      .fileWindowMessageItemIcon {
+        img {
+          width: 58px;
+          height: 58px;
+          border-radius: 50%;
+        }
+      }
+      .fileWindowMessageItemIcon {
+        padding-right: 15px;
+      }
+      .fileWindowMessageItem {
+        flex: 1;
+        .fileWindowMessageItemInfo {
+          display: flex;
+          align-items: center;
+          justify-content: space-between;
+          padding-bottom: 20px;
+          .fileWindowMessageItemName {
+            font-size: 18px;
+            color: #333;
+          }
+          .fileWindowMessageItemTime {
+            font-size: 14px;
+            color: #999;
+          }
+        }
+        .fileWindowMessageItemText {
+          font-size: 14px;
+          color: #999;
+        }
+      }
+    }
+    //文件列表
+    .fileWindowFlieBox {
+      .fileWindowFlieItem {
+        padding:30px 0 20px 0;
+        display: flex;
+        align-items: center;
+        border-bottom: 1px solid #E9EDF7;
+        .fileWindowFlieItemIcon {
+          margin-right: 10px;
+          img {
+            width: 42px;
+            height: 42px;
+          }
+        }
+        .fileWindowFlieItemMain {
+          flex: 1;
+          .fileWindowFlieItemTitle {
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            font-size: 16px;
+            color: #333;
+            margin-bottom: 6px;
+          }
+          .fileWindowFlieItemTime {
+            font-size: 14px;
+            color: #999;
+          }
+          .fileWindowFlieInfo {
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            font-size: 12px;
+            color: #999;
+          }
+        }
+      }
+    }
+    //图片列表
+    .fileWindowImageBox {
+      display: flex;
+      flex-wrap: wrap;
+      div {
+        width: 25%;
+        text-align: center;
+        padding: 20px 0 0 0;
+      }
+      img {
+        width: 150px;
+        height: 150px;
+        border-radius: 16px;
+        border: 1px solid #ECECEC;
+      }
+    }
+    //日期搜索
+    .fileWindowDateBox {
+      width: 100%;
+      padding: 30px 0;
+    }
+    .fileWindowDateButton {
+      margin-left: 10px;
+    }
+    //群成员搜索
+    .fileWindowGroupMain{
+      display: flex;
+      .fileWindowGroupUserLeft {
+        flex: 1;
+        box-sizing: border-box;
+        padding-right: 20px;
+      }
+      .fileWindowGroupUserRight {
+         width: 300px;
+        .fileWindowGroupUserBox {
+          padding: 30px 0;
+          .searchUserBox {
+            .searchNameEnglish {
+              font-size: 18px;
+              color: #999;
+              padding: 30px 0 20px 0;
+            }
+            .searchUserItem {
+              display: flex;
+              align-items: center;
+              .searchUserName {
+                font-size: 18px;
+                font-weight: bold;
+                color: #333;
+              }
+              img {
+                width: 38px;
+                height: 38px;
+                border-radius: 50%;
+                margin: 0 20px 0 0;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  //添加用户弹出框
+  .messageFormBox {
+    .messageFormTitle {
+      font-size: 18px;
+      padding-bottom: 20px;
+    }
+    .messageFormInput {
+      margin-bottom: 30px;
+    }
+  }
+  //弹出框底部按钮
+  .footerButtonBox {
+    padding-top: 40px;
+    text-align: center;
+  }
+  //加入群聊弹出框
+  .addGroupWindow {
+    .addGroupWindowImg {
+      img {
+        width:58px;
+        height: 58px;
+      }
+      text-align: center;
+      font-size: 18px;
+      color: #333;
+    }
+    .addGroupWindowTitle {
+      font-size: 18px;
+      color: #333;
+      text-align: center;
+      padding: 20px 0 40px 0;
+    }
+    .addGroupWindowText {
+      font-size: 12px;
+      color: #999;
+      text-align: center;
+    }
+  }
+  //表单微调 start------------------------------------------------------------>*/
+  ::v-deep .custom-form-item > .el-form-item__label {
+    line-height: 140px !important;
+  }
+  ::v-deep .custom-textarea .el-textarea__inner {
+    resize: none; /* 禁止用拖拽调整大小 */
+  }
+  ::v-deep .custom-align-right .el-form-item__label {
+    text-align: right; /* 设置标签文字右对齐 */
+  }
+  ::v-deep .el-select-group__title {
+    color: #909399;
+  }
+  ::v-deep .el-select {
+    width: 100% !important;
+  }
+  ::v-deep .el-tabs__active-bar{
+    height: 1px !important;
+  }
+  ::v-deep .el-tabs__nav-wrap::after {
+    height:1px !important;
+  }
+  ::v-deep .el-tabs__header {
+    margin-bottom: 0 !important;
+  }
+</style>

+ 646 - 0
src/views/chat/creatTopic.vue

@@ -0,0 +1,646 @@
+<template>
+  <div class="mainBox">
+    <div class="layerBox">
+      <tableTitle :name="tableDivTitle"/>
+      <el-form :model="form" ref="form" :rules="formRules" label-position="left" label-width="120px">
+        <div class="formDiv">
+          <div>
+            <el-form-item label="课题名称:" prop="cat_arr_id" class="custom-align-right">
+              <el-cascader :key="parentKey" v-model="form.cat_arr_id" placeholder="请选择课题名称" :props="parentData" filterable clearable></el-cascader>
+            </el-form-item>  
+            <el-form-item label="课题标题:" prop="keyword" class="custom-align-right">
+              <el-input v-model="form.keyword" autocomplete="off" placeholder="请输入资讯关键词"></el-input>
+            </el-form-item>
+            <div class="QuillTitle">
+              <span>* </span>课题内容:
+              <div @click="toggleSourceMode" class="QuillModelBtn">
+                {{ showHtml ? '切换到编辑模式' : '切换到源码模式' }}
+              </div>
+            </div>
+            <el-form-item label="" prop="content">
+              <div class="editor-container">
+                <div v-if="showHtml">
+                  <textarea v-model="editorHtml" style="width: 100%; height: 400px;"></textarea>
+                </div>
+                <div v-else>
+                  <quill-editor ref="quillEditor" v-model="form.content" :options="editorOptions" class="my-quill-editor"/>
+                </div>
+                <!-- 多图上传隐藏的input -->
+                <input type="file" ref="multiFileInput" @change="handleMultipleFiles" multiple hidden accept="image/jpeg, image/png" />
+              </div>
+            </el-form-item>
+            <el-form-item label="建立群聊:" prop="is_original" class="custom-align-right">
+              <el-radio-group v-model="form.is_original">
+                <el-radio :label="1">是</el-radio>
+                <el-radio :label="0">否</el-radio>
+              </el-radio-group>
+            </el-form-item>
+            <div>
+              <el-form-item label="群聊名称:" prop="copyfrom" class="custom-align-right">
+                <el-input v-model="form.copyfrom" autocomplete="off" placeholder="请输入来源名称"></el-input>
+              </el-form-item>
+              <el-form-item label="作者:" prop="linkurl" class="custom-align-right">
+                <el-input v-model="form.linkurl" autocomplete="off" placeholder="请输入来源链接"></el-input>
+              </el-form-item>
+            </div>
+          </div>
+        </div>
+      </el-form>
+    </div>
+    <div class="bottomBtnBox">
+      <el-button type="info" @click="returnPage">返回</el-button>
+      <el-button type="primary" @click="editToServe" v-if="editStatus==true">确定</el-button>
+      <el-button type="primary" @click="addToServe" v-else>发布</el-button>
+    </div>
+  </div>
+</template>
+
+<script>
+//表格标题
+import tableTitle from './components/tableTitle';
+//引入公用样式
+import '@/styles/global.less';
+
+import { quillEditor } from 'vue-quill-editor';
+import 'quill/dist/quill.snow.css';
+import ImageResize from 'quill-image-resize-module';
+import Quill from 'quill';  // 引入 Quill
+import Delta from 'quill-delta'; // 引入 Delta,用于手动修改文档
+
+// 注册 Image Resize 模块
+Quill.register('modules/imageResize', ImageResize);
+
+export default {
+  components: {
+    quillEditor,
+    tableTitle
+  },
+  data() {
+    //0.全局操作 start ------------------------------------------------------------>
+    //表单验证
+    const validateEmpty = (rule,value,callback) => {
+      if (value.length == 0) {
+        callback(new Error('该项不能为空!'))
+      } else {
+        callback()
+      }
+    }
+    const validateArray = (rule,value,callback) => {
+      if (value.length == 0) {
+        callback(new Error('该项不能为空!'))
+      } else {
+        callback()
+      }
+    }
+    let self = this;
+    //0.全局操作 end ------------------------------------------------------------>
+    return {
+      //1.表单项 start ------------------------------------------------------------>
+      editStatus:false,
+      tableDivTitle:"编辑课题",
+      disclaimer:true,//免责声明
+      //提交表单
+      form: {
+        //1.1使用了外链
+        title: '',//资讯标题
+        islink:0,//是否使用外链 0非 1是
+        linkurl:"",//外链地址
+        //1.2没有使用外链
+        cat_arr_id:'',//导航池名称
+        level:"",//推荐等级
+        imgurl:"",//缩略图
+        keyword:"",//关键词
+        introduce:"",//描述
+        content:"",//内容
+        author:"",//作者
+        hits:"",//浏览量
+        is_original:0,//是否为原创 0非 1是
+        copyfrom:"",//来源名称
+        fromurl:"",//来源地址
+        status:0//状态 0待发布 1已发布 404已删除
+      },
+      //1.2 表单验证规则
+      formRules: {
+        //资讯名称不能为空
+        title:[{required:true,trigger:'blur',validator:validateEmpty}],
+        //如果使用了外链,外链地址不能为空
+        linkurl:[{required:true,trigger:'blur',validator:validateEmpty}],
+        //导航池名称不能为空
+        cat_arr_id:[{required:true,trigger:'blur',validator:validateArray}],
+        //推荐等级不能为空
+        //level:[{required:true,trigger:'blur',validator:validateEmpty}],
+        //关键词不能为空
+        keyword:[{required:true,trigger:'blur',validator:validateEmpty}],
+        //描述不能为空
+        introduce:[{required:true,trigger:'blur',validator:validateEmpty}],
+        //内容不能为空
+        content:[{required:true,trigger:'blur',validator:validateEmpty}],
+        //作者不能为空
+        author:[{required:true,trigger:'blur',validator:validateEmpty}],
+        //是否原创不能为空
+        is_original:[{required:true,trigger:'blur',validator:validateEmpty}],
+        //来源名称和地址不能为空
+        copyfrom:[{required:true,trigger:'blur',validator:validateEmpty}],
+        fromurl:[{required:true,trigger:'blur',validator:validateEmpty}],
+        //缩略图不能为空
+        imgUrl:[{required:true,trigger:'blur',validator:validateEmpty}]
+      },
+      //1.3富文本编辑器配置
+      showHtml: false, //用于保存源码内容
+      editorHtml: '',
+      editorOptions: {
+        placeholder: '请输入内容...',
+        theme: 'snow',  // 主题样式
+        modules: {
+          toolbar: {
+            container: [
+              [{ 'font': [] }],                                // 字体
+              [{ 'header': [1, 2, 3, 4, 5, 6, false] }],       // 标题
+              [{ 'size': ['small', false, 'large', 'huge'] }],  // 字体大小
+              ['bold', 'italic', 'underline', 'strike'],        // 加粗、斜体、下划线、删除线
+              [{ 'color': [] }, { 'background': [] }],          // 文字颜色、背景颜色
+              [{ 'script': 'sub' }, { 'script': 'super' }],     // 上标、下标
+              [{ 'list': 'ordered'}, { 'list': 'bullet' }],     // 列表
+              [{ 'indent': '-1'}, { 'indent': '+1' }],          // 缩进
+              [{ 'align': [] }],                                // 对齐方式
+              ['blockquote', 'code-block'],                     // 引用、代码块
+              ['link', 'image', 'video'],                       // 链接、图片、视频
+              ['clean'],
+              [{ 'html': true }]  // 添加自定义按钮的占位符
+            ],
+            handlers: {
+              image: () => {
+                this.handleImageClick();
+              },
+              showHtml: function() {
+                this.$emit('toggleSourceMode');
+              }
+            }
+          },
+          imageResize: {
+            displayStyles: {
+              backgroundColor: 'black',
+              border: 'none',
+              color: 'white'
+            },
+            modules: ['Resize', 'DisplaySize', 'Toolbar']  // 启用不同的调整方式
+          }
+        }
+      },
+      //1.4图片上传
+      imgUrl:"",//在页面上显示缩略图
+      //获取父级导航池
+      parentKey:0,//获取父级导航
+      parentData: {
+        checkStrictly: true,
+        lazy: true,
+        async lazyLoad (node, resolve) {
+          const { level, data } = node;
+          if (data && data.children && data.children.length !== 0) {
+            return resolve(node)
+          }
+          console.log(level)
+          let parentId = level == 0 ? 0 : data.value
+          let parames = {
+            'pid':parentId
+          }
+          self.$store.dispatch('pool/categoryList',parames).then(res=> {
+            if (res.data) {
+              const nodes = res.data.map(item => ({
+                value: item.id,
+                label: item.name,
+                leaf: level >= 3,
+                children: []
+              }))
+              resolve(nodes)
+            }
+          })
+        }
+      },
+      //表单项 end ------------------------------------------------------------>
+    };
+  },
+  methods: {
+    //1.提交表单 start ------------------------------------------------------------>
+    //1.1 直接上传图片
+    beforeAvatarUpload(file) {
+      const isJPG = file.type === 'image/jpeg';
+      const isPNG = file.type === 'image/png';
+      const isLt2M = file.size / 1024 / 1024 < 2;
+
+      if (!isJPG && !isPNG) {
+        this.$message.error('上传缩略图只能是 JPG 或 PNG 格式!');
+        return false;
+      }
+      if (!isLt2M) {
+        this.$message.error('上传缩略图大小不能超过 2MB!');
+        return false;
+      }
+
+      const formData = new FormData();
+      formData.append('file', file);
+
+      this.$store.dispatch('pool/uploadFile',formData).then(res=> {
+        this.imgUrl = res.data.imgUrl;//显示缩略图
+        this.form.imgurl = res.data.imgUrl;//提供表单地址
+        console.log(res.data.imgUrl)
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '网络错误,请重试!'
+        });
+      })
+
+      // 阻止默认的上传行为
+      return false;
+    },
+    //1.2 提交表单
+    addToServe(){
+      //提交之前先判断是否为外链
+      //如果使用了外链,清理掉除了外链以外的内容
+      if(this.form.islink==true){
+        this.form.islink = 1;
+        this.cleatForm(1)
+      }else{
+        this.form.islink = 0;
+      }
+
+      //先进行验证
+      this.$refs.form.validate(valid => {
+        if (valid) {
+          //console.log(this.form)
+          this.$store.dispatch('news/addArticle',this.form).then(res=> {
+            //汇报结果
+            this.$message({
+              type: 'success',
+              message: '已成功添加资讯!'
+            });
+            this.cleatForm(2);
+            //返回列表页
+            this.returnPage()
+          }).catch(() => {
+            this.$message({
+              type: 'info',
+              message: '网络错误,请重试!'
+            });
+          })
+        }
+      })
+    },
+    //1.3 清理表单
+    cleatForm(type){
+      if(type==1){
+        //使用了外链,进行部分表单清理
+        //this.form.cat_arr_id = "";
+        this.form.level = "";
+        this.form.imgurl = "";
+        this.form.keyword = "";
+        this.form.introduce = "";
+        this.form.content = "";
+        //this.form.author = "";
+        this.form.hits = "";
+        this.form.is_original = "";
+        this.form.copyfrom = "";
+        this.form.fromurl = "";
+        this.form.status = "";
+      }
+      if(type==2){
+        //完全清理表单
+        this.form.title = "";
+        this.form.islink = "";
+        this.form.linkurl = "";
+        this.form.cat_arr_id = "";
+        this.form.level = "";
+        this.form.imgurl = "";
+        this.form.keyword = "";
+        this.form.introduce = "";
+        this.form.content = "";
+        this.form.author = "";
+        this.form.hits = "";
+        this.form.is_original = "";
+        this.form.copyfrom = "";
+        this.form.fromurl = "";
+        this.form.status = "";
+      }
+    },
+    //提交表单 end ------------------------------------------------------------>
+
+    //2.跳转操作 start ------------------------------------------------------------>
+    returnPage(){
+      this.$router.push({
+        path: '/articleList',
+      });
+    },
+    //跳转操作 end ------------------------------------------------------------>
+
+    //3.回显操作 ------------------------------------------------------------>
+    //3.1回显数据
+    getMainData() {
+      let data = {
+        id: this.$route.query.id
+      };
+      this.$store.dispatch('news/getArticleInfo', data).then(res => {
+        console.log(res);
+        this.form.title = res.data.title;
+        //判断是否使用了外链
+        if(res.data.islink==1){
+          this.form.islink = true;
+        }else{  
+          this.form.islink = false;
+        }
+        //不是原创的时候显示来源
+        if(res.data.is_original==1){
+          this.form.is_original = 1;
+        }else{
+          this.form.is_original = 0;
+          this.$nextTick(() => {
+            this.form.is_original = 0;
+            console.log('is_original:', this.form.is_original); // 确保值已更新
+          });
+          // <el-radio v-model="form.is_original" label="1">是</el-radio>
+          // <el-radio v-model="form.is_original" label="0">不是</el-radio>
+          this.form.linkurl = res.data.linkurl;
+        }
+        
+
+
+        // 回显导航池
+        this.form.cat_arr_id = Array.isArray(res.data.cat_arr_id) ? res.data.cat_arr_id : JSON.parse(res.data.cat_arr_id);
+        this.parentKey += 1; // 触发级联选择器重新加载
+        this.loadCascaderPath(this.form.cat_arr_id); // 加载路径数据
+
+        this.form.level = res.data.level;
+        this.form.imgurl = res.data.imgurl;
+        this.imgUrl = res.data.imgurl;
+        this.form.keyword = res.data.keyword;
+        this.form.introduce = res.data.introduce;
+        this.form.content = res.data.content;
+        this.form.author = res.data.author;
+        this.form.hits = res.data.hits;
+        this.form.is_original = res.data.is_original;
+        this.form.copyfrom = res.data.copyfrom;
+        this.form.fromurl = res.data.fromurl;
+        this.form.status = res.data.status;
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '网络错误,请重试!'
+        });
+      });
+    },
+    async loadCascaderPath(path) {
+      for (let i = 0; i < path.length; i++) {
+        const parentId = path[i - 1] || 0; // 获取当前层级的父级ID
+        const level = i; // 当前层级的索引
+
+        await this.$store.dispatch('pool/categoryList', { pid: parentId })
+          .then((res) => {
+            const nodes = res.data.map(item => ({
+              value: item.id,
+              label: item.name,
+              leaf: level >= 3, // 假设4层结构,设置叶子节点标记
+            }));
+
+            // 级联选择器加载数据
+            if (level === path.length - 1) {
+              this.form.cat_arr_id = path; // 确保最后一级路径正确设置
+              this.parentKey += 1; // 强制刷新 cascader
+            }
+          });
+      }
+    },
+    //1.3提交修改
+    editToServe(){
+      //提交之前先判断是否为外链
+      //如果使用了外链,清理掉除了外链以外的内容
+      if(this.form.islink==1){
+        this.cleatForm(1)
+      }
+      //添加要修改的id
+      this.form.id = this.editId;
+      //先进行验证
+      this.$refs.form.validate(valid => {
+        if (valid) {
+          //console.log(this.form)
+          this.$store.dispatch('news/updateArticle',this.form).then(res=> {
+            //汇报结果
+            this.$message({
+              type: 'success',
+              message: '已成功添加资讯!'
+            });
+            this.cleatForm(2);
+            //返回列表页
+            this.returnPage()
+          }).catch(() => {
+            this.$message({
+              type: 'info',
+              message: '网络错误,请重试!'
+            });
+          })
+        }
+      })
+    },
+    //跳转操作 end ------------------------------------------------------------>
+
+    //4.富文本编辑器 start ------------------------------------------------------------>
+    //4.1 编辑器点击上传图片
+    handleImageClick() {
+      this.$refs.multiFileInput.click(); // 打开文件选择框
+    },
+    handleMultipleFiles(event) {
+      const files = event.target.files;
+      if (files.length) {
+        this.uploadMultipleImages(files); // 处理多图片上传
+      }
+    },
+    uploadMultipleImages(files) {
+      const uploadPromises = [];
+      for (let i = 0; i < files.length; i++) {
+        uploadPromises.push(this.uploadImage(files[i]));
+      }
+
+      Promise.all(uploadPromises).then(urls => {
+        const quillEditor = this.$refs.quillEditor.quill;
+        urls.forEach(url => {
+          const range = quillEditor.getSelection();
+          quillEditor.insertEmbed(range.index, 'image', url); // 在编辑器中插入图片
+        });
+      }).catch(error => {
+        this.$message.error('图片上传失败,请重试!');
+      });
+    },
+    uploadImage(file) {
+      const formData = new FormData();
+      formData.append('file', file);
+      return this.$store.dispatch('pool/uploadFile', formData)
+        .then(res => {
+          if (res && res.data && res.data.imgUrl) {
+            return res.data.imgUrl;
+          } else {
+            throw new Error('图片上传失败');
+          }
+        })
+        .catch(error => {
+          this.$message.error('图片上传失败,请重试!');
+          throw error;
+        });
+    },
+
+    //4.2 图片粘贴上传
+    // 处理从网页粘贴的图片 URL
+    handleImageFromWeb(imageUrl) {
+      return new Promise((resolve) => {
+        console.log('开始下载图片:', imageUrl);
+
+        this.fetchImageAsBlob(imageUrl).then((blob) => {
+          console.log('图片已下载为 Blob:', blob);
+
+          const formData = new FormData();
+          formData.append('file', blob, 'image.jpg');
+
+          this.$store.dispatch('pool/uploadFile', formData).then((res) => {
+            if (res && res.data && res.data.imgUrl) {
+              console.log('图片上传成功:', res.data.imgUrl);
+              resolve(res.data.imgUrl);
+            } else {
+              console.log('图片上传失败,保留原 URL:', imageUrl);
+              resolve(imageUrl);
+            }
+          }).catch((error) => {
+            console.error('图片上传时出现错误:', error);
+            resolve(imageUrl);
+          });
+        }).catch((error) => {
+          console.error('图片下载失败:', error);
+          resolve(imageUrl);
+        });
+      });
+    },
+    fetchImageAsBlob(url) {
+      return fetch(url)
+        .then(response => {
+          if (!response.ok) {
+            throw new Error('Failed to fetch image');
+          }
+          return response.blob();
+        });
+    },
+    //编辑源码
+    toggleSourceMode() {
+      if (!this.showHtml) {
+        // 切换到源码模式,将编辑器内容同步到 textarea 中
+        this.editorHtml = this.$refs.quillEditor.quill.root.innerHTML;
+        this.showHtml = true; // 显示 textarea
+      } else {
+        // 切换回富文本模式,将 textarea 内容同步回编辑器
+        this.showHtml = false; // 显示 Quill 编辑器
+
+        // Quill 编辑器可能被销毁,所以使用 $nextTick 确保 DOM 渲染完成后再操作编辑器
+        this.$nextTick(() => {
+          if (this.$refs.quillEditor) {
+            this.$refs.quillEditor.quill.root.innerHTML = this.editorHtml;
+          } else {
+            console.error('Quill 编辑器实例未找到');
+          }
+        });
+      }
+    }
+    //富文本编辑器 end ------------------------------------------------------------>
+
+  },
+  mounted(){
+    //1.判断是新建还是回显
+    if(this.$route.query.id!=undefined){
+      this.editId = this.$route.query.id;
+      this.editStatus = true;
+      console.log("编辑新闻!")
+      this.getMainData();
+    }else{
+      this.editStatus = false;
+      console.log("添加新闻!")
+    }
+
+    //复制内容到富文本 start ------------------------------------------------------------>
+    this.$nextTick(() => {
+      const quillEditor = this.$refs.quillEditor.quill;
+
+      if (quillEditor) {
+        console.log('Quill 编辑器已初始化');
+
+        // 在粘贴事件触发时,记录所有 img 的 src
+        quillEditor.clipboard.addMatcher(Node.ELEMENT_NODE, (node, delta) => {
+          if (node.tagName === 'IMG') {
+            const imageUrl = node.getAttribute('src');
+            console.log('检测到粘贴的图片 URL:', imageUrl);
+
+            if (imageUrl && !imageUrl.startsWith('data:') && !imageUrl.startsWith('file://')) {
+              // 先处理图片上传
+              this.handleImageFromWeb(imageUrl).then((uploadedImageUrl) => {
+                // 查找编辑器中所有 img 标签并替换 src
+                const imgs = quillEditor.root.querySelectorAll('img');
+                imgs.forEach((img) => {
+                  if (img.getAttribute('src') === imageUrl) {
+                    img.setAttribute('src', uploadedImageUrl);  // 替换 src
+                    console.log('图片 src 已替换为:', uploadedImageUrl);
+                  }
+                });
+              });
+            }
+          }
+          return delta;  // 返回原始 delta
+        });
+      } else {
+        console.error('Quill 初始化失败');
+      }
+
+    });
+    //复制富文本 end ------------------------------------------------------------>
+  },
+};
+</script>
+
+<style scoped lang="less">
+  //文本编辑器
+  .QuillTitle {
+    line-height: 36px;
+    font-size: 14px;
+    color: #606266;
+    font-weight:bold;
+    padding-left: 30px;
+    span{
+      color: #ff4949
+    }
+    .QuillModelBtn {
+      display: inline-block;
+      margin-left: 10px;
+      font-size: 12px;
+      color: #999;
+      cursor: pointer;
+    }
+  }
+  .editor-container {
+    height: 420px;
+    padding-bottom:20px;
+  }
+  .my-quill-editor {
+    height: 320px;
+  }
+  .ql-editor {
+    height: 320px;
+  }
+  //执行v-deep穿透scope选择器 start------------------------------------------------------------>*/
+  ::v-deep .custom-form-item > .el-form-item__label {
+    line-height: 140px !important;
+  }
+  ::v-deep .custom-textarea .el-textarea__inner {
+    resize: none; /* 禁止用户拖拽调整大小 */
+  }
+  ::v-deep .custom-align-right .el-form-item__label {
+    text-align: right; /* 设置标签文字右对齐 */
+  }
+  ::v-deep .el-select {
+    width: 100%; /* 禁止用户拖拽调整大小 */
+  }
+  
+  //执行v-deep穿透scope选择器 end------------------------------------------------------------>*/
+</style>

+ 335 - 205
src/views/chat/hall.vue

@@ -1,10 +1,9 @@
 <template>
   <div class="mainBox">
-
     <div class="hallBox">
       <div class="hallLeft">
         <!--添加好友 start------------------------------------------>
-        <tableTitle :name="tableTitleName" @addUser="addUser" />
+        <hallTitle :name="tableTitleName" @addUser="addUser" />
         <!--添加好友 end------------------------------------------>
         <!--搜索 start------------------------------------------>
         <div class="searchBox">
@@ -15,7 +14,6 @@
           </el-input>
         </div>
         <!--搜索 end------------------------------------------>
-        <!--用户列表 start------------------------------------------>
         <div class="userListBox">
           <!--普通用户 start------------------------------------------>
           <div class="userItem">
@@ -35,7 +33,7 @@
           </div>
           <!--普通用户 end------------------------------------------>
           <!--管理员 start------------------------------------------>
-          <div class="userItem active">
+          <!-- <div class="userItem active">
             <div class="userAvatar">
               <img src="@/assets/chat/user/admin.png" alt="">
             </div>
@@ -49,25 +47,10 @@
                 <div class="userMessageTime">12:55</div>
               </div>
             </div>
-          </div>
+          </div> -->
           <!--管理员 end------------------------------------------>
           <!--管理员 start------------------------------------------>
-          <div class="userItem">
-            <div class="userAvatar">
-              <img src="@/assets/chat/user/group.jpg" alt="">
-            </div>
-            <div class="userInfo">
-              <div class="userName">
-                <div class="userNameText">群聊</div>
-                <div class="userMessageNum">99+</div>
-              </div>
-              <div class="userMessage">
-                <div class="userMessageText">用户输入文字用户输入文字用户输入文字用户输入文字</div>
-                <div class="userMessageTime">12:55</div>
-              </div>
-            </div>
-          </div>
-          <div class="userItem">
+          <!-- <div class="userItem">
             <div class="userAvatar">
               <img src="@/assets/chat/user/group.jpg" alt="">
             </div>
@@ -81,19 +64,21 @@
                 <div class="userMessageTime">12:55</div>
               </div>
             </div>
-          </div>
+          </div> -->
           <!--管理员 end------------------------------------------>
         </div>
-        <!--用户列表 end------------------------------------------>
       </div>
-      <div class="hallRight">
+      <!--右侧菜单 start------------------------------------------>
+      <div class="hallRight" v-if="ifNoMessage==true">
+        <div class="ifHallRigthNoMessage">恒星管理平台</div>
+      </div>
+      <div class="hallRight" v-else>
         <div class="UserNameBox ifNotice">
           <div class="userName">用户名称</div>
           <img src="@/assets/chat/fi_more.png" @click="rightSlideBoxShow = !rightSlideBoxShow" class="moreIcon">
           <div class="groupNotice">群公告群公告群公告群公告群公告群公告群公告群公告</div>
         </div>
         
-
         <div class="rightPositionBox">
           <div class="rightUserMessageBox">
             <div class="timeBox">
@@ -183,7 +168,6 @@
                 <span>"加入了群聊</span>
               </div>
             </div>
-
             <div class="meUserMessage">
               <!--发名片 start------------------------------------------>
               <div class="meUserMessageText">
@@ -208,8 +192,6 @@
                 <img src="@/assets/chat/user/user.png" alt="">
               </div>
             </div>
-
-
           </div>
           <div class="sendMessageBox">
             <div class="sendMessageTools">
@@ -229,10 +211,9 @@
               </el-input>
             </div>
             <div class="sendMessageButton">
-              <el-button type="primary">发送 <i class="el-icon-position"></i></el-button>
+              <el-button type="primary" size="medium">发送 <i class="el-icon-position"></i></el-button>
             </div>
           </div> 
-
           <!--右侧菜单 start------------------------------------------------------------>
           <div class="rightSlideBox" v-if="rightSlideBoxShow">
             <div class="rightSlideSearch">
@@ -247,7 +228,10 @@
             <div class="rightSlideUserBox">
               <div class="rightSlideUserItem">
                 <div class="rightSlideUserItemIcon">
-                  <el-dropdown placement="left-start">
+                  <span class="el-dropdown-link">
+                    <img src="@/assets/chat/user/user.png">
+                  </span>
+                  <!-- <el-dropdown placement="left-start">
                     <span class="el-dropdown-link">
                       <img src="@/assets/chat/user/user.png">
                     </span>
@@ -259,11 +243,65 @@
                       <el-dropdown-item>查看聊天记录</el-dropdown-item>
                       <el-dropdown-item>发送消息</el-dropdown-item>
                     </el-dropdown-menu>
-                  </el-dropdown>
+                  </el-dropdown> -->
                 </div>
                 <div class="rightSlideUserItemName">
                   用户名称
                 </div>
+                <div class="rightSlideUserItemMore">
+                  <div class="rightSlideUserItemMoreMain">
+                    <div class="rightSlideUserItemMoreMainIcon">
+                      <img src="@/assets/chat/user/user.png">
+                    </div>
+                    <div class="rightSlideUserItemMoreMainInfo">
+                      <div class="rightSlideUserItemMoreMainInfoTop">
+                        <div class="rightSlideUserItemMoreUserName">
+                          <div>用户名</div>
+                          <div class="rightSlideUserItemMoreUserMore">
+                            <img src="@/assets/chat/boy.png">
+                          </div>
+                        </div>
+                        <div class="rightSlideUserItemMoreUserMoreIcon">
+                          <img src="@/assets/chat/fi_more.png">
+                        </div>
+                      </div>
+                      <div class="rightSlideUserItemMoreNumber">
+                        账号:15210211200
+                      </div>
+                    </div>
+                  </div>
+                  <div class="rightSlideUserItemMoreLine">
+                    <div class="rightSlideUserItemMoreLineItem">
+                      <div class="rightSlideUserItemMoreTitle">备注</div>
+                      <div class="rightSlideUserItemMoreText">
+                        用户名
+                        <i class="el-icon-edit"></i>
+                      </div>
+                    </div>
+                    <div class="rightSlideUserItemMoreLineItem">
+                      <div class="rightSlideUserItemMoreTitle">共同群聊</div>
+                      <div class="rightSlideUserItemMoreText">0个</div>
+                    </div>
+                    <div class="rightSlideUserItemMoreLineItem">
+                      <div class="rightSlideUserItemMoreTitle">添加方式</div>
+                      <div class="rightSlideUserItemMoreText">通过账号添加</div>
+                    </div>
+                    <div class="rightSlideUserItemMoreLineButton">
+                      <div class="rightSlideUserItemMoreLineGroup">
+                        <img src="@/assets/chat/sendmessage.png">
+                        <div>推荐给朋友</div>
+                      </div>
+                      <div class="rightSlideUserItemMoreLineGroup">
+                        <img src="@/assets/chat/sendmessage.png">
+                        <div>发消息</div>
+                      </div>
+                      <div class="rightSlideUserItemMoreLineGroup">
+                        <img src="@/assets/chat/sendmessage.png">
+                        <div>删除联系人</div>
+                      </div>
+                    </div>
+                  </div>
+                </div>
               </div>
               <div class="rightSlideUserItem">
                 <div class="rightSlideUserItemIcon">
@@ -280,7 +318,6 @@
               显示更多 <i class="el-icon-arrow-down"></i>
             </div>
             <div class="rightLineBorder"></div>
-
             <!--聊天记录 start------------------------------------------------------------>
             <div class="rightSlideFunction">
               <div class="rightSlideFunctionItem">
@@ -303,7 +340,6 @@
               </div>
             </div>
             <!--聊天记录 end------------------------------------------------------------>
-
             <!--群聊设置 start------------------------------------------------------------>
             <div class="rightSlideFunction">
               <div class="groupSystem">
@@ -359,9 +395,8 @@
               退出群聊
             </div>
           </div>
-          <!--右侧菜单 end------------------------------------------------------------>
         </div>
-
+        <!--右侧菜单 end------------------------------------------>
       </div>
     </div>
     <!--大厅 end------------------------------------------------------------>
@@ -411,16 +446,14 @@
               <div class="searchWindowUserName">A农贸站群长</div>
             </div>
           </div>
-
-          <!--分享名片-->
+          <!--分享名片 start------------------------------------------------------------>
           <div class="shareCardBox">
             <div class="shareCardTitle">[名片]用户名称</div>
             <div class="shareCardInput">
               <el-input v-model="userCardMessage" placeholder="给用户留言"></el-input>
             </div>
           </div>
-
-
+          <!--分享名片 end------------------------------------------------------------>
           <div class="searchWindowFooter">
             <el-button type="info" @click="windowStatus = false">取消</el-button>
             <el-button type="primary">完成</el-button>
@@ -584,7 +617,6 @@
                     <div class="fileWindowMessageItemText">用用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息</div>
                   </div>
                 </div>
-                
               </div>
               <div class="fileWindowGroupUserRight">
                 <div class="fileWindowGroupUserBox">
@@ -602,10 +634,8 @@
                     </div>
                   </div>
                 </div>
-
               </div>
             </div>
-
           </el-tab-pane>
         </el-tabs>
         <!--聊天记录选项卡 end------------------------------------------------------------>
@@ -613,8 +643,6 @@
     </el-dialog>
     <!--聊天记录弹出框 end------------------------------------------------------------>
 
-
-
     <!--添加用户弹出框 start------------------------------------------------------------>
     <el-dialog :visible.sync="addUserWindowStatus" title="添加用户" :close-on-click-modal="false" width="420px">
       <div class="messageFormBox">
@@ -648,11 +676,21 @@
     </el-dialog>
     <!--群公告弹出框 end------------------------------------------------------------>
 
-
-
-
-
-
+    <!--加入群聊弹出框 start------------------------------------------------------------>
+    <el-dialog :visible.sync="addGroupWindow" title="加入群聊" :close-on-click-modal="false" width="420px">
+      <div class="addGroupWindow">
+        <div class="addGroupWindowImg">
+          <img src="@/assets/chat/user/group.jpg" alt="">
+        </div>
+        <div class="addGroupWindowTitle">某某群聊</div>
+        <div class="addGroupWindowText">某某好友"用户名称"邀请您加入"某某群聊",进入可查看群消息</div>
+        <div class="footerButtonBox">
+          <el-button type="info">取消</el-button>
+          <el-button type="primary" @click="addGroupWindow = false">确定</el-button>
+        </div>
+      </div>
+    </el-dialog>
+    <!--加入群聊弹出框 end------------------------------------------------------------>
 
     <!-- <div class="layerBox">
       <el-container style="height: 100vh;">
@@ -714,7 +752,6 @@
         </el-container>
       </el-container>
 
-
     </div> -->
     <!--大厅 end------------------------------------------------------------>
   </div>
@@ -726,32 +763,31 @@ import '@/styles/global.less';
 //引入baseUrl
 import URL from '@/utils/baseUrl';
 //引入组件
-import tableTitle from './components/tableTitle.vue';
+import hallTitle from './components/hallTitle.vue';
 
 
 export default {
   components: {
-    tableTitle
+    hallTitle
   },
   data() {
     return {
+      //全局配置 start---------------------------------------->
       tableTitleName:'聊天列表',
       userMessage:'',//用户消息
-      
+      ifNoMessage:false,//如果没有选择任何聊天
       ifTop:false,//是否为置顶  
       rightSlideBoxShow:false,//右侧菜单是否显示
+      activeName: 'all',//聊天记录选项卡
+      userCardMessage:'',//用户留言
+      //全局配置 end---------------------------------------->
 
-
-
+      //弹窗框相关 start---------------------------------------->
       groupWindowStatus:false,//添加聊天群组出框是否显示
       fileWindowStatus:false,//聊天记录弹出框是否显示
       addUserWindowStatus:false,//添加用户弹出框是否显示
       editGroupNoticeWindow:false,//编辑群公告弹出框
-
-      activeName: 'all',//聊天记录选项卡
-
-      userCardMessage:'',//用户留言
-
+      addGroupWindow:false,//加入群聊弹出框
       form:{
         //好友申请
         addUserForm:{
@@ -759,116 +795,118 @@ export default {
           nickname:"",//修改昵称
         }
       },
+      //弹窗框相关 end---------------------------------------->
       
-
-
-
-
-
-
-
-
-
-      //老刘的代码
+      //老刘的代码 start---------------------------------------->
       activeConversation: null,
       newMessage: '',
-      conversations: [
-       
-      ],
+      conversations: [],
       ws: null,
       contextMenuVisible: false, // 控制右键菜单的显示
       contextMenuX: 0, // 右键菜单的 X 坐标
       contextMenuY: 0, // 右键菜单的 Y 坐标
       selectedConversation: null // 选中的对话
+      //老刘的代码 end---------------------------------------->
     };
   },
   methods: {
-    selectConversation(conversation) {
-      this.activeConversation = conversation;
-    },
-    sendMessage() {
-      if (this.newMessage.trim() !== '') {
+    //老刘的代码 start---------------------------------------->
+    // selectConversation(conversation) {
+    //   this.activeConversation = conversation;
+    // },
+    // sendMessage() {
+    //   if (this.newMessage.trim() !== '') {
+    //     //msg_type 消息类型  talk_type:聊天类型 1单聊 2群聊
+    //     const message = { 
+    //       msg_type:1,
+    //       talk_type:this.activeConversation.talk_type,
+    //       content:this.newMessage,
+    //       session_id:this.activeConversation.session_id,
+    //       msg_type:1,
+    //       receiver_id:this.activeConversation.user_id?this.activeConversation.user_id:this.activeConversation.group_id
+    //     };
+    //     // this.activeConversation.messages.push(message);
+    //     console.log("发送消息",this.ws,WebSocket.OPEN)
+    //     if (this.ws && this.ws.readyState === WebSocket.OPEN) {
+    //       this.ws.send(JSON.stringify(message));
+    //     }
+    //     this.newMessage = '';
+    //   }
+    // },
+    // handleIncomingMessage(event) {
+    //   const message = JSON.parse(event.data);
+    //   console.log("监听消息:",message)
+    //   const conversation = this.conversations.find(conv => conv.session_id === message.session_id); // 假设所有消息都发送给Alice
+    //   if (conversation) {
+    //     conversation.messages.push(message);
+    //   }
+    // },
+    // //获取会话列表
+    // getTalkSessionList(){
+    //   let parames  = {
+    //     'page':1,
+    //     'pageSize':10
+    //   }
+    //   // this.$api.chat.getTalkSessionList(parames).then(res=>{
+    //   //     this.conversations =  res.data.row
+    //   // });
+    //   this.$store.dispatch('chat/getTalkSessionList',parames).then(res=> {
+    //     this.conversations =  res.data.row
+    //   }).catch(() => {
+    //     this.$message({
+    //       type: 'info',
+    //       message: '获取聊天记录失败!'
+    //     });
+    //   })
+    // },
+    // showContextMenu(event, conversation) {
+    //   this.contextMenuVisible = true; // 显示右键菜单
+    //   this.contextMenuX = event.clientX; // 获取鼠标 X 坐标
+    //   this.contextMenuY = event.clientY; // 获取鼠标 Y 坐标
+    //   this.selectedConversation = conversation; // 保存选中的对话
+    // },
+    // handleMenuCommand(command) {
+    //   switch (command) {
+    //     case 'view':
+    //       this.viewConversation(this.selectedConversation);
+    //       break;
+    //     case 'delete':
+    //       this.deleteConversation(this.selectedConversation);
+    //       break;
+    //     case 'edit':
+    //       this.editConversation(this.selectedConversation);
+    //       break;
+    //   }
+    //   this.contextMenuVisible = false; // 隐藏右键菜单
+    // },
+    // viewConversation(conversation) {
+    //   // 查看对话的逻辑
+    //   console.log('查看对话:', conversation);
+    // },
+    // deleteConversation(conversation) {
+    //   // 删除对话的逻辑
+    //   console.log('删除对话:', conversation);
+    // },
+    // editConversation(conversation) {
+    //   // 编辑对话的逻辑
+    //   console.log('编辑对话:', conversation);
+    // },
+    //老刘的代码 end---------------------------------------->
+    
+    //1.会话列表 start---------------------------------------->
+    //1.1获取会话列表
+    getConversationList(){
 
-        //msg_type 消息类型  talk_type:聊天类型 1单聊 2群聊
-        const message = { 
-          msg_type:1,
-          talk_type:this.activeConversation.talk_type,
-          content:this.newMessage,
-          session_id:this.activeConversation.session_id,
-          msg_type:1,
-          receiver_id:this.activeConversation.user_id?this.activeConversation.user_id:this.activeConversation.group_id
-        };
-        // this.activeConversation.messages.push(message);
-        console.log("发送消息",this.ws,WebSocket.OPEN)
-        if (this.ws && this.ws.readyState === WebSocket.OPEN) {
-          this.ws.send(JSON.stringify(message));
-        }
-        this.newMessage = '';
-      }
-    },
-    handleIncomingMessage(event) {
-      const message = JSON.parse(event.data);
-      console.log("监听消息:",message)
-      const conversation = this.conversations.find(conv => conv.session_id === message.session_id); // 假设所有消息都发送给Alice
-      if (conversation) {
-        conversation.messages.push(message);
-      }
     },
-    //获取会话列表
-    getTalkSessionList(){
-      let parames  = {
-        'page':1,
-        'pageSize':10
-      }
-      // this.$api.chat.getTalkSessionList(parames).then(res=>{
-      //     this.conversations =  res.data.row
-      // });
-      this.$store.dispatch('chat/getTalkSessionList',parames).then(res=> {
-        this.conversations =  res.data.row
-      }).catch(() => {
-        this.$message({
-          type: 'info',
-          message: '获取聊天记录失败!'
-        });
-      })
-    },
-    showContextMenu(event, conversation) {
-      this.contextMenuVisible = true; // 显示右键菜单
-      this.contextMenuX = event.clientX; // 获取鼠标 X 坐标
-      this.contextMenuY = event.clientY; // 获取鼠标 Y 坐标
-      this.selectedConversation = conversation; // 保存选中的对话
-    },
-    handleMenuCommand(command) {
-      switch (command) {
-        case 'view':
-          this.viewConversation(this.selectedConversation);
-          break;
-        case 'delete':
-          this.deleteConversation(this.selectedConversation);
-          break;
-        case 'edit':
-          this.editConversation(this.selectedConversation);
-          break;
-      }
-      this.contextMenuVisible = false; // 隐藏右键菜单
-    },
-    viewConversation(conversation) {
-      // 查看对话的逻辑
-      console.log('查看对话:', conversation);
-    },
-    deleteConversation(conversation) {
-      // 删除对话的逻辑
-      console.log('删除对话:', conversation);
-    },
-    editConversation(conversation) {
-      // 编辑对话的逻辑
-      console.log('编辑对话:', conversation);
+    //1.2选择会话
+    selectConversation(){
+
     },
+    //1.会话列表 end---------------------------------------->
 
 
 
-    //用户菜单操作
-    //--删除联系人 start---------------------------------------->
+    //我的代码 start---------------------------------------->
     deleteUser(id){
       //console.log("删除联系人",id)
       this.$confirm('此操作将删除该联系人,确定吗?', '提示', {
@@ -885,30 +923,11 @@ export default {
         });
       });
     },
-    //--删除联系人 end---------------------------------------->
+
     addUser(){
       this.groupWindowStatus = true;
     }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+    //我的代码 end---------------------------------------->
   },
   mounted() {
     //1.获取admin-token
@@ -946,7 +965,6 @@ export default {
 </script>
 
 <style scoped lang="less">
-
   .hallBox {
     display: flex;
     margin: 30px;
@@ -963,6 +981,8 @@ export default {
       }
       .userListBox {
         padding: 15px 0;
+        overflow-y: auto;
+        height: 1000px;
         .active {
           background: #F5F7FD;
           box-sizing: border-box;
@@ -1037,6 +1057,17 @@ export default {
       background: #fff;
       border-radius: 20px;
       position: relative;
+      height: 1184px;
+      display: flex;
+      flex-direction: column;
+      .ifHallRigthNoMessage {
+        color: #CCCCCC;
+        font-size: 32px;
+        font-weight: bold;
+        text-align: center;
+        height: 1184px;
+        line-height: 1184px;
+      }
       .userName {
         font-size: 20px;
         color: #333;
@@ -1074,11 +1105,14 @@ export default {
           text-overflow: ellipsis;
         }
       }
-
-      .rightPositionBox {
+      .rightPositionBox { 
+        flex: 1;
         position: relative;
         .rightUserMessageBox {
           padding: 40px;
+          height: 760px;
+          box-sizing: border-box;
+          overflow-y: auto;
           .timeBox {
             width: 100%;
             display: flex;
@@ -1201,16 +1235,12 @@ export default {
           }
         }
       }
-
-
-
-
-      
-
       //消息框
       .sendMessageBox {
         padding: 20px 40px;
         border-top: 1px solid #E7E7E7;
+        box-sizing: border-box;
+        height: 276px;
         .sendMessageTools {
           img {
             width: 36px;
@@ -1225,9 +1255,12 @@ export default {
         .sendMessageButton {
           padding-top: 20px;
           text-align: right;
+          button {
+            width: 120px;
+            height: 38px;
+          }
         }
       }
-      
       //右侧菜单
       .rightSlideBox {
         width: 420px;
@@ -1250,12 +1283,105 @@ export default {
           .rightSlideUserItem {
             margin-bottom: 20px;
             width: 25%;
+            position: relative;
+            //用户菜单
+            .rightSlideUserItemMore {
+              position: absolute;
+              background: #fff;
+              box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.1);
+              bottom: -360px;
+              left: -240px;
+              width: 280px;
+              height: 400px;
+              .rightSlideUserItemMoreMain {
+                display: flex;
+                align-items: center;
+                justify-content: flex-start;
+                padding:0 20px;
+                .rightSlideUserItemMoreMainIcon {
+                  img {
+                    width: 66px;
+                    height: 66px;
+                    border-radius: 50%;
+                  }
+                }
+                .rightSlideUserItemMoreMainInfo { 
+                  padding: 30px 20px;
+                  border-bottom: 1px solid #E9EDF7;
+                  .rightSlideUserItemMoreMainInfoTop {
+                    display: flex;
+                    align-items: center;
+                    justify-content: space-between;
+                    .rightSlideUserItemMoreUserName {
+                      display: flex;
+                      align-items: center;
+                      justify-content: center;
+                      font-size: 18px;
+                      .rightSlideUserItemMoreUserMore {
+                        margin-left: 10px;
+                        img {
+                          width: 12px;
+                          height: 12px;
+                        }
+                      }
+                    }
+                    .rightSlideUserItemMoreUserMoreIcon {
+                      img {
+                        width: 18px;
+                        height: 18px;
+                      }
+                    }
+                  }
+                }
+                .rightSlideUserItemMoreNumber {
+                  font-size: 14px;
+                  color: #999;
+                  margin-top: 10px;
+                }
+              }
+              .rightSlideUserItemMoreLine {
+                .rightSlideUserItemMoreLineItem {
+                  padding: 20px;
+                  border-bottom: 1px solid #E9EDF7;
+                  display: flex;
+                  .rightSlideUserItemMoreTitle {
+                    font-size: 16px;
+                    color: #999;
+                    width: 80px;
+                  }
+                  .rightSlideUserItemMoreText {
+                    font-size: 16px;
+                    color: #333;
+                    display: flex;
+                    align-items: center;
+                    justify-content: space-between;
+                    flex:1;
+                  }
+                }
+                .rightSlideUserItemMoreLineButton {
+                  padding-top: 25px;
+                  text-align: center;
+                  font-size: 14px;
+                  color:#5570F1;
+                  display: flex;
+                  align-items: center;
+                  justify-content: center;
+                  img {
+                    width: 25px;
+                    height: 25px;
+                    margin-bottom: 8px;
+                  }
+                  .rightSlideUserItemMoreLineGroup {
+                    width: 33.33%;
+                  }
+                }
+              }
+            }
             .rightSlideUserItemIcon {
               display: flex;
               align-items: center;
               justify-content: center;
               border-radius: 50%;
-
               img {
                 width: 58px;
                 height: 58px;
@@ -1309,7 +1435,6 @@ export default {
             }
           }
         }
-
         //群聊设置
         .groupSystem {
           border-bottom: 1px solid #E9EDF7;
@@ -1327,7 +1452,6 @@ export default {
             }
           }
         }
-
         .rightSlideFooter {
           font-size: 18px;
           color: #CC5F5F;
@@ -1340,7 +1464,6 @@ export default {
 
     }
   }
-
   //不同的消息类型
   //发送文件
   .messageTypeFile {
@@ -1390,7 +1513,6 @@ export default {
       color: #999;
     }
   }
-
   //发送名片
   .messageTypeCard {
     width: 321px;
@@ -1423,8 +1545,6 @@ export default {
       color: #999999;
     }
   }
-
-
   //发送图片
   .messageTypeImage {
     width: 200px;
@@ -1435,7 +1555,6 @@ export default {
       border: 1px solid #ECECEC;
     }
   }
-
   //发送群聊
   .messageGroupInvite {
     background: #fff;
@@ -1476,10 +1595,6 @@ export default {
       border-top: 1px solid #E9EDF7;
     }
   }
-
-
-
-
   //添加用户弹出框
   .searchWindow {
     display: flex;
@@ -1585,7 +1700,6 @@ export default {
       }
     }
   }
-   
   //聊天记录弹出框
   .fileWindow {
     .fileWindowHeader {
@@ -1738,12 +1852,7 @@ export default {
         }
       }
     }
-
-
-
-    
   }
-
   //添加用户弹出框
   .messageFormBox {
     .messageFormTitle {
@@ -1753,14 +1862,35 @@ export default {
     .messageFormInput {
       margin-bottom: 30px;
     }
-    
   }
   //弹出框底部按钮
   .footerButtonBox {
     padding-top: 40px;
     text-align: center;
   }
-
+  //加入群聊弹出框
+  .addGroupWindow {
+    .addGroupWindowImg {
+      img {
+        width:58px;
+        height: 58px;
+      }
+      text-align: center;
+      font-size: 18px;
+      color: #333;
+    }
+    .addGroupWindowTitle {
+      font-size: 18px;
+      color: #333;
+      text-align: center;
+      padding: 20px 0 40px 0;
+    }
+    .addGroupWindowText {
+      font-size: 12px;
+      color: #999;
+      text-align: center;
+    }
+  }
   //表单微调 start------------------------------------------------------------>*/
   ::v-deep .custom-form-item > .el-form-item__label {
     line-height: 140px !important;

+ 280 - 0
src/views/chat/topic.vue

@@ -0,0 +1,280 @@
+<template>
+  <div class="mainBox">
+    <!--搜索功能 start------------------------------------------------------------>
+    <div class="layerBox_search">
+      <div class="layerBoxLine">
+        <el-row>
+          <el-col :span="8">
+            <div class="searchBox">
+              <div class="searchTitle">课题标题:</div>
+              <el-input placeholder="请输入资讯题目" autocomplete="off" v-model="getApiData.title"/>
+            </div>
+          </el-col>
+          <el-col :span="8">
+            <div class="searchBox">
+              <div class="searchTitle">课题分类:</div>
+              <el-input placeholder="请输入导航池名称" autocomplete="off" v-model="getApiData.category_name"/>
+            </div>
+          </el-col>
+          <el-col :span="8">
+            <div class="searchBox">
+              <div class="searchTitle">作者:</div>
+              <el-input placeholder="请输入作者姓名" autocomplete="off" v-model="getApiData.author"/>
+            </div>
+          </el-col>
+        </el-row>
+      </div>
+      <div class="layerBoxLineTwo">
+        <el-row>
+          <el-col :span="8">
+            <div class="searchBox">
+              <div class="searchTitle">审核状态:</div>
+              <el-select v-model="getApiData.islink" placeholder="请选择..">
+                <el-option label="否" value="0"></el-option>
+                <el-option label="是" value="1"></el-option>
+              </el-select>
+            </div>
+          </el-col>
+        </el-row>
+      </div>
+    </div>
+    <div class="layerBoxNoBg">
+      <div>
+        <el-button type="primary" @click="goCreat">发布课题</el-button>
+      </div>
+      <div>
+        <el-button @click="clearSearchList">重置</el-button>
+        <el-button type="primary" @click="getData('search')">搜索</el-button>
+      </div>
+    </div>
+    <!--搜索功能 end------------------------------------------------------------>
+
+    <!--表格内容 start------------------------------------------------------------>
+    <div class="layerBox">
+      <tableTitle :name="tableDivTitle"/>
+      <el-row>
+        <template>
+          <el-table :data="tableData" style="width: 100%">
+            <el-table-column fixed prop="id" label="编号" width="50"></el-table-column>
+            <el-table-column prop="title" label="课题标题" width=""></el-table-column>
+            <el-table-column prop="category_name" label="课题分类" width=""></el-table-column>
+            <el-table-column prop="islink" label="作者" width=""></el-table-column>
+            <el-table-column prop="fromurl" label="创建时间" width=""></el-table-column>
+            <el-table-column prop="author" label="修改时间" width=""></el-table-column>
+            <el-table-column prop="status" label="状态" width="">
+              <template slot-scope="scope">
+                <span v-if="scope.row.status==404">404</span>
+                <el-switch
+                  v-else
+                  v-model="scope.row.status"
+                  :active-value="1"
+                  :inactive-value="0"
+                  @change="upRow(scope.row.id,scope.row.status)"
+                ></el-switch>
+              </template>
+            </el-table-column>
+            <el-table-column fixed="right" label="操作" width="280" header-align="center">
+              <template slot-scope="scope">
+                <div class="listBtnBox">
+                  <div class="listDeleteBtn" @click="deleteRow(scope.row.id, tableData)"><i class="el-icon-delete"></i>移除</div>
+                  <div class="listEditBtn" @click="goEdit(scope.row.id, tableData)"><i class="el-icon-edit-outline"></i>编辑</div>
+                  <div class="listMainBtn" @click="auditStatus=true"><i class="el-icon-edit-outline"></i>审核</div>
+                </div>
+              </template>
+            </el-table-column>
+          </el-table>
+        </template>
+      </el-row>
+    </div>
+    <!--分页 start------------------------------------------------------------>
+    <div class="alignBox">
+      <el-row>
+        <el-col :span="24">
+          <el-pagination @size-change="handleSizeChange" :current-page="getApiData.page" @current-change="handleCurrentChange" :page-size="10" layout="total, prev, pager, next, jumper" :total="allCount"></el-pagination>
+        </el-col>
+      </el-row>
+    </div>
+    <!--分页 end------------------------------------------------------------>
+    <!--表格内容 end------------------------------------------------------------>
+
+    <!--审核状态弹出框 start------------------------------------------------------------>
+    <el-dialog :visible.sync="auditStatus" title="审核状态" :close-on-click-modal="false" width="420px">
+      <div>
+        <div>
+          <el-radio-group v-model="radio">
+            <el-radio :label="1">通过</el-radio>
+            <el-radio :label="2">拒绝</el-radio>
+          </el-radio-group>
+        </div>
+        <div class="footerButtonBox">
+          <el-button type="info">取消</el-button>
+          <el-button type="primary">确定</el-button>
+        </div>
+      </div>
+    </el-dialog>
+    <!--审核状态弹出框 end------------------------------------------------------------>
+
+  </div>
+</template>
+
+<script>
+//表格标题
+import tableTitle from './components/tableTitle';
+//引入公用样式
+import '@/styles/global.less';
+
+export default {
+  components: {
+    tableTitle,//表格标题
+  },
+  data() {
+    return {
+      //1.列表和分页相关 start ------------------------------------------------------------>
+      tableDivTitle:"资讯列表",
+      tableData:[],//内容
+      editId:0,//要修改的网站id
+      getApiData:{
+        title:"",//标题
+        category_name:"",//导航池id
+        author:"",//作者
+        islink:"",//是否使用外链
+        status:"",//资讯状态
+        page:1,//当前是第几页
+        pageSize:10,//一共多少条
+      },
+      allCount:0,//总条数
+      form:{
+        radio:1 //1=通过 2=拒绝
+      },
+      auditStatus:false,//审核状态弹出框
+      //分页相关 end ------------------------------------------------------------>
+    }
+  },
+  methods: {
+    //1.列表和分页相关 start ------------------------------------------------------------>
+    //1.1 开始请求列表信息方法
+    getData(type){
+      if(type=="search"){
+        this.getApiData.page = 1;
+      }
+      this.$store.dispatch('news/getArticleList',this.getApiData).then(res=> {
+        //格式化:islink=0为不使用外面 islink=1为使用外链
+        //status=1为显示 status=2为不显示
+        let data = [];
+        for(let item of res.data.rows){
+          // if(item.status==0){item.status="隐藏"}
+          // if(item.status==1){item.status="显示"}
+          // if(item.status==404){item.status="已删除"}
+          if(item.islink==0){item.islink="否"}
+          if(item.islink==1){item.islink="是"}
+          data.push(item)
+        }
+        this.tableData = res.data.rows; //给与内容
+        this.allCount = res.data.count; //给与总条数
+      }).catch(() => {
+        this.$message({
+          type: 'warning',
+          message: '网络错误,请重试!'
+        });
+      })
+    },
+    //1.2 删除内容
+    deleteRow(id){
+      this.$confirm('此操作将永久删除该条数据, 是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        console.log("当前删除:" + id)
+        this.$store.dispatch('news/delArticle',{id:id}).then(res=> {
+          this.getData();
+          this.$message({
+            type: 'success',
+            message: '删除成功!'
+          });
+        }).catch(() => {
+          this.$message({
+            type: 'warning',
+            message: '网络错误,请重试!'
+          });
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'warning',
+          message: '已取消删除'
+        });
+      });
+    },
+    //1.3 修改网站状态
+    upRow(id,status){
+      let data = {
+        id:id,
+        status:status
+      }
+      this.$store.dispatch('news/upArticleStatus',data).then(res=> {
+        if(res.code==200){
+          this.$message({
+            type: 'success',
+            message: '资讯状态已修改!'
+          });
+        }
+      }).catch(() => {
+        this.$message({
+          type: 'warning',
+          message: '已取消删除'
+        });
+      });
+    },
+    //1.4 列表内容分页
+    //直接跳转
+    handleSizeChange(val) {
+      this.getApiData.page = val;
+      this.getData();
+    },
+    //1.5 点击分页
+    handleCurrentChange(val) {
+      this.getApiData.page = val;
+      this.getData();
+    },
+    //1.6 重置按钮
+    clearSearchList(){
+      this.tableData = [];
+      this.getApiData.title = "";
+      this.getApiData.category_name = "";
+      this.getApiData.author = "";
+      this.getApiData.islink = "";
+      this.getApiData.status = "";
+      this.getApiData.page = 1;
+      this.getApiData.pageSize = 10;
+      this.getData();
+    },
+    //列表和分页相关 end ------------------------------------------------------------>
+
+    //2.添加新闻 start ------------------------------------------------------------>
+    //跳转到资讯发布页面
+    goCreat(){
+      this.$router.push({
+        path: '/creatTopic',
+      });
+    },
+    goEdit(id){
+      let data = {
+        id:id
+      }
+      this.$router.push({
+        path: '/creatTopic',
+        query: data
+      });
+    }
+    //添加新闻 end ------------------------------------------------------------>
+  },
+  mounted(){
+    //1.获得初始数据
+    this.getData();
+  }
+}
+</script>
+
+<style scoped lang="less">
+
+</style>

+ 1 - 1
src/views/menu/menulist.vue

@@ -288,7 +288,7 @@ export default {
         this.parentKey += 1;
         console.log(this.pidArrData)
         console.log(data.pid)
-        this.form.pid_arr = data.pid;
+        this.form.pid_arr = [data.pid];
       }
       
       //回显示icon