连云港陪玩陪聊
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
chunwan/pages/pipei/shipin/detail.nvue

764 lines
21 KiB

<template>
<view class="room" :style="{'width': winWidth+'px', 'height': winHeight+'px'}">
<view class="room-navbar" :style="{'width': winWidth+'px', 'height': (statusBarHeight+44)+'px'}">
<view class="navbar" :style="{'width': winWidth+'px', 'margin-top': (statusBarHeight)+'px'}">
<view class="back" @click="onBack()" :style="{'top': (statusBarHeight)+'px'}">
<image class="img" src="@/static/arrow-left.png"></image>
</view>
<view class="title" :style="{'width': winWidth+'px'}"><text class="txt">{{title}}</text></view>
</view>
</view>
<view v-if="type == 2 || type == 4">
<!-- @click="qiehuan()" -->
<view class="room-hd" v-if="isOpenSocket == false">
<view class="a" v-if="isToggle">
<zego-local-view class="video-view" :style="{'width': winWidth+'px', 'height': winHeight+'px'}"></zego-local-view>
<zego-remote-view class="shitu" :streamID="sellerStreamId" :style="{'top': (statusBarHeight+60)+'px'}"></zego-remote-view>
</view>
<view class="a" v-else>
<zego-remote-view class="video-view" :streamID="sellerStreamId" :style="{'width': winWidth+'px', 'height': winHeight+'px'}"></zego-remote-view>
<zego-local-view class="shitu" :style="{'top': (statusBarHeight+60)+'px'}"></zego-local-view>
</view>
</view>
</view>
<view class="room-bd" :style="{'width': winWidth+'px', 'height': winHeight+'px'}" v-if="isOpenSocket">
<image class="pic" :style="{'width': winWidth+'px', 'height': winHeight+'px'}" src="@/static/yuyin-bg.png"></image>
<view class="dian-on" >
<view class="info">
<image class="avatar" :src="userOtherInfo.faceImage?userOtherInfo.faceImage:userOtherInfo.img"></image>
<view class="name"><text class="t">{{userOtherInfo.nickname}}</text></view>
<view class="txt"><text class="t">{{userOtherInfo.age}}岁/{{userOtherInfo.height}}</text></view>
</view>
<view class="tag">
<view class="titles"><text class="t">个性签名:</text></view>
<view class="descs">
<text class="t">{{userOtherInfo.declaration}}</text>
</view>
</view>
</view>
</view>
<view class="room-fd" v-if="type==1 || type==3" :style="{'width': winWidth+'px'}" >
<view class="item">
<view class="pic" @click="toggleYuyin()" v-if="isJieshou==true">
<image v-if="isYuyin" class="pimg" src="@/static/yuyin-01.png"></image>
<image v-else class="pimg" src="@/static/yuyin-01-on.png"></image>
</view>
<view class="txt" v-if="isJieshou==true">
<text class="t">{{isYuyin?'开启':'关闭'}}</text>
</view>
</view>
<view class="item" v-if="isJieshou">
<view class="pic">
<image @click="toGuaduan()" class="pimg" src="@/static/yuyin-02.png"></image>
</view>
<view class="txt">
<text class="t">挂断</text>
</view>
</view>
<template v-if="isJieshou == false">
<view class="item">
<view class="pic">
<image @click="toGuaduan()" class="pimg" src="@/static/yuyin-02.png"></image>
</view>
<view class="txt">
<text class="t">挂断</text>
</view>
</view>
<view class="item" v-if="isStart == false"></view>
<view class="item" v-if="isStart == false">
<view class="pic">
<image class="pimg" src="@/static/yuyin-05.png"></image>
</view>
<view class="txt">
<text class="t">{{isStart?'等待':'接受'}}</text>
</view>
</view>
</template>
<view class="item">
<view class="pic" @click="toggleYangsheng()" v-if="isJieshou==true">
<image class="pimg" v-if="isYangshengqi" src="@/static/yuyin-03.png"></image>
<image class="pimg" v-else src="@/static/yuyin-03-on.png"></image>
</view>
<view class="txt" v-if="isJieshou==true">
<text class="t">{{isYangshengqi?'开启':'关闭'}}</text>
</view>
</view>
</view>
<view class="room-fd" v-if="type==2 || type==4" :style="{'width': winWidth+'px'}" >
<view class="item" v-if="isJieshou">
<view class="pic" @click="toggleYuyin()" v-if="isJieshou==true">
<image v-if="isYuyin" class="pimg" src="@/static/yuyin-01.png"></image>
<image v-else class="pimg" src="@/static/yuyin-01-on.png"></image>
</view>
<view class="txt">
<text class="t">{{isYuyin?'开启':'关闭'}}</text>
</view>
</view>
<view class="item" v-if="isJieshou">
<view class="pic" @click="toggleYangsheng()">
<image class="pimg" v-if="isYangshengqi" src="@/static/yuyin-03.png"></image>
<image class="pimg" v-else src="@/static/yuyin-03-on.png"></image>
</view>
<view class="txt">
<text class="t">{{isYangshengqi?'开启':'关闭'}}</text>
</view>
</view>
<view class="item" v-if="isJieshou">
<view class="pic" @click="toggleShexiang()" v-if="isJieshou==true">
<image class="pimg" v-if="isShexiang" src="@/static/yuyin-04.png"></image>
<image class="pimg" v-else src="@/static/yuyin-04-on.png"></image>
</view>
<view class="txt">
<text class="t">{{isShexiang?'开启':'关闭'}}</text>
</view>
</view>
<template v-if="isJieshou == false">
<view class="item">
<view class="pic">
<image @click="toGuaduan()" class="pimg" src="@/static/yuyin-02.png"></image>
</view>
<view class="txt">
<text class="t">挂断</text>
</view>
</view>
<view class="item" v-if="isStart == false" @click="toJieshou1()">
<view class="pic">
<image class="pimg" src="@/static/yuyin-05.png"></image>
</view>
<view class="txt">
<text class="t">{{isStart?'等待':'接受'}}</text>
</view>
</view>
</template>
</view>
<template v-if="isJieshou">
<view class="room-fd1" v-if="type==2 || type==4" :style="{'width': winWidth+'px'}" >
<view class="items">
<view class="pic">
<image @click="toGuaduan()" class="pimg" src="@/static/yuyin-02.png"></image>
</view>
<image class="off" @click="toggleHuamian()" src="@/static/yuyin-off.png"></image>
</view>
</view>
</template>
</view>
</template>
<script>
let timer = null;
import api from '@/api/index.js'
import permision from "@/js_sdk/wa-permission/permission.js"
//导入 ZEGO Express SDK
import ZegoExpressEngine from '@/uni_modules/zego-ZegoExpressUniApp-JS/components/zego-ZegoExpressUniApp-JS/lib/ZegoExpressEngine';
import ZegoRemoteView from "@/uni_modules/zego-ZegoExpressUniApp-JS/components/zego-ZegoExpressUniApp-JS/zego-view/ZegoRemoteView";
import ZegoLocalView from "@/uni_modules/zego-ZegoExpressUniApp-JS/components/zego-ZegoExpressUniApp-JS/zego-view/ZegoLocalView";
let roomConfig = {};
roomConfig.isUserStatusNotify = true;
const profile = {
appID : 267111980,
appSign: 'afcaa90a7750ee556e450ca62287c5f9a362e9ed711789717cda0e18f088858e',
scenario : 0
};
export default {
components: {
ZegoLocalView,
ZegoRemoteView,
},
data() {
return {
isOpenSocket: true,
isYuyin: true,
isGuaduan: true,
isYangshengqi: true,
isShexiang: true,
isJieshou: true,
isToggle: true,
winWidth: 0,
winHeight: 0,
userInfo: {},
playStreamId: "",
title: "",
count: 0,
balanceInfo: {},
userOtherInfo: {},
background: {
// 导航栏背景图
background: 'url(https://api.lyiyuan.cn/profile/upload/static/yuyin-bg.png) center top no-repeat',
// 还可以设置背景图size属性
backgroundSize: '100 auto',
},
engine: null,
roomId: "",
type: 2,
statusBarHeight: 0,
sellerStreamId: "",
viewModeIndex: 0,
isCamera: true,
isStart: true,
toIsBack: true,
}
},
onLoad(o) {
console.log(o)
this.id = o.id;
this.type=o.type;
this.title = (this.type == 1||this.type == 3)?"语音通话":"视频通话";
this.isStart = (this.type == 3||this.type == 4)?(o.fid?false:true):true
this.isShexiang = (this.type == 2 || this.type == 4)?true:false
this.isJieshou = o.type<=2?true:false;
this.statusBarHeight = uni.getSystemInfoSync().statusBarHeight;
this.winWidth = uni.getSystemInfoSync().windowWidth;
this.winHeight = uni.getSystemInfoSync().windowHeight;
},
async onReady() {
const that = this;
uni.$on("watchEvent",function (obj) {
console.log(obj)
if(obj.topic == 'message'){
if(obj.type == 12){
if(uni.getStorageSync("userInfo").id == obj.sellerId){
that.isGuaduan = false;
that.toGuaduan(1)
}
}
}
})
uni.$on("toJieshouYinship",(obj)=>{
console.log("toJieshouYinship",obj)
if(obj.topic == 'message'){
if(obj.type == 20){
if(uni.getStorageSync("userInfo").id == obj.sellerId){
that.toJieshou();
this.isOpenSocket = false;
}else{
this.isOpenSocket = false;
}
}
}
})
// #ifdef APP-PLUS
if (uni.getSystemInfoSync().platform === "android") {
const res = await permision.requestAndroidPermission(
"android.permission.RECORD_AUDIO"
);
const res1 = await permision.requestAndroidPermission(
"android.permission.CAMERA"
);
if(res == 1 && res1 == 1){
if(this.type <= 2){
this.toPermission();
}else{
this.getUserInfo(1);
}
}
this.getOtherUserInfo()
return ;
}
// #endif
if(this.type <= 2){
this.toPermission();
}else{
this.getUserInfo(1);
}
this.getOtherUserInfo();
},
methods: {
qiehuan() {
this.isToggle = !this.isToggle;
console.log(this.isToggle)
},
toJieshou1() {
uni.$emit("jieshouYinship",{
"userId": uni.getStorageSync("userInfo").id,
sellerId: this.id,
type: 20,
"topic":"message",
})
if(this.isStart == false){
this.toJieshou();
}
},
onBack() {
const that = this;
uni.showModal({
title: "温馨提示",
content: "是否要退出房间?",
confirmColor: "#000000",
success(res) {
if(res.confirm){
that.isGuaduan = false
that.toGuaduan();
}
}
})
},
toGuaduan(type) {
if(type !=1){
uni.$emit("duanYinship",{
"userId": uni.getStorageSync("userInfo").id,
sellerId: this.id,
type: 12,
"topic":"message",
})
}
if(type == 1){
uni.$emit("showToast",this.isJieshou)
}
this.socialConsumption();
clearInterval(timer)
if(this.toIsBack == false){
return ;
}
this.toIsBack = false
this.isGuaduan = false
/** 停止推流 */
this.engine?.stopPublishingStream();
/** 停止本地预览 */
this.engine?.stopPreview();
/** 停止拉流 */
this.engine?.stopPlayingStream(this.sellerStreamId);
/** 退出房间 */
this.engine?.logoutRoom(this.roomId);
/** 销毁引擎 */
ZegoExpressEngine.destroyEngine();
uni.$off("watchEvent")
uni.$off("toJieshouYinship")
uni.navigateBack({
delta: 1
})
},
toJieshou() {
this.toPermission();
this.$forceUpdate();
},
toggleYuyin() {
this.isYuyin = !this.isYuyin;
this.engine.muteMicrophone(!this.isYuyin)
},
toggleShexiang() {
this.isShexiang = !this.isShexiang;
this.engine.enableCamera(this.isShexiang)
},
toggleHuamian() {
this.isCamera = !this.isCamera
this.engine.useFrontCamera(this.isCamera)
},
toggleYangsheng() {
this.isYangshengqi = ! this.isYangshengqi
this.engine.setAudioRouteToSpeaker(this.isCamera)
},
async toPermission() {
this.getUserInfo();
},
//查询个人信息
async getUserInfo(type) {
const { code, data , msg} = await api.findUserInfo({userId: uni.getStorageSync("userInfo").id});
if(code == 200){
this.userInfo = data;
if(type != 1){
this.userBalance();
this.loginRoom();
}
}else{
uni.showToast({
title: msg,
position: "bottom",
icon: "none",
})
}
},
//查询taren个人信息
async getOtherUserInfo(type) {
const { code, data , msg } = await api.findOtherUserInfo({userId: uni.getStorageSync("userInfo").id,sellerId: this.id,});
if(code == 200){
console.log("getOtherUserInfo",data)
this.userOtherInfo = data;
}else{
uni.showToast({
title: msg,
position: "bottom",
icon: "none",
})
}
},
async loginRoom(){
const that = this;
const res = await api.findZegoToken({
userId: uni.getStorageSync("userInfo").id,
sellerId: this.id
})
if(res.code == 200){
// 获取token传入
roomConfig.token = res.data.token;
this.playStreamId = res.data.userStreamId;
this.sellerStreamId = res.data.sellerStreamId;
this.roomId = res.data.roomId;
console.log("loginRoom11",res.data)
this.engine = await ZegoExpressEngine.createEngineWithProfile(profile);
this.engine.enableCamera(this.isShexiang)
// 创建美颜环境
await this.engine.startEffectsEnv();
this.engine.enableEffectsBeauty(true);
// 创建美颜参数对象
let beautyParam = {};
// 美白、红润、磨皮、锐化
beautyParam.whitenIntensity = this.userInfo.reserved5;
beautyParam.rosyIntensity = this.userInfo.reserved6;
beautyParam.smoothIntensity = this.userInfo.reserved7;
beautyParam.sharpenIntensity = this.userInfo.reserved8;
// 设置美颜参数
this.engine.setEffectsBeautyParam(beautyParam);
this.engine.useFrontCamera(this.isCamera)
// 以下为常用的房间相关回调
this.engine.on('roomStateUpdate', (roomID, state, errorCode, extendedData) => {
console.log("roomStateUpdate",roomID)
// 房间状态更新回调,登录房间后,当房间连接状态发生变更(如出现房间断开,登录认证失败等情况),SDK会通过该回调通知
}); ;
this.engine.on('roomUserUpdate', (roomID, updateType, userList) => {
// 用户状态更新,登录房间后,当房间内有用户新增或删除时,SDK会通过该回调通知
console.log("roomUserUpdate",roomID,updateType,userList)
});
this.engine.on('playerStateUpdate', (roomID, updateType, streamList) => {
console.log("playerStateUpdate",roomID)
// 调用拉流接口成功后,当拉流器状态发生变更,如出现网络中断导致推流异常等情况,SDK在重试拉流的同时,会通过该回调通知
});
this.engine.on('roomStreamUpdate', (roomID, updateType, streamList) => {
console.log("roomStreamUpdate",updateType,streamList)
// 流状态更新,登录房间后,当房间内有用户新推送或删除音视频流时,SDK会通过该回调通知
// this.sellerStreamId = streamList[0].streamID;
});
// 调用推流接口成功后,当推流器状态发生变更,如出现网络中断导致推流异常等情况,SDK在重试推流的同时,会通过该回调通知
that.engine.on('publisherStateUpdate', (streamID, state, errorCode, extendedData) => {
console.log("publisherStateUpdate",streamID)
});
// 登录房间
// 开始登录房间
this.engine.loginRoom(res.data.roomId,
{
'userID': uni.getStorageSync("userInfo").id,
'userName': uni.getStorageSync("userInfo").nickname
},
roomConfig
);
// this.viewModeIndex = ZegoViewMode.AspectFit;
this.engine.startPreview();
this.engine.startPublishingStream(this.playStreamId);
this.isJieshou = true;
clearInterval(timer);
that.title = that.formatFun(that.count)
timer = setInterval(()=>{
if(uni.getStorageSync("userInfo").sex == 1){
if(that.type == 1){
if(that.balanceInfo.voiceCoins*60 < that.count){
clearInterval(timer);
that.toGuaduan();
that.title = that.formatFun(that.count);
return ;
}
}else if(that.type == 2){
if(that.balanceInfo.videoCoins*60 < that.count){
clearInterval(timer);
that.toGuaduan();
that.title = that.formatFun(that.count);
return ;
}
}
}
that.count ++;
that.title = that.formatFun(that.count);
},1000)
setTimeout(()=>{
this.toTuiliu()
},100)
}
},
//检查次数
async userBalance() {
const { code, data } = await this.$api.userBalance({
userId: uni.getStorageSync("userInfo").id
})
if(code == 200){
this.balanceInfo = data
}
},
//结算 type:1.语音 2.视频 3.文字 4图片 5礼物6搭讪
async socialConsumption(type) {
await this.$api.socialConsumption({
userId: uni.getStorageSync("userInfo").id,
sellerId: this.id,
type: (this.type == 1|| this.type == 3)?1:2,
duration: this.count+1
})
this.userBalance();
},
formatFun(num){
let str = "",h,m,s;
h=Math.floor(num/3600);
m=Math.floor((num-h*3600)/60);
s=(num-h*3600-m*60);
str = (h<=9?'0'+h:h)+":"+(m<=9?'0'+m:m)+":"+(s<=9?'0'+s:s)
return str;
},
toTuiliu() {
const that = this;
console.log("toTuiliu",this.sellerStreamId)
that.engine.startPlayingStream(this.sellerStreamId);
that.isOpenSocket = false;
ZegoExpressEngine.instance().on("playerStateUpdate", (streamID, state, errorCode, extendedData) => {
/** 调用拉流接口成功后,当拉流器状态发生变更,如出现网络中断导致推流异常等情况,SDK在重试拉流的同时,会通过该回调通知 */
console.log("playerStateUpdate",streamID)
});
}
},
onBackPress() {
if(this.isGuaduan){
this.toGuaduan();
}
}
}
</script>
<style lang="scss">
.room{
background-color: #000;
&-navbar{
height: 44px;
position: fixed;
left: 0;
top: 0;
z-index: 122;
display: flex;
flex-direction: row;
.navbar{
flex-direction: row;
height: 44px;
line-height: 44px;
position: relative;
text-align: center;
font-size: 30px;
.txt{
font-size: 20px;
color: #ffffff;
}
.title{
display: flex;
align-items: center;
justify-content: center;
}
.back{
width: 50px;
height: 44px;
position: fixed;
left: 0;
z-index: 44;
display: flex;
align-items: center;
justify-content: center;
.img{
width: 20px;
height: 20px;
}
}
}
}
&-hd{
flex-direction: column;
position: relative;
z-index: 2;
.shitu{
width: 300rpx;
height: 380rpx;
border-radius: 10rpx;
overflow: hidden;
position: fixed;
right: 20rpx;
top: 120rpx;
z-index: 212;
}
}
&-bd{
position: relative;
.pic{
width: 100%;
height: 100%;
display: block;
}
.dian-on{
width: 650rpx;
min-height: 648rpx;
position: absolute;
margin-left: 50rpx;
top: 250rpx;
z-index: 1;
.tag{
width: 660rpx;
height: 330rpx;
background: rgba(35, 32, 48, 0.36);
border-radius: 20rpx;
margin: 0 auto;
padding: 30rpx;
box-sizing: border-box;
text-align: left;
margin-top: 30rpx;
.titles{
.t{
font-weight: bold;
font-size: 30rpx;
color: #FFFFFF;
}
}
.descs{
margin-top: 20rpx;
.t{
font-size: 24rpx;
color: #B8B7BC;
line-height: 45rpx;
font-weight: 400;
}
}
}
.info{
text-align: center;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
.avatar{
width: 180rpx;
height: 180rpx;
border-radius: 50%;
display: block;
margin: 0 auto;
}
.name{
font-weight: 500;
margin-top: 10rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
overflow: hidden;
text-align: center;
text-align: center;
margin-top: 10rpx;
.t{
font-size: 28rpx;
color: #FFFFFF;
}
}
.btn{
width: 170rpx;
line-height: 56rpx;
background: linear-gradient(0deg, #FF9124, #BD4700);
border-radius: 56rpx;
margin: 0 auto;
margin-top: 20rpx;
.t{
font-weight: bold;
font-size: 30rpx;
color: #FFFFFF;
}
}
.txt{
margin-top: 20rpx;
opacity: 0.3;
.t{
font-weight: 500;
font-size: 26rpx;
color: #FFFFFF;
}
}
}
}
}
&-fd{
height: 220rpx;
position: fixed;
left: 0;
bottom: 200rpx;
z-index: 122;
flex-direction: row;
.item{
flex: 1;
text-align: center;
font-size: 30rpx;
font-weight: 400;
display: flex;
justify-content: center;
align-items: center;
.txt{
margin-top: 20rpx;
.t{
font-size: 30rpx;
color: #ffffff;
}
}
.pic{
width: 130rpx;
height: 130rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto;
margin-bottom: 10rpx;
.pimg{
width: 130rpx;
height: 130rpx;
}
}
}
}
&-fd1{
height: 220rpx;
position: fixed;
left: 0;
bottom: 40rpx;
z-index: 44;
flex-direction: row;
flex-wrap: wrap;
.items{
flex: 1;
margin-top: 70rpx;
position: relative;
flex-direction: row;
display: flex;
justify-content: center;
align-items: center;
.pic{
width: 130rpx;
height: 130rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto;
margin-bottom: 10rpx;
.pimg{
width: 130rpx;
height: 130rpx;
}
}
.off{
width: 49rpx;
height: 44rpx;
position: absolute;
right: 200rpx;
z-index: 2;
top: 50rpx;
}
}
}
}
</style>