萤石云对接、温湿度卡片合并、接口更新

This commit is contained in:
吉浩茹
2025-10-06 15:06:48 +08:00
parent 5f20cc7cd3
commit 4b65bea0bb
21 changed files with 5445 additions and 1027 deletions

View File

@ -0,0 +1,351 @@
<template>
<view class="simple-video-player">
<view class="debug-info" v-if="showDebug">
<text>平台: {{ platform }}</text>
<text>状态: {{ status }}</text>
<text>播放状态: {{ isPlaying ? '播放中' : '已暂停' }}</text>
</view>
<!-- APP平台使用web-view -->
<!-- #ifdef APP-PLUS -->
<web-view
v-if="webviewUrl"
ref="videoWebview"
:src="webviewUrl"
class="video-webview"
@message="handleMessage"
></web-view>
<!-- #endif -->
<!-- H5平台提示 -->
<!-- #ifdef H5 -->
<view class="h5-tip">H5平台暂不支持</view>
<!-- #endif -->
<!-- 控制按钮 -->
<view class="control-buttons" v-if="!loading && !error">
<button class="control-btn play-btn" @click="togglePlay">
{{ isPlaying ? ' 暂停' : ' 播放' }}
</button>
<button class="control-btn refresh-btn" @click="refresh">
🔄 刷新
</button>
</view>
<view v-if="loading" class="loading">
<text>{{ loadingText }}</text>
</view>
<view v-if="error" class="error">
<text>{{ errorText }}</text>
<button @click="retry">重试</button>
</view>
</view>
</template>
<script>
export default {
name: 'EzvizVideoPlayerSimple',
props: {
showDebug: {
type: Boolean,
default: false
}
},
data() {
return {
platform: '',
status: '未初始化',
webviewUrl: '',
loading: false,
loadingText: '',
error: false,
errorText: '',
config: null,
isPlaying: true // 默认自动播放
}
},
mounted() {
this.detectPlatform()
},
methods: {
detectPlatform() {
// #ifdef H5
this.platform = 'H5'
// #endif
// #ifdef APP-PLUS
this.platform = 'APP'
// #endif
console.log('[简单播放器] 平台:', this.platform)
},
initEzuikit(config) {
console.log('[简单播放器] 初始化:', config)
if (!config || !config.accessToken || !config.play_url) {
this.error = true
this.errorText = '配置参数不完整'
return
}
this.config = config
this.loading = true
this.loadingText = '正在加载播放器...'
this.status = '加载中'
try {
const token = encodeURIComponent(config.accessToken)
const url = encodeURIComponent(config.play_url)
// 使用iframe版本内存占用更小
this.webviewUrl = `/static/html/ezviz-iframe.html?accessToken=${token}&playUrl=${url}`
console.log('[简单播放器] 使用iframe版本URL已设置')
setTimeout(() => {
if (this.loading) {
this.loading = false
this.status = '播放器已加载'
}
}, 3000)
} catch (err) {
console.error('[简单播放器] 错误:', err)
this.error = true
this.errorText = err.message
this.loading = false
}
},
handleMessage(event) {
console.log('[简单播放器] 收到消息:', event)
try {
const data = event.detail.data
const msg = Array.isArray(data) ? data[0] : data
if (msg && msg.type === 'success') {
this.loading = false
this.status = '播放成功'
} else if (msg && msg.type === 'error') {
this.loading = false
this.error = true
this.errorText = msg.message || '播放失败'
}
} catch (err) {
console.error('[简单播放器] 消息处理错误:', err)
}
},
retry() {
this.error = false
this.errorText = ''
if (this.config) {
this.initEzuikit(this.config)
}
},
// 切换播放/暂停
togglePlay() {
console.log('[简单播放器] 切换播放状态:', this.isPlaying ? '暂停' : '播放')
// 通过重新加载URL来实现播放/暂停
// 因为iframe播放器不支持直接控制所以采用重新加载的方式
if (this.isPlaying) {
// 暂停清空URL
this.webviewUrl = ''
this.isPlaying = false
this.status = '已暂停'
// 触发状态变化事件
this.$emit('playStateChange', false)
} else {
// 播放重新设置URL
if (this.config) {
const token = encodeURIComponent(this.config.accessToken)
const url = encodeURIComponent(this.config.play_url)
this.webviewUrl = `/static/html/ezviz-iframe.html?accessToken=${token}&playUrl=${url}`
this.isPlaying = true
this.status = '播放中'
// 触发状态变化事件
this.$emit('playStateChange', true)
}
}
// 返回新的播放状态
return this.isPlaying
},
// 获取当前播放状态
getPlayState() {
return this.isPlaying
},
// 刷新播放器
refresh() {
console.log('[简单播放器] 刷新播放器')
if (this.config) {
uni.showToast({
title: '正在刷新...',
icon: 'loading',
duration: 1000
})
// 先清空再重新加载
this.webviewUrl = ''
setTimeout(() => {
const token = encodeURIComponent(this.config.accessToken)
const url = encodeURIComponent(this.config.play_url)
this.webviewUrl = `/static/html/ezviz-iframe.html?accessToken=${token}&playUrl=${url}`
this.isPlaying = true
this.status = '播放中'
uni.showToast({
title: '刷新成功',
icon: 'success',
duration: 1500
})
}, 500)
}
}
}
}
</script>
<style scoped>
.simple-video-player {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
background: #000;
}
.debug-info {
position: absolute;
top: 10rpx;
left: 10rpx;
background: rgba(0,0,0,0.7);
color: white;
padding: 10rpx;
font-size: 24rpx;
z-index: 100;
}
.debug-info text {
display: block;
margin: 5rpx 0;
}
.video-webview {
width: 100%;
height: 50%;
}
.h5-tip {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
color: white;
font-size: 28rpx;
}
.loading {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
background: rgba(0,0,0,0.8);
color: white;
font-size: 28rpx;
z-index: 50;
}
.error {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: rgba(255,0,0,0.8);
color: white;
font-size: 28rpx;
z-index: 50;
padding: 40rpx;
}
.error text {
margin-bottom: 30rpx;
text-align: center;
}
.error button {
background: white;
color: #333;
padding: 20rpx 40rpx;
border-radius: 10rpx;
}
/* 控制按钮 */
.control-buttons {
position: absolute;
bottom: 30rpx;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 20rpx;
z-index: 100;
}
.control-btn {
background: rgba(0, 0, 0, 0.75);
color: white;
border: 2rpx solid rgba(255, 255, 255, 0.6);
padding: 16rpx 32rpx;
border-radius: 40rpx;
font-size: 24rpx;
font-weight: 600;
min-width: 140rpx;
backdrop-filter: blur(10rpx);
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.3);
transition: all 0.2s ease;
}
.control-btn:active {
background: rgba(0, 0, 0, 0.9);
transform: scale(0.96);
}
.play-btn {
background: rgba(46, 125, 50, 0.85);
border-color: rgba(76, 175, 80, 0.9);
}
.play-btn:active {
background: rgba(46, 125, 50, 1);
}
.refresh-btn {
background: rgba(25, 118, 210, 0.85);
border-color: rgba(33, 150, 243, 0.9);
}
.refresh-btn:active {
background: rgba(25, 118, 210, 1);
}
</style>