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时间卷积双向门控循环单元多头注意力机制多特征分类预测/故障识别分类效果基本介绍模型描述程序…

Android adb 常用命令

以下是一些常用的adb&#xff08;Android Debug Bridge&#xff09;命令列表&#xff1a; 连接设备&#xff1a; adb devices&#xff1a;列出已连接的 Android 设备。adb connect <设备IP地址>&#xff1a;通过TCP/IP连接到设备。adb disconnect <设备IP地址>&…

SpringBoot多级多模块聚合项目下maven打包报‘packaging‘ with value ‘jar‘ is invalid.

问题场景&#xff1a; SpringBoot多级多模块项目中部分pom文件报红&#xff0c;mvn clean时报错&#xff1a;‘packaging’ with value ‘jar’ is invalid. Aggregator projects require ‘pom’ as packaging. 项目背景 项目是一个多级多模块项目&#xff0c;简单分为&…

【系统架构设计师】- 知识点汇总(易错总结)

—————————————————————————————————— 一、函数依赖的推理规则&#xff1a; 1、自反律&#xff1a;若Y⊆X⊆U&#xff0c;则X→Y在R上成立。 2、增广律&#xff1a;若X→Y在R上成立&#xff0c;且Z⊆U&#xff0c;则XZ→YZ在R上也成立。 3、传…

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…

uniapp通过蓝牙传输数据 (ios)

在uni-app中&#xff0c;可以通过uni-ble&#xff08;uni-app官方提供的蓝牙插件&#xff09;来实现iOS设备上的蓝牙数据传输。 首先&#xff0c;确保已在uni-app的manifest.json文件中添加uni-ble插件的配置&#xff1a; "permission": { "scope.userLocati…

Windows power shell/cmd/shell/脚本

Windows power shell/cmd/shell/脚本 1、shell shell&#xff1a;shell脚本运行的环境&#xff0c;是一个概念不是特指 shell脚本&#xff1a;shell脚本就是将一系列命令按照一定的顺序保存到一个文本文件中&#xff0c;该文本文件被赋予执行权限&#xff0c;执行时依次执行…

【大模型】大模型 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;…

02 删改查

文章目录 CartControllerCartMapperCartDButilCartMapper.xmlgeneratorConfig.xmlmybatis-config.xmlcart.jspproducts.jsp(忽略)pom.xml CartController package controller;import mapper.CartMapper; import org.apache.ibatis.session.SqlSession; import pojo.Cart; impor…

UE4 方块排序动画

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

web渗透测试漏洞复现:ZooKeeper未授权漏洞复现

web渗透测试漏洞复现 1. ZooKeeper未授权漏洞复现1.1 ZooKeeper简介1.2 ZooKeeper漏洞复现1.3 ZooKeeper漏洞修复建议1. ZooKeeper未授权漏洞复现 1.1 ZooKeeper简介 ZooKeeper 是一个分布式的、开源的协调服务,最初由雅虎开发,现隶属于 Apache 软件基金会,是Google的Chub…

Java pdfbox 给 PDF 添加文字和图片水印 并旋转45度

POM <dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.27</version> </dependency> 代码&#xff1a; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdf…

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

引言 随着科技的不断进步和人工智能技术的快速发展&#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…