|
|
|
|
|
<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" 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 !== userid">
|
|
|
|
|
|
<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 selectable>{{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 class="message" v-if="item.type == 'product'">
|
|
|
|
|
|
|
|
|
|
|
|
<view v-if="item.send" class="msg-product" @click="gotoDetail(item)">
|
|
|
|
|
|
<view v-if="item.send.type==3" class="zx">
|
|
|
|
|
|
<view class="zxname">订单咨询</view>
|
|
|
|
|
|
<view class="zxview">查看订单</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="msg-con">
|
|
|
|
|
|
<image class="img" :src="item.send.pic" mode="aspectFit"></image>
|
|
|
|
|
|
<view class="info">
|
|
|
|
|
|
<view class="name">
|
|
|
|
|
|
<text class="ntxt">{{item.send.name}}</text>
|
|
|
|
|
|
<text v-if="item.send.spData" v-for="(value, key) in item.send.spData" :key="key" class="txt">
|
|
|
|
|
|
{{ key }}: {{ value }}
|
|
|
|
|
|
</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="xq">
|
|
|
|
|
|
<view class="list">
|
|
|
|
|
|
<view v-if="item.send.type==3" class="ord">
|
|
|
|
|
|
购买金额:¥ <text style="font-size: 30rpx;">{{item.send.price}}</text>{{(item.send.unit?'/'+item.send.unit:'')}}
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view v-else class="price">
|
|
|
|
|
|
¥{{item.send.price+(item.send.unit?'/'+item.send.unit:'')}}
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view v-if="item.send.quantity" class="qty">
|
|
|
|
|
|
{{item.send.quantity?'共('+item.send.quantity+(item.send.unit?item.send.unit:'件')+')':''}}
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<div v-if="item.send.spData" v-for="(value, key) in item.send.spData" :key="key" class="qty">
|
|
|
|
|
|
{{ key }}: {{ value }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<button class="btn" type="primary" v-if="item.send.type==1">去购买</button>
|
|
|
|
|
|
<button class="btn" type="primary" v-if="item.send.type==2">去购买</button>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="msg-m msg-right" v-if="item.fromuser == userid">
|
|
|
|
|
|
<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 v-if="item.type == 'txt'" class="message">
|
|
|
|
|
|
<view class="msg-text">
|
|
|
|
|
|
<text selectable>{{item.content}}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view v-if="item.type == 'image'" @tap="previewImg(item.content)" class="message">
|
|
|
|
|
|
<image :src="item.content" class="msg-img" mode="widthFix"></image>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view v-if="item.type == 'video'" class="messagevideo">
|
|
|
|
|
|
<!-- 视频 -->
|
|
|
|
|
|
<myVideo :videoUrl="item.content"></myVideo>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view v-if="item.type == 'audio'" @click="playVoice(item.content,item.ifaudio,index)" class="message">
|
|
|
|
|
|
<!-- 音频 -->
|
|
|
|
|
|
<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 v-if="item.type == 'product'" class="message" >
|
|
|
|
|
|
<view v-if="item.send" class="msg-product" @click="gotoDetail(item)">
|
|
|
|
|
|
<view v-if="item.send.type==3" class="zx">
|
|
|
|
|
|
<view class="zxname">订单咨询</view>
|
|
|
|
|
|
<view class="zxview">查看订单</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="msg-con">
|
|
|
|
|
|
<image class="img" :src="item.send.pic" mode="aspectFit"></image>
|
|
|
|
|
|
<view class="info">
|
|
|
|
|
|
<view class="name">
|
|
|
|
|
|
<text class="ntxt">{{item.send.name}}</text>
|
|
|
|
|
|
<text v-if="item.send.spData" v-for="(value, key) in item.send.spData" :key="key" class="txt">
|
|
|
|
|
|
{{ key }}: {{ value }}
|
|
|
|
|
|
</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="xq">
|
|
|
|
|
|
<view class="list">
|
|
|
|
|
|
<view v-if="item.send.type==3" class="ord">
|
|
|
|
|
|
购买金额:¥ <text style="font-size: 30rpx;">{{item.send.price}}</text>{{(item.send.unit?'/'+item.send.unit:'')}}
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view v-else class="price">
|
|
|
|
|
|
¥{{item.send.price+(item.send.unit?'/'+item.send.unit:'')}}
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="qty">
|
|
|
|
|
|
{{item.send.quantity?'共('+item.send.quantity+(item.send.unit?item.send.unit:'件')+')':''}}
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<button class="btn" type="primary" v-if="item.send.type==1">去购买</button>
|
|
|
|
|
|
<button class="btn" type="primary" v-if="item.send.type==2">去购买</button>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</scroll-view>
|
|
|
|
|
|
<view class="popup" v-if="ifsend&&sendinfo">
|
|
|
|
|
|
<view class="tipcon" click="gotoXQ()">
|
|
|
|
|
|
<image class="img" :src="sendinfo.pic" mode="aspectFit"></image>
|
|
|
|
|
|
<view class="info">
|
|
|
|
|
|
<view class="name">
|
|
|
|
|
|
<text class="ntxt">{{sendinfo.name}}</text>
|
|
|
|
|
|
<text v-if="sendinfo.spData" v-for="(value, key) in sendinfo.spData" :key="key" class="txt">
|
|
|
|
|
|
{{ key }}: {{ value }}
|
|
|
|
|
|
</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="xq">
|
|
|
|
|
|
<view class="list">
|
|
|
|
|
|
<view v-if="sendinfo.type==3" class="ord">
|
|
|
|
|
|
购买金额:¥ <text style="font-size: 30rpx;">{{sendinfo.price}}</text>{{(sendinfo.unit?'/'+sendinfo.unit:'')}}
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view v-else class="price">
|
|
|
|
|
|
¥{{sendinfo.price+(sendinfo.unit?'/'+sendinfo.unit:'')}}
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="qty">
|
|
|
|
|
|
{{sendinfo.quantity?'共('+sendinfo.quantity+(sendinfo.unit?sendinfo.unit:'件')+')':''}}
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<button class="btn" type="primary" v-if="sendinfo.type==1" @click="sendServer()">发送商品</button>
|
|
|
|
|
|
<button class="btn" type="primary" v-if="sendinfo.type==2" @click="sendServer()">发送课程</button>
|
|
|
|
|
|
<button class="btn" type="primary" v-if="sendinfo.type==3" @click="sendServer()">发送订单</button>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="close">
|
|
|
|
|
|
<uni-icons type="closeempty" color="#bebdbd" size="16" @click="close()" ></uni-icons>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<submit @inputs="inputs" @heights="heights"></submit>
|
|
|
|
|
|
<u-toast ref="uToast" />
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 普通弹窗 -->
|
|
|
|
|
|
<uni-popup ref="popup" background-color="#fff">
|
|
|
|
|
|
<view class="popup-content" :class="{ 'popup-height': 'right' }">
|
|
|
|
|
|
<view class="example">
|
|
|
|
|
|
<view class="order">
|
|
|
|
|
|
<view class="chatlist">
|
|
|
|
|
|
<view class="chatcell">
|
|
|
|
|
|
<image class="user-img" :src="info.teacherimg||'/static/image/jltx.png'"></image>
|
|
|
|
|
|
<text class="user-name">{{info.teachername||"教练"}}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="chatcell">
|
|
|
|
|
|
<image class="user-img" :src="info.friendimg||'/static/image/kfr.png'"></image>
|
|
|
|
|
|
<text class="user-name">{{info.friendname||"客服"}}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="chatcell">
|
|
|
|
|
|
<image class="user-img" :src="info.headImage||'/static/image/mr.png'"></image>
|
|
|
|
|
|
<text class="user-name">{{info.showNickName||"咨询用户"}}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="order">
|
|
|
|
|
|
<view class="lcon">
|
|
|
|
|
|
<view class="lhtxt">群聊名称</view>
|
|
|
|
|
|
<view class="ltxt">{{info.name||'未设置'}}</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="lcon">
|
|
|
|
|
|
<view class="lhtxt">群公告</view>
|
|
|
|
|
|
<view class="ltxt">{{info.notice||'未设置'}}</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="lcon">
|
|
|
|
|
|
<view class="lhtxt">备注</view>
|
|
|
|
|
|
<view class="ltxt">{{info.reason?info.reason:'无'}}</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="lcon">
|
|
|
|
|
|
<view class="lhtxt">在本群昵称</view>
|
|
|
|
|
|
<view class="ltxt">{{userName?userName:''}}</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</uni-popup>
|
|
|
|
|
|
|
|
|
|
|
|
</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,
|
|
|
|
|
|
userName: "",
|
|
|
|
|
|
userid: "",
|
|
|
|
|
|
userheadimg: "",
|
|
|
|
|
|
info:{
|
|
|
|
|
|
// chatId: chatid,
|
|
|
|
|
|
// chatName: data.name,
|
|
|
|
|
|
// chatAvatar: data.headImage,
|
|
|
|
|
|
// chatTime: timestamp,
|
|
|
|
|
|
// userid: data.ownerId,
|
|
|
|
|
|
// friendId: data.customerService, // 客服userid
|
|
|
|
|
|
// teacherId: data.instructor, // 教练userid
|
|
|
|
|
|
// minId: "", // 已读消息的最大id
|
|
|
|
|
|
// sort:"groupchat", // privatechat 私聊 groupchat 群聊
|
|
|
|
|
|
// from:"yh", // yh 用户咨询进入聊天框,message 从消息进入聊天框
|
|
|
|
|
|
// notice: data.notice,
|
|
|
|
|
|
// remarkNickName: data.remarkNickName,
|
|
|
|
|
|
// showNickName: data.showNickName,
|
|
|
|
|
|
// showGroupName: data.showGroupName,
|
|
|
|
|
|
// remarkGroupName: data.remarkGroupName,
|
|
|
|
|
|
// reason: data.reason,
|
|
|
|
|
|
// customerService: data.customerService,
|
|
|
|
|
|
// instructor: data.instructor,
|
|
|
|
|
|
// productId: data.productId,
|
|
|
|
|
|
// productName: data.productName,
|
|
|
|
|
|
// sendinfo:{
|
|
|
|
|
|
// type:1,// 1 商品,2 课程,3订单
|
|
|
|
|
|
// id:this.product.id,
|
|
|
|
|
|
// name:this.product.name,
|
|
|
|
|
|
// pic:this.product.pic,
|
|
|
|
|
|
// price:this.product.price,
|
|
|
|
|
|
// unit: this.product.unit,
|
|
|
|
|
|
// brandName:this.product.brandName,
|
|
|
|
|
|
// isCourse:this.product.isCourse
|
|
|
|
|
|
// }
|
|
|
|
|
|
},// 会话基本信息
|
|
|
|
|
|
imgurl:"",// uni.$http.baseUrl,
|
|
|
|
|
|
iftop:true,
|
|
|
|
|
|
msg: [], // 排序用,暂不使用
|
|
|
|
|
|
// 反转数据接收
|
|
|
|
|
|
unshiftmsg: [
|
|
|
|
|
|
// {
|
|
|
|
|
|
// fromuser: "11",
|
|
|
|
|
|
// fromname: "Madeline 老师 (女)",
|
|
|
|
|
|
// fromtime:'2025-06-20 10:00:00',
|
|
|
|
|
|
// headimg:require("@/static/image/i1.png"),
|
|
|
|
|
|
// content:'Hi,xxx,我是普拉提教练小a,周日上午10点的课您可以准时参加吧?',
|
|
|
|
|
|
// type:'txt'
|
|
|
|
|
|
// },
|
|
|
|
|
|
], // chatrurn
|
|
|
|
|
|
imgMsg: [],
|
|
|
|
|
|
scrollToView: '',
|
|
|
|
|
|
oldTime: new Date(),
|
|
|
|
|
|
inputh: '90',
|
|
|
|
|
|
ifaudio:false, // 是否音频
|
|
|
|
|
|
socketTask: null, // WebSocket实例
|
|
|
|
|
|
isConnected: false, // WebSocket连接状态
|
|
|
|
|
|
heartbeatInterval: null, // 心跳包20秒连接一次
|
|
|
|
|
|
heartbeatTimeout: 20000, // 心跳间隔时间,例如每20秒发送一次
|
|
|
|
|
|
// 是否需要发送 商品,课程,订单
|
|
|
|
|
|
ifsend: false,
|
|
|
|
|
|
sendinfo:{
|
|
|
|
|
|
// type:1,// 1 商品,2 课程,3订单
|
|
|
|
|
|
// id:63,
|
|
|
|
|
|
// orderId:"6455194061326336",
|
|
|
|
|
|
// name:"零基础教练培训",
|
|
|
|
|
|
// pic:"/static/image/i1.png",
|
|
|
|
|
|
// price:1000,
|
|
|
|
|
|
// unit: "元",
|
|
|
|
|
|
// brandName: "yoga",
|
|
|
|
|
|
// isCourse: 0,
|
|
|
|
|
|
// quantity:1,
|
|
|
|
|
|
// spData:{"颜色":"绿","尺寸":"80"}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
onLoad(options) {
|
|
|
|
|
|
var user = myCache('user');
|
|
|
|
|
|
// 本人聊天信息
|
|
|
|
|
|
this.userName=user.nickName?user.nickName:"";
|
|
|
|
|
|
this.userid=user.userid?user.userid:"";
|
|
|
|
|
|
this.userheadimg=user.avatar?user.avatar:require("@/static/image/girl.png");
|
|
|
|
|
|
if(options.data){
|
|
|
|
|
|
// 会话信息
|
|
|
|
|
|
this.info=JSON.parse(decodeURIComponent(options.data));
|
|
|
|
|
|
console.log("chat",this.info)
|
|
|
|
|
|
// 会话标题
|
|
|
|
|
|
var title = this.info.showGroupName;
|
|
|
|
|
|
uni.setNavigationBarTitle({
|
|
|
|
|
|
title: title,
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if(this.info.sendinfo){
|
|
|
|
|
|
this.ifsend=true;
|
|
|
|
|
|
this.sendinfo=this.info.sendinfo;
|
|
|
|
|
|
this.$forceUpdate();
|
|
|
|
|
|
}
|
|
|
|
|
|
else{
|
|
|
|
|
|
this.ifsend=false;
|
|
|
|
|
|
this.sendinfo=null;
|
|
|
|
|
|
this.$forceUpdate();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 先获取聊天记录缓存
|
|
|
|
|
|
this.getchatstore();
|
|
|
|
|
|
|
|
|
|
|
|
// 获取客服 和 教练 头像和名称
|
|
|
|
|
|
this.getrwinfo();
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
onShow() {
|
|
|
|
|
|
// 跳转到最后一条数据 与前面的:id进行对照
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
console.log("onShow")
|
|
|
|
|
|
this.screendo(this.unshiftmsg.length - 1);
|
|
|
|
|
|
}, 100);
|
|
|
|
|
|
|
|
|
|
|
|
// 如果心跳包在发送,先停止,再启动
|
|
|
|
|
|
if(this.heartbeatInterval){
|
|
|
|
|
|
clearInterval(this.heartbeatInterval); // 停止心跳包发送
|
|
|
|
|
|
}
|
|
|
|
|
|
// socket接收实时消息
|
|
|
|
|
|
this.socketinit();
|
|
|
|
|
|
},
|
|
|
|
|
|
onBackPress(options) {
|
|
|
|
|
|
if (options.from === 'backbutton') {
|
|
|
|
|
|
// 来自顶部菜单的返回按钮
|
|
|
|
|
|
// 在这里处理你的逻辑
|
|
|
|
|
|
console.log('返回按钮被点击');
|
|
|
|
|
|
this.closeWebSocket();
|
|
|
|
|
|
uni.onSocketClose(function (res) {
|
|
|
|
|
|
console.log('WebSocket 已关闭!');
|
|
|
|
|
|
});
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
//点击导航栏 buttons 时触发 添加任务
|
|
|
|
|
|
onNavigationBarButtonTap: async function(e) {
|
|
|
|
|
|
const index = e.index;
|
|
|
|
|
|
if (index === 0) {
|
|
|
|
|
|
this.$refs.popup.open("right");
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
beforeDestroy() {
|
|
|
|
|
|
console.log('界面关闭socket,beforeDestroy');
|
|
|
|
|
|
// 在组件销毁前,确保关闭 WebSocket 连接
|
|
|
|
|
|
this.closeWebSocket();
|
|
|
|
|
|
clearInterval(this.heartbeatInterval); // 停止心跳包发送
|
|
|
|
|
|
},
|
|
|
|
|
|
methods: {
|
|
|
|
|
|
// 获取客服和教练信息
|
|
|
|
|
|
async getrwinfo(){
|
|
|
|
|
|
// 客服
|
|
|
|
|
|
const {data: res} = await uni.$http.get("/api/friend/find/"+this.info.friendId);
|
|
|
|
|
|
if(res.data){
|
|
|
|
|
|
var data=res.data;
|
|
|
|
|
|
this.info.friendname=data.nickName?data.nickName:"客服";
|
|
|
|
|
|
this.info.friendimg=data.headImage?data.headImage:require("@/static/image/kfr.png");
|
|
|
|
|
|
this.$forceUpdate();
|
|
|
|
|
|
}
|
|
|
|
|
|
else{
|
|
|
|
|
|
this.info.friendname="客服";
|
|
|
|
|
|
this.info.friendimg=require("@/static/image/kfr.png");
|
|
|
|
|
|
this.$forceUpdate();
|
|
|
|
|
|
}
|
|
|
|
|
|
// 教练
|
|
|
|
|
|
const {data: res1} = await uni.$http.get("/api/friend/find/"+this.info.teacherId);
|
|
|
|
|
|
if(res1.data){
|
|
|
|
|
|
var data=res1.data;
|
|
|
|
|
|
this.info.teachername=data.nickName?data.nickName:"教练";
|
|
|
|
|
|
this.info.teacherimg=data.headImage?data.headImage:require("@/static/image/jltx.png");
|
|
|
|
|
|
this.$forceUpdate();
|
|
|
|
|
|
}
|
|
|
|
|
|
else{
|
|
|
|
|
|
this.info.teachername="教练";
|
|
|
|
|
|
this.info.teacherimg=require("@/static/image/jltx.png");
|
|
|
|
|
|
this.$forceUpdate();
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
gotoDetail(item){
|
|
|
|
|
|
var send=item.send;
|
|
|
|
|
|
if(send){
|
|
|
|
|
|
if(send.type==1){
|
|
|
|
|
|
// 商品
|
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
|
url: `/pages/product/detail?id=${send.id}`
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(send.type==2){
|
|
|
|
|
|
// 课程
|
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
|
url: `/pages/product/cdetail?id=${send.id}`
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(send.type==3){
|
|
|
|
|
|
// 订单详情
|
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
|
url: `/pages/order/orderinfo?id=${send.orderId}`
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
// 关闭框
|
|
|
|
|
|
close(){
|
|
|
|
|
|
this.ifsend=false;
|
|
|
|
|
|
this.$forceUpdate();
|
|
|
|
|
|
},
|
|
|
|
|
|
// 发送服务信息
|
|
|
|
|
|
sendServer(){
|
|
|
|
|
|
let data = {
|
|
|
|
|
|
"fromname": this.userName,
|
|
|
|
|
|
"fromuser": this.userid,
|
|
|
|
|
|
"headimg": this.userheadimg,
|
|
|
|
|
|
"toname": this.info.chatName, // 接收人
|
|
|
|
|
|
"touser": this.info.friendId, // 接收人姓名
|
|
|
|
|
|
"content": this.sendinfo.id,
|
|
|
|
|
|
"time": 0,
|
|
|
|
|
|
"ifaudio":false,
|
|
|
|
|
|
"fromtime": new Date(),
|
|
|
|
|
|
"type": "product", // this.sendinfo.type==3?"5":"6" // 5订单 6 商品
|
|
|
|
|
|
"send":this.sendinfo
|
|
|
|
|
|
};
|
|
|
|
|
|
this.unshiftmsg.push(data);
|
|
|
|
|
|
var rindex=this.unshiftmsg.length-1;
|
|
|
|
|
|
// 消息发送
|
|
|
|
|
|
this.onSendWS(data,rindex);
|
|
|
|
|
|
},
|
|
|
|
|
|
// 发送消息跳转详情
|
|
|
|
|
|
gotoXQ(){
|
|
|
|
|
|
if(this.sendinfo.type==1){
|
|
|
|
|
|
// 1 商品
|
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
|
url: `/pages/product/detail?id=`+this.sendinfo.id
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(this.sendinfo.type==2){
|
|
|
|
|
|
// 2 课程
|
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
|
url: `/pages/product/cdetail?id=`+this.sendinfo.id
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(this.sendinfo.type==3){
|
|
|
|
|
|
// 3订单
|
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
|
url: `/pages/order/orderinfo?id=`+this.sendinfo.id
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
// 获取聊天记录
|
|
|
|
|
|
getchatstore(){
|
|
|
|
|
|
var that=this;
|
|
|
|
|
|
try{
|
|
|
|
|
|
// 先获取会话缓存
|
|
|
|
|
|
var data= myCache(this.info.chatId)?myCache(this.info.chatId):[];
|
|
|
|
|
|
console.log("data",data)
|
|
|
|
|
|
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);
|
|
|
|
|
|
}
|
|
|
|
|
|
this.unshiftmsg.push(cell);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if(this.unshiftmsg.length<=0)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(this.info.from=="yh"){
|
|
|
|
|
|
// 首次会话自动信息
|
|
|
|
|
|
var cont = 'Hi,'+this.userName+',欢迎您!这是'+this.info.chatName+',请问有什么可以帮助您的呢?';
|
|
|
|
|
|
this.unshiftmsg = [
|
|
|
|
|
|
{
|
|
|
|
|
|
"fromname": this.info.chatName, // 发送人
|
|
|
|
|
|
"fromuser": this.info.friendId, // 发送人
|
|
|
|
|
|
"headimg": this.info.chatAvatar, // 发送人
|
|
|
|
|
|
"toname": this.userName, // 接收人
|
|
|
|
|
|
"touser": this.userid, // 接收人姓名
|
|
|
|
|
|
"content": cont,
|
|
|
|
|
|
"minId":this.info.minId,
|
|
|
|
|
|
"time": 0,
|
|
|
|
|
|
"ifaudio":false,
|
|
|
|
|
|
"fromtime": new Date(),
|
|
|
|
|
|
"type": 'txt'
|
|
|
|
|
|
}
|
|
|
|
|
|
];
|
|
|
|
|
|
this.$forceUpdate();
|
|
|
|
|
|
}
|
|
|
|
|
|
else{
|
|
|
|
|
|
// 首次会话自动信息
|
|
|
|
|
|
var cont = 'Hi,'+this.userName+',欢迎您!这是'+this.info.chatName+',请问有什么可以帮助您的呢?';
|
|
|
|
|
|
this.unshiftmsg = [
|
|
|
|
|
|
{
|
|
|
|
|
|
"fromname": this.info.chatName, // 发送人
|
|
|
|
|
|
"fromuser": this.info.friendId, // 发送人
|
|
|
|
|
|
"headimg": this.info.chatAvatar, // 发送人
|
|
|
|
|
|
"toname": this.userName, // 接收人
|
|
|
|
|
|
"touser": this.userid, // 接收人姓名
|
|
|
|
|
|
"content": cont,
|
|
|
|
|
|
"minId":this.info.minId,
|
|
|
|
|
|
"time": 0,
|
|
|
|
|
|
"ifaudio":false,
|
|
|
|
|
|
"fromtime": new Date(),
|
|
|
|
|
|
"type": 'txt'
|
|
|
|
|
|
}
|
|
|
|
|
|
];
|
|
|
|
|
|
this.$forceUpdate();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果是第一次接收消息没有缓存,且有minId则拉取离线消息
|
|
|
|
|
|
if(this.info.minId){
|
|
|
|
|
|
this.readUp(1);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else{
|
|
|
|
|
|
// 跳转到最后一条数据 与前面的:id进行对照
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
that.screendo(that.unshiftmsg.length-1);
|
|
|
|
|
|
}, 100);
|
|
|
|
|
|
// 已经有缓存,则拉取离线消息
|
|
|
|
|
|
this.info.minId=this.unshiftmsg[this.unshiftmsg.length-1].id;
|
|
|
|
|
|
this.$forceUpdate();
|
|
|
|
|
|
// 请求服务器加载加载拉取离线聊天记录
|
|
|
|
|
|
if(this.info.minId&&this.info.minId>0){
|
|
|
|
|
|
this.readUp(1);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
catch(err){
|
|
|
|
|
|
console.log(err);
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
// 定时心跳包
|
|
|
|
|
|
startHeartbeat() {
|
|
|
|
|
|
console.log("startHeartbeat")
|
|
|
|
|
|
this.heartbeatInterval = setInterval(() => {
|
|
|
|
|
|
if (this.socketTask) {
|
|
|
|
|
|
this.socketTask.send({
|
|
|
|
|
|
data: JSON.stringify({
|
|
|
|
|
|
'cmd': 1,//心跳
|
|
|
|
|
|
'data': {
|
|
|
|
|
|
'accessToken':uni.getStorageSync("token")
|
|
|
|
|
|
},
|
|
|
|
|
|
}) // 发送心跳包数据
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}, this.heartbeatTimeout);
|
|
|
|
|
|
},
|
|
|
|
|
|
// 关闭WebSocket连接
|
|
|
|
|
|
closeWebSocket() {
|
|
|
|
|
|
if (this.socket) {
|
|
|
|
|
|
uni.closeSocket();
|
|
|
|
|
|
this.socket = null;
|
|
|
|
|
|
this.isConnected = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
// ws接收消息
|
|
|
|
|
|
socketinit(){
|
|
|
|
|
|
var that = this;
|
|
|
|
|
|
if (!this.isConnected) {
|
|
|
|
|
|
this.socketTask=uni.connectSocket({
|
|
|
|
|
|
url: "wss://www.sanduolantoyoga.com/yoga-imserver/",
|
|
|
|
|
|
header: {
|
|
|
|
|
|
// 'content-type': 'application/json',
|
|
|
|
|
|
Authorization: uni.getStorageSync("token"),
|
|
|
|
|
|
},
|
|
|
|
|
|
success: (res) => {
|
|
|
|
|
|
console.log(res, 'socket连接成功success');
|
|
|
|
|
|
},
|
|
|
|
|
|
fail: (res) => {
|
|
|
|
|
|
console.log(res, 'socket连接失败')
|
|
|
|
|
|
},
|
|
|
|
|
|
complete: (res) => {
|
|
|
|
|
|
console.log(res,'socket连接成功complete');
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
uni.onSocketOpen(res => {
|
|
|
|
|
|
console.log('WebSocket连接已打开!');
|
|
|
|
|
|
that.isConnected = true;
|
|
|
|
|
|
// 发送登录心跳包
|
|
|
|
|
|
uni.sendSocketMessage({
|
|
|
|
|
|
data: JSON.stringify({
|
|
|
|
|
|
"cmd": 0,//心跳
|
|
|
|
|
|
"data": {
|
|
|
|
|
|
"accessToken":uni.getStorageSync("token"),
|
|
|
|
|
|
},
|
|
|
|
|
|
}), // 发送心跳包数据 // 发送的消息内容
|
|
|
|
|
|
success(re) {
|
|
|
|
|
|
console.log(re);
|
|
|
|
|
|
console.log('消息发送成功!')
|
|
|
|
|
|
},
|
|
|
|
|
|
fail(err) {
|
|
|
|
|
|
console.log(err);
|
|
|
|
|
|
console.log('消息发送失败!')
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
// 发送心跳包
|
|
|
|
|
|
this.startHeartbeat();
|
|
|
|
|
|
});
|
|
|
|
|
|
uni.onSocketMessage(res => {
|
|
|
|
|
|
console.log('收到WebSocket服务器消息:');
|
|
|
|
|
|
if(res.data){
|
|
|
|
|
|
let data=JSON.parse(res.data);
|
|
|
|
|
|
console.log(data);
|
|
|
|
|
|
if(data.cmd==4){
|
|
|
|
|
|
// 群聊
|
|
|
|
|
|
if(data.data){
|
|
|
|
|
|
data=data.data;
|
|
|
|
|
|
// 是此群聊发送来的消息
|
|
|
|
|
|
if(data.groupId==this.info.groupId){
|
|
|
|
|
|
// 加入聊天记录
|
|
|
|
|
|
// 消息类型 0:文字 1:图片 2:文件 3:语音 4:视频 5 订单 6 商品 10, "撤回" 11, "已读 "12, "消息已读回执 " 30,"加载中标记"
|
|
|
|
|
|
if(data.type==0||data.type==1||data.type==2||data.type==3||data.type==4||data.type==5||data.type==6){
|
|
|
|
|
|
this.getMsgSender(data)
|
|
|
|
|
|
}
|
|
|
|
|
|
else{
|
|
|
|
|
|
// 10, "撤回" 11, "已读 " 12, "消息已读回执 " 30,"加载中标记"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
uni.onSocketClose(res => {
|
|
|
|
|
|
console.log('WebSocket连接已关闭!');
|
|
|
|
|
|
that.isConnected = false;
|
|
|
|
|
|
clearInterval(that.heartbeatInterval); // 停止心跳包发送
|
|
|
|
|
|
});
|
|
|
|
|
|
uni.onSocketError(err => {
|
|
|
|
|
|
console.error('WebSocket连接打开失败,请检查:', err);
|
|
|
|
|
|
clearInterval(that.heartbeatInterval); // 停止心跳包发送
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
// 获取发送信息人信息
|
|
|
|
|
|
async getMsgSender(data){
|
|
|
|
|
|
var nickName="匿名";
|
|
|
|
|
|
var headImage="/static/image/girl.png";
|
|
|
|
|
|
const {data: res} = await uni.$http.get("/api/friend/find/"+data.sendId);
|
|
|
|
|
|
if(res.data){
|
|
|
|
|
|
// 客服头像和名称
|
|
|
|
|
|
nickName=res.data.nickName?res.data.nickName:"客服";
|
|
|
|
|
|
headImage=res.data.headImage?res.data.headImage:'/static/image/girl.png';
|
|
|
|
|
|
this.msgMerge(data,nickName,headImage);
|
|
|
|
|
|
}
|
|
|
|
|
|
else{
|
|
|
|
|
|
this.msgMerge(data,nickName,headImage);
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
async msgMerge(data,nickName,headImage){
|
|
|
|
|
|
|
|
|
|
|
|
if(data.type==0){
|
|
|
|
|
|
data.content=decodeURIComponent(data.content);
|
|
|
|
|
|
}
|
|
|
|
|
|
// 获取图片,为下面的预览做准备
|
|
|
|
|
|
if(data.type == 1) {
|
|
|
|
|
|
this.imgMsg.unshift(data.content)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let mdata = {
|
|
|
|
|
|
"fromname": nickName, // 发送消息人
|
|
|
|
|
|
"fromuser": data.sendId, // 发送消息人
|
|
|
|
|
|
"headimg": headImage,// 发送消息人头像
|
|
|
|
|
|
"toname": this.userName,
|
|
|
|
|
|
"touser": this.userid,
|
|
|
|
|
|
"content": data.content,
|
|
|
|
|
|
"readedCount": data.readedCount,
|
|
|
|
|
|
"time": data.type==3?5:0,
|
|
|
|
|
|
"ifaudio":data.type==3? true:false,
|
|
|
|
|
|
"fromtime": data.sendTime,
|
|
|
|
|
|
"type": data.type==0?'txt':(data.type==1?'image':data.type==3?'audio':(data.type==4?'video':(data.type==5?'order':(data.type==6?'product':'')))),
|
|
|
|
|
|
"id": data.id,
|
|
|
|
|
|
"sendId": data.sendId,
|
|
|
|
|
|
"atUserIds": data.atUserIds,
|
|
|
|
|
|
"send": data.type==6?await this.getProduct(data.content):(data.type==5?await this.getOrder(data.content):null)
|
|
|
|
|
|
};
|
|
|
|
|
|
this.unshiftmsg.push(mdata);
|
|
|
|
|
|
this.$forceUpdate();
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
this.screendo(this.unshiftmsg.length-1);
|
|
|
|
|
|
}, 100);
|
|
|
|
|
|
|
|
|
|
|
|
// 缓存聊天
|
|
|
|
|
|
myCache(this.info.chatId,this.unshiftmsg);
|
|
|
|
|
|
|
|
|
|
|
|
// 接收到socket后更新聊天列表记录
|
|
|
|
|
|
var chatlastinfo={
|
|
|
|
|
|
id: this.info.chatId,
|
|
|
|
|
|
groupId:this.info.groupId,
|
|
|
|
|
|
content:data.content,
|
|
|
|
|
|
type:data.type,
|
|
|
|
|
|
minId: data.id,
|
|
|
|
|
|
datetime: data.sendTime,
|
|
|
|
|
|
name: this.info.chatName,
|
|
|
|
|
|
userid: this.userid,
|
|
|
|
|
|
friendId: this.info.friendId, // 客服userid
|
|
|
|
|
|
teacherId: this.info.teacherId, // 教练userid
|
|
|
|
|
|
fromuser: this.info.friendId,
|
|
|
|
|
|
img: this.info.chatAvatar,
|
|
|
|
|
|
atUserIds: data.atUserIds,
|
|
|
|
|
|
sort:"groupchat"
|
|
|
|
|
|
};
|
|
|
|
|
|
this.updateChatList(chatlastinfo);
|
|
|
|
|
|
// 已读操作
|
|
|
|
|
|
this.readed();
|
|
|
|
|
|
},
|
|
|
|
|
|
async getProduct(id){
|
|
|
|
|
|
console.log("getProduct",id)
|
|
|
|
|
|
var rets=null;
|
|
|
|
|
|
const {data: res} = await uni.$http.post("/api/message/private/getProductForIm",{"productId":id});
|
|
|
|
|
|
if(res.data){
|
|
|
|
|
|
var data=res.data;
|
|
|
|
|
|
rets={
|
|
|
|
|
|
type:data.isCourse==0?1:2,// 1 商品,2 课程,3订单
|
|
|
|
|
|
id:data.id,
|
|
|
|
|
|
name:data.name,
|
|
|
|
|
|
pic:data.pic,
|
|
|
|
|
|
price:data.price,
|
|
|
|
|
|
unit: data.unit,
|
|
|
|
|
|
brandName:data.brandName,
|
|
|
|
|
|
isCourse:data.isCourse
|
|
|
|
|
|
}
|
|
|
|
|
|
console.log(rets)
|
|
|
|
|
|
return rets;
|
|
|
|
|
|
}
|
|
|
|
|
|
else{
|
|
|
|
|
|
return rets;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
async getOrder(id){
|
|
|
|
|
|
var rets=null;
|
|
|
|
|
|
const {data: res} = await uni.$http.post("/api/message/private/getOrderForIm",{"orderItemId":id});
|
|
|
|
|
|
if(res.data){
|
|
|
|
|
|
var data=res.data;
|
|
|
|
|
|
rets={
|
|
|
|
|
|
type:3,// 1 商品,2 课程,3订单
|
|
|
|
|
|
id:data.id,
|
|
|
|
|
|
orderId:data.orderId,
|
|
|
|
|
|
name:data.productName,
|
|
|
|
|
|
pic:data.pic?data.pic:'/static/image/nopic.png',
|
|
|
|
|
|
price:data.totalAmount,
|
|
|
|
|
|
quantity:data.quantity,
|
|
|
|
|
|
spData: data.spData? JSON.parse(data.spData):null
|
|
|
|
|
|
}
|
|
|
|
|
|
return rets;
|
|
|
|
|
|
}
|
|
|
|
|
|
else{
|
|
|
|
|
|
return rets;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
// 已读推送
|
|
|
|
|
|
async readed() {
|
|
|
|
|
|
const {data: res} = await uni.$http.put('/api/message/group/readed?groupId='+this.info.groupId);
|
|
|
|
|
|
},
|
|
|
|
|
|
// 已读推送
|
|
|
|
|
|
async readUp(ii) {
|
|
|
|
|
|
const {data: res} = await uni.$http.put('/api/message/group/readed?groupId='+this.info.groupId);
|
|
|
|
|
|
this.getList(ii);
|
|
|
|
|
|
},
|
|
|
|
|
|
// 加载对话
|
|
|
|
|
|
async getList(ii) {
|
|
|
|
|
|
var that=this;
|
|
|
|
|
|
const {data: res} = await uni.$http.get('/api/message/group/pullOfflineMessage',{minId: this.info.minId});
|
|
|
|
|
|
this.triggered = false;
|
|
|
|
|
|
if(res.data&&res.data.length>0){
|
|
|
|
|
|
const gotonum=res.data.length;
|
|
|
|
|
|
var type=0;
|
|
|
|
|
|
res.data.forEach((cell,i)=>{
|
|
|
|
|
|
type=cell.type;
|
|
|
|
|
|
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 == 1) {
|
|
|
|
|
|
this.imgMsg.unshift(cell.content)
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(cell.type==0){
|
|
|
|
|
|
cell.content=decodeURIComponent(cell.content);
|
|
|
|
|
|
}
|
|
|
|
|
|
// // 消息类型 0:文字 1:图片 2:文件 3:语音 4:视频 5 订单 6 商品 10, "撤回" 11, "已读 "12, "消息已读回执 " 30,"加载中标记"
|
|
|
|
|
|
let mdata = {
|
|
|
|
|
|
"fromname": this.userName,
|
|
|
|
|
|
"fromuser": this.userid,
|
|
|
|
|
|
"headimg": cell.headImage?cell.headImage:'/static/image/kfr.png',
|
|
|
|
|
|
"toname": cell.sendNickName, // 接收人
|
|
|
|
|
|
"touser": cell.sendId, // 接收人姓名
|
|
|
|
|
|
"content": cell.content,
|
|
|
|
|
|
"readedCount": cell.readedCount,
|
|
|
|
|
|
"time": cell.type==3?5:0,
|
|
|
|
|
|
"ifaudio":cell.type==3? true:false,
|
|
|
|
|
|
"fromtime": cell.sendTime,
|
|
|
|
|
|
"type": data.type==0?'txt':(data.type==1?'image':data.type==3?'audio':(data.type==4?'video':(data.type==5?'order':(data.type==6?'product':'')))),
|
|
|
|
|
|
"id": cell.id,
|
|
|
|
|
|
"sendId": cell.sendId,
|
|
|
|
|
|
"atUserIds": data.atUserIds,
|
|
|
|
|
|
};
|
|
|
|
|
|
this.unshiftmsg.unshift(mdata);
|
|
|
|
|
|
});
|
|
|
|
|
|
if(ii==2){
|
|
|
|
|
|
// 跳转到加载数据的第一条 与前面的:id进行对照
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
that.screendo(gotonum -1);
|
|
|
|
|
|
}, 100);
|
|
|
|
|
|
}
|
|
|
|
|
|
else{
|
|
|
|
|
|
// 跳转到最后一条数据 与前面的:id进行对照
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
that.screendo(that.unshiftmsg.length-1);
|
|
|
|
|
|
}, 100);
|
|
|
|
|
|
}
|
|
|
|
|
|
// 缓存聊天
|
|
|
|
|
|
myCache(this.info.chatId,this.unshiftmsg);
|
|
|
|
|
|
this.info.minId=this.unshiftmsg[this.unshiftmsg.length-1].id;
|
|
|
|
|
|
this.$forceUpdate();
|
|
|
|
|
|
|
|
|
|
|
|
// 离线加载后更新聊天列表记录
|
|
|
|
|
|
var chatlastinfo={
|
|
|
|
|
|
id: this.info.chatId,
|
|
|
|
|
|
groupId:this.info.groupId,
|
|
|
|
|
|
content:this.unshiftmsg[this.unshiftmsg.length-1].content,
|
|
|
|
|
|
type: type,
|
|
|
|
|
|
minId: this.unshiftmsg[this.unshiftmsg.length-1].id,
|
|
|
|
|
|
datetime: this.unshiftmsg[this.unshiftmsg.length-1].sendTime,
|
|
|
|
|
|
name: this.info.chatName,
|
|
|
|
|
|
userid: this.userid,
|
|
|
|
|
|
friendId: this.info.friendId, // 客服userid
|
|
|
|
|
|
teacherId: this.info.teacherId, // 教练userid
|
|
|
|
|
|
fromuser: this.unshiftmsg[this.unshiftmsg.length-1].touser,
|
|
|
|
|
|
img: this.unshiftmsg[this.unshiftmsg.length-1].headimg,
|
|
|
|
|
|
sort:"groupchat"
|
|
|
|
|
|
};
|
|
|
|
|
|
this.updateChatList(chatlastinfo);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
screendo(scrindex){
|
|
|
|
|
|
this.scrollToView = '';
|
|
|
|
|
|
// 跳转到最后一条数据 与前面的:id进行对照
|
|
|
|
|
|
this.$nextTick(function() {
|
|
|
|
|
|
this.scrollToView = 'msg' + scrindex
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
// 自定义下拉刷新控件被下拉
|
|
|
|
|
|
onPulling(e) {
|
|
|
|
|
|
var that=this;
|
|
|
|
|
|
if (!this.triggered) {
|
|
|
|
|
|
//下拉刷新,先变true再变false才能关闭
|
|
|
|
|
|
this.triggered = true;
|
|
|
|
|
|
//关掉圈圈,需要先执行完刷新操作
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
that.triggered = false;
|
|
|
|
|
|
}, 2000);
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
// 自定义下拉刷新被触发
|
|
|
|
|
|
onRefresh(event){
|
|
|
|
|
|
// 加载聊天记录
|
|
|
|
|
|
this.readUp(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;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
// 预览图片
|
|
|
|
|
|
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("inputs");
|
|
|
|
|
|
console.log(e);
|
|
|
|
|
|
var rindex=this.unshiftmsg.length-1;
|
|
|
|
|
|
|
|
|
|
|
|
let data = {
|
|
|
|
|
|
"fromname": this.userName,
|
|
|
|
|
|
"fromuser": this.userid,
|
|
|
|
|
|
"headimg": this.userheadimg,
|
|
|
|
|
|
"toname": this.info.chatName, // 接收人
|
|
|
|
|
|
"touser": this.info.friendId, // 接收人姓名
|
|
|
|
|
|
"content": e.type=='audio'?e.message.voice:e.message,
|
|
|
|
|
|
"time": e.type=='audio'?e.message.time:0,
|
|
|
|
|
|
"ifaudio":false,
|
|
|
|
|
|
"fromtime": new Date(),
|
|
|
|
|
|
"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.showLoading({
|
|
|
|
|
|
title: '图片上传中...'
|
|
|
|
|
|
});
|
|
|
|
|
|
uni.uploadFile({
|
|
|
|
|
|
url: uni.$http.baseUrl+"/api/image/upload",
|
|
|
|
|
|
filePath: e.message,
|
|
|
|
|
|
name: 'file',
|
|
|
|
|
|
header: {
|
|
|
|
|
|
'Authorization': token
|
|
|
|
|
|
},
|
|
|
|
|
|
success: res => {
|
|
|
|
|
|
console.log(res);
|
|
|
|
|
|
uni.hideLoading();
|
|
|
|
|
|
var rdata=JSON.parse(res.data);
|
|
|
|
|
|
if(rdata.data&&rdata.data.originUrl){
|
|
|
|
|
|
var url=rdata.data&&rdata.data.originUrl?rdata.data.originUrl:'';
|
|
|
|
|
|
data.content= url;
|
|
|
|
|
|
// 图片放入集合
|
|
|
|
|
|
if (e.type == 'image'&&url) {
|
|
|
|
|
|
this.imgMsg.push(url);
|
|
|
|
|
|
}
|
|
|
|
|
|
// 消息发送
|
|
|
|
|
|
this.onSendWS(data,rindex);
|
|
|
|
|
|
}
|
|
|
|
|
|
else{
|
|
|
|
|
|
this.$refs.uToast.show({
|
|
|
|
|
|
title:rdata.msg?rdata.msg:"图片上传失败...",
|
|
|
|
|
|
type: "error",
|
|
|
|
|
|
duration: 2000,
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
fail: res => {
|
|
|
|
|
|
uni.hideLoading();
|
|
|
|
|
|
console.log(res)
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(e.type=='audio'){
|
|
|
|
|
|
// 音频
|
|
|
|
|
|
// 先上传在传送消息
|
|
|
|
|
|
var token= uni.getStorageSync("token");
|
|
|
|
|
|
console.log('先上传在传送消息');
|
|
|
|
|
|
uni.showLoading({
|
|
|
|
|
|
title: '音频上传中...'
|
|
|
|
|
|
});
|
|
|
|
|
|
uni.uploadFile({
|
|
|
|
|
|
url: uni.$http.baseUrl+"/api/file/upload",
|
|
|
|
|
|
filePath: e.message.voice,
|
|
|
|
|
|
name: 'file',
|
|
|
|
|
|
header: {
|
|
|
|
|
|
'Authorization': token
|
|
|
|
|
|
},
|
|
|
|
|
|
success: res => {
|
|
|
|
|
|
console.log(res);
|
|
|
|
|
|
uni.hideLoading();
|
|
|
|
|
|
var rdata=JSON.parse(res.data);
|
|
|
|
|
|
console.log(rdata);
|
|
|
|
|
|
if(rdata.data&&rdata.data.originUrl){
|
|
|
|
|
|
var url=rdata.data&&rdata.data.originUrl?rdata.data.originUrl:'';
|
|
|
|
|
|
data.content= url;
|
|
|
|
|
|
console.log(data);
|
|
|
|
|
|
// 消息发送
|
|
|
|
|
|
this.onSendWS(data,rindex);
|
|
|
|
|
|
}
|
|
|
|
|
|
else{
|
|
|
|
|
|
this.$refs.uToast.show({
|
|
|
|
|
|
title:rdata.msg?rdata.msg:"音频上传失败...",
|
|
|
|
|
|
type: "error",
|
|
|
|
|
|
duration: 2000,
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
fail: res => {
|
|
|
|
|
|
uni.hideLoading();
|
|
|
|
|
|
console.log(res)
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(e.type=='video'){
|
|
|
|
|
|
// 视频
|
|
|
|
|
|
// 先上传在传送消息
|
|
|
|
|
|
var token= uni.getStorageSync("token");
|
|
|
|
|
|
console.log('先上传在传送消息');
|
|
|
|
|
|
uni.showLoading({
|
|
|
|
|
|
title: '视频上传中...'
|
|
|
|
|
|
});
|
|
|
|
|
|
uni.uploadFile({
|
|
|
|
|
|
url: uni.$http.baseUrl+"/api/file/upload",
|
|
|
|
|
|
filePath: e.message,
|
|
|
|
|
|
name: 'file',
|
|
|
|
|
|
header: {
|
|
|
|
|
|
'Authorization': token
|
|
|
|
|
|
},
|
|
|
|
|
|
success: res => {
|
|
|
|
|
|
uni.hideLoading();
|
|
|
|
|
|
console.log(res);
|
|
|
|
|
|
var rdata=JSON.parse(res.data);
|
|
|
|
|
|
console.log(rdata);
|
|
|
|
|
|
if(rdata.data){
|
|
|
|
|
|
var url=rdata.data;
|
|
|
|
|
|
data.content= url;
|
|
|
|
|
|
// 信息发送聊天框
|
|
|
|
|
|
this.unshiftmsg.push(data);
|
|
|
|
|
|
rindex=this.unshiftmsg.length-1;
|
|
|
|
|
|
// 跳转到最后一条数据 与前面的:id进行对照
|
|
|
|
|
|
this.screendo(this.unshiftmsg.length - 1);
|
|
|
|
|
|
// 消息发送
|
|
|
|
|
|
this.onSendWS(data,rindex);
|
|
|
|
|
|
}
|
|
|
|
|
|
else{
|
|
|
|
|
|
this.$refs.uToast.show({
|
|
|
|
|
|
title:rdata.msg?rdata.msg:"视频上传失败...",
|
|
|
|
|
|
type: "error",
|
|
|
|
|
|
duration: 2000,
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
fail: res => {
|
|
|
|
|
|
uni.hideLoading();
|
|
|
|
|
|
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);
|
|
|
|
|
|
}
|
|
|
|
|
|
var mtype= '0'; // 消息类型 0:文字 1:图片 2:文件 3:语音 4:视频 5订单 6 商品
|
|
|
|
|
|
if(msssagebf.type=='txt'){
|
|
|
|
|
|
mtype='0';
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(msssagebf.type=='image'){
|
|
|
|
|
|
mtype='1';
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(msssagebf.type=='audio'){
|
|
|
|
|
|
mtype='3';
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(msssagebf.type=='video'){
|
|
|
|
|
|
mtype='4';
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(msssagebf.type=='product'){
|
|
|
|
|
|
// 发送服务
|
|
|
|
|
|
if(this.sendinfo.type==3){
|
|
|
|
|
|
mtype='5';// 5订单 6 商品
|
|
|
|
|
|
}
|
|
|
|
|
|
else{
|
|
|
|
|
|
mtype='6';// 5订单 6 商品
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
var param={
|
|
|
|
|
|
"groupId": this.info.groupId,
|
|
|
|
|
|
"atUserIds": [this.info.friendId,this.info.teacherId],
|
|
|
|
|
|
"content": msssagebf.content,
|
|
|
|
|
|
"type": mtype
|
|
|
|
|
|
}
|
|
|
|
|
|
// 发送消息
|
|
|
|
|
|
const {data: res} = await uni.$http.post('/api/message/group/send',param);
|
|
|
|
|
|
if(res.data){
|
|
|
|
|
|
var rrdata=res.data;
|
|
|
|
|
|
if(rrdata.type==0){
|
|
|
|
|
|
rrdata.content=decodeURIComponent(rrdata.content);
|
|
|
|
|
|
}
|
|
|
|
|
|
this.unshiftmsg[this.unshiftmsg.length-1]["content"]=rrdata.content;
|
|
|
|
|
|
this.unshiftmsg[this.unshiftmsg.length-1]["id"]=rrdata.id;
|
|
|
|
|
|
this.unshiftmsg[this.unshiftmsg.length-1]["sendId"]=rrdata.sendId; // 发送人的id
|
|
|
|
|
|
this.unshiftmsg[this.unshiftmsg.length-1]["fromtime"]=rrdata.sendTime;
|
|
|
|
|
|
this.$forceUpdate();
|
|
|
|
|
|
// 缓存聊天
|
|
|
|
|
|
myCache(this.info.chatId,this.unshiftmsg);
|
|
|
|
|
|
// 更新聊天列表记录
|
|
|
|
|
|
var chatlastinfo={
|
|
|
|
|
|
id:this.info.chatId,
|
|
|
|
|
|
groupId:this.info.groupId,
|
|
|
|
|
|
content:rrdata.content,
|
|
|
|
|
|
type:mtype,
|
|
|
|
|
|
minId: rrdata.id,
|
|
|
|
|
|
datetime:rrdata.sendTime,
|
|
|
|
|
|
name: this.info.chatName,
|
|
|
|
|
|
userid: this.userid,
|
|
|
|
|
|
friendId: this.info.friendId, // 客服userid
|
|
|
|
|
|
teacherId: this.info.teacherId, // 教练userid
|
|
|
|
|
|
fromuser: this.info.friendId,
|
|
|
|
|
|
img: this.info.chatAvatar,
|
|
|
|
|
|
sort:"groupchat",
|
|
|
|
|
|
send:this.sendinfo
|
|
|
|
|
|
};
|
|
|
|
|
|
this.updateChatList(chatlastinfo);
|
|
|
|
|
|
|
|
|
|
|
|
if(mtype=='5'||mtype=='6'){
|
|
|
|
|
|
// 关闭发送服务窗口
|
|
|
|
|
|
this.ifsend=false;
|
|
|
|
|
|
this.sendinfo=null;
|
|
|
|
|
|
this.$forceUpdate();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else{
|
|
|
|
|
|
this.unshiftmsg.pop();
|
|
|
|
|
|
uni.showModal({
|
|
|
|
|
|
title: '提示',
|
|
|
|
|
|
content: res.msg?res.msg :'抱歉!信息发送失败..',
|
|
|
|
|
|
cancelText: '取消',
|
|
|
|
|
|
confirmText: '确定',
|
|
|
|
|
|
success: ress => {
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
updateChatList(chatlastinfo){
|
|
|
|
|
|
// 更新聊天列表记录
|
|
|
|
|
|
var chatlist = myCache("chatlist");
|
|
|
|
|
|
if(chatlist&&chatlist.length>0){
|
|
|
|
|
|
var ifexist=0;
|
|
|
|
|
|
chatlist.forEach((cell,i)=>{
|
|
|
|
|
|
if(cell.id==this.info.chatId){
|
|
|
|
|
|
ifexist++;
|
|
|
|
|
|
chatlist[i]=chatlastinfo;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
if(ifexist==0){
|
|
|
|
|
|
// 新增的添加
|
|
|
|
|
|
chatlist.unshift(chatlastinfo);
|
|
|
|
|
|
}
|
|
|
|
|
|
// 重新保存聊天记录
|
|
|
|
|
|
myCache("chatlist",chatlist);
|
|
|
|
|
|
}
|
|
|
|
|
|
else{
|
|
|
|
|
|
chatlist=[];
|
|
|
|
|
|
chatlist.push(chatlastinfo);
|
|
|
|
|
|
myCache("chatlist",chatlist);
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
//输入框高度
|
|
|
|
|
|
heights(e) {
|
|
|
|
|
|
this.inputh = e;
|
|
|
|
|
|
this.goBottom();
|
|
|
|
|
|
},
|
|
|
|
|
|
// 滚动到底部
|
|
|
|
|
|
goBottom() {
|
|
|
|
|
|
console.log("goBottom")
|
|
|
|
|
|
this.scrollToView = '';
|
|
|
|
|
|
this.screendo(this.unshiftmsg.length - 1);
|
|
|
|
|
|
},
|
|
|
|
|
|
handleImageError(e,index){
|
|
|
|
|
|
console.log(e,index);
|
|
|
|
|
|
this.unshiftmsg[index]["headimg"]= require("@/static/image/girl.png");
|
|
|
|
|
|
this.$forceUpdate();
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</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: 480rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.messagevideo {
|
|
|
|
|
|
max-width: 480rpx;
|
|
|
|
|
|
height: 300rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.msg-text {
|
|
|
|
|
|
font-size: 32rpx;
|
|
|
|
|
|
color: rgba(39, 40, 50, 1);
|
|
|
|
|
|
line-height: 44rpx;
|
|
|
|
|
|
padding: 18rpx 24rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.msg-img {
|
|
|
|
|
|
max-width: 400rpx;
|
|
|
|
|
|
border-radius: 20rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.msg-video{
|
|
|
|
|
|
width: 400rpx;
|
|
|
|
|
|
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: 400rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.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;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.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-product{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
background-color: #FFFFFF;
|
|
|
|
|
|
padding: 10rpx;
|
|
|
|
|
|
border-radius: 16rpx;
|
|
|
|
|
|
width: 480rpx;
|
|
|
|
|
|
margin-left: 12rpx;
|
|
|
|
|
|
.zx{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
margin: 10rpx;
|
|
|
|
|
|
.zxview{
|
|
|
|
|
|
color: darkgrey;
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
margin-right: 20rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.msg-con{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
padding: 10rpx;
|
|
|
|
|
|
border-radius: 16rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.img{
|
|
|
|
|
|
width: 120rpx;
|
|
|
|
|
|
height: 120rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.info{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
padding: 6rpx 8rpx;
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
margin-left: 10rpx;
|
|
|
|
|
|
background-color: #f4f4f4;
|
|
|
|
|
|
border-radius: 0 10rpx 10rpx 0;
|
|
|
|
|
|
.name{
|
|
|
|
|
|
width: 330rpx;
|
|
|
|
|
|
// white-space: nowrap; /* 防止文本换行 */
|
|
|
|
|
|
// overflow: hidden; /* 隐藏溢出的内容 */
|
|
|
|
|
|
// text-overflow: ellipsis; /* 溢出部分显示省略号 */
|
|
|
|
|
|
.txt{
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
color: darkgrey;
|
|
|
|
|
|
margin-left: 6rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.ntxt{
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
color: #000;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.sku{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
|
.txt{
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
color: darkgrey;
|
|
|
|
|
|
margin-right: 6rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.xq{
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
|
.list{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
.price{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
color: #ff007f;
|
|
|
|
|
|
}
|
|
|
|
|
|
.ord{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
color: #232323;
|
|
|
|
|
|
}
|
|
|
|
|
|
.qty{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
color: darkgrey;
|
|
|
|
|
|
margin-left: 8rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.btn{
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
font-family: PingFang SC-Medium, PingFang SC;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
color: #FCFCFD;
|
|
|
|
|
|
width: 110rpx;
|
|
|
|
|
|
height: 50rpx;
|
|
|
|
|
|
line-height: 50rpx;
|
|
|
|
|
|
background: #ff007f;
|
|
|
|
|
|
box-shadow: 0rpx 10rpx 30rpx 2rpx rgba(255,0,127,0.2);
|
|
|
|
|
|
border-radius: 60rpx;
|
|
|
|
|
|
opacity: 1;
|
|
|
|
|
|
margin-right: 10rpx;
|
|
|
|
|
|
margin-top: 10rpx;
|
|
|
|
|
|
margin-bottom: 10rpx;
|
|
|
|
|
|
padding-left:0 !important;
|
|
|
|
|
|
padding-right:0 !important;
|
|
|
|
|
|
&::after{
|
|
|
|
|
|
border:none;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.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: #00a89b;
|
|
|
|
|
|
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%;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.msg-product{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
background-color: #FFFFFF;
|
|
|
|
|
|
padding: 10rpx;
|
|
|
|
|
|
border-radius: 16rpx;
|
|
|
|
|
|
width: 480rpx;
|
|
|
|
|
|
margin-right: 12rpx;
|
|
|
|
|
|
.zx{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
margin: 10rpx;
|
|
|
|
|
|
.zxview{
|
|
|
|
|
|
color: darkgrey;
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
margin-right: 20rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.msg-con{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
padding: 10rpx;
|
|
|
|
|
|
border-radius: 16rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.img{
|
|
|
|
|
|
width: 120rpx;
|
|
|
|
|
|
height: 120rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.info{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
padding: 6rpx 8rpx;
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
margin-left: 10rpx;
|
|
|
|
|
|
background-color: #f4f4f4;
|
|
|
|
|
|
border-radius: 0 10rpx 10rpx 0;
|
|
|
|
|
|
.name{
|
|
|
|
|
|
width: 330rpx;
|
|
|
|
|
|
// white-space: nowrap; /* 防止文本换行 */
|
|
|
|
|
|
// overflow: hidden; /* 隐藏溢出的内容 */
|
|
|
|
|
|
// text-overflow: ellipsis; /* 溢出部分显示省略号 */
|
|
|
|
|
|
.txt{
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
color: darkgrey;
|
|
|
|
|
|
margin-left: 6rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.ntxt{
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
color: #000;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.sku{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
|
.txt{
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
color: darkgrey;
|
|
|
|
|
|
margin-right: 6rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.xq{
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
|
.list{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
.price{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
color: #ff007f;
|
|
|
|
|
|
}
|
|
|
|
|
|
.ord{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
color: #232323;
|
|
|
|
|
|
}
|
|
|
|
|
|
.qty{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
color: darkgrey;
|
|
|
|
|
|
margin-left: 8rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.btn{
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
font-family: PingFang SC-Medium, PingFang SC;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
color: #FCFCFD;
|
|
|
|
|
|
width: 110rpx;
|
|
|
|
|
|
height: 50rpx;
|
|
|
|
|
|
line-height: 50rpx;
|
|
|
|
|
|
background: #ff007f;
|
|
|
|
|
|
box-shadow: 0rpx 10rpx 30rpx 2rpx rgba(255,0,127,0.2);
|
|
|
|
|
|
border-radius: 60rpx;
|
|
|
|
|
|
opacity: 1;
|
|
|
|
|
|
margin-right: 10rpx;
|
|
|
|
|
|
margin-top: 10rpx;
|
|
|
|
|
|
margin-bottom: 10rpx;
|
|
|
|
|
|
padding-left:0 !important;
|
|
|
|
|
|
padding-right:0 !important;
|
|
|
|
|
|
&::after{
|
|
|
|
|
|
border:none;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.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%;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.popup{
|
|
|
|
|
|
position: fixed;
|
|
|
|
|
|
bottom: 180rpx;
|
|
|
|
|
|
/* #ifdef H5 */
|
|
|
|
|
|
bottom: 100rpx;
|
|
|
|
|
|
/* #endif */
|
|
|
|
|
|
left: 0;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
padding: 18rpx;
|
|
|
|
|
|
border-radius: 16rpx;
|
|
|
|
|
|
.tipcon{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
background-color: #FFFFFF;
|
|
|
|
|
|
padding: 16rpx;
|
|
|
|
|
|
border-radius: 16rpx;
|
|
|
|
|
|
.img{
|
|
|
|
|
|
width: 100rpx;
|
|
|
|
|
|
height: 100rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.info{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
margin-left: 16rpx;
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
.name{
|
|
|
|
|
|
width: 550rpx;
|
|
|
|
|
|
// white-space: nowrap; /* 防止文本换行 */
|
|
|
|
|
|
// overflow: hidden; /* 隐藏溢出的内容 */
|
|
|
|
|
|
// text-overflow: ellipsis; /* 溢出部分显示省略号 */
|
|
|
|
|
|
margin-right: 50rpx;
|
|
|
|
|
|
.txt{
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
color: darkgrey;
|
|
|
|
|
|
margin-left: 6rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.ntxt{
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
color: #000;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.sku{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
|
.txt{
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
color: darkgrey;
|
|
|
|
|
|
margin-right: 6rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.xq{
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
|
.list{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
align-items: flex-end;
|
|
|
|
|
|
}
|
|
|
|
|
|
.price{
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
color: #ff007f;
|
|
|
|
|
|
}
|
|
|
|
|
|
.ord{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
color: #232323;
|
|
|
|
|
|
}
|
|
|
|
|
|
.qty{
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
color: darkgrey;
|
|
|
|
|
|
margin-left: 6rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.btn{
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
font-family: PingFang SC-Medium, PingFang SC;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
color: #FCFCFD;
|
|
|
|
|
|
width: 150rpx;
|
|
|
|
|
|
height: 50rpx;
|
|
|
|
|
|
line-height: 50rpx;
|
|
|
|
|
|
background: #ff007f;
|
|
|
|
|
|
box-shadow: 0rpx 10rpx 30rpx 2rpx rgba(255,0,127,0.2);
|
|
|
|
|
|
border-radius: 10rpx;
|
|
|
|
|
|
opacity: 1;
|
|
|
|
|
|
margin-right: 10rpx;
|
|
|
|
|
|
padding-left:0 !important;
|
|
|
|
|
|
padding-right:0 !important;
|
|
|
|
|
|
&::after{
|
|
|
|
|
|
border:none;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.close{
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
top: 0;
|
|
|
|
|
|
right: 6rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.example {
|
|
|
|
|
|
width: 550rpx;
|
|
|
|
|
|
opacity: 1;
|
|
|
|
|
|
padding: 0;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
.order {
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
display: block;
|
|
|
|
|
|
background-color: #ffffff;
|
|
|
|
|
|
margin: 0 0 10rpx;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
padding: 0rpx 20rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.chatlist{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
|
padding: 20rpx 0 0 10rpx ;
|
|
|
|
|
|
}
|
|
|
|
|
|
.chatcell{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
min-width: 90rpx;
|
|
|
|
|
|
height: 150rpx;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
margin-right: 30rpx;
|
|
|
|
|
|
.user-img{
|
|
|
|
|
|
width: 90rpx;
|
|
|
|
|
|
height: 90rpx;
|
|
|
|
|
|
border-radius: 5rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.user-name{
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
color: #33383c;
|
|
|
|
|
|
margin-top: 16rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.lcon{
|
|
|
|
|
|
padding: 20rpx 10rpx;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
border-bottom: 1rpx solid #eee;
|
|
|
|
|
|
.lhtxt{
|
|
|
|
|
|
font-size: 30rpx;
|
|
|
|
|
|
color: #33383c;
|
|
|
|
|
|
line-height: 40rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.ltxt{
|
|
|
|
|
|
margin-top: 16rpx;
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
color: #888;
|
|
|
|
|
|
line-height: 30rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</style>
|