You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1036 lines
31 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="content">
<!-- 聊天内容 -->
<scroll-view class="chat" scroll-y="true" scroll-with-animation="true" :scroll-into-view="scrollToView"
refresher-enabled="true" :refresher-triggered="triggered" :refresher-threshold="100"
refresher-background="#f0f0f0" @refresherpulling="onPulling"
@refresherrefresh="onRefresh" @refresherrestore="onRestore" @refresherabort="onAbort">
<view class="chat-main" :style="{paddingBottom:inputh+'px'}">
<!-- <view class="chat-ls" v-if="unshiftmsg.length==0">
<view class="chat-time">现在可以开始聊天了.</view>
</view> -->
<view class="chat-ls">
<view class="msg-m msg-left">
<view class="user-img" >
<image class="uimg" :src="serviceimg"></image>
<text class="uname">{{servicename}}</text>
</view>
<view class="message">
<!-- 文字 -->
<view class="msg-text">
<text>Hi{{friendName}},我是您的专属客服{{servicename}},有什么问题都可以问我呦~</text>
</view>
</view>
</view>
<view class="msg-m msg-left">
<view class="user-img" >
<image class="uimg" :src="serviceimg"></image>
<text class="uname">{{servicename}}</text>
</view>
<view class="message">
<!-- 文字 -->
<view class="msg-text">
<view class="txtline" v-for="(item) in msg" :id="'msg'+ item.id" @click="gotoInfo(item)">
<text>
{{item.content}}
</text>
<image style="width: 40rpx; height: 40rpx;" src="/static/image/hot.png"></image>
</view>
</view>
</view>
</view>
</view>
<view class="chat-ls" v-for="(item,index) in unshiftmsg" :key="index" :id="'msg'+ index">
<view class="chat-time" v-if="item.fromtime != ''">{{changeTime(item.fromtime)}}</view>
<view class="msg-m msg-left" v-if="item.fromuser !== friendcode">
<view class="user-img" >
<image class="uimg" :src="item.headimg" @error="handleImageError($event,index)"></image>
<text class="uname">{{item.fromname}}</text>
</view>
<view class="message" v-if="item.type == 'txt'">
<!-- 文字 -->
<view class="msg-text">
<text>{{item.content}}</text>
</view>
</view>
<view class="message" v-if="item.type == 'image'" @tap="previewImg(item.content)">
<!-- 图像 -->
<image :src="item.content" class="msg-img" mode="widthFix"></image>
</view>
<view class="messagevideo" v-if="item.type == 'video'">
<!-- 视频 -->
<myVideo :videoUrl="item.content"></myVideo>
</view>
<view class="message" v-if="item.type == 'audio'" @click="playVoice(item.content,item.ifaudio,index)">
<!-- 音频 -->
<view class="msg-text voice" :style="{width:item.time*40+'rpx'}">
<view class="voicel" v-if="item.ifaudio" >
<div class="bg voicePlay"></div>
</view>
<image v-else src="../../static/icon/horn.png" class="voice-img"></image>
{{item.time}}″
</view>
</view>
</view>
<view class="msg-m msg-right" v-if="item.fromuser == friendcode">
<view class="user-img" >
<image class="uimg" :src="item.headimg" @error="handleImageError($event,index)" ></image>
<!-- <text class="uname">我</text> -->
<text class="uname">{{item.fromname}}</text>
</view>
<view class="message" v-if="item.type == 'txt'">
<view class="msg-text">
<text>{{item.content}}</text>
</view>
</view>
<view class="message" v-if="item.type == 'image'" @tap="previewImg(item.content)">
<image :src="item.content" class="msg-img" mode="widthFix"></image>
</view>
<view class="messagevideo" v-if="item.type == 'video'" >
<!-- 视频 -->
<myVideo :videoUrl="item.content"></myVideo>
</view>
<view class="message" v-if="item.type == 'audio'" @click="playVoice(item.content,item.ifaudio,index)">
<!-- 音频 -->
<view class="msg-text voice" :style="{width: item.time>2? item.time*40+'rpx' :'auto'}">
{{item.time}}″
<view class="voicel" v-if="item.ifaudio" >
<div class="bg voicePlay"></div>
</view>
<image v-else src="../../static/icon/hornrw.png" class="voice-img"></image>
</view>
</view>
</view>
</view>
</view>
</scroll-view>
<submit @inputs="inputs" @heights="heights"></submit>
<u-toast ref="uToast" />
</view>
</template>
<script>
import { myCache } from '../../utils/utils.js';
import dateTime from '@/common/dateTime.js';
import submit from '@/components/chat/submit.vue';
import myVideo from "@/components/myVideo.vue";
//音频播放
const innerAudioContext = uni.createInnerAudioContext();
export default {
components: {
submit,
myVideo
},
data() {
return {
text:"",
triggered: false,
friendName: "",
friendcode: "",
serviceimg: require("@/static/image/kfr.png"),
servicename: "伽伽",
info:{},// 老师信息
imgurl:"",// uni.$http.baseUrl,
iftop:true,
msg: [
{
id: "11",
content:'怎么改配送时间/地址/电话?'
},
{
id: "22",
content:'收到商品有问题怎么办?'
},
{
id: "33",
content:'我的订单什么时间配送?'
},
],
// 反转数据接收
unshiftmsg: [
// {
// fromuser: "11",
// fromname: "Madeline 老师 (女)",
// fromtime:'2025-06-20 10:00:00',
// headimg:require("@/static/image/i1.png"),
// content:'Hixxx我是普拉提教练小a周日上午10点的课您可以准时参加吧',
// type:'txt'
// },
],
imgMsg: [],
scrollToView: '',
oldTime: new Date(),
inputh: '90',
page:{
pageNum:'1',
pageSize: '50',
zid:null
},
ifcatch:true,
loadStatus:true,
ifaudio:false,
socket: null, // WebSocket实例
isConnected: false, // WebSocket连接状态
}
},
onLoad(options) {
var user= myCache("user");
this.friendName=user.username?user.username:"";
this.friendcode=user.userid?user.userid:"";
if(options.data){
console.log(options.data)
this.info=JSON.parse(decodeURIComponent(options.data));
console.log(this.info)
// 先获取缓存
this.getchatstore();
uni.setNavigationBarTitle({
title: this.info.name,
});
// socket 接受信息
// this.socketinit();
}
},
onShow() {
// 跳转到最后一条数据 与前面的:id进行对照
this.screendo(this.unshiftmsg.length - 1);
},
onBackPress(options) {
if (options.from === 'backbutton') {
// 来自顶部菜单的返回按钮
// 在这里处理你的逻辑
console.log('返回按钮被点击');
this.closeWebSocket();
uni.onSocketClose(function (res) {
console.log('WebSocket 已关闭!');
});
return false;
}
},
beforeDestroy() {
console.log('界面关闭socketbeforeDestroy');
// 在组件销毁前,确保关闭 WebSocket 连接
this.closeWebSocket();
},
//点击导航栏 buttons 时触发 添加任务
onNavigationBarButtonTap: async function(e) {
const _that = this;
const index = e.index;
if (index === 0) {
var data=encodeURIComponent(JSON.stringify(_that.info));
uni.navigateTo({
url: `/pages/chat/chatset?data=${data}`
});
}
},
methods: {
gotoInfo(item){
var data=encodeURIComponent(JSON.stringify(item));
uni.navigateTo({
url: `/pages/user/serviceInfo?data=${data}`
});
},
handleImageError(e,index){
console.log(e,index);
this.unshiftmsg[index]["headimg"]= require("@/static/image/girl.jpg");
this.$forceUpdate();
},
// 获取聊天缓存
getchatstore(){
var that=this;
try{
var data=myCache('chat-'+this.friendcode+'-'+this.info.id);
data.forEach((cell,i)=>{
cell["ifaudio"]=false;
//时间间隔处理
if (i < this.unshiftmsg.length - 1) {
//这里表示头部时间还是显示一下
let t = dateTime.spaceTime(this.oldTime, cell.fromtime);
if (t) {
this.oldTime = t;
}
cell.fromtime = t;
}
// 获取图片,为下面的预览做准备
if (cell.type == 'image') {
this.imgMsg.unshift(cell.content)
}
else if(cell.type=='txt'){
cell.content=decodeURIComponent(cell.content);
}
cell["headimg"]=require("@/static/image/girl.jpg"); //this.imgurl+'/images/'+ cell.fromuser+".jpg?id="+Math.random()*100;
this.unshiftmsg.push(cell);
// 跳转到最后一条数据 与前面的:id进行对照
setTimeout(() => {
that.screendo(that.unshiftmsg.length-2);
}, 200);
});
// 加载聊天记录
this.page.zid=this.info.id;
this.page.pageSize=that.unshiftmsg.length.toString();
this.getList(1);
}
catch(err){
console.log(err);
// 加载聊天记录
this.page.zid=this.info.id;
this.getList(1);
}
},
socketinit(){
var that = this;
if (!this.isConnected) {
this.socket = uni.connectSocket({
url: "ws://218.24.131.92:18080/websocketServer/"+that.info.id+'/'+that.friendcode,
// url: "ws://localhost:18080/websocketServer/"+that.info.id+'/'+that.friendcode,
});
uni.onSocketOpen(res => {
console.log('WebSocket连接已打开');
that.isConnected = true;
});
uni.onSocketMessage(res => {
console.log('收到WebSocket服务器消息', res.data);
if(res.data){
let data=JSON.parse(res.data);
console.log(data);
if(data.zid){
// 加入聊天框
if(data.type=='txt'){
data.content=decodeURIComponent(data.content);
}
that.unshiftmsg.push(data);
that.$forceUpdate();
// 跳转到最后一条数据 与前面的:id进行对照
that.$nextTick(function() {
that.scrollToView = 'msg' + (that.unshiftmsg.length);
});
}
}
});
uni.onSocketClose(res => {
console.log('WebSocket连接已关闭');
that.isConnected = false;
});
uni.onSocketError(err => {
console.error('WebSocket连接打开失败请检查', err);
});
}
},
// 发送WebSocket消息
sendWebSocketMessage() {
if (this.socket && this.isConnected) {
uni.sendSocketMessage({
data: '这是一条测试消息' // 发送的消息内容
});
} else {
console.error('WebSocket未连接或未打开请先连接WebSocket');
}
},
// 关闭WebSocket连接
closeWebSocket() {
if (this.socket) {
uni.closeSocket();
this.socket = null;
this.isConnected = false;
}
},
// 分页加载对话
async getList(ii) {
var that=this;
if(this.loadStatus)
{
if(!this.ifcatch&&this.unshiftmsg.length>0){
// 重置当前分页页数 当前分页
this.page.pageNum= '2';
this.page.pageSize=this.unshiftmsg.length.toString();
}
const {data: res} = await uni.$http.post('/hyLtjl/getLtjlFy',this.page);
// console.log('分页获取',this.page)
this.triggered = false;
if(res.success){
if(res.data&&res.data.records&&res.data.records.length>0){
if(this.ifcatch){
this.ifcatch=false;
this.unshiftmsg=[];
this.imgMsg=[];
}
const gotonum=res.data.records.length;
res.data.records.forEach((cell,i)=>{
cell["ifaudio"]=false;
//时间间隔处理
if (i < this.unshiftmsg.length - 1) {
//这里表示头部时间还是显示一下
let t = dateTime.spaceTime(this.oldTime, cell.fromtime);
if (t) {
this.oldTime = t;
}
cell.fromtime = t;
}
// 获取图片,为下面的预览做准备
if (cell.type == 'image') {
// cell.content=this.imgurl+'/images/'+cell.content;
this.imgMsg.unshift(cell.content)
}
else if(cell.type=='txt'){
cell.content=decodeURIComponent(cell.content);
}
cell["headimg"]=require("@/static/image/boy.jpg") ;//this.imgurl+'/images/'+ cell.fromuser+".jpg?id="+Math.random()*100;
this.unshiftmsg.unshift(cell);
});
if(ii==2){
// 跳转到最后一条数据 与前面的:id进行对照
setTimeout(() => {
that.screendo(gotonum -2);
}, 200);
}
else{
// 跳转到最后一条数据 与前面的:id进行对照
setTimeout(() => {
that.screendo(that.unshiftmsg.length-1);
}, 300);
}
// 缓存聊天
myCache('chat-'+this.friendcode+'-'+this.info.id, this.unshiftmsg);
}
else{
if(this.page.pageNum=='2'){
this.$refs.uToast.show({
title: "信息已加载完毕...",
type: "success",
duration: 2000,
});
}
this.loadStatus=false;
}
}
else{
this.$refs.uToast.show({
title: "信息加载失败...",
type: "error",
duration: 2000,
});
}
}
else{
this.triggered = false;
this.$refs.uToast.show({
title: "信息已加载完毕...",
type: "success",
duration: 2000,
});
}
},
screendo(scrindex){
this.scrollToView = '';
// 跳转到最后一条数据 与前面的:id进行对照
this.$nextTick(function() {
this.scrollToView = 'msg' + scrindex
});
},
// 自定义下拉刷新控件被下拉
onPulling(e) {
var that=this;
// console.log("onpulling", e);
if (!this.triggered) {
//下拉刷新先变true再变false才能关闭
this.triggered = true;
//关掉圈圈,需要先执行完刷新操作
setTimeout(() => {
that.triggered = false;
}, 2000);
}
},
// 自定义下拉刷新被触发
onRefresh(event){
console.log("下拉加载"+event);
// var row={
// "sendName": "゛时光い",
// "receviceName": "xpq",
// "sendText": "这是第页第1条未读消息",
// "fromtime": "2021-12-19 12:21:58",
// "updateTime": null,
// "chatmState": 1,
// "type": 0,
// "kfed": 0
// };
// this.unshiftmsg.unshift(row);
// 加载聊天记录
this.getList(2);
},
// 自定义下拉刷新被复位
onRestore() {
this.triggered = 'restore'; // 需要重置
console.log("onRestore");
},
// 自定义下拉刷新被中止
onAbort() {
this.triggered = false;
console.log("onAbort");
},
changeTime(date) {
return dateTime.dateTime1(date);
},
// 进行图片的预览
previewImg(e) {
let index = 0;
for (let i = 0; i < this.imgMsg.length; i++) {
if (this.imgMsg[i] == e) {
index = i;
}
}
console.log("index", index)
// 预览图片
uni.previewImage({
current: index,
urls: this.imgMsg,
longPressActions: {
itemList: ['发送给朋友', '保存图片', '收藏'],
success: function(data) {
console.log('选中了第' + (data.tapIndex + 1) + '个按钮,第' + (data.index + 1) + '张图片');
},
fail: function(err) {
console.log(err.errMsg);
}
}
});
},
//音频播放
playVoice(e,ifplay,index) {
var that=this;
// 先关闭停止所有
innerAudioContext.src = '';
innerAudioContext.stop();
that.unshiftmsg.forEach((cell,i)=>{
cell.ifaudio=false;
});
ifplay=!ifplay;
this.unshiftmsg[index].ifaudio=ifplay;
this.$forceUpdate();
if(ifplay){
innerAudioContext.src = e;
innerAudioContext.play(() => {
console.log('开始播放');
});
// 监听音频播放结束事件
innerAudioContext.onEnded((res) => {
console.log('音频播放结束');
that.unshiftmsg[index].ifaudio=!ifplay;
that.$forceUpdate();
// 在这里执行你想要的操作
});
// innerAudioContext.onPlay(() => {
// console.log('开始播放');
// });
}
else{
innerAudioContext.src = '';
innerAudioContext.stop();
}
},
//地图定位
covers(e) {
let map = [{
latitude: e.latitude,
longitude: e.longitude,
iconPath: '../../static/image/head.png'
}]
return (map);
},
//跳转地图信息
openLocation(e) {
uni.openLocation({
latitude: e.latitude,
longitude: e.longitude,
name: e.name,
address: e.address,
success: function() {
console.log('success');
}
});
},
fullscreenchange(e){
if(!e.detail.fullScreen){ // 退出全屏,锁定竖屏
plus.screen.lockOrientation('portrait-primary');
}
},
//接受输入内容
async inputs(e) {
console.log(e);
var rindex=this.unshiftmsg.length-1;
//时间间隔处理
let data = {
"fromname": this.friendName,
"fromuser": this.friendcode,
"headimg":require("@/static/image/girl.jpg"),
"toname": this.info.name, // 接收人
"touser": this.info.id, // 接收人姓名
"content": e.type=='audio'?e.message.voice:e.message,
"time": e.type=='audio'?e.message.time:0,
"ifaudio":false,
"fromtime": new Date(),
"zid": this.info.id,
"type": e.type
};
if(e.type!=='video'){
this.unshiftmsg.push(data);
rindex=this.unshiftmsg.length-1;
// 跳转到最后一条数据 与前面的:id进行对照
this.screendo(this.unshiftmsg.length - 1);
}
// 发送给服务器消息
var that = this;
if(e.type=='txt'){
// 文本
// 消息发送
this.onSendWS(data,rindex);
}
else if(e.type=='image'){
// 图片
// 先上传在传送消息
var token= uni.getStorageSync("token");
console.log('先上传在传送消息');
uni.uploadFile({
url: uni.$http.baseUrl+"/api/file/upload",
filePath: e.message,
name: 'file',
header: {
'token': token
},
success: res => {
console.log(res);
var rdata=JSON.parse(res.data);
console.log(rdata);
if(rdata.success){
var url=rdata.data&&rdata.data.length>0?rdata.data[0]:'';
data.content= this.imgurl+'/images/'+url;
console.log(data);
// 消息发送
this.onSendWS(data,rindex);
// 图片放入集合
if (e.type == 'image'&&url) {
this.imgMsg.push(this.imgurl+'/images/'+url);
}
}
},
fail: res => {
console.log(res)
}
});
}
else if(e.type=='audio'){
// 音频
// 先上传在传送消息
var token= uni.getStorageSync("token");
console.log('先上传在传送消息');
uni.uploadFile({
url: uni.$http.baseUrl+"/api/file/upload",
filePath: e.message.voice,
name: 'file',
header: {
'token': token
},
success: res => {
console.log(res);
var rdata=JSON.parse(res.data);
console.log(rdata);
if(rdata.success){
var url=rdata.data&&rdata.data.length>0?rdata.data[0]:'';
data.content= this.imgurl+'/images/'+url;
console.log(data);
// 消息发送
this.onSendWS(data,rindex);
}
},
fail: res => {
console.log(res)
}
});
}
else if(e.type=='video'){
// 视频
// 先上传在传送消息
var token= uni.getStorageSync("token");
console.log('先上传在传送消息');
uni.uploadFile({
url: uni.$http.baseUrl+"/api/file/upload",
filePath: e.message,
name: 'file',
header: {
'token': token
},
success: res => {
console.log(res);
var rdata=JSON.parse(res.data);
console.log(rdata);
if(rdata.success){
var url=rdata.data&&rdata.data.length>0?rdata.data[0]:'';
data.content= this.imgurl+'/images/'+url;
console.log(data);
// 信息发送聊天框
this.unshiftmsg.push(data);
rindex=this.unshiftmsg.length-1;
// 跳转到最后一条数据 与前面的:id进行对照
this.screendo(this.unshiftmsg.length - 1);
// 消息发送
this.onSendWS(data,rindex);
}
},
fail: res => {
console.log(res)
}
});
}
},
async onSendWS(datamsg,rindex){
var message=JSON.stringify(datamsg);
var msssagebf=JSON.parse(message);
if(msssagebf.type=='txt'){
msssagebf.content=encodeURIComponent(msssagebf.content);
}
message=JSON.stringify(msssagebf);
console.log(message);
var roomId = this.info.id;
var userId = this.friendcode;
var token=uni.getStorageSync("token");
var param={
"message":message,
"roomId":roomId,
"userId":userId,
"token":token
}
// 发送消息
const {data: res} = await uni.$http.get('/sendMessageTo',param);
console.log(res);
if(res.success){
if(res.data){
var rrdata=res.data;
if(rrdata.type=='txt'){
rrdata.content=decodeURIComponent(rrdata.content);
}
this.unshiftmsg[rindex]=rrdata;
this.$forceUpdate();
// 缓存聊天
myCache('chat-'+this.friendcode+'-'+this.info.id, this.unshiftmsg);
console.log(this.unshiftmsg);
}
}
},
//输入框高度
heights(e) {
this.inputh = e;
this.goBottom();
},
// 滚动到底部
goBottom() {
this.scrollToView = '';
this.screendo(this.unshiftmsg.length - 1);
}
}
}
</script>
<style lang="scss">
page {
height: 100%;
}
.content {
height: 100%;
background-color: rgba(244, 244, 244, 1);
position: relative;
}
::v-deep .uni-noticebar{
margin-bottom: 0 !important;
padding: 10rpx 12rpx !important;
border-radius: 10rpx;
}
.chat {
height: 100%;
.chat-main {
padding-left: 20rpx;
padding-right: 20rpx;
padding-top: 20rpx;
// padding-bottom: 120rpx; //
display: flex;
flex-direction: column;
}
.chat-ls {
.chat-time {
font-size: 24rpx;
color: rgba(39, 40, 50, 0.3);
line-height: 34rpx;
padding: 10rpx 0rpx;
text-align: center;
}
.msg-m {
display: flex;
padding: 20rpx 0;
.user-img {
flex: none;
width: 92rpx;
height: 90rpx;
border-radius: 20rpx;
text-align: center;
.uimg{
width: 70rpx;
height: 70rpx;
margin: 0 auto;
border-radius: 35rpx;
}
.uname{
height: 30rpx;
display: block;
margin: 0 auto;
line-height: 30rpx;
color: rgba(39, 40, 50, 0.5);
font-size: 24rpx;
}
}
.message {
flex: none;
max-width: 520rpx;
}
.messagevideo {
max-width: 520rpx;
height: 300rpx;
}
.msg-text {
font-size: 32rpx;
color: rgba(39, 40, 50, 1);
line-height: 44rpx;
padding: 18rpx 24rpx;
}
.msg-img {
max-width: 440rpx;
border-radius: 20rpx;
}
.msg-video{
width: 440rpx;
height: 300rpx;
border-radius: 20rpx;
}
.msg-map {
background: #fff;
width: 464rpx;
height: 284rpx;
overflow: hidden;
margin: 0 20rpx;
.map-name {
font-size: 32rpx;
color: rgba(39, 40, 50, 1);
line-height: 44rpx;
padding: 18rpx 24rpx 0 24rpx;
//
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
}
.map-address {
font-size: 24rpx;
color: rgba(39, 40, 50, 0.4);
padding: 0 24rpx;
//
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
}
.map {
padding-top: 8rpx;
width: 464rpx;
height: 190rpx;
}
}
.voice {
// width: 200rpx;
min-width: 100rpx;
max-width: 440rpx;
}
.voice-img {
width: 36rpx;
height: 36rpx;
}
}
.msg-left {
flex-direction: row;
.feed-imgy{
display: flex;
flex-direction: column;
justify-content: center;
align-self: center;
margin-right: 0rpx;
width: 95rpx;
height: 75rpx;
}
.feed-img{
display: flex;
flex-direction: column;
justify-content: center;
align-self: center;
margin-right: 0rpx;
width: 75rpx;
height: 75rpx;
}
.msg-text {
margin-left: 16rpx;
background-color: #fff;
border-radius: 0rpx 20rpx 20rpx 20rpx;
}
.txtline{
display: flex;
flex-direction: row;
margin: 3rpx 0;
border-bottom:1rpx solid #ddd;
padding: 10rpx 0;
}
.ms-img {
margin-left: 16rpx;
}
.msg-video{
margin-left: 16rpx;
}
.msh-map {
margin-left: 16rpx;
border-radius: 0rpx 20rpx 20rpx 20rpx;
}
.msg-img {
margin: 0 0 0 20rpx;
}
.voice {
text-align: left;
display: flex;
}
.voice-img {
transform: rotate(180deg);
width: 36rpx;
height: 36rpx;
padding-bottom: 4rpx;
margin-right: 10rpx;
}
.voicel{
height: 32rpx;
width: 32rpx;
}
.bg {
background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAAAYCAYAAAAF6fiUAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MEM0NzgwODc1MDY0MTFFRjk1QjhFRUUxQjYyOUQ5NDQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MEM0NzgwODg1MDY0MTFFRjk1QjhFRUUxQjYyOUQ5NDQiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowQzQ3ODA4NTUwNjQxMUVGOTVCOEVFRTFCNjI5RDk0NCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowQzQ3ODA4NjUwNjQxMUVGOTVCOEVFRTFCNjI5RDk0NCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PqxjhsEAAANzSURBVHjazJlLaNRQFIaTVIcRQUELoggVKYIgQvGFr40giLMRBAtjXblwUSmIK1vBTQUREUFB8NGdGwUXgoIVFwq6EGSkOAguXKiUQQq6kKK0Gv+LJ+HkTpLJfYUc+DnJ3M436Tn3eeKHYeiZ2NDQkGfZfCj03Nka6DzUgqZMYa1WS45HzIf15C/xqmeuE7ATOs3up1zxRefslYSgggn465j/GLpJ13ehfS75SEIu36/AFCQ6wQHoBbTgIOBZfBGow9AvaIXBb8d89PYFFpcEn7e5GAG+wXfPQc+g91DNQQKy+A3oB1SnkWDMR9BrbG0oxLeVgNAgCeLhF6FN0CuLiS3CP07+BDTgko/kbHC9BugG6w20ja63QxNSYk0tj/8EatP1uOYuKMFHoCdYW09+kDKnT0Kz0KjGKChik9AsxPkz0FnWvtIgsar8y2wUBDp8BDrBR+zS+CP4PCgyApZDa6Eb+ELDQQJiPs3DkV2FOnQ9atDjVfkPyS+DduvykQQtfpAypM7A3aPbB0iC7bNCgi+dRW6RP2owDanyf0Lv6HqPKl+KTxcf8czlBxnz2gjcPGXtiIOdSRb/Ofmt1KY7DanyZ8gP2uIjMYX4eXPeNPm9jg5Eafwv7IS+rkT+N/Kry+bnJeA3+T5HCUjjhxa3oCr8UOM3rfDzEnCQ/Fu2Q7K5be3i0+IWWadEfj/572Xzg4zywhW4VWwhs128y+LvJ9+mxbEs/mbyn2zxafHtyU87B4yzPe1JgOZZ8x8LwU/waTGL7BT5RwZTkSq/Rge06NCmxJfi08Wn8kQmP20ErKc56xIvpQJUx72NBMR8L1kKbkIb6fq6FKDQIb9BI1v8by91+YiPFj+1GgpYP4I9x+593IcZ05VOEsScOMfuxUuMr/Sg4uHHWNtSjUqlCv81HZDuQ8OqfPFChl7CxHx8NsbiE/Px+XChBKiYhXL0IPUMsYB9lopiddpthI74O9i0sIXVbbT5CPIAi02Cj7a2y2KcrjXp4UXpdpfUtmihIJfHjxbQp5rBL8xPC77NXY2JXaOeOS1t3fooAa74t9loaNrgI8gd1vsL8f0KvpSPdj4u3wuLncxFuj4mbSWVTH4pz3aSMR9/k8mv4jthz3HwD7HgXDAJfkaHTPDzgl+VKahs+wjdgT54/0vUzvhUos61fwIMANiWariLn8/jAAAAAElFTkSuQmCC);
width: 32rpx;
height: 32rpx;
background-size: 400%;
}
}
.msg-right {
flex-direction: row-reverse;
.feed-imgy{
display: flex;
flex-direction: column;
justify-content: center;
align-self: center;
margin-right: 0rpx;
width: 95rpx;
height: 75rpx;
}
.feed-img{
display: flex;
flex-direction: column;
justify-content: center;
align-self: center;
margin-right: 0rpx;
width: 75rpx;
height: 75rpx;
}
.msg-text {
margin-right: 16rpx;
background-color: #89965f;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
font-size: 32rpx;
color: #FFFFFF;
line-height: 48rpx;
border-radius: 20rpx 0rpx 20rpx 20rpx;
}
.ms-img {
margin-right: 16rpx;
}
.msg-img {
margin: 0 20rpx 0 0;
}
.msg-video{
margin: 0 20rpx 0 0;
}
.msh-map {
margin-left: 16rpx;
border-radius: 20rpx 0rpx 20rpx 20rpx;
}
.voice {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-end;
}
.voice-img {
display: block;
width: 36rpx;
height: 36rpx;
margin-left: 10rpx;
}
.voicel{
height: 32rpx;
width: 32rpx;
}
.bg {
background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAAAYCAYAAAAF6fiUAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6REJBQzQ1RjQ1MDYzMTFFRjk5QjZEQkI5MDlENzE3RTQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6REJBQzQ1RjU1MDYzMTFFRjk5QjZEQkI5MDlENzE3RTQiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpEQkFDNDVGMjUwNjMxMUVGOTlCNkRCQjkwOUQ3MTdFNCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpEQkFDNDVGMzUwNjMxMUVGOTlCNkRCQjkwOUQ3MTdFNCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pm5p+OoAAAKmSURBVHja1Jk/SBxBFMbdy6mHSEARNYIkhU0ICCEkEEynEYmkUEiTxmBtZZHCgGVsAgEhQozYaAo7G0GwjgemC1ZBgzbaKKnEIsb1HbwjH8PM7szdfEQffMzyzexvhn2zM/snSdO0wSOmRfdFc6JfDfGDzb++UUlAjmbTfzHi0T5UbP61Vl6DV3BxZggDYPNRyU1LQDtcnC9GXY/ojeh2HZ2z+ahbZD4lAZt6cQ4Mv1v0W+tm6+icza+qSOZTEvAAZudjo+5Q/SNRX40ds/m47JSIfFoC1nSQ24Y/r/4fUZdR1xHQMZtfVSOZH7LndPgmoEl0oQMdA/8OzNrXxjlzokvRgsfA2HxUM5nvUsmXbzt5CGZJE/jv1d832k8GPsmw+TgDEyLfd8PP5NsAM9q4bPi76r8FrwXgHzwHyOa7loDY/Kw73JtvAyzpCcvgtQLoKfgT6p0GDJDNtyWAwXepEMIvWF6O27Q8Aa8bjo/h+JGWWwEv32y+Ldh8jMsQvi0B1Y9DicUz/b9aNod8/SDzs/pk8V2Ry7cl4FTLTvCORBd63Av+Ny2HAwbF5tuCzXdFLt+WgD0t+8E7F/3Q40Hw17WuRbTqOSg23zbrGXyfyOdbNoYB2LBaLU8vx0b7UWj/0WOTYvNdGzGD76NMvu0OKGvWKjEO/ifY0KbB3xBN6eZ25jEr2HxXxOQnAf1m8x1ZW9SM7Rr+O8hmfx2z4jOZ71IsfoH9LegeDPSFUfcd3mSf1NjxXTI/64UsBj/av4WC47Y5EK3o8VejbkD0U1QUPa9xOTgk812bcSx+GrgM1fRLsvIl8Vxny4albqjOW5HNz+ubyY/2S/IZLBULhAGz+Tf+n7D5Ne8lYRBsPmXzjKWixyq1rOVD0Q7hZYXNz9oP/ntcCTAAHScbp0OSlTgAAAAASUVORK5CYII=);
width: 32rpx;
height: 32rpx;
background-size: 400%;
}
}
}
}
.voicePlay {
animation-name: voicePlay;
animation-duration: 1s;
animation-direction: normal;
animation-iteration-count: infinite;
animation-timing-function: steps(3);
}
@keyframes voicePlay {
0% {
background-position: 0;
}
100% {
background-position: 100%;
}
}
</style>