客户端app
This commit is contained in:
638
im-uniapp/wx/chatWindow/chat-item.vue
Normal file
638
im-uniapp/wx/chatWindow/chat-item.vue
Normal file
@@ -0,0 +1,638 @@
|
||||
<template>
|
||||
<!-- #ifdef APP-NVUE -->
|
||||
<cell>
|
||||
<!-- #endif -->
|
||||
<view class="zfb-tk-item" :class="[{ 'zfb-tk-msgleft': item.type == 1 }, { 'zfb-tk-msgright': item.type == 2 }, { 'zfb-tk-msgcenter': item.type == 3 }]">
|
||||
<openTool :class="[{ 'openTool-msgleft': item.type == 1 }, { 'openTool-msgright': item.type == 2 }]" :talkTo="talkTo" :ref="'toolx'+itemKey" :data="item" :itemKey="itemKey"></openTool>
|
||||
<image class="zfb-tk-avatar" @click="gochatOne(item)" v-if="item.type !== 3" :src="item.portrait" mode="aspectFill"></image>
|
||||
<view class="zfb-tk-item-contentx" @longpress="longpressItem($event,itemKey,item)">
|
||||
<view class="zfb-tk-item-contentx-c">
|
||||
<view class="zfb-tk-time-notsend wxfont fssb" @click="tryagin(item, itemKey)" v-if="item.sendtype && item.sendtype == 'error'"></view>
|
||||
<view class="zfb-tk-item-contentx-c-tool">
|
||||
<view class="zfb-tk-item-c" v-if="item.msgType == 'TEXT'">
|
||||
<text>{{ item.content }}</text>
|
||||
</view>
|
||||
<view class="zfb-tk-item-c" v-if="item.msgType == 'ALERT'">
|
||||
<text>{{ item.content }}</text>
|
||||
</view>
|
||||
<view class="zfb-tk-item-c-LOCATION" v-if="item.msgType == 'LOCATION'" @click="goMap(returnParse(item.content))">
|
||||
<view class="zfb-tk-item-c-LOCATION-name">{{ returnParse(item.content).name }}</view>
|
||||
<view class="zfb-tk-item-c-LOCATION-address">{{ returnParse(item.content).address }}</view>
|
||||
<image class="zfb-tk-item-c-LOCATION-map" src="../../static/wx/map.png" mode="aspectFit"></image>
|
||||
</view>
|
||||
<image class="zfb-tk-item-c-img" v-if="item.msgType == 'IMAGE'" :src="returnParse(item.content).url" mode="aspectFill" @click="$fc.previewImagesolo(returnParse(item.content).url)"></image>
|
||||
<view v-if="item.msgType == 'VOICE'" class="zfb-tk-item-c-VOICE">
|
||||
<view class="zfb-tk-item-c-VOICE-msg">
|
||||
<view class="zfb-tk-item-c-VOICE-tras" @click="showTrs=!showTrs">
|
||||
<text>转文字</text>
|
||||
<!-- <view class="zfb-tk-item-c-VOICE-tras-icon"></view> -->
|
||||
</view>
|
||||
<view class="zfb-tk-item-c" @click="playVOICE(returnParse(item.content).url)">
|
||||
<text>{{returnParse(item.content).time}}</text>
|
||||
<text class="wxfont yuyin" :class="{vmove:paused}"></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="item.msgType == 'TRTC_VOICE_END'" class="zfb-tk-item-c-TRTC_VOICE_END" @click="sendVoiceCall">
|
||||
<view class="zfb-tk-TRTC zfb-tk-item-c">
|
||||
<view class="wxfont yuyin3"></view>
|
||||
<text>语音通话 时长{{item.content}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="item.msgType == 'TRTC_VIDEO_END'" class="zfb-tk-item-c-TRTC_VIDEO_END" @click="sendVideoCall">
|
||||
<view class="zfb-tk-TRTC zfb-tk-item-c">
|
||||
<view class="wxfont shipin"></view>
|
||||
<text>视频通话 时长{{item.content}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="zfb-tk-item-c-video" v-if="item.msgType == 'VIDEO'" @click="openVideo(returnParse(item.content).videoUrl)">
|
||||
<image class="zfb-tk-item-c-img" :src="returnParse(item.content).url" mode="aspectFill"></image>
|
||||
<view class="zfb-tk-item-c-video-icon">
|
||||
<text class="wxfont bofang"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="zfb-tk-item-c-CARD" v-if="item.msgType == 'CARD'" @click="goAddfriend(returnParse(item.content))">
|
||||
<view class="zfb-tk-item-c-CARD-top">
|
||||
<image class="zfb-tk-item-c-CARD-top-img" :src="returnParse(item.content).avatar" mode=""></image>
|
||||
<view class="zfb-tk-item-c-CARD-top-content">
|
||||
<view class="zfb-tk-item-c-CARD-title">{{returnParse(item.content).name}}</view>
|
||||
<view class="zfb-tk-item-c-CARD-no">{{returnParse(item.content).chatNo}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="zfb-tk-item-c-CARD-card">推荐名片</view>
|
||||
</view>
|
||||
<view v-if="showTrs" class="zfb-tk-item-c-VOICE-tras-text">{{returnParse(item.content).text}}</view>
|
||||
<view class="zfb-tk-time" v-if="item.time">{{ timeDetia(item.time) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #ifdef APP-NVUE -->
|
||||
</cell>
|
||||
<!-- #endif -->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// #ifdef APP-PLUS
|
||||
const TUICalling = uni.requireNativePlugin("TUICallingUniPlugin-TUICallingModule");
|
||||
// #endif
|
||||
import openTool from './openTool.vue'
|
||||
export default {
|
||||
emits: ['tryagin','longpressItem'],
|
||||
name: 'chat-item',
|
||||
components:{
|
||||
openTool
|
||||
},
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
default: {}
|
||||
},
|
||||
talkTo: {
|
||||
type: Object,
|
||||
default: {}
|
||||
},
|
||||
itemKey: {
|
||||
type: Number
|
||||
},
|
||||
longTapItemKey: {
|
||||
type: [Number,String],
|
||||
default:''
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
longTapItemKey(v){
|
||||
if(this.itemKey==v){
|
||||
this.$refs['toolx'+v].showTab();
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
innerAudioContext:'',
|
||||
paused:false,
|
||||
showTrs:false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
sendVoiceCall(){
|
||||
//发起语音
|
||||
uni.showLoading({
|
||||
title:'发起语音通话'
|
||||
})
|
||||
var formdata={
|
||||
userId: this.talkTo.userId,
|
||||
msgType: "TRTC_VOICE_START",
|
||||
content: "TRTC_VOICE_START"
|
||||
}
|
||||
this.$http.request({
|
||||
url: '/chat/sendMsg',
|
||||
method: 'POST',
|
||||
data: JSON.stringify(formdata),
|
||||
success: (res) => {
|
||||
if(res.data.code=='200'){
|
||||
if(res.data.data.status!=='0'){
|
||||
uni.showToast({
|
||||
title:res.data.data.statusLabel,
|
||||
icon:'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
var userInfo=res.data.data.userInfo
|
||||
var data={
|
||||
userId:userInfo.userId,
|
||||
trtcId:userInfo.trtcId,
|
||||
nickName:userInfo.nickName,
|
||||
portrait:userInfo.portrait,
|
||||
startTime:new Date().getTime(),
|
||||
type:'audio'
|
||||
}
|
||||
uni.setStorage({
|
||||
key: 'call',
|
||||
data: JSON.stringify(data),
|
||||
success: function () {
|
||||
console.log('success');
|
||||
TUICalling.call({
|
||||
userID: userInfo.trtcId,
|
||||
type: 1
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
sendVideoCall(){
|
||||
//发起视频
|
||||
uni.showLoading({
|
||||
title:'发起视频通话'
|
||||
})
|
||||
var formdata={
|
||||
userId: this.talkTo.userId,
|
||||
msgType: "TRTC_VIDEO_START",
|
||||
content: "TRTC_VIDEO_START"
|
||||
}
|
||||
this.$http.request({
|
||||
url: '/chat/sendMsg',
|
||||
method: 'POST',
|
||||
data: JSON.stringify(formdata),
|
||||
success: (res) => {
|
||||
if(res.data.code=='200'){
|
||||
if(res.data.data.status!=='0'){
|
||||
uni.showToast({
|
||||
title:res.data.data.statusLabel,
|
||||
icon:'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
var userInfo=res.data.data.userInfo
|
||||
var data={
|
||||
userId:userInfo.userId,
|
||||
trtcId:userInfo.trtcId,
|
||||
nickName:userInfo.nickName,
|
||||
portrait:userInfo.portrait,
|
||||
startTime:new Date().getTime(),
|
||||
type:'video'
|
||||
}
|
||||
uni.setStorage({
|
||||
key: 'call',
|
||||
data: JSON.stringify(data),
|
||||
success: function () {
|
||||
console.log('success');
|
||||
TUICalling.call({
|
||||
userID: userInfo.trtcId,
|
||||
type: 2
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
goAddfriend(e){
|
||||
uni.navigateTo({
|
||||
url:'../personInfo/detail?param='+e.userId+'&source=2'
|
||||
})
|
||||
},
|
||||
openVideo(e){
|
||||
this.$fc.plusDownload({onlinePath:e}).then(res=>{
|
||||
this.$fc.plusOpenFile({filePath:res})
|
||||
})
|
||||
},
|
||||
playVOICE(url){
|
||||
this.showTrs=false
|
||||
if(this.paused){
|
||||
this.innerAudioContext.destroy()
|
||||
this.paused=!this.paused
|
||||
return
|
||||
}
|
||||
this.innerAudioContext = uni.createInnerAudioContext();
|
||||
// var url='https://www.w3school.com.cn/i/horse.ogg'
|
||||
this.innerAudioContext.sessionCategory='soloAmbient'
|
||||
this.innerAudioContext.src = url;
|
||||
this.innerAudioContext.play()
|
||||
|
||||
this.innerAudioContext.onPlay(() => {
|
||||
// console.log('播放')
|
||||
this.paused=true
|
||||
})
|
||||
this.innerAudioContext.onPause(() => {
|
||||
// console.log('暂停')
|
||||
this.paused=false
|
||||
this.innerAudioContext.destroy()
|
||||
})
|
||||
},
|
||||
goMap(e) {
|
||||
uni.openLocation({
|
||||
latitude: e.latitude,
|
||||
longitude: e.longitude,
|
||||
success: function() {}
|
||||
});
|
||||
},
|
||||
returnParse(txt) {
|
||||
return JSON.parse(txt);
|
||||
},
|
||||
tryagin(e, i) {
|
||||
this.$emit('tryagin', e, i);
|
||||
},
|
||||
gochatOne(e) {
|
||||
var source=e.windowType=="GROUP" ? '7' : '3'
|
||||
uni.navigateTo({
|
||||
url:'../personInfo/detail?param='+e.personId+'&source='+source
|
||||
})
|
||||
},
|
||||
longpressItem(e,i,v) {//长按回调
|
||||
console.log(e)
|
||||
this.$emit('longpressItem',e,i,v)
|
||||
if(this.itemKey==this.longTapItemKey){
|
||||
this.$refs['toolx'+this.itemKey].showTab();
|
||||
}
|
||||
},
|
||||
timeDetia: function(date) {
|
||||
var time;
|
||||
var d = new Date(date);
|
||||
var n = new Date();
|
||||
//获取时间戳
|
||||
var dd = d.getTime();
|
||||
var h = d.getHours();
|
||||
var m = d.getMinutes();
|
||||
var Y = d.getFullYear();
|
||||
var M = d.getMonth() + 1;
|
||||
var D = d.getDate();
|
||||
//现在时间
|
||||
var nn = n.getTime();
|
||||
var hh = n.getHours();
|
||||
var mm = n.getMinutes();
|
||||
var YY = n.getFullYear();
|
||||
var MM = n.getMonth() + 1;
|
||||
var DD = n.getDate();
|
||||
|
||||
if (D == DD && M == MM && Y == YY) {
|
||||
if (h < 10) {
|
||||
h = '0' + h;
|
||||
}
|
||||
if (m < 10) {
|
||||
m = '0' + m;
|
||||
}
|
||||
time = h + ':' + m;
|
||||
return time;
|
||||
} else if (D + 1 == DD && M == MM && Y == YY) {
|
||||
if (h < 10) {
|
||||
h = '0' + h;
|
||||
}
|
||||
if (m < 10) {
|
||||
m = '0' + m;
|
||||
}
|
||||
time = '昨天' + ' ' + h + ':' + m;
|
||||
return time;
|
||||
} else {
|
||||
if (M < 10) {
|
||||
M = '0' + M;
|
||||
}
|
||||
if (D < 10) {
|
||||
D = '0' + D;
|
||||
}
|
||||
if (h < 10) {
|
||||
h = '0' + h;
|
||||
}
|
||||
if (m < 10) {
|
||||
m = '0' + m;
|
||||
}
|
||||
time = Y + '年' + M + '月' + D + '日' + ' ' + h + ':' + m;
|
||||
return time;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$avatarsize: 80rpx;
|
||||
$border-radius: 12rpx;
|
||||
$textcolor: #fff;
|
||||
$descolor: #999;
|
||||
$leftbgcolor: #00aaff;
|
||||
$rightbgcolor: #4cd964;
|
||||
|
||||
.zfb-tk-item {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
flex-wrap: wrap;
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.zfb-tk-item .zfb-tk-item-c text {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.zfb-tk-msgleft,
|
||||
.zfb-tk-msgright {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.zfb-tk-msgleft {
|
||||
float: left;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.zfb-tk-item .zfb-tk-item-c::after {
|
||||
position: absolute;
|
||||
content: '';
|
||||
width: 14rpx;
|
||||
height: 14rpx;
|
||||
top: 34rpx;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.zfb-tk-msgleft .zfb-tk-item-c::after {
|
||||
background: $leftbgcolor;
|
||||
left: -7rpx;
|
||||
}
|
||||
|
||||
.zfb-tk-msgright .zfb-tk-item-c::after {
|
||||
background: $rightbgcolor;
|
||||
right: -7rpx;
|
||||
}
|
||||
|
||||
.zfb-tk-avatar {
|
||||
min-width: $avatarsize;
|
||||
width: $avatarsize;
|
||||
height: $avatarsize;
|
||||
border-radius: $border-radius;
|
||||
}
|
||||
|
||||
.zfb-tk-msgleft .zfb-tk-avatar {
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
|
||||
.zfb-tk-msgright .zfb-tk-avatar {
|
||||
margin-left: 12rpx;
|
||||
}
|
||||
|
||||
.zfb-tk-msgright {
|
||||
float: right;
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.zfb-tk-msgcenter {
|
||||
font-size: 28rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
float: left;
|
||||
width: 100%;
|
||||
color: $descolor;
|
||||
}
|
||||
|
||||
.zfb-tk-item-c {
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
border-radius: $border-radius;
|
||||
}
|
||||
|
||||
.zfb-tk-msgleft .zfb-tk-item-c,
|
||||
.zfb-tk-msgright .zfb-tk-item-c {
|
||||
min-height: $avatarsize;
|
||||
background: $leftbgcolor;
|
||||
color: $textcolor;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.zfb-tk-msgright .zfb-tk-item-c {
|
||||
background: $rightbgcolor;
|
||||
}
|
||||
|
||||
.zfb-tk-username {
|
||||
color: $descolor;
|
||||
}
|
||||
|
||||
.zfb-tk-time {
|
||||
font-size: 24rpx;
|
||||
text-align: center;
|
||||
color: $descolor;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.zfb-tk-msgright .zfb-tk-time {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.zfb-tk-msgleft .zfb-tk-time {
|
||||
text-align: left;
|
||||
}
|
||||
.zfb-tk-time-notsend {
|
||||
font-size: 64rpx;
|
||||
color: #fa5151;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
.zfb-tk-item-c-LOCATION {
|
||||
border: 1px #f6f6f6 solid;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 445rpx;
|
||||
border-radius: 12rpx;
|
||||
padding: 24rpx;
|
||||
}
|
||||
.zfb-tk-item-c-LOCATION-name {
|
||||
font-size: 28rpx;
|
||||
color: #101010;
|
||||
font-weight: bold;
|
||||
}
|
||||
.zfb-tk-item-c-LOCATION-address {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
.zfb-tk-item-c-LOCATION-map {
|
||||
background-color: #e5ffff;
|
||||
overflow: hidden;
|
||||
width: 445rpx;
|
||||
height: 150rpx;
|
||||
}
|
||||
.zfb-tk-item-c-img{
|
||||
border: 1px #eee solid;
|
||||
max-width: 310rpx;
|
||||
max-height: 450rpx;
|
||||
}
|
||||
.zfb-tk-item-c-video{
|
||||
position: relative;
|
||||
}
|
||||
.zfb-tk-item-c-video-icon{
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%,-50%);
|
||||
display: flex;flex-direction: row;justify-content: center;align-items: center;
|
||||
}
|
||||
.zfb-tk-item-c-video-icon text{
|
||||
font-size: 64rpx;
|
||||
color: #dddddd;
|
||||
text-shadow: 0px 0px 5px rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
.zfb-tk-item-c-VOICE{}
|
||||
.vmove{
|
||||
animation: scalev 1s linear infinite;
|
||||
transform: scale(1);
|
||||
}
|
||||
@keyframes scalev {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.3);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
.zfb-tk-item-c-VOICE-tras{
|
||||
display: flex;flex-direction: row;align-items: center;
|
||||
}
|
||||
.zfb-tk-item-c-VOICE-tras text{
|
||||
padding:6rpx 12rpx;
|
||||
font-size: 24rpx;
|
||||
background-color: #eee;
|
||||
border-radius: 12rpx;
|
||||
color: #bcbcbc;
|
||||
margin:0 12rpx;
|
||||
}
|
||||
.zfb-tk-item-c-VOICE-tras-icon{
|
||||
margin: 6rpx;
|
||||
width: 16rpx;
|
||||
height: 16rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #fa5151;
|
||||
position: relative;
|
||||
}
|
||||
.zfb-tk-item-c-VOICE-tras-text{
|
||||
width: 100%;
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
word-break: break-all;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
.zfb-tk-msgright .zfb-tk-item-c-VOICE-tras-text{
|
||||
text-align: right;
|
||||
}
|
||||
.zfb-tk-msgleft .zfb-tk-item-c-VOICE-tras-text{
|
||||
text-align: left;
|
||||
}
|
||||
.zfb-tk-msgleft .zfb-tk-item-c-VOICE-msg{
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
.zfb-tk-msgleft .zfb-tk-item-c-VOICE-tras{
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
.zfb-tk-item-c-VOICE-msg .zfb-tk-item-c{
|
||||
display: flex;flex-direction: row;align-items: center;
|
||||
}
|
||||
.zfb-tk-item-c-VOICE-msg{
|
||||
display: flex;flex-direction: row;align-items: center;
|
||||
}
|
||||
.zfb-tk-item-c-CARD{
|
||||
width: 440rpx;
|
||||
box-sizing: border-box;
|
||||
border: 1px #f6f6f6 solid;
|
||||
padding: 24rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
.zfb-tk-item-c-CARD-top{
|
||||
display: flex;flex-direction: row;align-items: center;
|
||||
}
|
||||
.zfb-tk-item-c-CARD-top-img{
|
||||
width: 80rpx;
|
||||
min-width: 80rpx;
|
||||
height: 80rpx;
|
||||
margin-right: 24rpx;
|
||||
border-radius: 6rpx;
|
||||
}
|
||||
.zfb-tk-item-c-CARD-top-content{
|
||||
overflow: hidden;
|
||||
display: flex;flex-direction: column;
|
||||
}
|
||||
.zfb-tk-item-c-CARD-title{
|
||||
color: #070707;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
.zfb-tk-item-c-CARD-no{
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.zfb-tk-item-c-CARD-card{
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
|
||||
.zfb-tk-item-contentx{
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-width: 544rpx;
|
||||
}
|
||||
.zfb-tk-item-contentx-name{
|
||||
color: #7C7C7E;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.zfb-tk-msgright .zfb-tk-item-contentx{
|
||||
align-items: flex-end;
|
||||
}
|
||||
.zfb-tk-msgleft .zfb-tk-item-contentx{
|
||||
align-items: flex-start;
|
||||
}
|
||||
.zfb-tk-item-contentx-c{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
}
|
||||
.zfb-tk-msgleft .zfb-tk-item-contentx-c{
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
.zfb-tk-msgright .zfb-tk-item-contentx-c{
|
||||
flex-direction: row;
|
||||
}
|
||||
.zfb-tk-TRTC{
|
||||
align-items: center;
|
||||
display: flex;flex-direction: row;
|
||||
}
|
||||
.zfb-tk-TRTC .wxfont{
|
||||
font-size: 42rpx;
|
||||
}
|
||||
.zfb-tk-item-contentx-c-tool{display: flex;flex-direction: column;}
|
||||
.zfb-tk-msgleft .zfb-tk-item-contentx-c-tool{
|
||||
align-items: flex-start;
|
||||
}
|
||||
.zfb-tk-msgright .zfb-tk-item-contentx-c-tool{
|
||||
align-items: flex-end;
|
||||
}
|
||||
</style>
|
||||
887
im-uniapp/wx/chatWindow/index.vue
Normal file
887
im-uniapp/wx/chatWindow/index.vue
Normal file
@@ -0,0 +1,887 @@
|
||||
<template>
|
||||
<view>
|
||||
<watermark></watermark>
|
||||
<uni-popup ref="popup" type="center">
|
||||
<view class="popsendCard" :style="'height:' + windowHeight + 'px'"><sendCard @click="sendCardclick"></sendCard></view>
|
||||
</uni-popup>
|
||||
<uni-popup ref="popupfavorites" type="center" background-color="#fff" style="background-color: #fff;">
|
||||
<scroll-view scroll-y :style="'height:' + windowHeight + 'px'"><favorites type="2" @clickitem="clickitem"></favorites></scroll-view>
|
||||
</uni-popup>
|
||||
<view class="zfb-tk-main">
|
||||
<uni-list class="zfb-tk-conent" :border="false" style="background: none;"><chatItem v-for="(v, index) in chatWindowData" :key="'key' + index" :talkTo="talkTo" :itemKey="index" :item="v" @tryagin="tryagin" @longpressItem="longpressItem" :longTapItemKey="longTapItemKey"></chatItem></uni-list>
|
||||
<view class="autodownView"></view>
|
||||
</view>
|
||||
<view :style="'height: ' + keyboardHeight + 'px'"></view>
|
||||
<view v-if="showtool || showEmojitool" :style="'height:558rpx'"></view>
|
||||
<view class="zfb-tk-send-tool" :style="'transform: translateY(-' + keyboardHeight + 'px)'">
|
||||
<view class="zfb-tk-send-tool-c">
|
||||
<view class="zfb-tk-send-tool-icon wxfont" @click="changeShowVice" :class="showVice ? 'jianpan' : 'yuyin2'"></view>
|
||||
<view class="zfb-tk-send-tool-vioce" v-if="showVice"><view class="zfb-tk-send-tool-vioce-item" @longpress="startRecord" @touchend="endRecord">按住说话</view></view>
|
||||
<view v-else class="zfb-tk-send-tool-input-box" @click="msgFocus = true"><textarea @focus="showtool = false" :focus="msgFocus" class="zfb-tk-send-tool-input" :adjust-position="false" v-model="msg" placeholder="" hold-keyboard confirm-type="send" @confirm="sendMsg(msg, 'TEXT')" :maxlength="-1" auto-height /></view>
|
||||
<view @click="changeEmojiTool" class="zfb-tk-send-tool-more wxfont biaoqing"></view>
|
||||
<view v-if="msg !== ''" class="zfb-tk-send-tool-text" @touchend.prevent="sendMsg(msg, 'TEXT')" :style="{ background: msg !== '' ? '#1BC418' : '#F7F7F7', color: msg !== '' ? '#fff' : '#ddd', 'border-color': msg !== '' ? '#1BC418' : '#ddd' }">发送</view>
|
||||
<view v-else @click="changeTool" class="zfb-tk-send-tool-more wxfont gengduo"></view>
|
||||
</view>
|
||||
<view v-if="showtool" class="zfb-tk-send-tools">
|
||||
<view class="zfb-tk-send-tools-item" v-for="(v, i) in toolist" @click="toolClick(v)">
|
||||
<view class="zfb-tk-send-tools-icon"><view class="wxfont" :class="v.icon"></view></view>
|
||||
<view class="zfb-tk-send-tools-text">{{ v.title }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view :scroll-y="true" v-if="showEmojitool" class="wxemojitool">
|
||||
<view class="wxemojitool-content">
|
||||
<view class="wxemojitool-item" @click="addMsg(v)" v-for="(v, i) in emojilist" :key="i">{{ v }}</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<zmm-upload-image chooseType="chooseMedia" :show="false" ref="upload" @allComplete="upLoadallComplete" @oneComplete="upLoadoneComplete"></zmm-upload-image>
|
||||
<!-- #ifndef H5 -->
|
||||
<view class="zfb-tk-recorder" v-show="showRecorder"><zmm-recorder :show="showRecorder" ref="rec" @recorderStop="recorderStop"></zmm-recorder></view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// #ifdef APP-PLUS
|
||||
const TUICalling = uni.requireNativePlugin('TUICallingUniPlugin-TUICallingModule');
|
||||
// #endif
|
||||
let observer = null;
|
||||
import favorites from '../favorites/index.vue';
|
||||
import chatItem from './chat-item.vue';
|
||||
import sendCard from './sendCard.vue';
|
||||
export default {
|
||||
components: {
|
||||
chatItem,
|
||||
sendCard,
|
||||
favorites
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isBottomHeight: '',
|
||||
clickToSubmitSure: null,
|
||||
autodown: true,
|
||||
emojilist: ['😁', '😂', '😃', '😄', '😅', '😆', '😉', '😊', '😋', '😌', '😍', '😏', '😒', '😓', '😔', '😖', '😘', '😚', '😜', '😝', '😞', '😠', '😡', '😢', '😣', '😤', '😥', '😨', '😩', '😪', '😫', '😭', '😰', '😱', '😲', '😳', '😵', '😷', '😸', '😹', '😺', '😻', '😼', '😽', '😾', '😿', '🙀', '🙅', '🙆', '🙇', '🙈', '🙉', '🙊', '🙋', '🙌', '🙍', '🙎', '🙏'],
|
||||
showRecorder: false,
|
||||
showVice: false,
|
||||
toolist: [
|
||||
{
|
||||
title: '相册',
|
||||
icon: 'tupian'
|
||||
},
|
||||
{
|
||||
title: '拍摄',
|
||||
icon: 'xiangji'
|
||||
},
|
||||
{
|
||||
title: '位置',
|
||||
icon: 'dingwei'
|
||||
},
|
||||
{
|
||||
title: '语音',
|
||||
icon: 'yrecord'
|
||||
},
|
||||
{
|
||||
title: '名片',
|
||||
icon: 'mingpian'
|
||||
},
|
||||
{
|
||||
title: '收藏',
|
||||
icon: 'shoucang'
|
||||
}
|
||||
],
|
||||
msgFocus: false,
|
||||
showtool: false,
|
||||
showEmojitool: false,
|
||||
msg: '',
|
||||
timer: '',
|
||||
talkTo: '',
|
||||
keyboardHeight: 0,
|
||||
windowHeight: 0,
|
||||
longTapItemKey: '',
|
||||
// chatWindowData:[],
|
||||
localData: {},
|
||||
showtitleNViewBtns: true
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
userinfo() {
|
||||
return this.$store.state.userInfo;
|
||||
},
|
||||
chatListInfo() {
|
||||
return this.$store.state.chatlist[this.talkTo.userId];
|
||||
},
|
||||
chatDataState() {
|
||||
return this.$store.state.chatDataState;
|
||||
},
|
||||
chatDataUserId() {
|
||||
return this.$store.state.chatDataUserId;
|
||||
},
|
||||
chatWindowData() {
|
||||
this.$store.dispatch('getchatDatalist');
|
||||
if (this.$store.state.chatDatalist[this.talkTo.userId]) {
|
||||
return this.$store.state.chatDatalist[this.talkTo.userId].list;
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
chatDataState: {
|
||||
deep: true,
|
||||
immediate: true,
|
||||
handler(v) {
|
||||
if (this.chatDataUserId == this.talkTo.userId) {
|
||||
this.scrolltoBottom();
|
||||
this.clickToSubmitSure();
|
||||
}
|
||||
}
|
||||
},
|
||||
keyboardHeight: {
|
||||
deep: true,
|
||||
immediate: true,
|
||||
handler(v) {
|
||||
if (v > 0) {
|
||||
this.showEmojitool = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
onLoad(e) {
|
||||
this.talkTo = e;
|
||||
// 根据Id
|
||||
this.$store
|
||||
.dispatch('createChatObj', {
|
||||
userId: this.talkTo.userId,
|
||||
windowType: this.talkTo.windowType
|
||||
})
|
||||
.then(res => {
|
||||
this.localData = res.data;
|
||||
if (e.windowType == 'SINGLE') {
|
||||
uni.setNavigationBarTitle({
|
||||
title: this.localData.fromInfo.nickName
|
||||
});
|
||||
}
|
||||
this.$store.dispatch('getchatDatalist');
|
||||
this.$store.dispatch('getChatList');
|
||||
if (this.localData.fromInfo && this.localData.fromInfo.userType == 'normal') {
|
||||
this.toolist.push({
|
||||
title: '音视频',
|
||||
icon: 'yspin'
|
||||
});
|
||||
} else {
|
||||
this.$fc.setTitleNViewBtns(0, '');
|
||||
this.showtitleNViewBtns = false;
|
||||
}
|
||||
if (this.localData.groupInfo && this.localData.groupInfo.userId) {
|
||||
this.$fc.setTitleNViewBtns(0, '\ue623');
|
||||
this.showtitleNViewBtns = true;
|
||||
}
|
||||
this.scrolltoBottom();
|
||||
});
|
||||
this.clickToSubmitSure = this.$fc.debounce(
|
||||
() => {
|
||||
observer = uni.createIntersectionObserver(this);
|
||||
observer.relativeTo('.zfb-tk-main').observe('.autodownView', res => {
|
||||
var isBottomH = res.intersectionRect.top + res.intersectionRect.height;
|
||||
if (!this.isBottomHeight) {
|
||||
this.isBottomHeight = res.relativeRect.height + res.relativeRect.top - 56;
|
||||
}
|
||||
|
||||
if (parseInt(isBottomH) < parseInt(this.isBottomHeight) + 40) {
|
||||
this.autodown = true;
|
||||
} else {
|
||||
this.autodown = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
100,
|
||||
false
|
||||
);
|
||||
},
|
||||
onPageScroll() {
|
||||
this.clickToSubmitSure();
|
||||
},
|
||||
onReady() {},
|
||||
onShow() {
|
||||
if (this.chatListInfo && this.chatListInfo.nickName) {
|
||||
uni.setNavigationBarTitle({
|
||||
title: this.chatListInfo.nickName
|
||||
});
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// #ifdef APP-PLUS
|
||||
uni.onKeyboardHeightChange(res => {
|
||||
this.keyboardHeight = res.height;
|
||||
});
|
||||
// #endif
|
||||
},
|
||||
onUnload() {
|
||||
if (observer) {
|
||||
observer.disconnect();
|
||||
}
|
||||
if (this.chatListInfo) {
|
||||
this.chatListInfo.num = 0;
|
||||
this.$store.dispatch('updateChatListInfoById', { userId: this.talkTo.userId, data: this.chatListInfo });
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addMsg(e) {
|
||||
this.msg += e;
|
||||
},
|
||||
clickitem(e, i) {
|
||||
//发送收藏
|
||||
this.sendMsg(e.content, e.collectType);
|
||||
this.closepopup('popupfavorites');
|
||||
},
|
||||
longpressItem(e, i) {
|
||||
this.longTapItemKey = i;
|
||||
},
|
||||
startRecord() {
|
||||
this.$refs['rec'].startRecord();
|
||||
this.showRecorder = true;
|
||||
},
|
||||
endRecord() {
|
||||
this.$refs['rec'].stopRecord();
|
||||
},
|
||||
recorderStop(e) {
|
||||
uni.showLoading({ title: '发送中' });
|
||||
this.$http.uploadFile({
|
||||
url: '/file/uploadAudio',
|
||||
filePath: e.recordFilePath,
|
||||
name: 'file',
|
||||
fileType: 'audio',
|
||||
success: res => {
|
||||
var data = JSON.parse(res.data);
|
||||
if (data.code == 200) {
|
||||
var msg = {
|
||||
time: e.recordTime,
|
||||
url: data.data.fullPath,
|
||||
text: data.data.sourceText
|
||||
};
|
||||
this.sendMsg(JSON.stringify(msg), 'VOICE');
|
||||
}
|
||||
}
|
||||
});
|
||||
this.$refs['rec'].clear(); //清理录音
|
||||
// 隐藏语音组件
|
||||
this.showRecorder = false;
|
||||
// this.showtool=false
|
||||
},
|
||||
changeShowVice() {
|
||||
this.showVice = !this.showVice;
|
||||
},
|
||||
upLoadoneComplete(e) {
|
||||
this.sendMsg(JSON.stringify(e), e.type);
|
||||
},
|
||||
upLoadallComplete(e) {
|
||||
// this.sendMsg(JSON.stringify(e),'IMAGE')
|
||||
},
|
||||
changeEmojiTool() {
|
||||
this.showEmojitool = !this.showEmojitool;
|
||||
this.showtool = false;
|
||||
},
|
||||
changeTool() {
|
||||
this.showtool = !this.showtool;
|
||||
this.showEmojitool = false;
|
||||
},
|
||||
sendCardclick(e) {
|
||||
this.$refs.popup.close();
|
||||
this.sendMsg(JSON.stringify(e.item.data), 'CARD');
|
||||
},
|
||||
open() {
|
||||
uni.getSystemInfo({
|
||||
success: res => {
|
||||
this.windowHeight = res.windowHeight;
|
||||
}
|
||||
});
|
||||
this.$refs.popup.open('top');
|
||||
},
|
||||
closepopup(e) {
|
||||
this.$refs[e].close();
|
||||
},
|
||||
openpopup(e) {
|
||||
this.$refs[e].open('top');
|
||||
},
|
||||
tryagin(e, i) {
|
||||
//重新发送
|
||||
this.chatWindowData.splice(i, 1);
|
||||
this.chatWindowData.splice(i, 1);
|
||||
this.$store.dispatch('updateChatById', {
|
||||
userId: this.talkTo.userId,
|
||||
data: this.chatWindowData
|
||||
});
|
||||
this.$nextTick(() => {
|
||||
this.sendMsg(e.content, e.msgType);
|
||||
});
|
||||
},
|
||||
sendVoiceCall() {
|
||||
//发起语音
|
||||
uni.showLoading({
|
||||
title: '发起语音通话'
|
||||
});
|
||||
var formdata = {
|
||||
userId: this.talkTo.userId,
|
||||
msgType: 'TRTC_VOICE_START',
|
||||
content: 'TRTC_VOICE_START'
|
||||
};
|
||||
this.$http.request({
|
||||
url: '/chat/sendMsg',
|
||||
method: 'POST',
|
||||
data: JSON.stringify(formdata),
|
||||
success: res => {
|
||||
if (res.data.code == '200') {
|
||||
if (res.data.data.status !== '0') {
|
||||
uni.showToast({
|
||||
title: res.data.data.statusLabel,
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
var userInfo = res.data.data.userInfo;
|
||||
var data = {
|
||||
userId: userInfo.userId,
|
||||
trtcId: userInfo.trtcId,
|
||||
nickName: userInfo.nickName,
|
||||
portrait: userInfo.portrait,
|
||||
startTime: new Date().getTime(),
|
||||
type: 'audio'
|
||||
};
|
||||
uni.setStorage({
|
||||
key: 'call',
|
||||
data: JSON.stringify(data),
|
||||
success: function() {
|
||||
TUICalling.call({
|
||||
userID: userInfo.trtcId,
|
||||
type: 1
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
sendVideoCall() {
|
||||
//发起视频
|
||||
uni.showLoading({
|
||||
title: '发起视频通话'
|
||||
});
|
||||
var formdata = {
|
||||
userId: this.talkTo.userId,
|
||||
msgType: 'TRTC_VIDEO_START',
|
||||
content: 'TRTC_VIDEO_START'
|
||||
};
|
||||
this.$http.request({
|
||||
url: '/chat/sendMsg',
|
||||
method: 'POST',
|
||||
data: JSON.stringify(formdata),
|
||||
success: res => {
|
||||
if (res.data.code == '200') {
|
||||
if (res.data.data.status !== '0') {
|
||||
uni.showToast({
|
||||
title: res.data.data.statusLabel,
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
var userInfo = res.data.data.userInfo;
|
||||
var data = {
|
||||
userId: userInfo.userId,
|
||||
trtcId: userInfo.trtcId,
|
||||
nickName: userInfo.nickName,
|
||||
portrait: userInfo.portrait,
|
||||
startTime: new Date().getTime(),
|
||||
type: 'video'
|
||||
};
|
||||
uni.setStorage({
|
||||
key: 'call',
|
||||
data: JSON.stringify(data),
|
||||
success: function() {
|
||||
TUICalling.call({
|
||||
userID: userInfo.trtcId,
|
||||
type: 2
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
toolClick(e) {
|
||||
switch (e.title) {
|
||||
case '位置':
|
||||
uni.chooseLocation({
|
||||
success: res => {
|
||||
this.sendMsg(JSON.stringify(res), 'LOCATION');
|
||||
}
|
||||
});
|
||||
break;
|
||||
case '相册':
|
||||
this.$refs['upload'].chooseTap();
|
||||
break;
|
||||
case '语音':
|
||||
this.startRecord();
|
||||
break;
|
||||
case '名片':
|
||||
this.open();
|
||||
break;
|
||||
case '音视频':
|
||||
uni.showActionSheet({
|
||||
itemList: ['视频通话', '语音通话'],
|
||||
success: res => {
|
||||
switch (res.tapIndex) {
|
||||
case 0:
|
||||
this.sendVideoCall();
|
||||
break;
|
||||
case 1:
|
||||
this.sendVoiceCall();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
case '收藏':
|
||||
this.openpopup('popupfavorites');
|
||||
uni.getSystemInfo({
|
||||
success: res => {
|
||||
// #ifdef APP-PLUS
|
||||
this.windowHeight = res.windowHeight - res.statusBarHeight - res.safeArea.top - res.safeAreaInsets.top;
|
||||
// #endif
|
||||
// #ifndef APP-PLUS
|
||||
this.windowHeight = res.windowHeight;
|
||||
// #endif
|
||||
}
|
||||
});
|
||||
break;
|
||||
case '拍摄':
|
||||
// #ifdef APP-PLUS
|
||||
var _this = this;
|
||||
uni.showActionSheet({
|
||||
itemList: ['拍摄图片', '拍摄视频'],
|
||||
success: res => {
|
||||
switch (res.tapIndex) {
|
||||
case 0:
|
||||
getImage();
|
||||
break;
|
||||
case 1:
|
||||
getVideo();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
fail: function(res) {
|
||||
console.log(res.errMsg);
|
||||
}
|
||||
});
|
||||
function getImage() {
|
||||
//拍照事件
|
||||
var cmr = plus.camera.getCamera();
|
||||
cmr.captureImage(
|
||||
function(p) {
|
||||
plus.io.resolveLocalFileSystemURL(
|
||||
p,
|
||||
function(entry) {
|
||||
//读取图片信息
|
||||
compressImage(entry.toLocalURL(), entry.name); //压缩图片
|
||||
},
|
||||
function(e) {
|
||||
console.log('读取拍照文件错误:' + e.message);
|
||||
}
|
||||
);
|
||||
},
|
||||
function(e) {
|
||||
console.log(e);
|
||||
},
|
||||
{
|
||||
filename: 'file:///storage/emulated/0/Documents/weiliao/'
|
||||
}
|
||||
);
|
||||
}
|
||||
function getVideo() {
|
||||
//拍摄视频
|
||||
var cmr = plus.camera.getCamera();
|
||||
cmr.startVideoCapture(
|
||||
function(p) {
|
||||
plus.io.resolveLocalFileSystemURL(
|
||||
p,
|
||||
function(entry) {
|
||||
//读取文件信息
|
||||
compressVideo(entry.fullPath, entry.name); //压缩视频
|
||||
},
|
||||
function(e) {
|
||||
console.log('读取视频文件错误:' + e.message);
|
||||
}
|
||||
);
|
||||
},
|
||||
function(e) {
|
||||
console.log(e);
|
||||
},
|
||||
{
|
||||
filename: 'file:///storage/emulated/0/Documents/weiliao/'
|
||||
}
|
||||
);
|
||||
}
|
||||
function compressImage(url, filename) {
|
||||
//压缩图片
|
||||
var name = 'file:///storage/emulated/0/Documents/weiliao/' + filename;
|
||||
plus.zip.compressImage(
|
||||
{
|
||||
src: url, //src: (String 类型 )压缩转换原始图片的路径
|
||||
dst: name, //压缩转换目标图片的路径
|
||||
quality: 60, //quality: (Number 类型 )压缩图片的质量.取值范围为1-100
|
||||
overwrite: true //overwrite: (Boolean 类型 )覆盖生成新文件
|
||||
},
|
||||
function(e) {
|
||||
//压缩后
|
||||
// openFile(e.target)
|
||||
uni.showLoading({ title: '发送中' });
|
||||
sendPhoto(e.target); //发送
|
||||
},
|
||||
function(error) {
|
||||
console.log('压缩图片失败,请稍候再试');
|
||||
}
|
||||
);
|
||||
}
|
||||
function compressVideo(url, filename) {
|
||||
//压缩视频
|
||||
// var name = 'file:///storage/emulated/0/Documents/weiliao/compress/' + filename;
|
||||
plus.zip.compressVideo(
|
||||
{
|
||||
src: url, //src: (String 类型 )压缩转换原始路径
|
||||
// filename: name, //压缩后的路径
|
||||
quality: 'medium' //压缩级别low medium high
|
||||
},
|
||||
function(e) {
|
||||
//压缩后
|
||||
// openFile(e.tempFilePath)
|
||||
uni.showLoading({ title: '发送中' });
|
||||
sendVideo(e.tempFilePath); //发送
|
||||
},
|
||||
function(error) {
|
||||
console.log('压缩视频失败,请稍候再试');
|
||||
}
|
||||
);
|
||||
}
|
||||
function openFile(filePath) {
|
||||
//打开文件
|
||||
let system = uni.getSystemInfoSync().platform;
|
||||
if (system == 'ios') {
|
||||
filePath = encodeURI(filePath);
|
||||
}
|
||||
uni.openDocument({
|
||||
filePath,
|
||||
success: res => {
|
||||
console.log('打开文件成功');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function sendPhoto(filePath) {
|
||||
//发送图片
|
||||
_this.$http.uploadFile({
|
||||
url: '/file/upload',
|
||||
filePath: filePath,
|
||||
name: 'file',
|
||||
fileType: 'image',
|
||||
success: res => {
|
||||
var data = JSON.parse(res.data);
|
||||
if (data.code == 200) {
|
||||
var msg = {
|
||||
name: data.data.fileName,
|
||||
url: data.data.fullPath
|
||||
};
|
||||
_this.sendMsg(JSON.stringify(msg), 'IMAGE');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function sendVideo(filePath) {
|
||||
//发送视频
|
||||
_this.$http.uploadFile({
|
||||
url: '/file/uploadVideo',
|
||||
filePath: filePath,
|
||||
name: 'file',
|
||||
fileType: 'video',
|
||||
success: res => {
|
||||
var data = JSON.parse(res.data);
|
||||
if (data.code == 200) {
|
||||
var msg = {
|
||||
name: data.data.fileName,
|
||||
videoUrl: data.data.fullPath,
|
||||
url: data.data.screenShot
|
||||
};
|
||||
_this.sendMsg(JSON.stringify(msg), 'VIDEO');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
// #endif
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
sendMsg(e, msgType) {
|
||||
if (!e) {
|
||||
return;
|
||||
}
|
||||
this.$fc.pushOutMsg({
|
||||
msgContent: e,
|
||||
msgType: msgType,
|
||||
windowType: this.talkTo.windowType,
|
||||
userId: this.talkTo.userId
|
||||
});
|
||||
this.msg = '';
|
||||
// #ifdef H5
|
||||
this.msgFocus = false;
|
||||
this.$nextTick(() => {
|
||||
this.msgFocus = true;
|
||||
});
|
||||
// #endif
|
||||
},
|
||||
startRecognize() {
|
||||
//语音文本输入
|
||||
// #ifdef H5
|
||||
uni.showToast({
|
||||
title: 'H5暂不支持',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
// #endif
|
||||
let _this = this;
|
||||
let options = {};
|
||||
options.engine = 'baidu';
|
||||
options.punctuation = false; // 是否需要标点符号
|
||||
options.timeout = 10 * 1000;
|
||||
plus.speech.startRecognize(
|
||||
options,
|
||||
function(s) {
|
||||
_this.msg = _this.msg + s;
|
||||
},
|
||||
function(e) {
|
||||
uni.showToast({
|
||||
title: '语音识别失败:' + e.message,
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
);
|
||||
},
|
||||
scrolltoBottom() {
|
||||
if (this.autodown) {
|
||||
this.$nextTick(() => {
|
||||
this.timer = setTimeout(() => {
|
||||
uni.pageScrollTo({
|
||||
scrollTop: 9999999,
|
||||
duration: 10
|
||||
});
|
||||
}, 200);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
onNavigationBarButtonTap(e) {
|
||||
if (!this.showtitleNViewBtns) {
|
||||
return;
|
||||
}
|
||||
switch (e.index) {
|
||||
case 0:
|
||||
if (this.talkTo.windowType == 'GROUP') {
|
||||
uni.redirectTo({
|
||||
url: '../groupInfo/detail?param=' + this.talkTo.userId
|
||||
});
|
||||
}
|
||||
if (this.talkTo.windowType == 'SINGLE') {
|
||||
uni.redirectTo({
|
||||
url: '../personInfo/detail?param=' + this.talkTo.userId
|
||||
});
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.autodownView {
|
||||
height: 1px;
|
||||
width: 100%;
|
||||
opacity: 0;
|
||||
}
|
||||
.uni-list {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.zfb-tk-main {
|
||||
padding: 0 12px;
|
||||
padding-bottom: 112rpx;
|
||||
}
|
||||
|
||||
.zfb-tk-send-tool {
|
||||
background: #f7f7f7;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
transition: all 0.1s;
|
||||
}
|
||||
.zfb-tk-send-tools {
|
||||
height: 558rpx;
|
||||
width: 100%;
|
||||
background-color: #f7f7f7;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
.zfb-tk-send-tools-item {
|
||||
padding: 35rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.zfb-tk-send-tools-icon {
|
||||
background-color: #fff;
|
||||
width: 110rpx;
|
||||
height: 110rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
.zfb-tk-send-tools-icon .wxfont {
|
||||
color: #181818;
|
||||
font-size: 64rpx;
|
||||
}
|
||||
.zfb-tk-send-tools-text {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
.zfb-tk-send-tool-c {
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
padding: 16rpx 12rpx;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
border: 1px #ddd solid;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.zfb-tk-send-tool-c .zfb-tk-send-tool-btn {
|
||||
transition: color 0.5s;
|
||||
}
|
||||
.zfb-tk-send-tool-input-box {
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
margin: 0 12rpx;
|
||||
min-height: 75rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 24rpx;
|
||||
padding-top: 18rpx;
|
||||
max-height: 225rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.zfb-tk-send-tool .zfb-tk-send-tool-input {
|
||||
padding: 0 24rpx;
|
||||
box-sizing: border-box !important;
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
}
|
||||
.zfb-tk-send-tool-vioce {
|
||||
box-sizing: border-box;
|
||||
margin: 0 12rpx;
|
||||
width: 100%;
|
||||
height: 75rpx;
|
||||
border-radius: 24rpx;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
.zfb-tk-send-tool-vioce-item {
|
||||
text-align: center;
|
||||
font-size: 24rpx;
|
||||
line-height: 75rpx;
|
||||
flex: 1;
|
||||
}
|
||||
.zfb-tk-send-tool-vioce-item:nth-child(1) {
|
||||
border-right: 1px #eee solid;
|
||||
}
|
||||
.zfb-tk-send-tool-text {
|
||||
white-space: nowrap;
|
||||
padding: 10rpx 24rpx;
|
||||
border-radius: 12rpx;
|
||||
border: 1px #ddd solid;
|
||||
background: #f7f7f7;
|
||||
color: #ddd;
|
||||
}
|
||||
.zfb-tk-send-tool-more {
|
||||
font-size: 64rpx;
|
||||
color: #333;
|
||||
}
|
||||
.zfb-tk-send-tool-icon {
|
||||
font-size: 64rpx;
|
||||
color: #333;
|
||||
}
|
||||
.zfb-tk-recorder {
|
||||
width: 250rpx;
|
||||
height: 250rpx;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
bottom: 680rpx;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
position: fixed;
|
||||
border-radius: 50%;
|
||||
background-color: #f8f8f8;
|
||||
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.05);
|
||||
padding: 20rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.popsendCard {
|
||||
display: flex;
|
||||
background-color: #fff;
|
||||
overflow: auto;
|
||||
}
|
||||
.popsendCard-close {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
height: 70rpx;
|
||||
line-height: 70rpx;
|
||||
font-size: 42rpx;
|
||||
background-color: #fff;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 9999;
|
||||
}
|
||||
.wxemojitool {
|
||||
height: 558rpx;
|
||||
}
|
||||
.wxemojitool-content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.wxemojitool-item {
|
||||
font-size: 44rpx;
|
||||
width: 93rpx;
|
||||
height: 93rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
228
im-uniapp/wx/chatWindow/openTool.vue
Normal file
228
im-uniapp/wx/chatWindow/openTool.vue
Normal file
@@ -0,0 +1,228 @@
|
||||
<template>
|
||||
<view class="openTool" :class="itemKey==0 ? 'frist-openTool' : ''" @touchmove.stop.prevent="moveHandle('touchmove')" @click="moveHandle('click')" v-if="show">
|
||||
<view class="openTool-wx" :animation="animationData">
|
||||
<view class="openTool-wx-list" v-if="data">
|
||||
<view class="openTool-wx-list-item" @click="copyText(data.content)" v-if="data.msgType == 'TEXT'">
|
||||
<view class="openTool-wx-list-item-icon"><view class="wxfont wxcopy"></view></view>
|
||||
<view class="text">复制</view>
|
||||
</view>
|
||||
<view class="openTool-wx-list-item" @click="shoucang" v-if="data.msgType !== 'TRTC_VOICE_END'&&data.msgType !== 'TRTC_VIDEO_END'">
|
||||
<view class="openTool-wx-list-item-icon"><view class="wxfont shoucang"></view></view>
|
||||
<view class="text">收藏</view>
|
||||
</view>
|
||||
<view class="openTool-wx-list-item" @click="shanchu">
|
||||
<view class="openTool-wx-list-item-icon"><view class="wxfont wxdelete"></view></view>
|
||||
<view class="text">删除</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="openTool-wx-icon"></view>
|
||||
</view>
|
||||
<view class="openTool-wx-model"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
show:false,
|
||||
animationData: {}
|
||||
};
|
||||
},
|
||||
props: {
|
||||
data:{
|
||||
type:[Object,String]
|
||||
},
|
||||
talkTo:{
|
||||
type:[Object,String,Number]
|
||||
},
|
||||
itemKey:{
|
||||
type:[Object,String,Number]
|
||||
},
|
||||
list: {
|
||||
type: Array,
|
||||
default() {
|
||||
return [{}];
|
||||
}
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
mounted() {
|
||||
var animation = uni.createAnimation({
|
||||
duration: 300,
|
||||
timingFunction: 'linear'
|
||||
});
|
||||
this.animation = animation;
|
||||
},
|
||||
methods: {
|
||||
copyText(e){
|
||||
uni.setClipboardData({
|
||||
data: e,
|
||||
success: function() {
|
||||
uni.showToast({
|
||||
title: '复制成功',
|
||||
icon: 'none',
|
||||
position: 'bottom'
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
shoucang(){
|
||||
this.$http.request({
|
||||
url: '/collect/add',
|
||||
method: 'POST',
|
||||
data:JSON.stringify({
|
||||
collectType: this.data.msgType,
|
||||
content: this.data.content
|
||||
}),
|
||||
success: (res) => {
|
||||
if (res.data.code == 200) {
|
||||
uni.showToast({
|
||||
title:'收藏成功',
|
||||
icon:'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
shanchu(){
|
||||
this.$store.dispatch('getchatDatalist');
|
||||
this.$store.dispatch('getChatList');
|
||||
var chatWindowData = this.$store.state.chatDatalist[this.talkTo.userId].list
|
||||
var chatListInfo = this.$store.state.chatlist[this.talkTo.userId]
|
||||
if((this.itemKey+1)==chatWindowData.length){
|
||||
chatListInfo['content']=''
|
||||
this.$store.dispatch('updateChatListInfoById',{
|
||||
userId: this.talkTo.userId,
|
||||
data: chatListInfo
|
||||
});
|
||||
}
|
||||
chatWindowData.splice(this.itemKey, 1);
|
||||
this.$store.dispatch('updateChatById', { userId: this.talkTo.userId,data: chatWindowData });
|
||||
},
|
||||
showAnimation() {
|
||||
this.animation.opacity(1).step();
|
||||
this.animationData = this.animation.export();
|
||||
},
|
||||
hideAnimation() {
|
||||
this.animation.opacity(0).step();
|
||||
this.animationData = this.animation.export();
|
||||
},
|
||||
moveHandle(e) {
|
||||
this.hiddenTab()
|
||||
},
|
||||
showTab(){
|
||||
this.show=true
|
||||
setTimeout(()=>{
|
||||
this.showAnimation()
|
||||
},30)
|
||||
},
|
||||
hiddenTab(){
|
||||
this.show=false
|
||||
this.hideAnimation()
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
/* 黑色版 */
|
||||
.openTool{
|
||||
width: 552rpx;
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
}
|
||||
.openTool-wx {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: wrap;
|
||||
opacity: 0;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
.openTool-wx-model{
|
||||
background-color: rgba(0,0,0,0);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.openTool-wx-list {
|
||||
width: 100%;
|
||||
padding: 6rpx 24rpx;
|
||||
box-sizing: border-box;
|
||||
background-color: #4C4C4C;
|
||||
border-radius: 10rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-around;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.openTool-wx-list-item {
|
||||
margin:6rpx 24rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.openTool-wx-list-item .text {
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
border-bottom: 1px #535353 solid;
|
||||
flex: 1;
|
||||
}
|
||||
.openTool-wx-list-item:nth-last-child(1) .text{
|
||||
border: none;
|
||||
}
|
||||
|
||||
.openTool-wx-list-item-icon {
|
||||
color: #fff;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
.openTool-wx-icon {
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
border: 5px solid transparent;
|
||||
border-top-color: #4C4C4C;
|
||||
margin: 0 auto;
|
||||
margin-bottom: -5px;
|
||||
}
|
||||
.openTool-wx-list-item-icon .wxfont {
|
||||
font-size: 42rpx;
|
||||
}
|
||||
.openTool-msgright{
|
||||
margin-left: auto;
|
||||
/* margin-right: 92rpx; */
|
||||
right: 92rpx;
|
||||
}
|
||||
.openTool-msgleft{
|
||||
margin-right: auto;
|
||||
/* margin-left: 92rpx; */
|
||||
left: 92rpx;
|
||||
}
|
||||
.openTool-msgright .openTool-wx-icon{
|
||||
margin-right: 24rpx;
|
||||
}
|
||||
.openTool-msgleft .openTool-wx-icon{
|
||||
margin-left: 24rpx;
|
||||
}
|
||||
.frist-openTool{
|
||||
bottom: auto;
|
||||
top: 100%;
|
||||
}
|
||||
.frist-openTool .openTool-wx{
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
.frist-openTool .openTool-wx .openTool-wx-icon{
|
||||
border-bottom-color: #4C4C4C;
|
||||
border-top-color: transparent;
|
||||
margin-bottom: 0;
|
||||
margin-top: -5px;
|
||||
}
|
||||
</style>
|
||||
52
im-uniapp/wx/chatWindow/sendCard.vue
Normal file
52
im-uniapp/wx/chatWindow/sendCard.vue
Normal file
@@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<view class="xw-book">
|
||||
<watermark></watermark>
|
||||
<uni-indexed-list-wx :showAdd="false" :options="list" @click="bindClick"></uni-indexed-list-wx>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
emits:['click'],
|
||||
data() {
|
||||
return {
|
||||
list: [],
|
||||
path:''
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getflist()
|
||||
},
|
||||
methods: {
|
||||
bindClick(e){
|
||||
this.$emit('click',e)
|
||||
},
|
||||
getflist(){
|
||||
this.$http.request({
|
||||
url: '/friend/friendList',
|
||||
method: 'POST',
|
||||
data:JSON.stringify({}),
|
||||
success: (res) => {
|
||||
if (res.data.code == 200) {
|
||||
var data=res.data.data
|
||||
var list=[]
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var item=data[i]
|
||||
list.push({
|
||||
name:item.nickName,
|
||||
avatar:item.portrait,
|
||||
userId:item.userId,
|
||||
chatNo:item.chatNo
|
||||
})
|
||||
}
|
||||
this.list=this.$fc.sortList({list:list,key:'name'})
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
Reference in New Issue
Block a user