wangwei há 4 anos atrás
pai
commit
48a6e0ad24
2 ficheiros alterados com 206 adições e 183 exclusões
  1. 182 173
      src/components/ChatFrame.vue
  2. 24 10
      src/components/ChatList.vue

+ 182 - 173
src/components/ChatFrame.vue

@@ -110,10 +110,7 @@
                 </div>
               </div> -->
               <!-- 视频格式文件 -->
-              <div
-                class="message-content-image"
-                v-if="item.type === 'video'"
-              >
+              <div class="message-content-image" v-if="item.type === 'video'">
                 <video
                   style="width: 255px"
                   src="https://media.w3.org/2010/05/sintel/trailer.mp4"
@@ -248,10 +245,7 @@
                 </div>
               </div> -->
               <!-- 视频格式文件 -->
-              <div
-                class="message-content-image"
-                v-if="item.type === 'video'"
-              >
+              <div class="message-content-image" v-if="item.type === 'video'">
                 <video
                   style="width: 255px"
                   src="https://media.w3.org/2010/05/sintel/trailer.mp4"
@@ -275,7 +269,13 @@
           <div class="tools" style="margin: 10px">
             <el-popover placement="top" width="300" trigger="click">
               <Emoji @addEmoji="addEmoji" />
-              <el-button class="iconfont open_emoji_icon" style="color:rgb(44,60,80)" type="text" slot="reference">&#xe612;</el-button>
+              <el-button
+                class="iconfont open_emoji_icon"
+                style="color:rgb(44,60,80)"
+                type="text"
+                slot="reference"
+                >&#xe612;</el-button
+              >
             </el-popover>
             <el-upload
               ref="upload"
@@ -297,16 +297,16 @@
           </div>
         </div>
         <div class="input-box">
-          <div 
-            id="charInput" 
+          <div
+            id="charInput"
             @click="saveRangeLocal"
-            @focus="saveRangeLocal" 
-            @input="saveRangeLocal" 
+            @focus="saveRangeLocal"
+            @input="saveRangeLocal"
             @keydown.enter="stopPropagation"
             @keyup.enter="sendMsg"
-            class="chatframe_input_con scrollbar" 
-            contenteditable="true">
-          </div>
+            class="chatframe_input_con scrollbar"
+            contenteditable="true"
+          ></div>
           <div class="send-footer">
             <el-button
               type="info"
@@ -330,25 +330,25 @@
 import { isUrl, parseHtml } from "@/utils/common";
 import Emoji from "./Emoji.vue";
 import { mapState, mapActions } from "vuex";
-let emojiData = require('./../assets/emoji/emoji.json')
-import request from '@/api/require'
+let emojiData = require("./../assets/emoji/emoji.json");
+import request from "@/api/require";
 export default {
   name: "ChatFrame",
   props: ["selected", "tab"],
   components: {
-    Emoji,
+    Emoji
   },
   data() {
     return {
       baseUrl: "http://192.168.100.8:3000/",
       emojiIcon: emojiData.icon,
-      inputRange: '',               // 光标
-      emojiPath: new Map(),         // emoji表情地址map对象,
+      inputRange: "", // 光标
+      emojiPath: new Map(), // emoji表情地址map对象,
       msg: "",
       friend_record_list: [],
       room_record_list: [],
       messageType: "",
-      uploadProgress: false,
+      uploadProgress: false
     };
   },
   computed: {
@@ -363,38 +363,36 @@ export default {
     }),
     ...mapState({
       roomRecord: state => state.chat.roomRecord
-    }),
+    })
   },
   watch: {
     selected(newVal, o) {
-      if (this.tab === 'friends') {
-        console.log('================================================')
-        console.log(`this.friendRecord`, this.friendRecord)
-        console.log(`newVal`, newVal)
-        console.log(`this.friendRecord[newVal.id]`, this.friendRecord[newVal.id])
-        console.log(`this.friendRecord`, this.friendRecord)
-
+      if (this.tab === "friends") {
         if (this.friendRecord[newVal.id]) {
           this.friend_record_list = this.friendRecord[newVal.id];
         } else {
-          this.$store.commit('chat/set_friend_record', [newVal.id])
+          this.$store.commit("chat/set_friend_record", [newVal.id]);
           this.friend_record_list = this.friendRecord[newVal.id];
-          console.log(`this.friendRecord`, this.friendRecord)
+          console.log(`this.friendRecord`, this.friendRecord);
         }
       } else {
         if (this.roomRecord[newVal.id]) {
           this.room_record_list = this.roomRecord[newVal.id];
         } else {
-          this.$store.commit('chat/set_room_record', newVal.id)
+          this.$store.commit("chat/set_room_record", newVal.id);
           this.room_record_list = this.roomRecord[newVal.id];
-          console.log(`this.room_record_list[newVal.id]`, this.room_record_list)
-        } 
+          console.log(
+            `this.room_record_list[newVal.id]`,
+            this.room_record_list
+          );
+        }
       }
       this.$nextTick(() => {
-        document.getElementById('charInput').innerText = ''
-        this.msg = ''
-        this.$refs["myScrollbar"].wrap.scrollTop =
-          this.$refs["myScrollbar"].wrap.scrollHeight;
+        document.getElementById("charInput").innerText = "";
+        this.msg = "";
+        this.$refs["myScrollbar"].wrap.scrollTop = this.$refs[
+          "myScrollbar"
+        ].wrap.scrollHeight;
       });
     }
   },
@@ -415,14 +413,16 @@ export default {
       let fd = new FormData();
       fd.append("filename", file);
       // upload_file(fd).then(
-      request.upload_file(file).then(res => {
-        console.log(`res5555`, res)
-      })
-      .catch(err => {
-        console.log(`err`, err)
-      })
+      request
+        .upload_file(file)
+        .then(res => {
+          console.log(`res5555`, res);
+        })
+        .catch(err => {
+          console.log(`err`, err);
+        });
       this.$http.post(this.baseUrl + "api/upload/", fd).then(
-        (res) => {
+        res => {
           if (
             file.type === "image/jpeg" ||
             file.type === "image/png" ||
@@ -430,7 +430,7 @@ export default {
           ) {
             this.messageType = "image";
             this.sendMsg(null, res.data.data);
-            console.log(`res.data.data`, res.data.data)
+            console.log(`res.data.data`, res.data.data);
             console.log("========is image =====");
           } else {
             this.messageType = "file";
@@ -440,7 +440,7 @@ export default {
           console.log(`res1111`, res);
           console.log("======success====");
         },
-        (res) => {
+        res => {
           this.$message.error("文件发送失败");
           console.log("===========shibai====");
           //  this.importDataBtnText='导入失败';
@@ -459,17 +459,20 @@ export default {
      */
     _parseHtml(text) {
       const regex2 = /!!\[(.+?)\]!!/g;
-      const codeList = text.match(regex2)
-      let html = text
+      const codeList = text.match(regex2);
+      let html = text;
       if (codeList) {
-        codeList.map((item) => {
-        const code = item.match(/\[(.+?)\]/g)[0] 
-        html = html.replace(item, "<img style='width: 20px; height: 20px;vertical-align: sub;' src='" +
-          this.getIconPic(code) +
-          "' unicode = '" +
-          code +
-          "' alt='' >")
-        })
+        codeList.map(item => {
+          const code = item.match(/\[(.+?)\]/g)[0];
+          html = html.replace(
+            item,
+            "<img style='width: 20px; height: 20px;vertical-align: sub;' src='" +
+              this.getIconPic(code) +
+              "' unicode = '" +
+              code +
+              "' alt='' >"
+          );
+        });
       }
       return parseHtml(html);
     },
@@ -509,7 +512,7 @@ export default {
       while (count < file.size) {
         fileChunkList.push({
           file: file.slice(count, count + size),
-          partNumber: num,
+          partNumber: num
         });
         count += size;
         num++;
@@ -530,13 +533,13 @@ export default {
           width = 138;
           return {
             width: `${width + 12}px`,
-            height: `${height + 12}px`,
+            height: `${height + 12}px`
           };
         }
       }
       return {
         width: `${width + 12}px`,
-        height: `${height + 12}px`,
+        height: `${height + 12}px`
       };
     },
 
@@ -593,16 +596,19 @@ export default {
     },
 
     // 初始化emoji的map对象
-    initEmojiPic () {
-      let map = new Map()
+    initEmojiPic() {
+      let map = new Map();
 
       for (const key in emojiData.icon) {
         emojiData.icon[key].forEach(item => {
-          map.set(item.unicode, require('./../assets/emoji/icon/' + item.unicode + '.png'))
-        })
+          map.set(
+            item.unicode,
+            require("./../assets/emoji/icon/" + item.unicode + ".png")
+          );
+        });
       }
 
-      this.emojiPath = map
+      this.emojiPath = map;
     },
     // 通过Unicode码从map中获取emoji
     getIconPic(unicode) {
@@ -611,92 +617,98 @@ export default {
 
     // ===============================================================
     // 将输入框中的图片替换为emoji表情
-    formatInputCon () {
-      let inputValue = document.getElementById('charInput').innerHTML
+    formatInputCon() {
+      let inputValue = document.getElementById("charInput").innerHTML;
+
+      inputValue = inputValue.replace(/<img.*?(?:>|\/>)/gi, val => {
+        let unicode =
+          "!!" + val.match(/unicode=[\'\"]?([^\'\"]*)[\'\"]?/i)[1] + "!!";
 
-      inputValue = inputValue.replace(/<img.*?(?:>|\/>)/gi, (val) => {
-        let unicode = '!!' + val.match(/unicode=[\'\"]?([^\'\"]*)[\'\"]?/i)[1] + '!!'
-        
-        return unicode
-      })
+        return unicode;
+      });
 
-      return inputValue
+      return inputValue;
     },
 
     // 将emoji表情转换为图片
-    changeEmojiCon (str) {
-      let patt = /[\ud800-\udbff][\udc00-\udfff]/g    // 检测utf16字符正则
+    changeEmojiCon(str) {
+      let patt = /[\ud800-\udbff][\udc00-\udfff]/g; // 检测utf16字符正则
+
+      str = str.replace(patt, char => {
+        let H, L, code;
 
-      str = str.replace(patt, (char) => {
-        let H, L, code
-        
         if (char.length === 2) {
-          H = char.charCodeAt(0)   // 取出高位
-          L = char.charCodeAt(1)   // 取出低位
-          code = (H - 0xD800) * 0x400 + 0x10000 + L - 0xDC00   // 转换算法
-          return "&#" + code + ";"
+          H = char.charCodeAt(0); // 取出高位
+          L = char.charCodeAt(1); // 取出低位
+          code = (H - 0xd800) * 0x400 + 0x10000 + L - 0xdc00; // 转换算法
+          return "&#" + code + ";";
         } else {
-          return char
+          return char;
         }
-      })
+      });
 
-      str = str.replace(/&#{1}[0-9]+;{1}/ig, (a) => {
-        let unicode = a.replace(/^&#{1}/ig, '')
-        
-        unicode = unicode.replace(/;{1}$/ig, '')
-        unicode = 'U+' + (parseFloat(unicode).toString(16).toUpperCase())
+      str = str.replace(/&#{1}[0-9]+;{1}/gi, a => {
+        let unicode = a.replace(/^&#{1}/gi, "");
 
-        return "<img src='"+ this.getIconPic(unicode) +"'/>"
-      })
+        unicode = unicode.replace(/;{1}$/gi, "");
+        unicode =
+          "U+" +
+          parseFloat(unicode)
+            .toString(16)
+            .toUpperCase();
 
-      return str
+        return "<img src='" + this.getIconPic(unicode) + "'/>";
+      });
+
+      return str;
     },
     // 延时记录光标到位置
-    chartFramRange (type) { 
+    chartFramRange(type) {
       try {
-        if (type === 'click') {
-          this.inputRange = window.getSelection().getRangeAt(0)
+        if (type === "click") {
+          this.inputRange = window.getSelection().getRangeAt(0);
         }
 
-        if (type === 'focus') {
-          this.inputRange = window.getSelection().getRangeAt(0)
+        if (type === "focus") {
+          this.inputRange = window.getSelection().getRangeAt(0);
         }
       } catch (err) {
-        console.log(type)
+        console.log(type);
       }
 
       return new Promise((resolve, reject) => {
         setTimeout(() => {
-          this.inputRange = window.getSelection().getRangeAt(0)
-          resolve(this.inputRange)
-        }, 0)
-      })
+          this.inputRange = window.getSelection().getRangeAt(0);
+          resolve(this.inputRange);
+        }, 0);
+      });
     },
 
-
     // 延时记录光标到位置
-    saveRangeLocal () {
+    saveRangeLocal() {
       setTimeout(() => {
-        this.inputRange = window.getSelection().getRangeAt(0)
-      }, 0)
+        this.inputRange = window.getSelection().getRangeAt(0);
+      }, 0);
     },
     // ================================================================
     // 阻止回车键默认事件
     stopPropagation(e) {
-       if (e && e.keyCode === 13) {
+      if (e && e.keyCode === 13) {
         e.cancelBubble = true;
         e.preventDefault();
         e.stopPropagation();
       }
     },
     sendMsg(e, fileurl) {
-      console.log(`e============`, e)
-     
-      if (fileurl) { // 上传文件路径
+      console.log(`e============`, e);
+
+      if (fileurl) {
+        // 上传文件路径
         this.msg = fileurl;
-      } else { // 输入框信息
-        this.msg = this.formatInputCon().replace(/<br>/g, '\r\n')
-        console.log(`this.msg`, this.msg)
+      } else {
+        // 输入框信息
+        this.msg = this.formatInputCon().replace(/<br>/g, "\r\n");
+        console.log(`this.msg`, this.msg);
       }
       if (this.msg.trim() === "") {
         this.msg = "";
@@ -709,36 +721,35 @@ export default {
         ...this.self,
         id: this.socket.id,
         msg: this.msg,
-        type: this.messageType,
+        type: this.messageType
       };
       if (this.tab === "friends") {
         msgInfo.toid = this.selected.id;
         this.socket.emit("private message", this.selected.id, msgInfo);
-        const msgData = [this.selected.id, msgInfo]
-        this.$store.commit('chat/set_friend_record', msgData)
+        const msgData = [this.selected.id, msgInfo];
+        this.$store.commit("chat/set_friend_record", msgData);
         this.friend_record_list = this.friendRecord[this.selected.id];
       } else {
-        console.log('=======ROOM CHAT========')
+        console.log("=======ROOM CHAT========");
         msgInfo.roomId = this.selected.id;
         this.socket.emit("chat-room", this.selected.id, msgInfo);
-        this.$store.commit('chat/set_room_record', msgInfo)
+        this.$store.commit("chat/set_room_record", msgInfo);
         this.room_record_list = this.roomRecord[this.selected.id];
       }
       this.$nextTick(() => {
         // 输入enter后置空
-        document.getElementById('charInput').innerText = ''
-        this.msg = ""; 
+        document.getElementById("charInput").innerText = "";
+        this.msg = "";
         this.messageType = "";
         // 滚动到底部
-        this.$refs["myScrollbar"].wrap.scrollTop =
-          this.$refs["myScrollbar"].wrap.scrollHeight;
+        this.$refs["myScrollbar"].wrap.scrollTop = this.$refs["myScrollbar"].wrap.scrollHeight;
       });
     },
 
     closeScoket() {
       // 断开连接
       this.$socket.close();
-    },
+    }
   },
   created() {
     // const room_record_str = getCookie("room_record");
@@ -750,9 +761,9 @@ export default {
     //   this.friend_record = JSON.parse(friend_record_str);
     // }
   },
-  mounted () {
-    this.initEmojiPic()
-  },
+  mounted() {
+    this.initEmojiPic();
+  }
 };
 </script>
 
@@ -831,7 +842,7 @@ export default {
 }
 .receive-record-item {
   margin: 2px;
-  background: #fff
+  background: #fff;
 }
 .input-box {
   display: flex;
@@ -847,53 +858,51 @@ export default {
   text-align: right;
 }
 
-
 .chatframe_input_con {
-    display: inline-block;
-    width: 92%;
-    height: 95px;
-    resize: none;
-    padding: 5px 15px;
-    line-height: 1.5;
-    box-sizing: border-box;
-    font-size: inherit;
-    color: #606266;
-    background-color: #fff;
-    outline: none;
-    overflow-y: scroll;
-    margin-bottom: 20px;
-    
-    // 超出自动换行 -- 火狐
-    word-wrap: break-word;
-    word-break: break-all;
-
-    // 滚动样式 细 - 火狐
-    scrollbar-width: thin;
-
-  }
+  display: inline-block;
+  width: 92%;
+  height: 95px;
+  resize: none;
+  padding: 5px 15px;
+  line-height: 1.5;
+  box-sizing: border-box;
+  font-size: inherit;
+  color: #606266;
+  background-color: #fff;
+  outline: none;
+  overflow-y: scroll;
+  margin-bottom: 20px;
+
+  // 超出自动换行 -- 火狐
+  word-wrap: break-word;
+  word-break: break-all;
+
+  // 滚动样式 细 - 火狐
+  scrollbar-width: thin;
+}
 
-  .chatframe-text {
-    min-height: 200px;
-    width: 500px;
-    box-sizing: border-box;
-    padding: 10px 15px;
-    margin-top: 5px;
-    background: #EAEDF1;
-    color: #282828;
-    border-radius: 4px;
-    word-wrap: break-word;
-    word-break: break-all;
-    line-height: 18px;
-    white-space: pre-wrap;
-    position: relative;
-  }
+.chatframe-text {
+  min-height: 200px;
+  width: 500px;
+  box-sizing: border-box;
+  padding: 10px 15px;
+  margin-top: 5px;
+  background: #eaedf1;
+  color: #282828;
+  border-radius: 4px;
+  word-wrap: break-word;
+  word-break: break-all;
+  line-height: 18px;
+  white-space: pre-wrap;
+  position: relative;
+}
 
-  .text_emoji {
-    img {
-      display:inline-block; 
-      width: 20px; 
-      height: 20px;
-      vertical-align: bottom;
-    }
+.text_emoji {
+  img {
+    display: inline-block;
+    width: 20px;
+    height: 20px;
+    vertical-align: bottom;
   }
+}
 </style>

+ 24 - 10
src/components/ChatList.vue

@@ -45,12 +45,25 @@
             <div class="group-name" @click="selected(item)">
               {{ item.name }}
             </div>
+            <template>
+              <el-popconfirm
+                title="确定退出群聊?"
+                @confirm="leaveRoom(item)"
+                icon="el-icon-info"
+                icon-color="red"
+                confirm-button-type="danger"
+              >
+                <el-button slot="reference" class="leave-room-btn">
+                  <i class="el-icon-close"></i>
+                </el-button>
+              </el-popconfirm>
+            </template>
           </div>
         </div>
         <div class="create-room">
           <button @click="createRoom">创建群聊</button>
           <button @click="joinRoom">加入群聊</button>
-          <button @click="leaveRoom">离开群聊</button>
+          <!-- <button @click="leaveRoom">离开群聊</button> -->
         </div>
       </el-tab-pane>
     </el-tabs>
@@ -80,7 +93,6 @@
           @click="join"
           >加入</el-button
         >
-        <el-button v-else @click="leave">退出房间</el-button>
       </div>
     </el-dialog>
   </div>
@@ -156,9 +168,9 @@ export default {
       this.dialog_title = "创建群聊";
       console.log("创建群聊");
     },
-    leaveRoom() {
-      this.dialogVisible = true;
-      this.dialog_title = "离开群聊";
+    leaveRoom(room) {
+      this.socket.emit("leave-room", room.id);
+      console.log("离开群聊");
     },
     create() {
       this.socket.emit("create-room", this.group_name);
@@ -170,11 +182,6 @@ export default {
       this.getRoomList();
       this.dialogVisible = false;
     },
-    leave() {
-      this.$socket.emit("leave-room", this.group_name);
-      console.log("离开群聊");
-      this.dialogVisible = false;
-    }
   },
   mounted() {
     // this.friend_list = this.$store.getters['chat/userList']
@@ -239,4 +246,11 @@ export default {
 .create-btn {
   margin-top: 20px;
 }
+.leave-room-btn {
+    width: 20px;
+    height: 20px;
+    padding: 0;
+    background: transparent;
+    border: none;
+}
 </style>