赞
踩
一、首先配置全局websocket
创建webSocket.js:
- // global.js
- export default {
- ws: {},
- setWs: function(newWs) {
- this.ws = newWs
- }
- }
-
main.js引入:
- import webSocket from './utils/webSocket.js'
- Vue.prototype.$webSocket = webSocket
在其他页面使用:
this.$webSocket.ws
二、App.vue监听websocket
- created() {
- this.initWebsocket();
- }
- methods: {
- initWebsocket() {
- let that = this
- if ('WebSocket' in window) {
- that.ws = new WebSocket('ws://127.0.0.1:30000/ws')
- that.$webSocket.setWs(that.ws)
- that.ws.onopen = function () {
- setTimeout(() => {
- that.queryMessage()
- }, 500)
- }
- //that.onopen(); 这个地方未定义是会报错,所以我写成了 that.ws.onopen = function() {console.log('开始连接')};
- that.ws.onclose = function () {
- // 关闭 websocket
- console.log('连接已关闭...')
- setTimeout(() => {
- that.initWebsocket()
- }, 2000)
- }
- } else {
- // 浏览器不支持 WebSocket
- console.log('您的浏览器不支持 WebSocket!')
- }
- },
- queryMessage() {
- let that = this;
- let customerList = this.$store.state.permission.customerList;
- let expertList = this.$store.state.permission.expertList;
- for (let index = 0; index < customerList.length; index++) {
- let msg = {
- type: "login",
- uid: customerList[index].id
- };
- if (that.$webSocket.ws && that.$webSocket.ws.readyState == 1) {
- that.$webSocket.ws.send(JSON.stringify(msg));
- }
- }
- for (let index = 0; index < expertList.length; index++) {
- let msg = {
- type: "login",
- uid: expertList[index].id
- };
- if (that.$webSocket.ws && that.$webSocket.ws.readyState == 1) {
- that.$webSocket.ws.send(JSON.stringify(msg));
- }
- }
- that.$webSocket.ws.onmessage = function (res) {
- let jsonData = JSON.parse(res.data);
- let data = jsonData.data;
- //新推过来条数
- let customerList = that.$store.state.permission.customerList;
- for (let index = 0; index < customerList.length; index++) {
- if(jsonData.uid == customerList[index].id){
- axios.post("获取总条数接口",{uid:customerList[index].id}).then(res=>{
- if(res.data.success == true){
- if(customerList[index].msgNum == null){
- customerList[index].msgNum=0;
- customerList[index].msgNum+=res.data.data;
- }
- }
- })
- if (data.type == "newConv") {
- if (customerList[index].id != data.send_uid) {
- customerList[index].msgNum++;
- break;
- }
- } else if (data.type == "newMsg") {
- if (customerList[index].id != data.send_uid) {
- customerList[index].msgNum++;
- break;
- }
- }
- }
- }
- that.$store.state.permission.customerList = customerList;
- //新推过来条数
- let expertList = that.$store.state.permission.expertList;
- for (let index = 0; index < expertList.length; index++) {
- if(jsonData.uid == expertList[index].id){
- axios.post("获取总条数接口",{uid:expertList[index].id}).then(res=>{
- if(res.data.success == true){
- if(expertList[index].msgNum == null){
- expertList[index].msgNum=0;
- expertList[index].msgNum+=res.data.data;
- }
- }
- })
- if (data.type == "newConv") {
- if (expertList[index].id != data.send_uid) {
- expertList[index].msgNum++;
- break;
- }
- } else if (data.type == "newMsg") {
- if (expertList[index].id != data.send_uid) {
- expertList[index].msgNum++;
- break;
- }
- }
- }
- }
- that.$store.state.permission.expertList = expertList;
- };
- }
- }
- }
三、聊天界面
- <template>
- <div class="ContactWrap" v-if="uid != 0">
- <div class="Contact">
- <div class="ContactSide">
- <!-- <div class="ContactSide-tip"></div> -->
- <div >
- <div v-for="(item,index) in userList" :key="index" >
- <div class="ContactItem" @click="chooseUser(item)" :class="{ChooseItem : item.uid == chooseId}">
- <img class="UserAvator" :src="item.avatar" />
- <div class="UserContent">
- <div class="UserMsg">
- <span class="UserName" style="padding-left:5px;">{{item.nickname}}</span>
- <span class="MsgTime">{{item.last_msg_time.split(' ')[0]}}</span>
- </div>
- <div class="UserSnippet" style="padding-top:8px;" :title="title">{{customMethod(item.msg_type,item.msg_content)}}</div>
- <span v-if="item.unreadCount != 0" style="float:right; display:inline-block; border-radius:5px 5px 5px 5px;line-height: 90px;height:15px;margin-left:100px;margin-top:-15px;color:rgb(255 255 255);font-size:10px;background-color:#cccccc;display:flex;justify-content:center;align-items:center;">{{item.unreadCount}}</span>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="ContactBox">
- <div class="ContactBox-header" style="font-size:18px;">{{titename}}</div>
- <div class="MessageBox" ref="MessageBox">
- <div
- v-for="(item,index) in chatList"
- :key="index"
- class="Message"
- :style="item.send_uid == uid?'flex-direction:row-reverse':''"
- >
- <!-- <div class="UserHead"> -->
- <img :src="item.send_uid == uid? pcimg:duifangimg" class="UserAvator" />
- <!-- </div> -->
- <div class="UserMsg" :class="item.send_uid == uid?'RightMessage':'LeftMessage'">
- <span v-if="item.msg_type == 1" :style="item.send_uid == uid?' float: right;':''">{{item.msg_content}}</span>
- <span
- :style="item.send_uid == uid?' float: right;':''"
- v-if=" item.msg_type == 2 "
- >
- <video
- style="width: 160px"
- controls="controls"
- :src="item.msg_content"
- alt=""
- srcset=""
- ></video>
- </span>
- <span
- :style="item.send_uid == uid?' float: right;':''"
- v-if="item.msg_type == 4 "
- >
- <img
- v-image-preview
- :src="item.msg_content"
- alt=""
- srcset=""
- style="
- vertical-align: text-top;
- display: inline-block;
- width: 40px;
- height:40px
- "
- />
- </span>
- <span
- :style="item.send_uid == uid?' float: right;':''"
- v-if="item.msg_type == 3 "
- >
- <audio
- style="width: 200px"
- controls="controls"
- :src="item.msg_content"
- alt=""
- srcset=""
- ></audio>
- </span>
- </div>
- </div>
- </div>
- <!-- 输入框 -->
- <div class="InputBox">
- <div v-if="titename != ''">
- <textarea v-model="msg" style="resize:none" class="InputTextarea" rows="3" ></textarea>
- <div class="InputBox-footer">
- <!-- <div class="FooterDesc">按Enter键发送</div> -->
- <button class="sendButton" @click="sendmsg($event)">发送</button>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </template>
- <script>
- import util from "@/utils/index.js";
- import axios from "axios";
- export default {
- name: "Chat",
- components: {},
- data() {
- return {
- uid: 0,
- ws: null,
- msg: "", //聊天信息
- chatList: [
- // {
- // id: 14,
- // content: "哈哈哈",
- // avaUrl:
- // "https://pic4.zhimg.com/v2-a12b2d609fa2d5d16c10ea069419f3c3_xs.jpg"
- // },
- // {
- // id: 1,
- // content: "嘿嘿嘿",
- // avaUrl:
- // "https://pic4.zhimg.com/v2-a12b2d609fa2d5d16c10ea069419f3c3_xs.jpg"
- // },
- ], //聊天记录
- userList: [
- // {
- // uid:1,
- // username: "test1",
- // content: "美美哒",
- // time: "6-22",
- // avaUrl:
- // "https://pic4.zhimg.com/v2-a12b2d609fa2d5d16c10ea069419f3c3_xs.jpg"
- // },
- // {
- // uid:2,
- // username: "test2",
- // content: "活好每一天",
- // time: "6-22",
- // avaUrl:
- // "https://pic4.zhimg.com/v2-a12b2d609fa2d5d16c10ea069419f3c3_xs.jpg"
- // },
- ],
- chooseId:0,
- titename:"",
- title: "",
- conv_id:"",
- duifangimg:"",
- };
- },
- props:['fuid','pcimg'],
- mounted() {
- this.uid = this.fuid;//可以自己写个假数据
- setTimeout(() => {
- this.getChatList();
- }, 300);
- //this.initWebsocket();
- },
- watch:{ //监听value的变化,进行相应的操做便可
- fuid: function(a,b){ //a是value的新值,b是旧值
- this.uid = this.fuid;
- this.chatList =[]
- this.getChatList();
- }
- },
- methods: {
- //发送信息
- sendmsg(event) {
- event.preventDefault()
- let msg = {"type":"send","send_id":this.uid,"receive_id":this.chooseId,"msg_type":"1","content":this.msg};
- if (this.$webSocket.ws && this.$webSocket.ws.readyState == 1) {
- this.$webSocket.ws.send(JSON.stringify(msg));
- }
- setTimeout(() => {
- this.getMsgList(this.conv_id);
- }, 500)
- this.msg = "";
- },
- //滚动条滚动到底部
- scrollBottm() {
- let el = this.$refs["MessageBox"];
- el.scrollTop = el.scrollHeight;
- },
- //选择联系人
- chooseUser(user){
- this.chooseId = user.uid;
- this.titename = user.nickname;
- this.getMsgList(user.conv_id);
- },
- //获取聊天列表
- getChatList(){
- axios.post("聊天列表接口",{uid:this.uid}).then(res=>{
- if(res.data.success == true){
- this.userList = res.data.data;
- if(this.userList.length>0){
- this.chooseId = this.userList[0].uid;
- this.titename = this.userList[0].nickname;
- this.conv_id = this.userList[0].conv_id;
- this.getMsgList(this.userList[0].conv_id);
- this.duifangimg = this.userList[0].avatar;
- }else{
- this.chooseId = '';
- this.titename = '';
- }
-
- }
- })
- },
- //获取聊天记录
- getMsgList(chooseId){
- axios.post("聊天记录接口",{cid:chooseId,uid:this.uid,pagesize:'10'}).then(res=>{
- if(res.data.success == true){
- this.chatList = res.data.data;
- let msgNums = 0;
- for(let i=0;i<this.userList.length;i++){
- if(this.userList[i].conv_id == chooseId){
- msgNums = this.userList[i].unreadCount;
- this.userList[i].unreadCount = 0;
- this.$emit('getInitData',this.fuid,msgNums);
- }
- }
- setTimeout(() => {
- this.scrollBottm();
- }, 50);
- }
- })
- },
- //隐藏字符串
- customMethod(type,msg){
- if(type == '1'){
- if(msg.length<10){
- return msg;
- }else{
- this.title=msg.substring(0,10)+'...';
- return msg.substring(0,10)+'...';
- }
- }else {
- this.title='媒体消息';
- return '[媒体消息]';
- }
- },
- //重新计算未读消息数
- getUnreadNum(msgNums){
- //把未读消息数清空
- // for (let index = 0; index < this.$store.state.permission.customerList.length; index++) {
- // if(this.fuid == this.$store.state.permission.customerList[index].id){
- // if(this.$store.state.permission.customerList[index].msgNum != null && this.$store.state.permission.customerList[index].msgNum >= msgNums){
- // this.$store.state.permission.customerList[index].msgNum = this.$store.state.permission.customerList[index].msgNum - msgNums;
- // }else{
- // this.$store.state.permission.customerList[index].msgNum = 0;
- // }
- // }
- // }
- // for (let index = 0; index < this.$store.state.permission.expertList.length; index++) {
- // if(this.fuid == this.$store.state.permission.expertList[index].id){
- // if(this.$store.state.permission.expertList[index].msgNum != null && this.$store.state.permission.expertList[index].msgNum >= msgNums){
- // this.$store.state.permission.expertList[index].msgNum = this.$store.state.permission.expertList[index].msgNum - msgNums;
- // }else{
- // this.$store.state.permission.expertList[index].msgNum = 0;
- // }
- // }
- // }
-
- }
- }
- }
-
- </script>
- <style lang="scss" scoped>
- .Contact {
- height: 704px;
- width: 100%;
- background-color: #fff;
- border: 1px solid #ebebeb;
- box-shadow: 0 0 4px 0 rgba(26, 26, 26, 0.1);
- border-radius: 3px;
- display: flex;
- //联系人
- .ContactSide {
- width: 500px;
- height: 100%;
- border-right: 1px solid #ebebeb;
- .ContactSide-tip {
- height: 60px;
- line-height: 40px;
- font-weight: 600;
- padding: 0 30px;
- border-bottom: 1px solid #ebebeb;
- }
- }
- .ContactItem {
- padding: 12px 20px 12px 29px;
- cursor: pointer;
- display: flex;
- border-bottom: 1px solid #f7f8fa;
- .UserContent {
- flex: 1;
- .UserMsg {
- display: flex;
- align-items: center;
- justify-content: space-between;
- .UserName {
- font-size: 15px;
- columns: #444444;
- font-weight: 600;
- }
- .MsgTime {
- font-size: 12px;
- color: #999999;
- float: right;
- }
- }
- }
- }
- .ChooseItem{
- background: #f5f4f4;
- }
- .UserAvator {
- width: 40px;
- height: 40px;
- border-radius: 50%;
- margin-right: 10px;
- }
- .ContactBox {
- width: 100%;
- &-header {
- background: #fafafa;
- font-size: 15px;
- // margin: 0 14px;
- // height: 20px;
- padding-bottom: 21px;
- padding-top: 22px;
- border-bottom: 1px solid #ebebeb;
- font-weight: 600;
- text-align: center;
- }
- //聊天框
- .MessageBox {
- height: 470px;
- overflow: scroll;
- .Message {
- display: flex;
- margin: 20px;
- .UserMsg {
- max-width: 388px;
- border-radius: 8px;
- padding: 6px 12px;
- font-size: 14px;
- position: relative;
- margin: 0 8px;
- text-align: left;
- white-space: pre-wrap;
- word-break: break-all;
- }
- .LeftMessage {
- background-color: #f6f6f6;
- color: #444;
- &::after {
- content: "";
- position: absolute;
- width: 8px;
- height: 8px;
- left: -4px;
- top: 14px;
- background: #f6f6f6;
- -webkit-transform: rotate(45deg);
- transform: rotate(45deg);
- }
- }
- .RightMessage {
- background-color: #0084ff;
- color: #fff;
- &::after {
- content: "";
- position: absolute;
- width: 8px;
- height: 8px;
- right: -4px;
- top: 14px;
- background: #0084ff;
- -webkit-transform: rotate(45deg);
- transform: rotate(45deg);
- }
- }
- }
- }
- //输入框
- .InputBox {
- padding: 0 10px;
- border-top: 1px solid #ebebeb;
- display: flex;
- flex-direction: column;
- justify-content: space-between;
- height: 168px;
- background: #fff;
- z-index: 10;
- .InputTextarea {
- margin-top: 20px;
- width: 100%;
- border: none;
- font-size: 14px;
- flex: 1;
- height:90px;
- }
- &-footer {
- display: flex;
- align-items: center;
- justify-content: flex-end;
- height: 40px;
- .FooterDesc {
- font-size: 14px;
- color: #bfbfbf;
- padding-right: 10px;
- }
- .sendButton {
- color: #fff;
- background-color: #0084ff;
- border-radius: 6px;
- width: 72px;
- height: 32px;
- font-size: 13px;
- line-height: 32px;
- text-align: center;
- }
- }
- }
- }
- }
-
- </style>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。