|
|
@ -5,32 +5,47 @@ |
|
|
|
<swiper :indicator-dots="false" :autoplay="true" :interval="3000" :duration="500" circular |
|
|
|
style="width: 100%; height: 400rpx;"> |
|
|
|
<swiper-item v-for="(item, index) in bannerList" :key="item.id || index"> |
|
|
|
<view v-if="item.type == 1" class="video-container" @click="playVideo(item, index)"> |
|
|
|
<view v-if="item.type == 1" class="video-container"> |
|
|
|
<!-- 预览状态:显示封面图 --> |
|
|
|
<image |
|
|
|
v-if="!videoPlayingStates[index]" |
|
|
|
:src="item.image || ''" |
|
|
|
mode="aspectFill" |
|
|
|
style="width: 100%; height: 100%;" |
|
|
|
class="video-poster" |
|
|
|
@click="playVideoFullscreen(item, index)" |
|
|
|
/> |
|
|
|
<!-- 播放状态:显示视频 --> |
|
|
|
<video |
|
|
|
v-else |
|
|
|
:id="`video-${index}`" |
|
|
|
:src="item.voUrl" |
|
|
|
:autoplay="false" |
|
|
|
:muted="true" |
|
|
|
:autoplay="true" |
|
|
|
:muted="false" |
|
|
|
:loop="false" |
|
|
|
:controls="true" |
|
|
|
:show-play-btn="true" |
|
|
|
:show-center-play-btn="true" |
|
|
|
:show-center-play-btn="false" |
|
|
|
:show-fullscreen-btn="true" |
|
|
|
:show-progress="true" |
|
|
|
:show-mute-btn="true" |
|
|
|
:enable-progress-gesture="true" |
|
|
|
:enable-play-gesture="true" |
|
|
|
object-fit="cover" |
|
|
|
:poster="item.image || ''" |
|
|
|
style="width: 100%; height: 100%;" |
|
|
|
@fullscreenchange="onFullscreenChange" |
|
|
|
@play="onVideoPlay(index)" |
|
|
|
@pause="onVideoPause(index)" |
|
|
|
@ended="onVideoEnded(index)" |
|
|
|
></video> |
|
|
|
<view v-if="!videoPlayingStates[index]" class="video-overlay"> |
|
|
|
<view class="play-button"> |
|
|
|
<uni-icons type="play-filled" size="60" color="#fff"></uni-icons> |
|
|
|
</view> |
|
|
|
<!-- 播放按钮覆盖层 --> |
|
|
|
<view v-if="!videoPlayingStates[index]" class="video-overlay" @click="playVideoFullscreen(item, index)"> |
|
|
|
<!-- <view class="play-button-large"> |
|
|
|
<uni-icons type="play-filled" size="50" color="#fff"></uni-icons> |
|
|
|
</view> --> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
<image v-else :src="item.image" mode="aspectFill" style="width: 100%; height: 100%;" /> |
|
|
|
<image v-else :src="item.image" mode="aspectFill" style="width: 100%; height: 100%;" @click="showServiceQrcode" /> |
|
|
|
</swiper-item> |
|
|
|
</swiper> |
|
|
|
</view> |
|
|
@ -180,6 +195,37 @@ |
|
|
|
</template> |
|
|
|
</uv-tabbar-item> |
|
|
|
</uv-tabbar> |
|
|
|
|
|
|
|
<!-- 客服二维码弹窗 --> |
|
|
|
<view v-if="showQrcodeModal" class="qrcode-modal-mask" @click="closeQrcodeModal"> |
|
|
|
<view class="qrcode-modal-content" @click.stop> |
|
|
|
<view class="qrcode-modal-header"> |
|
|
|
<text class="qrcode-modal-title">联系客服</text> |
|
|
|
<view class="qrcode-modal-close" @click="closeQrcodeModal"> |
|
|
|
<uni-icons type="close" size="24" color="#999"></uni-icons> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
<view class="qrcode-modal-body"> |
|
|
|
<image |
|
|
|
v-if="serviceQrcodeUrl" |
|
|
|
:src="serviceQrcodeUrl" |
|
|
|
mode="aspectFit" |
|
|
|
class="qrcode-modal-img" |
|
|
|
:show-menu-by-longpress="true" |
|
|
|
@longpress="onQrcodeLongPress" |
|
|
|
></image> |
|
|
|
<view v-else class="qrcode-placeholder"> |
|
|
|
<text>二维码加载中...</text> |
|
|
|
</view> |
|
|
|
<text class="qrcode-modal-tip">长按识别二维码添加客服微信</text> |
|
|
|
<!-- <view class="qrcode-actions"> |
|
|
|
<button class="save-btn" @click="saveQrcodeToAlbum" v-if="serviceQrcodeUrl"> |
|
|
|
保存到相册 |
|
|
|
</button> |
|
|
|
</view> --> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
</template> |
|
|
|
|
|
|
@ -194,6 +240,7 @@ |
|
|
|
priceList: [], |
|
|
|
records: [], |
|
|
|
videoPlayingStates: {}, // 记录每个视频的播放状态 |
|
|
|
showQrcodeModal: false, // 控制二维码弹窗显示 |
|
|
|
destinations: [ |
|
|
|
// { |
|
|
|
// icon: '/static/home/爱心援乡.png', |
|
|
@ -242,6 +289,10 @@ |
|
|
|
sbk_cion() { |
|
|
|
const item = getApp().globalData.configData.find(i => i.keyName === 'sbk_cion') |
|
|
|
return item ? item.keyContent : '' |
|
|
|
}, |
|
|
|
serviceQrcodeUrl() { |
|
|
|
const item = getApp().globalData.configData.find(i => i.keyName === 'kefu_code') |
|
|
|
return item ? item.keyContent : '' |
|
|
|
} |
|
|
|
}, |
|
|
|
methods: { |
|
|
@ -370,15 +421,120 @@ |
|
|
|
}, |
|
|
|
|
|
|
|
// 视频相关方法 |
|
|
|
playVideo(item, index) { |
|
|
|
const videoContext = uni.createVideoContext(`video-${index}`, this); |
|
|
|
if (this.videoPlayingStates[index]) { |
|
|
|
// 如果正在播放,暂停视频 |
|
|
|
videoContext.pause(); |
|
|
|
} else { |
|
|
|
// 如果未播放,开始播放 |
|
|
|
videoContext.play(); |
|
|
|
playVideoFullscreen(item, index) { |
|
|
|
if (!this.videoPlayingStates[index]) { |
|
|
|
// 第一次点击:显示视频并开始播放 |
|
|
|
this.$set(this.videoPlayingStates, index, true); |
|
|
|
|
|
|
|
// 等待视频元素渲染后再进行操作 |
|
|
|
this.$nextTick(() => { |
|
|
|
setTimeout(() => { |
|
|
|
const videoContext = uni.createVideoContext(`video-${index}`, this); |
|
|
|
if (videoContext) { |
|
|
|
// 直接进入全屏播放 |
|
|
|
videoContext.requestFullScreen({ |
|
|
|
direction: -1 // 自动选择方向 |
|
|
|
}); |
|
|
|
} |
|
|
|
}, 200); |
|
|
|
}); |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
// 显示客服二维码弹窗 |
|
|
|
showServiceQrcode() { |
|
|
|
this.showQrcodeModal = true; |
|
|
|
}, |
|
|
|
|
|
|
|
// 关闭二维码弹窗 |
|
|
|
closeQrcodeModal() { |
|
|
|
this.showQrcodeModal = false; |
|
|
|
}, |
|
|
|
|
|
|
|
// 处理二维码长按事件 |
|
|
|
onQrcodeLongPress() { |
|
|
|
console.log('长按二维码'); |
|
|
|
// 在微信小程序中,show-menu-by-longpress="true" 会自动处理长按识别 |
|
|
|
// 这里可以添加一些反馈提示 |
|
|
|
uni.showToast({ |
|
|
|
title: '长按识别二维码', |
|
|
|
icon: 'none', |
|
|
|
duration: 1500 |
|
|
|
}); |
|
|
|
}, |
|
|
|
|
|
|
|
// 保存二维码到相册 |
|
|
|
saveQrcodeToAlbum() { |
|
|
|
if (!this.serviceQrcodeUrl) { |
|
|
|
uni.showToast({ |
|
|
|
title: '二维码还未加载完成', |
|
|
|
icon: 'none' |
|
|
|
}); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 先授权相册权限 |
|
|
|
uni.getSetting({ |
|
|
|
success: (res) => { |
|
|
|
if (!res.authSetting['scope.writePhotosAlbum']) { |
|
|
|
// 没有权限,申请权限 |
|
|
|
uni.authorize({ |
|
|
|
scope: 'scope.writePhotosAlbum', |
|
|
|
success: () => { |
|
|
|
this.doSaveQrcodeImage(); |
|
|
|
}, |
|
|
|
fail: () => { |
|
|
|
// 权限被拒绝,引导用户手动开启 |
|
|
|
uni.showModal({ |
|
|
|
title: '提示', |
|
|
|
content: '需要您授权保存相册权限', |
|
|
|
showCancel: false, |
|
|
|
success: () => { |
|
|
|
uni.openSetting(); |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
}); |
|
|
|
} else { |
|
|
|
// 已有权限,直接保存 |
|
|
|
this.doSaveQrcodeImage(); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}, |
|
|
|
|
|
|
|
// 执行保存二维码图片 |
|
|
|
doSaveQrcodeImage() { |
|
|
|
uni.downloadFile({ |
|
|
|
url: this.serviceQrcodeUrl, |
|
|
|
success: (res) => { |
|
|
|
if (res.statusCode === 200) { |
|
|
|
uni.saveImageToPhotosAlbum({ |
|
|
|
filePath: res.tempFilePath, |
|
|
|
success: () => { |
|
|
|
uni.showToast({ |
|
|
|
title: '保存成功', |
|
|
|
icon: 'success' |
|
|
|
}); |
|
|
|
}, |
|
|
|
fail: (err) => { |
|
|
|
console.log('保存失败', err); |
|
|
|
uni.showToast({ |
|
|
|
title: '保存失败', |
|
|
|
icon: 'none' |
|
|
|
}); |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
}, |
|
|
|
fail: (err) => { |
|
|
|
console.log('下载失败', err); |
|
|
|
uni.showToast({ |
|
|
|
title: '下载失败', |
|
|
|
icon: 'none' |
|
|
|
}); |
|
|
|
} |
|
|
|
}); |
|
|
|
}, |
|
|
|
|
|
|
|
onVideoPlay(index) { |
|
|
@ -389,8 +545,23 @@ |
|
|
|
this.$set(this.videoPlayingStates, index, false); |
|
|
|
}, |
|
|
|
|
|
|
|
onVideoEnded(index) { |
|
|
|
// 视频播放结束,回到预览状态 |
|
|
|
this.$set(this.videoPlayingStates, index, false); |
|
|
|
}, |
|
|
|
|
|
|
|
onFullscreenChange(e) { |
|
|
|
console.log('全屏状态改变:', e.detail); |
|
|
|
const videoIndex = e.target.id.replace('video-', ''); |
|
|
|
|
|
|
|
if (e.detail.fullScreen) { |
|
|
|
// 进入全屏时,不做任何操作 |
|
|
|
console.log('进入全屏模式,方向:', e.detail.direction); |
|
|
|
} else { |
|
|
|
// 退出全屏时,回到预览状态 |
|
|
|
console.log('退出全屏模式,回到预览状态'); |
|
|
|
this.$set(this.videoPlayingStates, videoIndex, false); |
|
|
|
} |
|
|
|
}, |
|
|
|
// 初始化页面数据的方法 |
|
|
|
initializePageData() { |
|
|
@ -487,6 +658,15 @@ |
|
|
|
width: 100%; |
|
|
|
height: 100%; |
|
|
|
|
|
|
|
.video-poster { |
|
|
|
cursor: pointer; |
|
|
|
transition: transform 0.2s ease; |
|
|
|
|
|
|
|
&:active { |
|
|
|
transform: scale(0.98); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
.video-overlay { |
|
|
|
position: absolute; |
|
|
|
top: 0; |
|
|
@ -494,21 +674,28 @@ |
|
|
|
right: 0; |
|
|
|
bottom: 0; |
|
|
|
background: rgba(0, 0, 0, 0.3); |
|
|
|
z-index: 10; |
|
|
|
cursor: pointer; |
|
|
|
display: flex; |
|
|
|
flex-direction: column; |
|
|
|
justify-content: center; |
|
|
|
align-items: center; |
|
|
|
z-index: 10; |
|
|
|
|
|
|
|
.play-button { |
|
|
|
width: 120rpx; |
|
|
|
height: 120rpx; |
|
|
|
background: rgba(0, 0, 0, 0.6); |
|
|
|
.play-button-large { |
|
|
|
width: 100rpx; |
|
|
|
height: 100rpx; |
|
|
|
background: rgba(0, 0, 0, 0.7); |
|
|
|
border-radius: 50%; |
|
|
|
display: flex; |
|
|
|
justify-content: center; |
|
|
|
align-items: center; |
|
|
|
backdrop-filter: blur(10rpx); |
|
|
|
transition: all 0.3s ease; |
|
|
|
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.3); |
|
|
|
|
|
|
|
&:active { |
|
|
|
transform: scale(0.9); |
|
|
|
background: rgba(0, 0, 0, 0.8); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -1031,4 +1218,110 @@ |
|
|
|
transform: scale(1); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 客服二维码弹窗样式 |
|
|
|
.qrcode-modal-mask { |
|
|
|
position: fixed; |
|
|
|
top: 0; |
|
|
|
left: 0; |
|
|
|
right: 0; |
|
|
|
bottom: 0; |
|
|
|
background: rgba(0, 0, 0, 0.6); |
|
|
|
display: flex; |
|
|
|
justify-content: center; |
|
|
|
align-items: center; |
|
|
|
z-index: 9999; |
|
|
|
backdrop-filter: blur(5rpx); |
|
|
|
} |
|
|
|
|
|
|
|
.qrcode-modal-content { |
|
|
|
background: #fff; |
|
|
|
border-radius: 24rpx; |
|
|
|
width: 600rpx; |
|
|
|
max-width: 90vw; |
|
|
|
animation: fadeInScale 0.3s ease; |
|
|
|
overflow: hidden; |
|
|
|
} |
|
|
|
|
|
|
|
.qrcode-modal-header { |
|
|
|
display: flex; |
|
|
|
justify-content: space-between; |
|
|
|
align-items: center; |
|
|
|
padding: 40rpx 40rpx 20rpx 40rpx; |
|
|
|
border-bottom: 1rpx solid #f0f0f0; |
|
|
|
} |
|
|
|
|
|
|
|
.qrcode-modal-title { |
|
|
|
font-size: 36rpx; |
|
|
|
font-weight: bold; |
|
|
|
color: #333; |
|
|
|
} |
|
|
|
|
|
|
|
.qrcode-modal-close { |
|
|
|
padding: 10rpx; |
|
|
|
margin: -10rpx; |
|
|
|
} |
|
|
|
|
|
|
|
.qrcode-modal-body { |
|
|
|
padding: 40rpx; |
|
|
|
display: flex; |
|
|
|
flex-direction: column; |
|
|
|
align-items: center; |
|
|
|
} |
|
|
|
|
|
|
|
.qrcode-modal-img { |
|
|
|
width: 400rpx; |
|
|
|
height: 400rpx; |
|
|
|
border-radius: 16rpx; |
|
|
|
margin-bottom: 30rpx; |
|
|
|
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1); |
|
|
|
} |
|
|
|
|
|
|
|
.qrcode-placeholder { |
|
|
|
width: 400rpx; |
|
|
|
height: 400rpx; |
|
|
|
border-radius: 16rpx; |
|
|
|
margin-bottom: 30rpx; |
|
|
|
background: #f5f5f5; |
|
|
|
display: flex; |
|
|
|
justify-content: center; |
|
|
|
align-items: center; |
|
|
|
|
|
|
|
text { |
|
|
|
color: #999; |
|
|
|
font-size: 28rpx; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
.qrcode-modal-tip { |
|
|
|
font-size: 28rpx; |
|
|
|
color: #666; |
|
|
|
text-align: center; |
|
|
|
line-height: 1.4; |
|
|
|
margin-bottom: 20rpx; |
|
|
|
} |
|
|
|
|
|
|
|
.qrcode-actions { |
|
|
|
display: flex; |
|
|
|
justify-content: center; |
|
|
|
margin-top: 20rpx; |
|
|
|
} |
|
|
|
|
|
|
|
.save-btn { |
|
|
|
background: linear-gradient(90deg, #ff8917, #ffd01e); |
|
|
|
color: #fff; |
|
|
|
border: none; |
|
|
|
border-radius: 25rpx; |
|
|
|
padding: 16rpx 40rpx; |
|
|
|
font-size: 28rpx; |
|
|
|
font-weight: bold; |
|
|
|
|
|
|
|
&::after { |
|
|
|
border: none; |
|
|
|
} |
|
|
|
|
|
|
|
&:active { |
|
|
|
opacity: 0.8; |
|
|
|
} |
|
|
|
} |
|
|
|
</style> |