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.mzph.cn/news/788630.shtml

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

相关文章

分类预测 | Matlab实现TCN-BiGRU-Mutilhead-Attention时间卷积双向门控循环单元多头注意力机制多特征分类预测/故障识别

分类预测 | Matlab实现TCN-BiGRU-Mutilhead-Attention时间卷积双向门控循环单元多头注意力机制多特征分类预测/故障识别 目录 分类预测 | Matlab实现TCN-BiGRU-Mutilhead-Attention时间卷积双向门控循环单元多头注意力机制多特征分类预测/故障识别分类效果基本介绍模型描述程序…

Vue-Next-Admin:适配手机、平板、PC的开源后台管理模板

摘要&#xff1a;随着移动设备和PC的普及&#xff0c;为了满足不同设备的需求&#xff0c;开发一个能够自适应手机、平板和PC的后台管理系统变得至关重要。本文将介绍一个基于Vue3.x、Typescript、Vite、Element Plus等技术的开源模板库——Vue-Next-Admin&#xff0c;帮助开发…

FebHost:人工智能时代的新宠儿.AI域名

近年来,人工智能技术在各行各业迅猛发展,正在深刻改变着我们的生活。作为AI领域的专属域名,.AI域名正成为越来越多企业和个人的首选。 那么,.AI域名到底是什么呢?它是一种特殊的顶级域名(Top-Level Domain, TLD),于2013年由 安哥拉政府正式退出。与其他通用顶级域名如.com、.…

华为ensp路由器模拟ftp服务器访问

众所周知ensp的pc只有ping功能&#xff0c;ssh、telnet、ftp都无法实现&#xff0c;所以想实现需要更换为路由器 R1需要FTP到server的ftp服务 server的FTP配置就这些命令&#xff0c;主要的是路径&#xff0c;然后在网络可达的情况下就可以进行登录测试了 aaa local-user hu…

【大模型】大模型 CPU 推理之 llama.cpp

【大模型】大模型 CPU 推理之 llama.cpp llama.cpp安装llama.cppMemory/Disk RequirementsQuantization测试推理下载模型测试 参考 llama.cpp 描述 The main goal of llama.cpp is to enable LLM inference with minimal setup and state-of-the-art performance on a wide var…

unity 使用Base64编码工具对xml json 或者其他文本进行加密 解密

Base64编码加密解密工具 这是一个加密解密的网页工具&#xff0c;别人可以把他加密后的字符串给你&#xff0c;然后你可以用代码解密出来&#xff0c; 或者自己对内容进行加密&#xff0c;解密处理。 /// <summary>/// Base64 解码/// </summary>string DecodeBase…

基于 NGINX 的 ngx_http_geoip2 模块 来禁止国外 IP 访问网站

基于 NGINX 的 ngx_http_geoip2 模块 来禁止国外 IP 访问网站 一、安装 geoip2 扩展依赖 [rootfxkj ~]# yum install libmaxminddb-devel -y二、下载 ngx_http_geoip2_module 模块 [rootfxkj tmp]# git clone https://github.com/leev/ngx_http_geoip2_module.git三、解压模…

55、美国德克萨斯大学奥斯汀分校、钱德拉家族电气与计算机工程系:通过迁移学习解决BCI个体差异性[不得不说,看技术还得是老美]

2024年2月5日跨被试最新文章&#xff1a; 德州州立大学奥斯汀分校研究团队最近的一项研究成果&#xff0c;通过非侵入式的脑机接口&#xff0c;可以让被试不需要任何校准就可以使用脑机接口设备&#xff0c;这意味着脑机接口具备了大规模被使用的潜力。 一般来说&#xff0c;…

UE4 方块排序动画

【动画效果】 入动画&#xff1a; 出动画&#xff1a; 【分析】 入动画&#xff1a;方块动画排序方式为Z字形&#xff0c;堆砌方向为X和Y轴向 出动画&#xff1a;方块动画排序方式为随机 【关键蓝图】 1.构建方块砌体 2.入/出动画

人工智能+的广泛应用,已渗透到生活的方方面面

引言 随着科技的不断进步和人工智能技术的快速发展&#xff0c;我们正处于一个人工智能时代。人工智能不仅仅是一种技术&#xff0c;更是一种革命性的变革力量&#xff0c;它正在以前所未有的方式改变着我们的生活和工作方式。 人工智能&#xff08;AI&#xff09;指的是人工…

【容易不简单】love 2d Lua 俄罗斯方块超详细教程

源码已经更新在CSDN的码库里&#xff1a; git clone https://gitcode.com/funsion/love2d-game.git 一直在找Lua 能快速便捷实现图形界面的软件&#xff0c;找了一堆&#xff0c;终于发现love2d是小而美的原生lua图形界面实现的方式。 并参考相关教程做了一个更详细的&#x…

某音乐平台歌曲信息逆向之webpack扣取

逆向网址 aHR0cHM6Ly95LnFxLmNvbS8 逆向链接 aHR0cHM6Ly95LnFxLmNvbS9uL3J5cXEvc29uZ0RldGFpbC8wMDJkdzRndjFabWlHdA 逆向接口 aHR0cHM6Ly91Ni55LnFxLmNvbS9jZ2ktYmluL211c2ljcy5mY2c 逆向过程 请求方式&#xff1a;POST 逆向参数 sign zzbd8c72309rdslvlnjwk8pthj2lw462f12…

ubuntu-server部署hive-part3-安装mysql

参照 https://blog.csdn.net/qq_41946216/article/details/134345137 操作系统版本&#xff1a;ubuntu-server-22.04.3 虚拟机&#xff1a;virtualbox7.0 部署mysql 下载上传 下载地址 https://downloads.mysql.com/archives/community/ 以root用户上传&#xff0c;/usr/loc…

Three.js阴影贴图

生成阴影贴图的步骤如下&#xff1a; 从光位置视点&#xff08;阴影相机&#xff09;创建深度图。从相机的角度进行屏幕渲染在每个像素点&#xff0c;将阴影相机的MVP矩阵计算出的深度值与深度图值进行比较如果深度图值较低&#xff0c;则说明该像素点存在阴影 &#xff0c;因…

隐私计算实训营第七讲-隐语SCQL的架构详细拆解

隐私计算实训营第七讲-隐语SCQL的架构详细拆解 文章目录 隐私计算实训营第七讲-隐语SCQL的架构详细拆解1.SCQL Overview1.1 多方数据分析场景1.2 多方数据分析技术路线1.2.1 TEE SQL方案1.2.2 MPC SQL方案 1.3 Secure Collaborative Query Language(SCQL)1.3.1 SCQL 系统组件1.…

rust项目组织结构和集成测试举例

概述 在学习rust的过程中&#xff0c;当项目结构略微复杂的时候&#xff0c;写集成测试的时候发现总是不能引用项目中的代码&#xff0c;导致编写测试用例失败。查阅了教程&#xff0c;一般举例都很简单。查阅了谷歌和百度以及ai&#xff0c;也没有找到满意的答案。这里记录一…

用户体验:探讨Facebook如何优化用户体验

在数字化时代&#xff0c;用户体验是社交媒体平台成功与否的关键因素之一。作为全球最大的社交媒体平台之一&#xff0c;Facebook一直在努力优化用户体验&#xff0c;从功能设计到内容呈现再到隐私保护&#xff0c;不断提升用户满意度。本文将深入探讨Facebook如何优化用户体验…

【EasyExcel】—— 实现excel动态表头设置、多个sheet

引入jar <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.0</version></dependency>代码 public static void main(String[] args) {//选择存储地址String fileName "/User…

Linux基础概念

Linux Linux 和 UNIX 中的文件系统是一个以 / 为根的树状式文件结构&#xff0c;/ 是 Linux 和 UNIX 中的根目录&#xff0c;同样它也是文件系统的起点。所有的文件和目录都位于 / 路径下&#xff0c;包括经常听到的 /usr、/etc、/bin、/home 等。在早期的 UNIX 系统中&#x…

论文阅读RangeDet: In Defense of Range View for LiDAR-based 3D Object Detection

文章目录 RangeDet: In Defense of Range View for LiDAR-based 3D Object Detection问题笛卡尔坐标结构图Meta-Kernel Convolution RangeDet: In Defense of Range View for LiDAR-based 3D Object Detection 论文&#xff1a;https://arxiv.org/pdf/2103.10039.pdf 代码&…