<template>
|
<view :data-theme='theme()' :class="theme() || ''">
|
<view class="album-container">
|
<view class="top-box bg-white">
|
<view class="d-b-c p20 pt10">
|
<view class="inner-tab">
|
<view class="item" :class="{'active':file_type=='image'}" @click="changeFileType('image')">
|
<view class="box">活动照片</view>
|
</view>
|
<view class="item" :class="{'active':file_type=='video'}" @click="changeFileType('video')">
|
<view class="box">活动视频</view>
|
</view>
|
</view>
|
<view class="top-add d-s-c f24" @click="openUpload">
|
<text class="iconfont icon-ziyuan2 f26 mr10"></text>
|
<text>上传{{ file_type=='image'?'照片':'视频' }}</text>
|
</view>
|
</view>
|
</view>
|
<scroll-view scroll-y="true" class="scroll-Y" :style="'height:' + scrollviewHigh + 'px;'" :show-scrollbar="false" @scroll="handleScroll" lower-threshold="50" @scrolltolower="scrolltolowerFunc">
|
<!-- 图片 -->
|
<view class="album-box d-s-s f-w" v-if="file_type=='image'">
|
<view class="album-item" v-for="(item, index) in listData" :key="index" @click="previewImage(index)">
|
<image class="image" :src="item.file_path" mode="aspectFill" lazy-load></image>
|
</view>
|
</view>
|
<!-- 视频 -->
|
<view class="album-box album-video" v-else>
|
<view class="video-item" :id="'videoItem' + item.file_id" v-for="(item, index) in listData" :key="item.file_id">
|
<video
|
:id="'video' + item.file_id"
|
class="video radius24"
|
:src="item.file_path"
|
:controls="true"
|
:enable-progress-gesture="true"
|
object-fit="cover"
|
:autoplay="false"
|
@play="onVideoPlay(item.file_id)"
|
@pause="onVideoPause"
|
@ended="onVideoEnded"
|
></video>
|
</view>
|
</view>
|
<!-- 没有记录 -->
|
<view class="none-data-box" v-if="listData.length==0">
|
<image :src="remoteImg('no_thing')" mode="widthFix"></image>
|
<text>暂无数据</text>
|
</view>
|
<uni-load-more v-else :loadingType="loadingType"></uni-load-more>
|
</scroll-view>
|
</view>
|
<!-- 上传文件 -->
|
<Upload v-if="isupload" :file_type="file_type" :is_original="true" @getImgs="returnImgsFunc"></Upload>
|
<!-- 图片预览 -->
|
<imagePreview ref="image_preview" :show="showPreview" :images="previewImages" @close="closePreview" @delete="handleDeleteImage"></imagePreview>
|
</view>
|
</template>
|
|
<script>
|
import uniLoadMore from '@/components/uni-load-more.vue';
|
import imagePreview from './popup/imagePreview.vue';
|
import Upload from '@/components/upload/upload.vue';
|
export default {
|
components: {
|
uniLoadMore,
|
imagePreview, // 图片预览
|
Upload
|
},
|
data() {
|
return {
|
/*手机高度*/
|
phoneHeight: 0,
|
/*可滚动视图区域高度*/
|
scrollviewHigh: 0,
|
/*是否可见*/
|
Visible: false,
|
listData: [],
|
file_type: 'image',
|
/*最后一页码数*/
|
last_page: 0,
|
/*当前页面*/
|
page: 1,
|
/*每页条数*/
|
list_rows: 10,
|
/*有没有更多*/
|
no_more: false,
|
/*是否正在加载*/
|
loading: false,
|
previewIndex: 0, // 当前预览的图片索引
|
previewImages: [],
|
showPreview: false, // 是否显示预览
|
// 视频相关
|
currentPlayId: null, // 当前正在播放的视频id
|
scrollTimer: null, // 防抖计时器
|
lastScrollTop: 0, // 记录上次滚动位置
|
activity_id: '',
|
isupload: false,
|
};
|
},
|
computed: {
|
/*加载中状态*/
|
loadingType() {
|
if (this.loading) {
|
return 1;
|
} else {
|
if (this.listData.length != 0 && this.no_more) {
|
return 2;
|
} else {
|
return 0;
|
}
|
}
|
}
|
},
|
onLoad(e) {
|
this.activity_id = e.activity_id;
|
},
|
mounted() {
|
this.init();
|
this.getData();
|
},
|
watch: {
|
isOpenAlbum: function(n, o) {
|
if (n != o) {
|
this.Visible = n;
|
}
|
}
|
},
|
created() {
|
|
},
|
// 页面卸载时清除定时器
|
onUnload() {
|
if (this.scrollTimer) {
|
clearTimeout(this.scrollTimer);
|
}
|
},
|
methods: {
|
/*初始化*/
|
init() {
|
let _this = this;
|
uni.getSystemInfo({
|
success(res) {
|
_this.phoneHeight = res.windowHeight;
|
// 计算组件的高度
|
let view = uni.createSelectorQuery().select('.top-box');
|
view.boundingClientRect(data => {
|
let h = _this.phoneHeight - data.height;
|
_this.scrollviewHigh = h;
|
}).exec();
|
}
|
});
|
},
|
|
/*初始化列表数据*/
|
initData() {
|
this.page = 1;
|
this.last_page = 0;
|
this.listData = [];
|
},
|
|
/*获取数据*/
|
getData() {
|
let self = this;
|
self.loading = true;
|
self._get(
|
'branch.admin.activityFile/lists', {
|
activity_id: self.activity_id,
|
file_type: self.file_type,
|
page: self.page,
|
list_rows: self.list_rows,
|
// pay_source: self.getPlatform(),
|
},
|
function(res) {
|
self.loading = false;
|
self.listData = self.listData.concat(res.data.list.data);
|
self.last_page = res.data.list.last_page;
|
if (res.data.list.last_page <= 1) {
|
self.no_more = true;
|
} else {
|
self.no_more = false;
|
}
|
}
|
);
|
},
|
|
/*上传*/
|
openUpload() {
|
this.isupload = true;
|
},
|
|
/*获取图片*/
|
returnImgsFunc(e) {
|
let self = this;
|
if (e != null) {
|
let form = [];
|
e.forEach((item) => {
|
form.push({
|
activity_id: self.activity_id,
|
file_id: item.file_id,
|
file_type: self.file_type
|
});
|
});
|
setTimeout(() => {
|
// 保存文件
|
self._post(
|
'branch.admin.activityFile/add', {formData: JSON.stringify(form)},
|
function(res) {
|
self.initData();
|
self.getData();
|
uni.hideLoading();
|
uni.showToast({
|
title: '上传成功',
|
duration: 1000,
|
icon: 'success'
|
});
|
}
|
);
|
}, 500)
|
|
}
|
this.isupload = false;
|
},
|
|
// 防抖函数
|
debounce(func, wait) {
|
return (...args) => {
|
clearTimeout(this.scrollTimer)
|
this.scrollTimer = setTimeout(() => {
|
func.apply(this, args)
|
}, wait)
|
}
|
},
|
|
// 滚动处理函数 - 使用防抖优化
|
handleScroll(e) {
|
// 立即更新滚动位置,用于判断滚动方向
|
const scrollTop = e.detail.scrollTop
|
const scrollDirection = scrollTop > this.lastScrollTop ? 'down' : 'up'
|
|
// 只在向下滚动时检查视频可见性
|
if (scrollDirection === 'down') {
|
// 使用防抖处理滚动检查
|
this.debounceScrollCheck(scrollTop)
|
}
|
|
// 保存当前滚动位置
|
this.lastScrollTop = scrollTop
|
},
|
|
// 防抖后的滚动检查
|
debounceScrollCheck: function() {
|
// 防抖包装,实际执行的是这个函数
|
return this.debounce(function(scrollTop) {
|
// 如果没有正在播放的视频,直接返回
|
if (!this.currentPlayId) return
|
|
// 获取当前播放视频的位置
|
this.checkVideoVisibility(this.currentPlayId)
|
}, 150) // 150ms延迟,可根据需要调整
|
},
|
|
// 检查视频可见性
|
checkVideoVisibility(videoId) {
|
const query = uni.createSelectorQuery().in(this)
|
query.select('#videoItem' + videoId).boundingClientRect()
|
query.exec(res => {
|
if (res[0]) {
|
const rect = res[0]
|
const windowHeight = uni.getSystemInfoSync().windowHeight
|
|
// 判断视频是否完全滑出可视区域
|
// 这里可以调整阈值,例如当视频顶部距离屏幕底部超过一定距离时暂停
|
if (rect.bottom < -50 || rect.top > windowHeight + 50) {
|
this.pauseVideo(videoId)
|
}
|
}
|
})
|
},
|
|
// 播放视频
|
playVideo(id) {
|
// 如果之前有播放的视频,先停止
|
if (this.currentPlayId && this.currentPlayId !== id) {
|
this.pauseVideo(this.currentPlayId)
|
}
|
|
this.currentPlayId = id
|
this.$nextTick(() => {
|
const videoContext = uni.createVideoContext('video' + id, this)
|
videoContext.play()
|
})
|
},
|
|
// 暂停视频
|
pauseVideo(id) {
|
const videoContext = uni.createVideoContext('video' + id, this)
|
videoContext.pause()
|
// 如果暂停的是当前播放的视频,清空currentPlayId
|
if (this.currentPlayId === id) {
|
this.currentPlayId = null
|
}
|
},
|
|
onVideoPlay(id) {
|
console.log('视频开始播放:', id)
|
this.playVideo(id);
|
// this.currentPlayId = id
|
},
|
|
onVideoPause() {
|
console.log('视频暂停')
|
},
|
|
onVideoEnded() {
|
console.log('视频播放结束')
|
this.currentPlayId = null
|
},
|
|
/*可滚动视图区域到底触发*/
|
scrolltolowerFunc() {
|
let self = this;
|
if (self.no_more) {
|
return;
|
}
|
self.page++;
|
if (self.page <= self.last_page) {
|
self.getData();
|
} else {
|
self.no_more = true;
|
}
|
},
|
|
changeFileType(e) {
|
this.file_type = e;
|
this.initData();
|
this.getData();
|
},
|
|
// 显示预览
|
previewImage(e) {
|
this.previewIndex = e;
|
this.previewImages = this.listData.map(item => {
|
return {
|
file_id: item.file_id,
|
file_path: item.file_path,
|
file_type: item.file_type,
|
is_original: item.is_original,
|
};
|
});
|
this.showPreview = true;
|
this.$refs.image_preview.current = e;
|
},
|
|
// 关闭预览
|
closePreview() {
|
this.showPreview = false;
|
},
|
|
/*关闭弹窗*/
|
closePopup(e) {
|
this.$emit('close', e);
|
}
|
}
|
};
|
</script>
|
|
<style lang="scss" scoped>
|
.top-box {
|
.inner-tab {
|
position: relative;
|
width: 360rpx;
|
height: 70rpx;
|
display: flex;
|
justify-content: space-around;
|
align-items: center;
|
background: #ffffff;
|
z-index: 9;
|
.item {
|
flex: 1;
|
height: 100%;
|
line-height: 70rpx;
|
position: relative;
|
color: #999;
|
font-size: 28rpx;
|
&.active {
|
color: #333333;
|
font-weight: bold;
|
&::after {
|
content: '';
|
width: 72rpx;
|
height: 4rpx;
|
background: #EE1414;
|
border-radius: 2rpx;
|
position: absolute;
|
bottom: 6rpx;
|
left: 0;
|
right: 0;
|
margin: auto;
|
}
|
}
|
.box {
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
flex-direction: row;
|
}
|
}
|
}
|
.top-add {
|
@include background_color('background_color');
|
height: 60rpx;
|
border-radius: 80rpx;
|
color: #ffffff;
|
padding: 0 20rpx;
|
margin-left: 30rpx;
|
|
.iconfont {
|
color: #ffffff;
|
}
|
}
|
}
|
|
.album-box {
|
padding: 15rpx 15rpx;
|
.album-item {
|
width: 50%;
|
padding: 15rpx;
|
box-sizing: border-box;
|
.image {
|
width: 100%;
|
height: 220rpx;
|
border-radius: 12rpx;
|
}
|
}
|
}
|
|
.album-video {
|
.video-item {
|
padding: 15rpx;
|
.video {
|
width: 100%;
|
height: 380rpx;
|
}
|
}
|
}
|
|
</style>
|