|
|
@@ -87,20 +87,24 @@
|
|
|
:enable-progress-gesture="false" vslide-gesture-in-fullscreen="true"
|
|
|
:show-center-play-btn="false" :http-cache="false" loop @error="videoError"
|
|
|
@timeupdate="onVideoTimeUpdate" @loadeddata="onVideoLoaded"
|
|
|
- @loadedmetadata="onVideoMetaLoaded" @pause="onVideoPause" @play="onVideoPlay">
|
|
|
+ @loadedmetadata="onVideoMetaLoaded" @pause="onVideoPause" @play="onVideoPlay"
|
|
|
+ :initial-time="liveItem.totalSeconds" :enable-play-gesture="true">
|
|
|
</video>
|
|
|
-
|
|
|
+ <view v-if="liveItem.videoUrl&&liveItem.liveType==3" class="lable">直播回放</view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="videolist" v-if="liveItem.status==4">
|
|
|
+ <view class="video" :class="liveItem.showType == 1 ? 'video_row' : ''">
|
|
|
<!-- 直播回放 -->
|
|
|
+ <!-- @seek="onVideoSeek" -->
|
|
|
<video v-if="liveItem.videoUrl&&liveItem.liveType==3" :id="`myVideo_${liveId}`" class="item"
|
|
|
:src="liveItem.videoUrl" :controls="true" object-fit="contain" :custom-cache="false"
|
|
|
:enable-progress-gesture="liveItem.isSpeedAllowed" vslide-gesture-in-fullscreen="true"
|
|
|
:show-center-play-btn="true" :http-cache="false" loop @error="videoError"
|
|
|
@timeupdate="onVideoTimeUpdate" @loadeddata="onVideoLoaded"
|
|
|
@loadedmetadata="onVideoMetaLoaded" @pause="onVideoPause" @play="onVideoPlay"
|
|
|
- @seek="onVideoSeek">
|
|
|
+ :enable-play-gesture="true">
|
|
|
</video>
|
|
|
- <view v-if="liveItem.videoUrl&&liveItem.liveType==2" class="time">{{liveItem.totalTime}}
|
|
|
- </view>
|
|
|
<view v-if="liveItem.videoUrl&&liveItem.liveType==3" class="lable">直播回放</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
@@ -110,7 +114,8 @@
|
|
|
:enable-progress-gesture="false" vslide-gesture-in-fullscreen="false"
|
|
|
:show-center-play-btn="false" :http-cache="false" loop @error="videoError"
|
|
|
@loadeddata="onVideoLoaded" @loadedmetadata="onVideoMetaLoaded" @pause="onVideoPause"
|
|
|
- @play="onVideoPlay" :disable-progress="true">
|
|
|
+ @play="onVideoPlay" :disable-progress="true" :initial-time="liveItem.totalSeconds"
|
|
|
+ :enable-play-gesture="true">
|
|
|
</video>
|
|
|
|
|
|
<image v-if="liveItem.status==1&&!liveItem.previewUrl" class="img" src="/static/images/no_live.png">
|
|
|
@@ -174,13 +179,12 @@
|
|
|
|
|
|
<!-- 底部输入框和操作按钮 -->
|
|
|
<view class="justify-between p24">
|
|
|
- <view class="x-f"
|
|
|
+ <view class="x-f justify-between"
|
|
|
:style="{background:'#393939' ,padding: '10rpx 14rpx 10rpx 32rpx',boxSizing: 'border-box',borderRadius: '36rpx',width: isFocus ? '100%' : '580rpx'}">
|
|
|
- <u-input :placeholder="placeholderText" border="none" customStyle='font-size:24rpx;'
|
|
|
- v-model="value" shape='circle' color="#ffffff" placeholderStyle="color:#e7e7e7"
|
|
|
- :adjust-position="false" :scroll-with-animation="false" class="ml20" @focus="inputFocus"
|
|
|
- @blur="inputBlur">
|
|
|
- </u-input>
|
|
|
+ <input :placeholder="placeholderText" v-model="value" placeholder-style="color:#e7e7e7;"
|
|
|
+ placeholder-class="placeholder-style" class="ml20 input-native" @focus="inputFocus"
|
|
|
+ @blur="inputBlur"
|
|
|
+ style="border: none; font-size: 24rpx; color: #ffffff; background: transparent; width: 70%;" />
|
|
|
<view class="send" @click="sendMsg()">发送</view>
|
|
|
</view>
|
|
|
<view class="justify-between mr15 align-center" v-if="!isFocus">
|
|
|
@@ -321,10 +325,16 @@
|
|
|
<image class="w24 mr16" src="/static/images/search.png" mode="widthFix" />
|
|
|
<input placeholder="请搜索商品" v-model="inputInfo" @input="handleSearchInput" />
|
|
|
</view>
|
|
|
- <view class=" search-top" @click="goOrderList()">
|
|
|
+ <view class=" search-top" @click="navgetTo('/pages_shopping/live/order')">
|
|
|
<image class="w48 h48" src="/static/images/order.png" />
|
|
|
<view>订单</view>
|
|
|
</view>
|
|
|
+
|
|
|
+ <view class=" search-top"
|
|
|
+ @click="navgetTo('/pages_shopping/live/storeOrderRefundList?liveId='+liveId)">
|
|
|
+ <image class="w48 h48" src="/static/images/after_sales.png" />
|
|
|
+ <view>售后</view>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
|
|
|
<scroll-view enable-flex scroll-y class="shop-list" :style="{ height: boxHeight + 'px' }">
|
|
|
@@ -402,7 +412,8 @@
|
|
|
currentActivities, //红包 卡片 抽奖
|
|
|
getlive,
|
|
|
subNotifyLive,
|
|
|
- internetTraffic // 流量(缓冲百分比)
|
|
|
+ internetTraffic, // 流量(缓冲百分比),
|
|
|
+ liveInternetTraffic // 直播流量(缓冲百分比),
|
|
|
} from '@/api/living.js'
|
|
|
import {
|
|
|
getUserInfo
|
|
|
@@ -428,6 +439,10 @@
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
+ totalTraffic: 0, // 总流量(字节)
|
|
|
+ bitrate: 1000000, // 默认码率 1Mbps
|
|
|
+ trafficTimer: null,
|
|
|
+
|
|
|
stayTime: 0,
|
|
|
startTime: 0,
|
|
|
|
|
|
@@ -449,7 +464,7 @@
|
|
|
shownEntryUsers: new Set(), // 存储已显示过「进入提示」的用户ID
|
|
|
isPageUnloading: false, // 标记页面是否正在卸载(区分主动离开vs重连out)
|
|
|
|
|
|
- templateId: 'fxYJu817lxHNKXl0hJypb54UnGRCNAoI72Qf-xjKCik',
|
|
|
+ templateId: 'fxYJu817lxHNKXl0hJypb-y-lLm8CNmGbcwpQmasCVg',
|
|
|
isAgreement: false,
|
|
|
socket: null, // WebSocket 实例
|
|
|
isSocketOpen: false, // 连接是否已打开
|
|
|
@@ -461,10 +476,8 @@
|
|
|
isManualClose: false, // 是否手动关闭(用于区分主动关闭和异常断开)
|
|
|
pingTimeoutTimer: null, // 心跳超时定时器
|
|
|
|
|
|
- // wsNewUrl: 'wss://api.fhhx.runtzh.com/app/webSocket',
|
|
|
wsNewUrl: 'wss://api.fhhx.runtzh.com/ws/app/webSocket',
|
|
|
// wsNewUrl: 'ws://192.168.10.166:7114/ws/app/webSocket',
|
|
|
- // wsNewUrl:'ws://192.168.10.166:7014/app/webSocket',
|
|
|
qrFrom: null,
|
|
|
scene: '',
|
|
|
|
|
|
@@ -530,8 +543,6 @@
|
|
|
scrollTimer: null, // 滚动防抖定时器
|
|
|
|
|
|
|
|
|
-
|
|
|
-
|
|
|
showRed: true,
|
|
|
searchTimer: null,
|
|
|
isCollect: false,
|
|
|
@@ -552,14 +563,7 @@
|
|
|
timestamp: '',
|
|
|
liveId: null,
|
|
|
userinfo: '', //用户信息
|
|
|
- // path: 'http://192.168.10.166/dev-api', //余红奇
|
|
|
- // path: 'http://v56c9b8e.natappfree.cc', //余红奇
|
|
|
- // path: 'live.test.ylrztop.com/prod-api', //余红奇
|
|
|
- value: '',
|
|
|
- talkdisabled: false, //输入框是否禁用
|
|
|
- autoplay: false, //视频自动播放
|
|
|
showadd: false,
|
|
|
- videoContext: '',
|
|
|
livedata: {}, //直播间点赞、关注、在线人数数据
|
|
|
userData: {},
|
|
|
|
|
|
@@ -574,7 +578,7 @@
|
|
|
this.liveId = options.liveId;
|
|
|
}
|
|
|
this.getUserInfo()
|
|
|
- this.previousToken = uni.getStorageSync('AppToken')
|
|
|
+ this.previousToken = ('AppToken')
|
|
|
this.initTime();
|
|
|
this.userinfo = uni.getStorageSync("userInfo")
|
|
|
this.userData = uni.getStorageSync("userData")
|
|
|
@@ -617,14 +621,6 @@
|
|
|
console.error("直播间 ID(liveId)未获取到");
|
|
|
}
|
|
|
})
|
|
|
- // if (!this.previousToken) {
|
|
|
- // console.log("未检测到AppToken,跳转到登录页");
|
|
|
- // // let backUrl = '/pages_course/living?liveId=' + (this.liveId || '');
|
|
|
- // uni.navigateTo({
|
|
|
- // url: '/pages/auth/login?&isLive=ture'
|
|
|
- // });
|
|
|
- // return;
|
|
|
- // }
|
|
|
|
|
|
},
|
|
|
onPullDownRefresh() {
|
|
|
@@ -643,26 +639,20 @@
|
|
|
}
|
|
|
this.uuId = generateRandomString(16)
|
|
|
const currentToken = await uni.getStorageSync('AppToken')
|
|
|
- console.log("token在这里", currentToken)
|
|
|
const isLiveLogin = uni.getStorageSync('isLiveLogin')
|
|
|
this.share = uni.getStorageSync('share')
|
|
|
this.scene = uni.getStorageSync('scene')
|
|
|
- console.log("onshow分享", this.share)
|
|
|
- console.log("onshow扫码", this.scene)
|
|
|
if (this.share && this.share.length > 0) {
|
|
|
this.liveId = this.share.liveId
|
|
|
this.qrFrom = `&companyId=${this.share.companyId}&companyUserId=${this.share.companyUserId}`;
|
|
|
uni.removeStorageSync('share')
|
|
|
}
|
|
|
if (this.scene) {
|
|
|
- console.log("有扫码")
|
|
|
const decodedScene = decodeURIComponent(this.scene);
|
|
|
- console.log("有扫码decodedScene", decodedScene)
|
|
|
const params = {};
|
|
|
decodedScene.split('&').forEach(item => {
|
|
|
const [key, value] = item.split('=');
|
|
|
params[key] = value;
|
|
|
- console.log("扫码参数", params)
|
|
|
this.liveId = params.a;
|
|
|
})
|
|
|
if (params.b && params.c) {
|
|
|
@@ -671,7 +661,6 @@
|
|
|
uni.removeStorageSync('scene')
|
|
|
}
|
|
|
if (isLiveLogin) {
|
|
|
- console.log("登录了")
|
|
|
if (this.liveId) {
|
|
|
await this.getliving(this.liveId)
|
|
|
this.getCurrentActivities()
|
|
|
@@ -684,7 +673,6 @@
|
|
|
// 恢复播放和连接
|
|
|
await this.resumePageActivity()
|
|
|
this.userinfo = JSON.parse(uni.getStorageSync("userInfo"))
|
|
|
- // this.userData =await uni.getStorageSync("userData")
|
|
|
|
|
|
this.isAgreement = uni.getStorageSync('isAgreement')
|
|
|
this.previousToken = currentToken
|
|
|
@@ -692,13 +680,18 @@
|
|
|
this.$nextTick(() => {
|
|
|
this.setVideoProgress();
|
|
|
});
|
|
|
- console.log("预约liveiD", this.liveId)
|
|
|
if (this.lookTimer) {
|
|
|
clearInterval(this.lookTimer)
|
|
|
this.lookTimer = null;
|
|
|
this.stayTime = 0;
|
|
|
this.startTime = 0;
|
|
|
}
|
|
|
+ if (this.trafficTimer) {
|
|
|
+ clearInterval(this.trafficTimer)
|
|
|
+ this.trafficTimer = null;
|
|
|
+ this.startTime = 0;
|
|
|
+ this.totalTraffic = 0;
|
|
|
+ }
|
|
|
this.startTimer()
|
|
|
},
|
|
|
|
|
|
@@ -718,60 +711,53 @@
|
|
|
},
|
|
|
computed: {
|
|
|
filteredViewers() {
|
|
|
- // 1. 强制兜底:若 liveViewers 不是数组(如 null/undefined),直接返回空数组
|
|
|
const safeLiveViewers = Array.isArray(this.liveViewersData) ? this.liveViewersData : [];
|
|
|
- // 2. 截取前3项(空数组 slice 不会报错)
|
|
|
+ // 截取前3项
|
|
|
return safeLiveViewers.slice(0, 3);
|
|
|
},
|
|
|
isCurrentUserWon() {
|
|
|
- // 兜底条件:确保prizeInfo是数组、当前用户ID存在
|
|
|
if (!Array.isArray(this.prizeInfo) || !this.userData?.userId) {
|
|
|
return false;
|
|
|
}
|
|
|
- // 匹配逻辑:检查prizeInfo中是否有userId与当前用户一致的项
|
|
|
return this.prizeInfo.some(item => {
|
|
|
- // 兼容item.userId可能是数字/字符串的情况,统一转为字符串比较
|
|
|
return String(item.userId) === String(this.userData.userId);
|
|
|
});
|
|
|
}
|
|
|
},
|
|
|
- onHide() {
|
|
|
-
|
|
|
- },
|
|
|
+ onHide() {},
|
|
|
|
|
|
onUnload() {
|
|
|
- this.suspendPageActivity()
|
|
|
- this.liveUserCalled = false
|
|
|
- // if (this.liveItem) {
|
|
|
- // this.pauseVideo();
|
|
|
- // this.clearTimeTimer();
|
|
|
- // }
|
|
|
|
|
|
+ this.stopHeartBeat()
|
|
|
+ this.saveVideoProgress()
|
|
|
|
|
|
+ if (this.liveItem) {
|
|
|
+ this.pauseVideo()
|
|
|
+ this.clearTimeTimer()
|
|
|
+ }
|
|
|
+ this.liveUserCalled = false
|
|
|
this.loadUserColorsFromStorage();
|
|
|
if (this.liveViewDataTimer) {
|
|
|
clearInterval(this.liveViewDataTimer);
|
|
|
this.liveViewDataTimer = null;
|
|
|
}
|
|
|
- // console.log('页面卸载,清理资源');
|
|
|
this.isPageUnloading = true; // 标记为主动离开
|
|
|
|
|
|
- // 1. 先关闭WebSocket
|
|
|
+ // 先关闭WebSocket
|
|
|
this.closeWebSocket(true);
|
|
|
|
|
|
- // 2. 清除所有定时器
|
|
|
+ // 清除所有定时器
|
|
|
this.clearAllTimers();
|
|
|
|
|
|
- // 3. 暂停视频
|
|
|
+ // 暂停视频
|
|
|
const videoId = `myVideo_${this.liveId}`;
|
|
|
const videoContext = uni.createVideoContext(videoId, this);
|
|
|
if (videoContext) {
|
|
|
videoContext.pause();
|
|
|
}
|
|
|
|
|
|
- // 4. 移除事件监听
|
|
|
|
|
|
- // 5. 清除特定定时器
|
|
|
+ // 清除特定定时器
|
|
|
if (this.redTimer) {
|
|
|
clearInterval(this.redTimer);
|
|
|
this.redTimer = null;
|
|
|
@@ -797,6 +783,12 @@
|
|
|
this.stayTime = 0;
|
|
|
this.startTime = 0;
|
|
|
}
|
|
|
+ if (this.trafficTimer) {
|
|
|
+ clearInterval(this.trafficTimer)
|
|
|
+ this.trafficTimer = null;
|
|
|
+ this.startTime = 0;
|
|
|
+ this.totalTraffic = 0;
|
|
|
+ }
|
|
|
},
|
|
|
|
|
|
mounted() {
|
|
|
@@ -839,36 +831,74 @@
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
+ //直播计算流量
|
|
|
+ startTrafficCalculation() {
|
|
|
+ this.startTime = Date.now();
|
|
|
+ var that = this
|
|
|
+ this.trafficTimer = setInterval(() => {
|
|
|
+ that.calculateTraffic();
|
|
|
+ }, 5000); // 每5秒计算一次
|
|
|
+ },
|
|
|
+ // 计算流量
|
|
|
+ calculateTraffic() {
|
|
|
+ const currentTime = Date.now();
|
|
|
+ const duration = (currentTime - this.startTime) / 1000; // 持续时间(秒)
|
|
|
+ // 流量 = 码率 × 时间
|
|
|
+ // 码率单位: bps, 时间单位: 秒, 流量单位: 比特
|
|
|
+ const trafficBits = this.bitrate * duration;
|
|
|
+ // 转换为字节
|
|
|
+ this.totalTraffic = trafficBits / 8;
|
|
|
+ this.getLiveInternetTraffic()
|
|
|
+ },
|
|
|
+
|
|
|
startTimer() {
|
|
|
this.startTime = Date.now()
|
|
|
-
|
|
|
this.lookTimer = setInterval(() => {
|
|
|
this.stayTime = Math.floor((Date.now() - this.startTime) / 1000)
|
|
|
}, 1000)
|
|
|
},
|
|
|
+
|
|
|
// 缓冲
|
|
|
- getInternetTraffic() {
|
|
|
- if (!this.liveItem.videoId ||!this.liveItem.videoType) return;
|
|
|
+ getLiveInternetTraffic() {
|
|
|
if (!this.liveId) return;
|
|
|
const currentTime = this.stayTime / this.liveItem.duration * 100;
|
|
|
const param = {
|
|
|
- companyId: this.companyId || '',
|
|
|
- companyUserId: this.companyUserId || '',
|
|
|
userId: this.userData.userId || '',
|
|
|
liveId: this.liveId || '',
|
|
|
+ uuId: dayjs().format('YYYYMMDD') + this.uuId,
|
|
|
+ duration: this.liveItem.duration,
|
|
|
+ internetTraffic: this.totalTraffic,
|
|
|
+ }
|
|
|
+
|
|
|
+ internetTraffic(param)
|
|
|
+ },
|
|
|
+ // 缓冲
|
|
|
+ getInternetTraffic() {
|
|
|
+ // if (!this.liveItem.videoId || !this.liveItem.videoType) return;
|
|
|
+ if (!this.liveId||!this.liveId||!this.userData.userId||!this.uuId) return;
|
|
|
+ const currentTime = this.stayTime / this.liveItem.duration * 100;
|
|
|
+ const param = {
|
|
|
videoType: this.liveItem.videoType,
|
|
|
videoId: this.liveItem.videoId,
|
|
|
+ userId: this.userData.userId,
|
|
|
+ liveId: this.liveId,
|
|
|
uuId: dayjs().format('YYYYMMDD') + this.uuId,
|
|
|
duration: this.liveItem.duration,
|
|
|
bufferRate: currentTime,
|
|
|
}
|
|
|
+ if (this.liveItem.status == 1) {
|
|
|
+ param.videoType = this.liveItem.previewVideoType || ''
|
|
|
+ param.videoId = this.liveItem.previewVideoId || ''
|
|
|
+ }
|
|
|
+ if (this.liveItem.liveType == 1) {
|
|
|
+ param.bufferRate = this.totalTraffic
|
|
|
+ }
|
|
|
internetTraffic(param)
|
|
|
},
|
|
|
scrollToBottom() {
|
|
|
this.$nextTick(() => {
|
|
|
setTimeout(() => {
|
|
|
const query = uni.createSelectorQuery().in(this);
|
|
|
-
|
|
|
// 获取 scroll-view 和内容的高度
|
|
|
query.select('.scrolly').boundingClientRect(scrollRect => {
|
|
|
query.select('.scrolly').scrollOffset(scrollOffset => {
|
|
|
@@ -883,28 +913,17 @@
|
|
|
},
|
|
|
// 恢复页面活动
|
|
|
async resumePageActivity() {
|
|
|
- console.log("恢复了")
|
|
|
+ await this.getliving(this.liveId)
|
|
|
if (this.liveItem) {
|
|
|
this.playVideo()
|
|
|
this.startTimeTimer(this.liveItem)
|
|
|
-
|
|
|
}
|
|
|
if (!this.isSocketAvailable()) {
|
|
|
this.initSocket()
|
|
|
}
|
|
|
-
|
|
|
},
|
|
|
|
|
|
- // 暂停页面活动
|
|
|
- suspendPageActivity() {
|
|
|
- this.stopHeartBeat()
|
|
|
- this.saveVideoProgress()
|
|
|
|
|
|
- if (this.liveItem) {
|
|
|
- this.pauseVideo()
|
|
|
- this.clearTimeTimer()
|
|
|
- }
|
|
|
- },
|
|
|
// 获取用户专属随机色(缓存机制:同一用户始终用同一颜色)
|
|
|
getUserRandomColor(userId) {
|
|
|
if (!userId) {
|
|
|
@@ -919,7 +938,6 @@
|
|
|
this.userRandomColors[userId] = color;
|
|
|
// 存储到本地缓存,确保页面刷新后颜色不变
|
|
|
this.saveUserColorsToStorage();
|
|
|
-
|
|
|
return color;
|
|
|
}, // 基于用户ID生成稳定颜色(不是完全随机)
|
|
|
generateStableColor(userId) {
|
|
|
@@ -933,7 +951,6 @@
|
|
|
'#DDA0DD', '#98D8C8', '#F7DC6F', '#BB8FCE', '#85C1E9',
|
|
|
'#F8C471', '#82E0AA', '#F1948A', '#85C1E9', '#D7BDE2'
|
|
|
];
|
|
|
-
|
|
|
return colorPool[seed % colorPool.length];
|
|
|
}, // 保存颜色映射到本地存储
|
|
|
saveUserColorsToStorage() {
|
|
|
@@ -974,7 +991,6 @@
|
|
|
await getUserInfo().then(
|
|
|
res => {
|
|
|
if (res.code == 200) {
|
|
|
- console.log("用户信息>>", res)
|
|
|
this.userData = res.user;
|
|
|
|
|
|
} else {
|
|
|
@@ -986,43 +1002,22 @@
|
|
|
},
|
|
|
rej => {}
|
|
|
);
|
|
|
- }, // 检查WebSocket连接状态
|
|
|
- getSocketState() {
|
|
|
- if (!this.socket) return 'CLOSED';
|
|
|
-
|
|
|
- const states = {
|
|
|
- 0: 'CONNECTING',
|
|
|
- 1: 'OPEN',
|
|
|
- 2: 'CLOSING',
|
|
|
- 3: 'CLOSED'
|
|
|
- };
|
|
|
- return states[this.socket.readyState] || 'UNKNOWN';
|
|
|
- },
|
|
|
+ },
|
|
|
|
|
|
- // 在控制台输出连接状态(调试用)
|
|
|
- logSocketState() {
|
|
|
- console.log('WebSocket状态:', {
|
|
|
- socket: !!this.socket,
|
|
|
- isSocketOpen: this.isSocketOpen,
|
|
|
- readyState: this.getSocketState(),
|
|
|
- reconnectCount: this.reconnectCount
|
|
|
- });
|
|
|
- },
|
|
|
+
|
|
|
+ //订阅消息
|
|
|
handleAgreement() {
|
|
|
- const templateId = this.templateId; // 先保存到局部变量
|
|
|
+ const templateId = this.templateId;
|
|
|
uni.requestSubscribeMessage({
|
|
|
tmplIds: [templateId],
|
|
|
- success: (res) => { // 使用箭头函数保持this指向
|
|
|
- console.log("订阅结果", res);
|
|
|
- console.log("模板订阅状态", res[templateId]);
|
|
|
-
|
|
|
+ success: (res) => {
|
|
|
+ // console.log("订阅结果", res);
|
|
|
+ // console.log("模板订阅状态", res[templateId]);
|
|
|
if (res[templateId] === "accept") {
|
|
|
-
|
|
|
uni.showToast({
|
|
|
title: '订阅成功,开播将提醒您',
|
|
|
icon: 'success'
|
|
|
});
|
|
|
-
|
|
|
this.callSendMessageApi()
|
|
|
} else if (res[templateId] === 'reject') {
|
|
|
uni.showToast({
|
|
|
@@ -1045,25 +1040,21 @@
|
|
|
}
|
|
|
});
|
|
|
},
|
|
|
- // 调用后端发送订阅消息的接口
|
|
|
async callSendMessageApi() {
|
|
|
if (!this.userData.userId) return;
|
|
|
- console.log("订阅在这里", this.userData.userId)
|
|
|
const templateData = {
|
|
|
taskName: this.liveId,
|
|
|
userId: this.userData.userId,
|
|
|
- templateId: this.templateId, // 你的模板ID
|
|
|
+ templateId: this.templateId, // 模板ID
|
|
|
data: {
|
|
|
thing6: this.liveItem.liveName,
|
|
|
date7: this.liveItem.startTime,
|
|
|
}
|
|
|
};
|
|
|
- // 调用后端接口(后端负责调用微信订阅消息发送接口)
|
|
|
subNotifyLive(templateData).then(res => {
|
|
|
if (res.code == 200) {
|
|
|
this.isAgreement = true;
|
|
|
uni.setStorageSync('isAgreement', true);
|
|
|
- console.log("订阅消息", res)
|
|
|
} else {
|
|
|
uni.showToast({
|
|
|
title: res.msg,
|
|
|
@@ -1145,6 +1136,11 @@
|
|
|
// 处理重连逻辑
|
|
|
handleReconnect() {
|
|
|
this.resetReconnectState();
|
|
|
+ // uni.onNetworkStatusChange(res=>{
|
|
|
+ // if (res.networkType === 'wifi') {
|
|
|
+
|
|
|
+ // }
|
|
|
+ // })
|
|
|
this.stopHeartBeat();
|
|
|
if (this.reconnectCount < this.maxReconnectAttempts) {
|
|
|
this.reconnectCount++;
|
|
|
@@ -1194,7 +1190,6 @@
|
|
|
if (this.liveItem.liveType !== 2 && this.liveItem.liveType !== 3) {
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
let currentTime = 0;
|
|
|
if (this.liveItem.liveType === 2) {
|
|
|
// 录播:计算当前时间与开始时间的差值,对视频总时长取模
|
|
|
@@ -1222,7 +1217,6 @@
|
|
|
onVideoTimeUpdate(e) {
|
|
|
// 获取当前播放时间
|
|
|
this.videoCurrentTime = e.detail.currentTime;
|
|
|
-
|
|
|
// 每隔5秒保存一次进度(避免频繁存储)
|
|
|
if (Math.floor(this.videoCurrentTime) % 5 === 0) {
|
|
|
this.saveVideoProgress();
|
|
|
@@ -1305,7 +1299,6 @@
|
|
|
icon: 'none'
|
|
|
});
|
|
|
this.isShowCoupon = false
|
|
|
- // const couponData = res.data || {};
|
|
|
} else {
|
|
|
uni.showToast({
|
|
|
title: res.msg,
|
|
|
@@ -1379,14 +1372,6 @@
|
|
|
);
|
|
|
},
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
// 商品收藏
|
|
|
onGoodsCollect(item) {
|
|
|
if (!item || item.length === 0 || !item.goodsId) {
|
|
|
@@ -1430,6 +1415,11 @@
|
|
|
// console.log('直播状态变化:', e.detail.code, e.detail);
|
|
|
// 可以根据状态码处理不同的直播状态
|
|
|
const stateCode = e.detail.code;
|
|
|
+ if (e.detail.code == -2301 || e.detail.code == -2302) {
|
|
|
+ this.playVideo()
|
|
|
+ } else if (e.detail.code == 2004) {
|
|
|
+ this.calculateTimeDiff(this.liveItem)
|
|
|
+ }
|
|
|
// 2001: 已经连接服务器
|
|
|
// 2002: 已经连接服务器,开始拉流
|
|
|
// 2003: 网络接收到首个视频数据包(IDR)
|
|
|
@@ -1501,13 +1491,16 @@
|
|
|
return;
|
|
|
}
|
|
|
const now = new Date();
|
|
|
- let diffMs = Math.max(0, now - time); // 直播:已播放时长(现在-开始时间)
|
|
|
+ let diffMs = Math.max(0, now.getTime() - time.getTime())
|
|
|
+ // let diffMs = now - time; // 直播:已播放时长(现在-开始时间)
|
|
|
// 步骤4:转换为 时:分:秒(补零处理)
|
|
|
+
|
|
|
const totalSeconds = Math.floor(diffMs / 1000);
|
|
|
const hours = this.padZero(Math.floor(totalSeconds / 3600));
|
|
|
const minutes = this.padZero(Math.floor((totalSeconds % 3600) / 60));
|
|
|
const seconds = this.padZero(totalSeconds % 60);
|
|
|
this.$set(this.liveItem, "totalTime", `${hours}:${minutes}:${seconds}`);
|
|
|
+ // this.$set(this.liveItem, "diffMs", diffMs);
|
|
|
this.$set(this.liveItem, "totalSeconds", totalSeconds);
|
|
|
},
|
|
|
|
|
|
@@ -1590,8 +1583,10 @@
|
|
|
if (this.liveItem.liveType === 1 && this.liveItem.livingUrl && this.liveItem.status == 2) {
|
|
|
const livePlayerId = `myLivePlayer_${this.liveId}`;
|
|
|
const livePlayerContext = uni.createLivePlayerContext(livePlayerId, this);
|
|
|
+
|
|
|
if (livePlayerContext) {
|
|
|
livePlayerContext.play();
|
|
|
+ this.startTrafficCalculation();
|
|
|
}
|
|
|
} else if (this.liveItem.status == 1 && this.liveItem.previewUrl) {
|
|
|
const videoId = `myVideo_${this.liveId}`;
|
|
|
@@ -1599,21 +1594,33 @@
|
|
|
if (videoContext) {
|
|
|
videoContext.play();
|
|
|
}
|
|
|
- }
|
|
|
- // 回放视频使用video
|
|
|
- else if (this.liveItem.liveType === 2 && this.liveItem.videoUrl && this.liveItem.status == 2) {
|
|
|
+ } else if (this.liveItem.liveType === 2 && this.liveItem.videoUrl && this.liveItem.status == 2) {
|
|
|
const videoId = `myVideo_${this.liveId}`;
|
|
|
const videoContext = uni.createVideoContext(videoId, this);
|
|
|
if (videoContext) {
|
|
|
videoContext.play();
|
|
|
}
|
|
|
- } else if (this.liveItem.liveType === 3 && this.liveItem.videoUrl && this.liveItem.status == 2) {
|
|
|
+ } // 回放视频使用video
|
|
|
+ else if (this.liveItem.liveType === 3 && this.liveItem.videoUrl && this.liveItem.status == 4) {
|
|
|
const videoId = `myVideo_${this.liveId}`;
|
|
|
const videoContext = uni.createVideoContext(videoId, this);
|
|
|
if (videoContext) {
|
|
|
videoContext.play();
|
|
|
}
|
|
|
}
|
|
|
+ //流量
|
|
|
+ let that = this;
|
|
|
+ if (
|
|
|
+ (this.liveItem.liveType === 1 && this.liveItem.status == 1 && !this.liveItem.previewUrl) ||
|
|
|
+ (this.liveItem.liveType === 1 && this.liveItem.status == 2)
|
|
|
+ ) return;
|
|
|
+ if (this.trafficInterval != null) {
|
|
|
+ clearInterval(that.trafficInterval);
|
|
|
+ }
|
|
|
+ this.trafficInterval = setInterval(function() {
|
|
|
+ that.getInternetTraffic();
|
|
|
+ }, 10000);
|
|
|
+
|
|
|
} catch (error) {
|
|
|
console.error("播放视频失败:", error);
|
|
|
}
|
|
|
@@ -1821,11 +1828,10 @@
|
|
|
}
|
|
|
return str.slice(0, maxLength) + '...'; // 截断后加省略号
|
|
|
},
|
|
|
-
|
|
|
- // 去订单列表
|
|
|
- goOrderList() {
|
|
|
+ // 跳转页面
|
|
|
+ navgetTo(url) {
|
|
|
uni.navigateTo({
|
|
|
- url: "/pages_shopping/live/order"
|
|
|
+ url: url
|
|
|
})
|
|
|
},
|
|
|
|
|
|
@@ -1862,6 +1868,7 @@
|
|
|
this.liveStartTimer = setInterval(async () => {
|
|
|
this.liveCountdown = this.handleTime(res.data.startTime, 0);
|
|
|
if (!this.liveCountdown) {
|
|
|
+ uni.removeStorageSync('isAgreement');
|
|
|
await this.getliving(this.liveId);
|
|
|
clearInterval(this.liveStartTimer);
|
|
|
}
|
|
|
@@ -1878,27 +1885,22 @@
|
|
|
console.log("地址在", this.liveItem.livingUrl)
|
|
|
this.$set(this.liveItem, 'livingUrl', livingUrl);
|
|
|
this.$set(this.liveItem, 'videoUrl', ''); // 清空回放视频
|
|
|
- } else if (res.data.liveType === 2 || res.data.liveType === 3) {
|
|
|
+ } else if (res.data.liveType === 2) {
|
|
|
// 回放视频 2录播 3直播回放
|
|
|
this.$set(this.liveItem, 'videoUrl', res.data.videoUrl);
|
|
|
this.$set(this.liveItem, 'livingUrl', '');
|
|
|
- } else {
|
|
|
- // 未开播
|
|
|
- this.$set(this.liveItem, 'livingUrl', '');
|
|
|
- this.$set(this.liveItem, 'videoUrl', '');
|
|
|
}
|
|
|
+ } else if (res.data.status == 4 && res.data.liveType == 3) {
|
|
|
+ this.$set(this.liveItem, 'videoUrl', res.data.videoUrl);
|
|
|
+ this.$set(this.liveItem, 'livingUrl', '');
|
|
|
+ } else {
|
|
|
+ // 未开播
|
|
|
+ this.$set(this.liveItem, 'livingUrl', '');
|
|
|
+ this.$set(this.liveItem, 'videoUrl', '');
|
|
|
}
|
|
|
await this.getLiveMsg(this.liveItem);
|
|
|
await this.getliveViewData(this.liveItem);
|
|
|
|
|
|
- //流量
|
|
|
- let that = this
|
|
|
- if (this.trafficInterval != null) {
|
|
|
- clearInterval(that.trafficInterval)
|
|
|
- }
|
|
|
- this.trafficInterval = setInterval(function() {
|
|
|
- that.getInternetTraffic()
|
|
|
- },60000);
|
|
|
|
|
|
this.$set(this.liveItem, 'autoplay', res.data.liveType !== 0);
|
|
|
this.$set(this.liveItem, 'showType', res.data.showType);
|
|
|
@@ -1917,39 +1919,7 @@
|
|
|
});
|
|
|
}
|
|
|
},
|
|
|
- // initPlayerComponent() {
|
|
|
- // const {
|
|
|
- // liveType,
|
|
|
- // status,
|
|
|
- // liveId,
|
|
|
- // livingUrl,
|
|
|
- // videoUrl
|
|
|
- // } = this.liveItem;
|
|
|
- // // 仅在“直播中”(status:2)时初始化
|
|
|
- // if (status !== 2) return;
|
|
|
- // this.$nextTick(() => { // 等待视图更新后再操作组件
|
|
|
- // // 1. 直播流(liveType:1):初始化 live-player
|
|
|
- // if (liveType === 1 && livingUrl) {
|
|
|
- // const livePlayerId = `myLivePlayer_${liveId}`;
|
|
|
- // const livePlayerContext = uni.createLivePlayerContext(livePlayerId, this);
|
|
|
- // if (livePlayerContext) {
|
|
|
- // livePlayerContext.stop(); // 先停止旧流
|
|
|
- // livePlayerContext.play(); // 播放新流
|
|
|
- // }
|
|
|
- // }
|
|
|
-
|
|
|
- // // 2. 录播/回放(liveType:2/3):初始化 video
|
|
|
- // if ((liveType === 2 || liveType === 3) && videoUrl) {
|
|
|
- // const videoId = `myVideo_${liveId}`;
|
|
|
- // const videoContext = uni.createVideoContext(videoId, this);
|
|
|
- // if (videoContext) {
|
|
|
- // videoContext.stop(); // 停止旧视频
|
|
|
- // videoContext.seek(0); // 重置到开头
|
|
|
- // videoContext.play(); // 播放新视频
|
|
|
- // }
|
|
|
- // }
|
|
|
- // });
|
|
|
- // },
|
|
|
+
|
|
|
// 设置视频播放
|
|
|
maskString(str, maskChar = '*') {
|
|
|
// 如果str是undefined或null,直接返回空字符串
|