rkljw 2 днів тому
батько
коміт
c101e068cf

+ 2 - 0
package.json

@@ -20,6 +20,7 @@
     "clipboard": "2.0.4",
     "codemirror": "5.45.0",
     "core-js": "3.6.5",
+    "dayjs": "^1.11.13",
     "driver.js": "0.9.5",
     "dropzone": "5.5.1",
     "echarts": "4.2.1",
@@ -29,6 +30,7 @@
     "js-cookie": "2.2.0",
     "jsonlint": "1.6.3",
     "jszip": "3.2.1",
+    "mitt": "^3.0.1",
     "normalize.css": "7.0.0",
     "nprogress": "0.2.0",
     "path-to-regexp": "2.4.0",

+ 23 - 2
src/App.vue

@@ -1,14 +1,19 @@
 <template>
   <div id="app">
     <router-view />
-    <ChatFloatButton v-if="!showChat && this.$store.state.user.name" @open="showChat = true" />
-    <ChatPanel v-if="showChat && this.$store.state.user.name" @close="showChat = false" />
+    <ChatFloatButton ref="chatFloatButton" v-show="!showChat && $store.state.user.name" @open="showChat = true" />
+    <ChatPanel
+      ref="chatPanel"
+      v-show="showChat && $store.state.user.name"
+      @close="showChat = false"
+    />
   </div>
 </template>
 
 <script>
 import ChatFloatButton from './layout/components/Chat/ChatFloatButton.vue'
 import ChatPanel from './layout/components/Chat/ChatPanel.vue'
+import emitter from '@/eventBus';
 
 export default {
   name: 'App',
@@ -17,6 +22,22 @@ export default {
     return {
       showChat: false
     }
+  },
+  mounted() {
+    emitter.on('view-group-chat', this.handleViewGroupChat);
+  },
+  beforeDestroy() {
+    emitter.off('view-group-chat', this.handleViewGroupChat);
+  },
+  methods: {
+    handleViewGroupChat(val) {
+      this.showChat = true; // 先显示 ChatPanel
+      this.$nextTick(() => {
+        if (this.$refs.chatPanel) {
+          this.$refs.chatPanel.viewGroupChat(val);// 这里调用 selectGroup 或其它弹窗方法
+        }
+      });
+    }
   }
 }
 </script>

+ 25 - 1
src/api/chat.js

@@ -347,4 +347,28 @@ export function getTopicClassInfo(data) {
     data
   })
 }
-//7.课题分类 end ------------------------------------->
+//7.课题分类 end ------------------------------------->
+//获取商圈列表
+export const getBusinessDistrictList = (params) => {
+  return request({
+    url: '/chat/getBusinessDistrictList',
+    method: 'get',
+    params
+  })
+} 
+
+export const getTopicType = (data) => {
+  return request({
+    url: '/chat/topicType',
+    method: 'post',
+    data
+  })
+}
+
+export const getTopicDataInfo = (data) => {
+  return request({
+    url: '/chat/getTopicInfo',
+    method: 'post',
+    data
+  })
+}

+ 3 - 0
src/eventBus.js

@@ -0,0 +1,3 @@
+import mitt from 'mitt';
+const emitter = mitt();
+export default emitter;

+ 129 - 86
src/layout/components/Chat/ChatPanel.vue

@@ -177,6 +177,7 @@
     heigth="80%"
     class="chat-dialog"
     top="2vh"
+    :model="false"
   >
     <!--右侧菜单 start------------------------------------------------------------>
         <div class="hallRight">
@@ -618,7 +619,7 @@
           </div>
         </div>
     </el-dialog>
-    <el-dialog :visible.sync="groupWindowStatus" :close-on-click-modal="false" width="1028px">
+    <el-dialog :visible.sync="groupWindowStatus" :modal="false" :close-on-click-modal="false" width="1028px">
       <div class="searchWindow">
         <div class="searchWindowLeft">
           <div class="searchUserWindowBox">
@@ -705,7 +706,7 @@
       </div>
     </el-dialog>
     <!--分享群聊 start------------------------------------------------------------>
-      <el-dialog :visible.sync="shareGroupWindowStatus" title="分享群聊" :close-on-click-modal="false" width="420px">
+      <el-dialog :visible.sync="shareGroupWindowStatus" :modal="false" title="分享群聊" :close-on-click-modal="false" width="420px">
         <div>
           <div class="shareCardWindowBox">
             <el-tabs v-model="shareGroupActive" type="card" @tab-click="handleClickShareGroupCard">
@@ -750,7 +751,7 @@
       <!--分享群聊 end------------------------------------------------------------>
   
       <!--放大图片 start------------------------------------------------------------>
-      <el-dialog :visible.sync="imgZoomStatus" title="图片详情" :close-on-click-modal="false" max-width="600px">
+      <el-dialog :visible.sync="imgZoomStatus" :modal="false" title="图片详情" :close-on-click-modal="false" max-width="600px">
         <div>
           <div class="imgZoomBox">
             <img :src="imgZoomUrl">
@@ -760,8 +761,8 @@
           </div>
         </div>
       </el-dialog>
-            <!--聊天记录弹出框 start------------------------------------------------------------>
-            <el-dialog :visible.sync="fileWindowStatus" title="聊天记录" :close-on-click-modal="false" width="757px">
+      <!--聊天记录弹出框 start------------------------------------------------------------>
+      <el-dialog :visible.sync="fileWindowStatus" title="聊天记录" :model="false" :close-on-click-modal="false" width="757px">
         <div class="fileWindow">
           <div class="fileWindowHeader">
             <el-input
@@ -927,7 +928,7 @@
                         <div class="fileWindowMessageItemName">用户名称</div>
                         <div class="fileWindowMessageItemTime">12:40</div>
                       </div>
-                      <div class="fileWindowMessageItemText">用用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息</div>
+                      <div class="fileWindowMessageItemText">用用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息</div>
                     </div>
                   </div>
                 </div>
@@ -957,7 +958,7 @@
       <!--聊天记录弹出框 end------------------------------------------------------------>
             <!--编辑群成员弹出框 start------------------------------------------------------------>
       <!--编辑时 左侧显示的是好友列表 右侧显示的是群成员-->
-      <el-dialog :visible.sync="groupEditWindowStatus" :close-on-click-modal="false" width="1028px" @closed="cancelEditGroupMember">
+      <el-dialog :visible.sync="groupEditWindowStatus" :model="false" :close-on-click-modal="false" width="1028px" @closed="cancelEditGroupMember">
         <div class="searchWindow">
           <div class="searchWindowLeft">
             <div class="searchUserWindowBox">
@@ -1052,7 +1053,7 @@
       </el-dialog>
       <!--编辑群成员弹出框 end------------------------------------------------------------>
       <!--群名称弹出框 start------------------------------------------------------------>
-      <el-dialog :visible.sync="editGroupNameWindow" title="编辑群名称" :close-on-click-modal="false" width="420px">
+      <el-dialog :visible.sync="editGroupNameWindow" title="编辑群名称" :model="false" :close-on-click-modal="false" width="420px">
         <div>
           <div>
             <el-input type="textarea" resize="none" v-model="editMessageTitle" placeholder="请输入" maxlength="20"></el-input>
@@ -1064,8 +1065,8 @@
         </div>
       </el-dialog>
       <!--群名称弹出框 end------------------------------------------------------------>
-            <!--群公告弹出框 start------------------------------------------------------------>
-            <el-dialog :visible.sync="editGroupNoticeWindow" title="编辑群公告" :close-on-click-modal="false" width="420px">
+      <!--群公告弹出框 start------------------------------------------------------------>
+      <el-dialog :visible.sync="editGroupNoticeWindow" title="编辑群公告" :model="false" :close-on-click-modal="false" width="420px">
         <div>
           <div>
             <el-input type="textarea" resize="none" v-model="editGroupProfile" placeholder="请输入" rows="10" maxlength="500"></el-input>
@@ -1079,7 +1080,7 @@
       <!--群公告弹出框 end------------------------------------------------------------>
   
       <!--查看群公告 start------------------------------------------------------------>
-      <el-dialog :visible.sync="groupProfileWindow" title="群公告详情" :close-on-click-modal="false" width="420px">
+      <el-dialog :visible.sync="groupProfileWindow" title="群公告详情" :model="false" :close-on-click-modal="false" width="420px">
         <div>
           <div class="groupProfileBox">
             {{groupProfile}}
@@ -1090,8 +1091,8 @@
         </div>
       </el-dialog>
       <!--查看群公告 end------------------------------------------------------------>
-            <!--分享名片 start------------------------------------------------------------>
-            <el-dialog :visible.sync="userCardWindowStatus" title="分享名片" :close-on-click-modal="false" width="420px">
+      <!--分享名片 start------------------------------------------------------------>
+      <el-dialog :visible.sync="userCardWindowStatus" title="分享名片" :model="false" :close-on-click-modal="false" width="420px">
         <div>
           <div class="shareCardWindowBox">
             <el-tabs v-model="shareTableActive" type="card" @tab-click="handleClickShareCard">
@@ -1136,7 +1137,7 @@
       <!--分享名片 end------------------------------------------------------------>
         
       <!--发送好友申请弹出框 start------------------------------------------------------------>
-      <el-dialog :visible.sync="addFriendWindowStatus" title="朋友申请" :close-on-click-modal="false" width="420px">
+      <el-dialog :visible.sync="addFriendWindowStatus" title="朋友申请" :model="false" :close-on-click-modal="false" width="420px">
         <div>
           <div>
             <el-form :model="form" ref="form" autocomplete="off" label-position="left">
@@ -1156,7 +1157,7 @@
       <!--发送好友申请弹出框 end------------------------------------------------------------>
 
       <!--加入群聊弹出框 start------------------------------------------------------------>
-      <el-dialog :visible.sync="addGroupWindow" title="加入群聊" :close-on-click-modal="false" width="420px">
+      <el-dialog :visible.sync="addGroupWindow" title="加入群聊" :model="false" :close-on-click-modal="false" width="420px">
         <div class="addGroupWindow">
           <div class="addGroupWindowImg">
             <img src="@/assets/chat/user/group.jpg" alt="">
@@ -1175,6 +1176,7 @@
           title=" "
           :close-on-click-modal="false"
           width="420px"
+          :model="false"
         >
         <div class="searchFriendBox" >
               <div class="searchFriendItem">
@@ -1200,17 +1202,9 @@
             </div>
       </el-dialog>
       <!--请求验证弹出框 start------------------------------------------------------------>
-      <el-dialog :visible.sync="friendWindowStatus" title="通过朋友验证" :close-on-click-modal="false" width="420px">
+      <el-dialog :visible.sync="friendWindowStatus" title="通过朋友验证" :model="false" :close-on-click-modal="false" width="420px">
         <div>
           <div class="friendWindowText">
-            <!--此处修改备注是没用的,修改备注需要friendId,但是此时你们还不是好友,改不了备注-->
-            <!-- <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> -->
             确定要添加<span>{{friendInfo.user_name}}</span>为好友吗?
           </div>
           <div class="footerButtonBox">
@@ -1221,7 +1215,7 @@
       </el-dialog>
       <!--请求验证弹出框 end------------------------------------------------------------>
       <!--修改备注弹出框 start------------------------------------------------------------>
-      <el-dialog :visible.sync="editWindowStatus" title="修改备注" :close-on-click-modal="false" width="420px">
+      <el-dialog :visible.sync="editWindowStatus" title="修改备注" :modal="false" :close-on-click-modal="false" width="420px">
         <div>
           <div>
             <el-form :model="form" ref="form" autocomplete="off" label-position="left">
@@ -1261,6 +1255,7 @@
               </div>
             </div>
       </el-dialog>
+      <!-- <el-button class="top-button" type="primary" @click="viewGroupChat">查看群聊</el-button> -->
     </div>
    
   </template>
@@ -1278,9 +1273,11 @@
     name: "ChatPanel",
     data() {
       return {
+        token:'',
         ones:0,
         messageContent:{},
         avatar:this.$store.state.user.avatar,
+        user_id:this.$store.state.user.userid,
         showfrindDialog:false,
         activeTab: 0,
         groupList: [],
@@ -1452,7 +1449,6 @@
       clickShowMessage() {
         // 先关闭所有旧消息
         this.$message.closeAll();
-
         this.$message({
           dangerouslyUseHTMLString: true,
           message: `
@@ -1463,7 +1459,8 @@
               <span>收到新消息</span>
             </div>
           `,
-          duration: 3000,
+          duration: 300000,
+          customClass:'message-new'
         });
 
         setTimeout(() => {
@@ -1853,6 +1850,7 @@
       //2.2 选择群聊
       //2.1.1 在会话列表中选择一个群聊
       selectGroup(item){
+        console.log("群聊接收值:",item)
         this.$fixModalZIndex();
         this.showDialog = true;
         //选择会话的时候开启loading框
@@ -2020,6 +2018,7 @@
       },
       //2.3.8 群弹出框回显群内成员
       editGroupMember(){
+
         //1.打开编辑窗口
         this.groupEditWindowStatus = true;
         //2.获得好友列表
@@ -2029,8 +2028,7 @@
             item.status = false; //默认未选中
           }
           this.friendsList = res.data;
-          console.log(this.friendsList)
-          console.log(this.groupUserList)
+
           //4.判断一下groupUserList是否包含friendsList中的成员,如果包含,就把friendsList中的成员status设置为true
           this.friendsList.forEach(item => {
             console.log(item.user_id)
@@ -2421,20 +2419,23 @@
       //5.1 接受消息
       handleIncomingMessage(event) {
         const message = JSON.parse(event.data);
-        this.clickShowMessage();
-        console.log("监听消息1:",message)
-        if(this.ones==0){
-          this.ones = 1
-          this.getConversationList();          
-        }
-        console.log(message.receiver_id)
-        this.conversationList.forEach(item => {
-          if(item.receiver_id==message.receiver_id){
-            console.log("当前消息属于当前的聊天窗口!")
-            this.messageContent = message;
-          }
-        });
+        // this.clickShowMessage();
+        console.log("监听消息1:",message.user_id,"===",this.myUserId,"##",this.user_id)
+        // if(this.ones==0){
+        //   this.ones = 1
+        //   this.getConversationList();          
+        // }
+        // console.log(message.receiver_id)
+        // this.conversationList.forEach(item => {
+        //   if(item.receiver_id==message.receiver_id){
+        //     console.log("当前消息属于当前的聊天窗口!")
+        //     this.messageContent = message;
+        //   }
+        // });
         // console.log(message.receiver_id.length == 18)
+        if(message.user_id && (message.user_id !=this.user_id)){
+          this.clickShowMessage(message);
+        }
         //第一步:先判断是否为群消息
         if (message.receiver_id && message.receiver_id.length == 18) {
           //第二步:判断当前接收的消息是否显示到聊天框中
@@ -2867,7 +2868,7 @@
       
       //2.3 删除好友
       deleteFriend(id){
-        console.log(id);
+        this.showfrindDialog = false;
         if(id){
           this.editFriendId = String(id);
         }
@@ -2876,14 +2877,14 @@
           confirmButtonText: '确定',
           cancelButtonText: '取消',
           type: 'warning',
-          zIndex: 11000, // 新增,确保弹窗在最上层
-          modal: false // 移除蒙层
+          // zIndex: 11000, // 新增,确保弹窗在最上层
         }).then(() => {
           console.log(this.editFriendId);
           this.$store.dispatch('chat/delFriend',{friend_id:this.editFriendId}).then(res=> {
             this.$message.success('删除成功!')
             //关闭用户详情显示
             this.pagestatus = 1;
+            this.showfrindDialog = false;
             //重新装在用户列表
             this.getUserFriendList();
           })
@@ -2955,6 +2956,7 @@
       //3.操作弹出框 start------------------------------------------------------------>
       //用户菜单操作
       openWindow(item){
+        this.$message.closeAll();
         this.form.id = item.id;
         this.form.friend_id = item.friend_id;
         this.friendInfo = item;
@@ -2962,6 +2964,7 @@
         this.friendWindowStatus = true;
       },
       openEditWindow(id){
+
         //打开修改备注弹出框
         this.editWindowStatus = true;
       },
@@ -3067,12 +3070,35 @@
           document.addEventListener('mouseup', onMouseUp);
         });
       },
+      viewGroupChat(info) {
+        // 这里可以添加查看群聊的逻辑
+        console.log('查看群聊',info);
+        const item = {
+            "receiver_id": info.group_id,
+            "num": 18085,
+            "max_id": '',
+            "user_name": null,
+            "avatar": null,
+            "mobile": null,
+            "group_name": info.group_name,
+            "type": "group",
+            "name": info.group_name,
+            "is_group": 1
+        }
+        this.selectGroup(item);
+      },
+      openGroupChat(id) {
+        console.log('打开群聊',id);
+        // 你的逻辑,比如显示面板、加载群聊数据等
+        // this.showPanel = true;
+        // this.loadGroupChat(id);
+      }
     },
     mounted() {
-      console.log("=====fuck")
+      console.log("用户头像信息:",this.$store.state.user.avatar)
       //开启websocket连接 start---------------------------------------->
       //1.获取admin-token
-      const adminToken = document.cookie.split('; ').find(row => row.startsWith('Admin-Token=')).split('=')[1];
+      const adminToken = this.token;
       console.log("Admin-Token:", adminToken);
   
       //2.连接websocket 
@@ -3125,35 +3151,6 @@
         }
       };
       //从通讯录创建单聊 end---------------------------------------->
-
-      // if (!document.getElementById('custom-message-style')) {
-      //   const style = document.createElement('style');
-      //   style.id = 'custom-message-style';
-      //   style.innerHTML = `
-      //     .el-message {
-      //       min-width: auto !important;
-      //       padding: 0 !important;
-      //       background: transparent !important;
-      //       border: none !important;
-      //       box-shadow: 0 2px 8px rgba(0,0,0,0.4) !important;
-      //       border-radius:100px !important;
-      //     }
-      //     .el-message .el-message__icon {
-      //       display: none !important;
-      //     }
-      //     .el-message .my-custom-message {
-      //       background: #fff !important;
-      //       color: #000 !important;
-      //       border-radius: 4px !important;
-      //       box-shadow: 0 2px 8px rgba(0,0,0,0.5) !important;
-      //       border: none !important;
-      //       padding: 8px 16px !important;
-      //       display: flex;
-      //       align-items: center;
-      //     }
-      //   `;
-      //   document.head.appendChild(style);
-      // }
       this.initDrag();
     },
     beforeDestroy() {
@@ -3165,6 +3162,33 @@
         this.ws.close();
       }
       clearInterval(this.getFriendApplyListStatus);
+    },
+    watch: {
+      // 监听 user.avatar 的变化
+      '$store.state.user.avatar'(newVal, oldVal) {
+        if (newVal) {
+          // 这里可以安全地使用 avatar
+          this.avatar = newVal
+          console.log('avatar 变化了:', newVal);
+          // 你的逻辑...
+        }
+      },
+      '$store.state.user.userid'(newVal, oldVal) {
+        if (newVal) {
+          // 这里可以安全地使用 avatar
+          this.user_id = newVal
+          console.log('user_id 变化了:', newVal);
+          // 你的逻辑...
+        }
+      },
+      '$store.state.user.token': {  
+        handler(newValue, oldValue) {  
+          this.token = newValue
+        },  
+        immediate: true, 
+      } 
+
+
     }
   };
   </script>
@@ -4167,7 +4191,7 @@
       .hallRight {
         flex: 1;
         background: #fff;
-        border-radius: 20px;
+        border-radius: 2px;
         position: relative;
         // min-height: 500px;
         display: flex;
@@ -5798,8 +5822,8 @@
         color: #999;
       }
     }
-        //发送名片
-        .messageTypeCard {
+    //发送名片
+    .messageTypeCard {
       width: 321px;
       background: #fff;
       border-radius: 16px;
@@ -5840,8 +5864,8 @@
         border: 1px solid #ECECEC;
       }
     }
-        //发送群聊
-        .messageGroupInvite {
+    //发送群聊
+    .messageGroupInvite {
       background: #fff;
       border-radius: 16px;
       border: 1px solid #E9EDF7;
@@ -5904,9 +5928,6 @@
       }
     }
     .searchFriendBox {
-          
-        
-         
             .searchFriendItem {
               display: flex;
               align-items: center;
@@ -5995,8 +6016,30 @@
             text-align: center;
             font-size: 18px;
             height: 400px;
-            line-height: 400px;
+            line-height: 350px;
           }
-  
 
+</style>
+<style >
+.message-new {
+    min-width: auto !important;
+    padding: 0 !important;
+    background: transparent !important;
+    border: none !important;
+    box-shadow: 0 2px 8px rgba(0,0,0,0.4) !important;
+    border-radius:100px !important;
+}
+.message-new .el-message__icon {
+    display: none !important;
+}
+.message-new .my-custom-message {
+    background: #fff !important;
+    color: #000 !important;
+    border-radius: 4px !important;
+    box-shadow: 0 2px 8px rgba(0,0,0,0.5) !important;
+    border: none !important;
+    padding: 8px 16px !important;
+    display: flex;
+    align-items: center;
+}
 </style>

+ 1 - 1
src/main.js

@@ -37,7 +37,7 @@ Vue.prototype.$fixModalZIndex = function() {
     const modals = document.querySelectorAll('.v-modal');
     modals.forEach(modal => {
       if (parseInt(modal.style.zIndex, 10) > 10999) {
-        modal.style.zIndex = 10999;
+        modal.style.zIndex = 9999;
       }
     });
   });

+ 32 - 0
src/router/index.js

@@ -1348,6 +1348,38 @@ export const constantRoutes = [
       }
     ]
   },
+  {
+    path: '/businessDistrict',
+    component: Layout,
+    children: [
+      {
+        name: '',
+        path: '',
+        component: () => import('@/views/chat/businessDistrict.vue'),
+        meta: {
+          title: '商圈',
+          hidden: true,
+          breadcrumb: true
+        }
+      }
+    ]
+  },
+  {
+    path: '/businessDistrictDetail',
+    component: Layout,
+    children: [
+      {
+        name: '',
+        path: '',
+        component: () => import('@/views/chat/businessDistrictDetail.vue'),
+        meta: {
+          title: '商圈详情',
+          hidden: true,
+          breadcrumb: true
+        }
+      }
+    ]
+  },
   // --------------企业管理fr--------------end---------
   // --------------通栏版式管理fr--------------start---------
   {

+ 472 - 0
src/views/chat/businessDistrict.vue

@@ -0,0 +1,472 @@
+<template>
+  <!-- 路由白名单位管理 -->
+  <div>
+      <!-- 头部搜索框部分 -->
+      <div class="title">
+          <el-row>
+             
+            <el-col :span="6" class="left">
+                <div class="searchBox">
+                      <div class="searchTitle">分类</div>
+                      <el-select v-model="type" clearable placeholder="请选择">
+                        <el-option
+                          v-for="item in classList"
+                          :key="item.value"
+                          :label="item.label"
+                          :value="item.value">
+                        </el-option>
+                      </el-select>
+                  </div>
+                  
+              </el-col>
+              <el-col :span="6" class="left">
+              
+                  <div class="searchBox">
+                      <div class="searchTitle">商圈名称</div>
+                      <el-input v-model="title" class="input" clearable placeholder="请输入商圈名称"></el-input>
+                  </div>
+              </el-col>
+              <el-col :span="6" class="left">
+              
+              <div class="searchBox">
+                  <div class="searchTitle">日期</div>
+                  <el-date-picker
+                    v-model="created_at"
+                    type="date"
+                    format="yyyy-MM-dd"
+                    placeholder="选择日期">
+                  </el-date-picker>
+              </div>
+          </el-col>
+              <el-col :span="6" class="right">
+                  <div class="btnList">
+                      <button class="search" @click="getData">搜索</button>
+                      <button class="reset" @click="goReset">重置</button>
+                  </div>
+              </el-col>
+          </el-row>
+      </div>
+      <!--表格内容 start------------------------------------------------------------>
+      <div class="layerBox">
+          <tableTitle :name="tableDivTitle" />
+          <el-row>
+              <template>
+                  <el-table class="my-table" v-loading="loading" :data="tableData" style="width: 100%">
+                      <el-table-column fixed prop="id" label="编号" width="90">
+                      </el-table-column>
+                      <el-table-column prop="title" label="商圈名称">
+                      </el-table-column>
+                      <el-table-column prop="topicname" label="分类" width="150">
+                      </el-table-column>
+                      <el-table-column prop="author" label="作者" width="150">
+                      </el-table-column>
+                      <el-table-column prop="created_at" label="创建时间" width="200">
+                      </el-table-column>
+                      <el-table-column prop="updated_at" label="修改时间" width="200">
+                      </el-table-column>
+                       <el-table-column fixed="right" label="操作" width="100"  align="center">
+                          <template slot-scope="scope">
+                              <div class="listBtnBox">
+                                <div class="listMainBtn" @click="manageRow(scope.row.id, tableData)"><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 background @size-change="handleSizeChange" @current-change="handleCurrentChange"
+                      :current-page="page" :page-size="pageSize" layout="total, prev, pager, next, jumper"
+                      :total="total">
+                  </el-pagination>
+              </el-col>
+          </el-row>
+      </div>
+      <!--分页 end------------------------------------------------------------>
+      <!--表格内容 end------------------------------------------------------------>
+  </div>
+</template>
+
+<script>
+//表格标题
+import tableTitle from './components/tableTitle.vue';
+import dayjs from 'dayjs';
+
+//引入公用样式
+import '@/styles/global.less';
+import { getTopicType,getBusinessDistrictList} from '@/api/chat'
+
+function formatDate(date) {
+  if (!date) return '';
+  const d = new Date(date);
+  const year = d.getFullYear();
+  const month = String(d.getMonth() + 1).padStart(2, '0');
+  const day = String(d.getDate()).padStart(2, '0');
+  return `${year}-${month}-${day}`;
+}
+
+export default {
+  components: {
+      tableTitle,//表格标题-
+  },
+  data() {
+     
+      return {
+          classList:[],//分类列表
+          tableDivTitle: "我加入的商圈",  //列表标题
+          loading: true, //加载中
+          tableData: [],//表格数据
+          webSiteLoading: false,
+          // 分页相关
+          page: 1,
+          pageSize: 10,
+          total: 0,
+          title:'',
+          type:'',
+          created_at: '',
+      }
+  },
+  methods: {
+      //1.列表和分页相关 start ------------------------------------------------------------>
+      //1.1 开始请求列表信息方法
+      getData() {
+        getBusinessDistrictList({
+                  page: this.page,
+                  page_size: this.pageSize,
+                  type: this.type,
+                  title: this.title,
+                  created_at: formatDate(this.created_at), // 只传年月日
+              }).then(data => {
+                  this.loading=false;
+                  console.log("返回数据",data);
+                  this.tableData = data.data.list
+                  this.total = data.data.total
+             
+              })
+      },
+
+      //1.4 列表内容分页
+      //直接跳转
+      handleSizeChange(val) {
+          this.page = val;
+          this.getData();
+      },
+      //1.5 点击分页
+      handleCurrentChange(val) {
+          this.page = val;
+          this.getData();
+      },
+     
+      //1.7 重置按钮
+      goReset() {
+          this.page = 1
+          this.peageSize = 10
+          this.title = ''
+          this.type = ''
+          this.created_at = ''
+          this.getData()
+      },
+      manageRow(id){
+        this.$router.push({
+          path: '/businessDistrictDetail',
+          query: {
+            id: id
+          }
+        })
+      }
+ 
+  },
+  mounted() {
+      this.getData()
+      //获取分类列表
+      getTopicType({}).then(data => {
+          this.classList = data.data
+      })
+  },
+}
+</script>
+
+<style scoped lang="less">
+input[aria-hidden=true] {
+    display: none !important;
+}
+
+// 提示信息
+.tips {
+    margin: 30px;
+    background-color: #e9ecf9;
+    border-radius: 11px;
+    .tipsIcon {
+        margin: 10px 15px;
+        display: inline-block;
+        width: 24px;
+        height: 24px;
+        background: url("../../assets/advertise/Info Circle.png") no-repeat;
+        vertical-align: middle;
+    }
+    .tipsText {
+        font-size: 14px;
+        color: #666666;
+    }
+}
+
+// 头部
+.title {
+    margin: 30px 30px 20px 30px;
+    padding: 30px 30px 40px 30px;
+    background-color: #fff;
+    border-radius: 20px 20px 20px 20px;
+    border: 1px solid #E9EDF7;
+    .left {
+        float: left;
+    }
+    .right {
+        float: right;
+    }
+    .searchBox {
+        ::v-deep .el-input {
+            position: relative;
+            font-size: 14px;
+            display: inline-block;
+            width: 80%;
+        }
+
+        .searchTitle {
+            padding-bottom: 10px;
+            font-family: Microsoft YaHei, Microsoft YaHei;
+            font-weight: 400;
+            font-size: 14px;
+            color: #999999;
+            line-height: 16px;
+        }
+
+        .el-select {
+            width: 100%;
+            display: inline-block;
+            position: relative;
+        }
+    }
+
+
+    .btnList {
+        float: right;
+        padding-top: 28px;
+
+        button {
+            height: 38px;
+            border: none;
+            border-radius: 8px;
+            padding: 0 30px;
+        }
+
+        .search {
+            background-color: #5570f1;
+            color: #fff;
+            margin-right: 20px;
+        }
+
+        .reset {
+            font-family: Microsoft YaHei, Microsoft YaHei;
+            font-weight: 400;
+            font-size: 16px;
+            color: #333333;
+            background: #F5F7FB;
+            border-radius: 8px 8px 8px 8px;
+            border: 1px solid rgba(85, 112, 241, 0.11);
+        }
+    }
+}
+
+.layerBox {
+    padding: 30px 20px;
+    position: relative;
+
+    .btn {
+        position: absolute;
+        top: 30px;
+        right: 20px;
+        height: 38px;
+        color: #fff;
+        background-color: #5570f1;
+        border: none;
+        border-radius: 8px;
+        padding: 8px 28px 9px;
+        box-sizing: border-box;
+    }
+
+    .listBtnBox {
+        justify-content: left;
+    }
+
+
+    .listDeleteBtn,
+    .listEditBtn,
+    .listLookBtn {
+        margin-left: 0px;
+        padding-left: 0px;
+        margin-right: 20px;
+        width: 76px;
+        height: 36px;
+        line-height: 36px;
+    }
+
+
+    .listLookBtn {
+        text-align: center;
+        border-radius: 8px;
+        cursor: pointer;
+        color: #55b5f1;
+        background-color: rgba(85, 181, 241, 0.16);
+
+        >i {
+            padding-right: 8px;
+        }
+    }
+
+    ::v-deep .el-form-item {
+        margin-bottom: 50px;
+    }
+
+    ::v-deep .el-select {
+        width: 100%;
+    }
+
+    ::v-deep .el-input--medium,
+    ::v-deep .el-form-item__label {
+        line-height: 36px;
+        font-size: 16px;
+    }
+}
+
+// 弹出层内容
+.dialogText {
+    margin: 0 7px 0 3px;
+    padding-bottom: 1px;
+    padding: 30px 60px 1px 20px;
+    background-color: #f5f7fb;
+
+    .adImage {
+        width: 140px;
+        height: 140px;
+        line-height: 210px;
+        border-radius: 12px;
+        border: 1px solid rgba(85, 112, 241, 0.11);
+
+        img {
+            width: 140px;
+            height: 80px;
+        }
+    }
+
+
+
+    ::v-deep .avatar {
+        width: 140px;
+        height: auto;
+    }
+
+    .price {
+        ::v-deep .el-input {
+            width: 29%;
+        }
+    }
+
+    .example {
+        font-family: Microsoft YaHei;
+        color: #5570F1;
+    }
+
+    .el_btnList {
+        margin-right: 15px;
+        margin-top: 20px;
+    }
+
+    //日期时间选择器的宽
+    ::v-deep .el-date-editor.el-input {
+        width: 48%;
+    }
+
+    ::v-deep .el-button+.el-button {
+        margin-left: 0px;
+    }
+
+    ::v-deep .el-select {
+        width: 100%;
+    }
+
+    ::v-deep .el-form-item {
+        margin-bottom: 50px;
+    }
+}
+
+// 弹出层按钮
+.dialogBtn {
+    text-align: center;
+    margin: 50px auto 20px;
+
+    button {
+        width: 184px;
+        padding: 16px;
+        font-family: Microsoft YaHei, Microsoft YaHei;
+        font-weight: 400;
+        font-size: 20px;
+        border: none;
+        border-radius: 12px 12px 12px 12px;
+    }
+
+    // 取消
+    .cancel {
+        color: #333333;
+        background-color: #f5f7fb;
+        border: 2px solid rgba(85, 112, 241, 0.11);
+    }
+
+    // 提交
+    .submit {
+        color: #fff;
+        background-color: #5570F1;
+        margin-left: 40px;
+    }
+}
+
+//审核弹出框
+.radioGroup {
+    ::v-deep .el-form-item {
+        margin-top: 40px;
+        margin-bottom: 0;
+    }
+}
+
+.graph {
+    background-color: #f5f7fb;
+    padding: 60px 100px;
+    overflow: hidden;
+
+    li {
+        float: left;
+    }
+
+    >li:first-child {
+        margin-right: 100px;
+    }
+}
+
+.dialog-footer {
+    margin: 0 auto;
+}
+
+.titleWidth {
+//   width: 600px;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+::v-deep.el-cascader{
+    width: 100%;
+}
+</style>

+ 404 - 0
src/views/chat/businessDistrictDetail.vue

@@ -0,0 +1,404 @@
+<template>
+    <div class="mainBox">
+      <div class="layerBox">
+        <tableTitle :name="tableDivTitle" />
+        <el-row>
+          <template>
+            <!-- 在此位置下面写 -->
+            <div class="article-detail">
+              <div class="article-card">
+                <div class="article-title">
+                  {{ dataInfo.title }}
+                  <el-tag type="info" class="article-tag">{{ dataInfo.topicname }}</el-tag>
+                </div>
+                <div class="article-meta">
+                  <span class="article-meta-item1">{{ dataInfo.nickname }}</span>
+                  <span class="article-meta-item2">{{ dataInfo.group_name }}</span>
+                  <el-button  class="top-button" type="primary" @click="viewGroupChat">查看群聊</el-button>
+                </div>
+                <el-divider></el-divider>
+                <div class="background-color">
+                  <div class="article-author">
+                    <div class="article_box">
+                        <div
+                          class="article_panel"
+                          :class="{ collapsed: !isExpanded }"
+                        >
+                          <div v-html="dataInfo.content"></div>
+                        </div>
+                        <span
+                          class="article_panel_btn"
+                          v-if="!isExpanded"
+                          @click="toggleExpand"
+                        >阅读全文
+                        <i class="el-icon-arrow-down" ></i>
+                            
+                      </span>
+                    </div>
+                  </div>
+                </div>
+              </div>
+              <div class="comment-section">
+                <div class="box_1 clearfix">
+                <div class="box_in">评论:</div>
+              </div>
+               
+                <div class="comment-list">
+                  <div class="comment_li" v-for="(per_obj,keys) in replyList" :key="keys">
+                          <el-avatar
+                      class="comment_li_img"
+                      :src="per_obj.avatar"
+                    />
+                       <div class="comment_li_name">{{ per_obj.nickname }}:</div> 
+                       <div class="comment_li_text">
+                           {{ per_obj.content }}
+                        </div> 
+                       <div class="comment_li_time">{{ per_obj.created_at }}</div> 
+                  </div>  
+                </div>
+                <div class="alignBox">
+                  <el-row>
+                    <el-col :span="24">
+                      <el-pagination :current-page="getApiData.page" @size-change="handleSizeChange"
+                        @current-change="handleCurrentChange" :page-size="5" layout="total, prev, pager, next, jumper"
+                        :total="allCount"></el-pagination>
+                    </el-col>
+                  </el-row>
+                </div>
+                <div class="comment-actions">
+                  <el-button @click="goBack">返回</el-button>
+                  <el-button type="primary" @click="viewGroupChat">查看群聊</el-button>
+                </div>
+              </div>
+            </div>
+          </template>
+        </el-row>
+      </div>
+
+    </div>
+  </template>
+  
+  <script>
+  //表格标题
+  import tableTitle from './components/tableTitle';
+  //引入公用样式
+  import '@/styles/global.less';
+  import InputTag from '@/components/InputTag'
+  import { getTopicDataInfo,getTopicReply} from '@/api/chat'
+  import emitter from '@/eventBus';
+  
+  export default {
+    components: {
+      tableTitle,//表格标题
+      InputTag
+    },
+    data() {
+      let self = this;
+      return {
+        id:'',
+        dataInfo:{},
+        isExpanded: false, // btn添加展开状态
+        //1.列表和分页相关 start ------------------------------------------------------------>
+        tableDivTitle: "商圈详情",
+        getApiData: {
+          page: 1,//当前是第几页
+          pageSize: 5,//一共多少条
+        },
+        allCount: 0,//总条数
+        replyList:[],
+        currentGroupId: null
+      }
+    },
+    methods: {
+        //1.4 列表内容分页
+      //直接跳转
+      handleSizeChange(val) {
+          this.getApiData.page = val;
+          this.getTopicReplyList();
+      },
+      //1.5 点击分页
+      handleCurrentChange(val) {
+          this.getApiData.page = val;
+          this.getTopicReplyList();
+      },
+        toggleExpand() { // 添加切换方法
+            
+           this.isExpanded = true;
+        },
+        getDataINfo(){
+          getTopicDataInfo({
+                id:self.id
+              }).then(data => {
+                  // this.loading=false;
+                  console.log("返回数据",data.data);
+                  this.dataInfo = data.data;
+                  console.log("赋值:",self.dataInfo)
+             
+              })
+        },
+        getTopicReplyList(){
+          getTopicReply({
+                id:self.id,
+                page:this.getApiData.page,
+                page_size:this.getApiData.pageSize
+              }).then(data => {
+                this.replyList = data.data.data;
+                this.allCount = data.data.total;
+             
+              })
+        },
+        goBack() {
+          this.$router.back();
+        },
+        viewGroupChat() {
+          console.log('[businessDistrictDetail] 触发 view-group-chat 事件,id1:', this.dataInfo);
+          emitter.emit('view-group-chat', this.dataInfo);
+        },
+        handleViewGroupChat(ids) {
+          console.log('[businessDistrictDetail] 收到 view-group-chat 事件,id2:', ids);
+          // 这里一般不需要监听自己发的事件,除非有特殊需求
+        }
+    },
+    mounted() {
+      // 1.获取详情数据
+      self.id = this.$route.query.id+'';
+      this.getDataINfo();
+      this.getTopicReplyList();
+      // 可选:如果你需要监听(一般只在调试时用)
+      emitter.on('view-group-chat', this.handleViewGroupChat);
+    },
+    beforeDestroy() {
+      emitter.off('view-group-chat', this.handleViewGroupChat);
+    }
+  }
+  </script>
+  
+  <style scoped lang="less">
+   .article-detail {
+    // padding: 24px;
+    // background: #f5f7fa;
+    min-height: 100vh;
+
+  .article-card {
+    margin-bottom: 24px;
+    padding: 24px 0px;
+    background: #fff;
+    // border-radius: 8px;
+    // box-shadow: 0 2px 8px rgba(0,0,0,0.04);
+
+    .article-title {
+      font-family: Microsoft YaHei, Microsoft YaHei;
+      font-weight: bold;
+      font-size: 28px;
+      color: #333333;
+      display: flex;
+      align-items: center;
+      .article-tag {
+        background: rgba(85,112,241,0.16) !important;
+        border-radius: 3px 3px 3px 3px !important;
+        margin-left: 12px;
+        font-size: 14px;
+        height: 22px;
+        line-height: 22px;
+        padding: 0 10px;
+        border-radius: 4px;
+        font-weight: 400;
+        font-size: 14px;
+        color: #5570F1;
+      }
+    }
+    .article-meta {
+      margin-top: 31px;
+      color: #888;
+      font-size: 16px;
+      display: flex;
+      align-items: center;
+      .article-link {
+        margin-left: 12px;
+      }
+    }
+    .article-content {
+      // margin: 18px 0 12px 0;
+      color: #444;
+      font-size: 15px;
+      line-height: 1.8;
+      word-break: break-all;
+    }
+    .article-author {
+      margin-top: 12px;
+      color: #999;
+      font-size: 18px;
+      span {
+        font-weight: 400;
+        font-size: 18px;
+        color: #6A82F3;
+        text-align: center;
+        // margin-right: 16px;
+        display:block;
+        line-height:30px;
+      }
+    }
+  }
+
+  .comment-section {
+    // padding: 24px 32px;
+    background: #fff;
+    border-radius: 8px;
+    .comment-title {
+      font-weight: bold;
+      font-size: 22px;
+      color: #5570F1;
+      // font-size: 16px;
+      // font-weight: bold;
+      // color: #333;
+      margin-bottom: 8px;
+      text-align: left;
+    }
+    // 蓝色短分割线,宽度10%,居中
+    .el-divider {
+      margin: 8px auto 16px auto;
+      border: none;
+      height: 0;
+      width: 10%;
+      min-width: 40px;
+      max-width: 100px;
+      border-top: 2px solid #5570F1;
+      border-radius: 2px;
+      background: transparent;
+    }
+    .comment-list {
+        margin-top:40px;
+        .comment_li{background:#FAFAFA;border:solid 1px #E1E1E1;overflow:hidden;margin-bottom:20px;}
+        .comment_li_img{float:left;width:52px;height:52px;border-radius:50%;margin:30px 0px 30px 30px;}
+        .comment_li_name{float:left;margin:44px 0px 44px 20px;color:#333;font-size:16px;line-height:24px;}
+        .comment_li_text{float:left;margin:45px 0px 11px 20px;color:#333;font-size:16px;line-height:24px;                   font-weight:bold;width:1000px; }
+        .comment_li_time{float:right;margin:44px 30px 44px 0px;color:#999;font-size:16px;line-height:24px; }
+      margin-bottom: 16px;
+      .comment-item {
+        display: flex;
+        align-items: center;
+        padding: 12px 0;
+        border-bottom: 1px solid #f0f0f0;
+        &:last-child {
+          border-bottom: none;
+        }
+        .comment-avatar {
+          width: 36px;
+          height: 36px;
+          margin-right: 12px;
+        }
+        .comment-content {
+          .comment-user {
+            font-size: 15px;
+            color: #555;
+            font-weight: 500;
+          }
+          .comment-time {
+            font-size: 12px;
+            color: #aaa;
+            margin-top: 2px;
+          }
+        }
+      }
+    }
+    .comment-actions {
+      display: flex;
+      justify-content: center;
+      gap: 16px;
+      margin-top: 12px;
+    }
+  }
+  .article-meta-item1 {
+    position: relative;
+    padding-left: 27px;
+    &::before {
+      content: '';
+      display: inline-block;
+      width: 20px;
+      height: 20px;
+      background: url('http://img.bjzxtw.org.cn/master/www/admin/renwu.png') no-repeat center center;
+      background-size: contain;
+      position: absolute;
+      left: 0;
+      top: 50%;
+      transform: translateY(-50%);
+      margin-right: 4px;
+    }
+  }
+  .article-meta-item2 {
+    position: relative;
+    padding-left: 27px;
+    margin-left:40px;
+    &::before {
+      content: '';
+      display: inline-block;
+      width: 20px;
+      height: 20px;
+      background: url('http://img.bjzxtw.org.cn/master/www/admin/wechat.png') no-repeat center center;
+      background-size: contain;
+      position: absolute;
+      left: 0;
+      top: 50%;
+      transform: translateY(-50%);
+      margin-right: 4px;
+    }
+  }
+  .top-button{
+    margin-left: 30px;
+  }
+  .background-color{
+    background: #f0f2f5;
+    padding: 10px 20px 0px 20px;
+  }
+  .clearfix::after{
+    content:'';
+    display: block;height: 0;
+    visibility: hidden;
+    clear: both;
+  }
+  .box_1{
+    border-bottom:solid 1px #E9EDF7;
+    box-sizing:border-box;
+  }
+  .box_in{
+    font-weight: bold;
+    float:left;
+    font-size:22px;
+    color:#5570F1;
+    height:33px;
+    line-height:33px;
+    border-bottom:solid 2px #5570F1;
+    margin-bottom:-1px;
+  }
+}
+.article_box{margin-top:11;overflow:hidden;}
+.article_panel {
+  transition: max-height 0.3s;
+  overflow: hidden;
+  position: relative;
+  max-height: none;
+  // 展开时无高度限制
+  &.collapsed {
+    max-height: 270px; // 固定高度
+    // 可选:加渐变遮罩
+    &::after {
+      content: '';
+      position: absolute;
+      left: 0; right: 0; bottom: 0;
+      // height: 36px;
+      background: linear-gradient(to bottom, rgba(255,255,255,0), #fff 80%);
+      pointer-events: none;
+    }
+  }
+}
+.article_panel_btn {
+  display: inline-block;
+  color: #5570F1;
+  cursor: pointer;
+  margin-top: 8px;
+  font-size: 15px;
+}
+.dot1{word-break: keep-all; white-space: nowrap;overflow:hidden;text-overflow:ellipsis;
+}
+</style>
+