vue 加 websocket 聊天

<template><div style="height: 100%; width: 100%; background-color: #fff"><div class="wrap"><!-- 头部 --><div class="titleBox"><imgsrc="@/assets/image/avatar.png"style="argin: 10px 20px 10px 20px;width: 40px;height: 40px;"class="head_portrait"/><span style="color: #fff;font-size: 15px;">官方客服</span></div><!-- 底部 --><div class="infoBox"><!-- 左边用户列表 --><div class="userList"><div class="searchBox"><el-input  placeholder="请输入内容" v-model="search" class="input-with-select" size="mini" @input="inquire"><i  class="el-icon-search el-input__icon" slot="suffix" @click="handleIconClick"  /></el-input>
<!--            <el-button-->
<!--              icon="el-icon-plus"-->
<!--              size="mini"-->
<!--              type="primary"-->
<!--              @click="dialogVisible = true"-->
<!--            ></el-button>--></div><div class="userListBox" ref="scrollUserBox" id="userBox"><div v-if="list!=null && list.length > 0"  v-for="(item, index) in list" :key="index"@click="getAct(item, index)" :class="item.opposUserId == act ? 'userFlexAct' : 'userFlex'" ><el-badge :hidden="item.unreadCount ==0" :value="item.unreadCount" :max="99" class="item"><div><img  :src="item.avatar"   class="head_portrait2"  style="margin-left: 20px ; "  /></div></el-badge><div style="margin-right: 10px;"></div><div style="margin-right: 40px"><div style="color: #565656" class="nickName">{{ item.nickName }}</div><div class="userInfo" v-if="item.messageType==1" >{{item.message}}</div><div class="userInfo" v-if="item.messageType==2" >[商品]</div><div class="userInfo" v-if="item.messageType==3" >[图片]</div><div class="userInfo" v-if="item.messageType==4" >[订单]</div></div><div style="margin-right: 10px; font-size: 14px; color: #ccc">{{ formatDate(item.createTime) }}</div></div></div></div><!-- 右边输入框和信息展示 --><div class="infoList"><!-- 信息 --><div class="infoTop" ref="scrollBox" id="box"><div  v-for="(item, index) in info" :key="index"><!-- 显示时间信息 --><div class="chatInfoRight1 " v-if="shouldShowTime(index)">{{ formatDate1(item.createTime) }}</div><div :class="(item.fromUserId == item.userId && item.fromUserType != 1) ?   'chatInfoRight' :'chatInfoLeft' ">
<!--                <img :src="item.avatar" alt="头像" class="head_portrait2" />--><img :src="(item.fromUserId == item.userId && item.fromUserType != 1) ?  require('@/assets/image/avatar.png') : item.avatar" class="head_portrait2" style="margin-left: 20px;" /><div :class="(item.fromUserId == item.userId && item.fromUserType != 1) ?  'chatRight' : 'chatLeft'"><!-- 文字 --><div class="text" v-if="item.messageType==1" >{{item.message}}</div><!-- 商品 --><div v-if="item.messageType==2" class="text"><!--                  @click="openUrl(`/pages/goodsDetail?id=${parseMessage(item.message).productId}`)"--><div class="goods1"style="width: 200px;height: 70px;margin: 0 auto;background-color: #FFF;display: flex; "><image-preview :src="item.message" :width="60" :height="60"/><div class="right1"style="flex: 1;margin: auto 0;height: 60px;margin-left: 10px;"><div style="color: #333;height: 30px;line-height: 30px;     font-size: 14px; " class="right_title">{{parseMessage(item.message).productName}}</div><div style="height: 30px;color: #ff0000;line-height: 30px;    font-size: 12px;">¥{{parseMessage(item.message).merchantPrice}}</div></div></div></div><!-- 图片 --><div v-if="item.messageType==3" class="text"><image-preview :src="item.message" :width="70" :height="70"/></div></div></div></div></div><!-- 输入框 --><div class="infoBottom"><div class="infoIcon"><mesImg v-if='isshow==1?true:false'  v-model="imgUrl"/>
<!--              <i @click="extend('发送商品')" class="el-icon-sell"></i>-->
<!--              <i @click="extend('设置')" class="el-icon-setting"></i>-->
<!--              <i @click="extend('聊天记录')" class="el-icon-chat-dot-round"></i>-->
<!--              <i @click="extend('更多选项')" class="el-icon-more-outline"></i>--></div><textarea   maxlength="255"show-word-limittype="textarea"class="infoInput"v-model="textarea"@keydown.enter.exact="handlePushKeyword($event)"@keyup.ctrl.enter="lineFeed":disabled='isshow==1?false:true'/><div class="fasong" @click="setUp(1)" v-show="isshow==1?true:false">发送</div></div></div></div></div><!-- 搜索框边 + 号弹框 --><el-dialogtitle="选择需要添加的联系人":visible.sync="dialogVisible"width="30%":modal="false"><span>自定义页面,还没想好写什么功能</span><span slot="footer" class="dialog-footer"><el-button @click="dialogVisible = false">取 消</el-button><el-button type="primary" @click="dialogVisible = false">确 定</el-button></span></el-dialog></div>
</template><script>
import {getMesList,getMesInfo} from "@/api/ums/umsUser";
import axios from 'axios'
export default {watch: {imgUrl(newVal, oldVal) {if (newVal) {this.textarea =this.$constants.baseURL + this.imgUrl;this.setUp(3);}},},data() {return {socket: null,imgUrl: "",queryParams:{pageNum: 1,pageSize: 10,userId:this.$store.getters.userId,userType:2,},queryParamsUser:{pageNum: 1,pageSize: 10,userId:this.$store.getters.userId,userType:2,},// 在线状态state: 1,//搜索用户search: "",user: "",info: [],list:[],total:0,userIdserTotal:0,//用户点击选中变色act: Number,// 加号弹框dialogVisible: false,//历史信息userInfoList: [],//输入框textarea: "",//滚动条距离顶部距离scrollTop: 0,//滚动条距离顶部距离scrollUserTop: 0,//发送和输入显隐isshow:0};},created() {this.socket = new WebSocket('ws://192.168.1.140:9092/front/websocket/2:'+this.$store.getters.userId); // 替换成你的WebSocket服务器地址this.socket.onmessage = this.handleMessage;this.handleMesList()// this.setUserPageScrollTo()},methods: {// 计算是否显示时间信息的函数shouldShowTime(index) {if (index === 0) {return true; // 第一条消息肯定要显示时间信息}const currentItem = this.info[index];const prevItem = this.info[index - 1];const currentTime = new Date(currentItem.createTime);const prevTime = new Date(prevItem.createTime);const timeDiff = currentTime - prevTime; // 计算时间差,单位为毫秒const minutesDiff = Math.floor(timeDiff / 1000 / 60); // 转换为分钟return minutesDiff >= 3; // 如果时间差大于等于3分钟,则显示时间信息},// 解析消息字符串为对象parseMessage(message) {try {return JSON.parse(message);} catch (error) {console.error("Error parsing message:", error);return {}; // 返回空对象以避免渲染错误}},handleMessage(event) {try {const message = JSON.parse(event.data);// 判断发的信息是不是当前会话if (this.user.opposUserId == message.userId){this.getAct(this.user);}else {this.queryParams.pageNum = 1this.handleMesList();}// 处理收到的消息// 例如,将消息添加到相应的聊天记录中} catch (error) {// console.error('Received message is not in JSON format:', event.data);}},// 左侧列表handleMesList(){getMesList(this.queryParams).then(response => {this.list = response.rowsthis.total = response.total});// 直接调用不生效:因为你历史数据刚给,渲染的时候盒子高度还没有成型,所以直接调用拿不到,用个定时器让他在下一轮循环中调用,盒子就已经生成了this.$nextTick(() => { // 一定要用nextTickthis.setUserPageScrollTo();//页面滚动条距离顶部高度等于这个盒子的高度this.$refs.scrollUserBox.scrollUserTop = this.$refs.scrollUserBox.scrollHeight;})},//切换客服状态uploadState(state) {if (state !== 4) {this.state = state;} else {this.$confirm("是否退出登录?", "提示", {confirmButtonText: "确定",cancelButtonText: "取消",type: "warning",}).then(() => {this.$message({type: "success",message: "退出成功!",});}).catch(() => {this.$message({type: "info",message: "已取消退出",});});}},//搜索iconhandleIconClick() {alert("搜索");console.log(1);},//点击用户getAct(val) {console.log(val,11)this.isshow=1// 点击用户切换数据时先清除监听滚动事件,防止出现没有历史数据的用户,滚动条为0,会触发滚动事件this.$refs.scrollBox.removeEventListener("scroll", this.srTop);//点击变色this.act = val.opposUserId;//清空消息数组// this.info = [];this.queryParamsUser.toUserId = val.opposUserIdthis.queryParamsUser.pageNum = 1getMesInfo(this.queryParamsUser).then(response => {this.info = response.rowsthis.userTotal = response.totalthis.queryParams.pageNum = 1this.handleMesList()// 直接调用不生效:因为你历史数据刚给,渲染的时候盒子高度还没有成型,所以直接调用拿不到,用个定时器让他在下一轮循环中调用,盒子就已经生成了this.$nextTick(() => { // 一定要用nextTickthis.setPageScrollTo();//页面滚动条距离顶部高度等于这个盒子的高度this.$refs.scrollBox.scrollTop = this.$refs.scrollBox.s

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/586955.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【JavaSE】解密 继承和多态(下)

前言 紧接着上篇 解密继承和多态&#xff08;上&#xff09;~ 欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎指出~ 目录 前言 protected关键字 在同一包下同一类可以访问 代码理解 在同一包下不同类可以访问 代码理解 …

YARN集群 和 MapReduce 原理及应用

YARN集群模式 本文内容需要基于 Hadoop 集群搭建完成的基础上来实现 如果没有搭建&#xff0c;请先按上一篇: <Linux 系统 CentOS7 上搭建 Hadoop HDFS集群详细步骤> 搭建&#xff1a;https://mp.weixin.qq.com/s/zPYsUexHKsdFax2XeyRdnA 配置hadoop安装目录下的 etc…

【每日一题】894. 所有可能的真二叉树-2024.4.2

题目&#xff1a; 894. 所有可能的真二叉树 给你一个整数 n &#xff0c;请你找出所有可能含 n 个节点的 真二叉树 &#xff0c;并以列表形式返回。答案中每棵树的每个节点都必须符合 Node.val 0 。 答案的每个元素都是一棵真二叉树的根节点。你可以按 任意顺序 返回最终的…

火鸟门户系统—旅游度假模块

旅游度假 简介 旅游度假功能为用户提供一站式旅游度假服务&#xff0c;车站、酒店民宿、门票、跟团游、货运、签证等多个方面&#xff0c;满足用户多样化的旅游需求。 功能 订单&#xff1a;提供订单预订服务&#xff0c;用户可以根据自身需求选择合适的旅行产品。酒店民宿…

Chronos: 将时间序列作为一种语言进行学习

这是一篇非常有意思的论文&#xff0c;它将时间序列分块并作为语言模型中的一个token来进行学习&#xff0c;并且得到了很好的效果。 Chronos是一个对时间序列数据的概率模型进行预训练的框架&#xff0c;它将这些值标记为与基于transformer的模型(如T5)一起使用。模型将序列的…

OpenHarmony:全流程讲解如何编写ADC平台驱动以及应用程序

ADC&#xff08;Analog to Digital Converter&#xff09;&#xff0c;即模拟-数字转换器&#xff0c;可将模拟信号转换成对应的数字信号&#xff0c;便于存储与计算等操作。除电源线和地线之外&#xff0c;ADC只需要1根线与被测量的设备进行连接。 一、案例简介 该程序是基于…

为何网易游戏会选择引入OceanBase数据库

本文作者&#xff1a;田维繁&#xff0c;网易游戏关系型数据库小组负责人 作为中国游戏开发领域的佼佼者&#xff0c;网易游戏始终站在网络游戏自主研发的前沿。其产品及周边产品线丰富多样&#xff0c;因此&#xff0c;为满足各种业务场景的需求&#xff0c;需要多种不同的数据…

STM32 DWT数据观察触发器作为延时函数的使用

STM32 DWT数据观察触发器作为延时函数的使用 &#x1f4d1;DWT(Data Watchpoint and Trace数据观察触发器&#xff09;描述 &#x1f4dd;DWT是属于处理器内核单元中的调试组件之一&#xff0c;由四个比较器组成。它们可配置为&#xff1a;硬件监视点或对ETM或PC采样器或数据地…

实验四 微信小程序智能手机互联网程序设计(微信程序方向)实验报告

请编写一个用户登录界面&#xff0c;提示输入用户名和密码进行登录&#xff1b; 代码 index.wxml <view class"user"> <form bindreset""> <view>用户名&#xff1a;</view><input type"text"name""/>…

为什么要选择第三方软件测试机构?CMA、CNAS第三方软件测试机构推荐

第三方软件测试机构是独立于软件开发方和软件使用方的中立机构&#xff0c;致力于对软件产品进行全面、客观、专业的测试和评估&#xff0c;为软件开发方和使用方提供全面的技术支持和服务。 一、为什么要选择第三方软件测试机构   1、专业性强&#xff1a;拥有专业的测试团…

AI论文速读 | 【综述】用于轨迹数据管理和挖掘的深度学习:综述与展望

论文标题&#xff1a;Deep Learning for Trajectory Data Management and Mining: A Survey and Beyond 作者&#xff1a;Wei Chen(陈伟), Yuxuan Liang(梁宇轩), Yuanshao Zhu, Yanchuan Chang, Kang Luo, Haomin Wen(温浩珉), Lei Li, Yanwei Yu(于彦伟), Qingsong Wen(文青…

短视频短剧小程序搭建支持抖音快手百度微信h5端源码+教程

短视频短剧小程序搭建支持抖音快手百度微信h5端源码教程 预览 https://duanju.baicaitang.cn/h5/#/ 安装 一个备案域名服务器阿里云oss 后端搭建 1、导入数据库sql 2、设置运行目录 /public 3、伪静态 location / {index index.html index.htm index.php;#主要是这一段一定要…