Files
xdd-uniapp-new/pages/VideoPlayBackList/VideoPlayBackList.vue
T

256 lines
6.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view>
<view class="type-list flex ai-center">
<view class="item" :class="{'active':type===item.value}" v-for="(item,index) in typeList" :key="index"
@click="changeType(item)">{{ item.label }}
</view>
</view>
<view class="list" v-show="hasList">
<view class="video-waterfalls-wrap">
<view class="waterfalls-column">
<view class="item" v-for="(item,index) in leftList" :key="item.id || index" @click="goDetail(item)">
<image class="cover" :src="item.cover" mode="widthFix" lazy-load></image>
<view class="content">
<view class="title more-t">{{ item.title }}</view>
<view class="footer flex jc-between ai-center">
<view class="visit flex ai-center">
<image class="icon" style="margin-right: 8rpx" :src="item.storeLogo" mode="scaleToFill"></image>
{{ item.storeName }}
</view>
<image class="icon flex-0" :src="webUrl+'/20210806121203835373.png'" mode="scaleToFill"></image>
</view>
</view>
</view>
</view>
<view class="waterfalls-column">
<view class="item" v-for="(item,index) in rightList" :key="item.id || index" @click="goDetail(item)">
<image class="cover" :src="item.cover" mode="widthFix" lazy-load></image>
<view class="content">
<view class="title more-t">{{ item.title }}</view>
<view class="footer flex jc-between ai-center">
<view class="visit flex ai-center">
<image class="icon" style="margin-right: 8rpx" :src="item.storeLogo" mode="scaleToFill"></image>
{{ item.storeName }}
</view>
<image class="icon flex-0" :src="webUrl+'/20210806121203835373.png'" mode="scaleToFill"></image>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="v4-nodata" v-show="!hasList">
<image src="@/static/images/img_nodata.png" mode="scaleToFill"/>
<view class="text">暂无数据</view>
</view>
</view>
</template>
<script>
import {getStoreVideoType, getArticleList} from '@/api/public'
import {getVideoList} from '@/api/user'
import { pageListenMixins } from '@/mixins/pageListenMixins'
// 封面固定宽度(rpx
const COVER_WIDTH = 332
// 每项除封面外的文字内容预估高度(rpx)
const TEXT_HEIGHT = 120
export default {
mixins: [pageListenMixins],
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
typeList: [{'label': '全部', 'value': ''}],
type: '',
page: 1,
limit: 10,
keyword: '',
leftList: [],
rightList: [],
leftHeight: 0,
rightHeight: 0,
isWait: false,
pageKeyId: Object.freeze('findVideoList')
}
},
computed: {
hasList() {
return this.leftList.length + this.rightList.length > 0
}
},
onLoad(options) {
if (!options.click) {
uni.switchTab({ url: '/pages/home/index' })
return
}
this.getType()
this.fetchList()
},
onReachBottom() {
this.page++
this.fetchList()
},
methods: {
getType() {
getStoreVideoType().then(({data}) => {
if (data.length > 0) {
data.forEach(item => {
this.typeList.push(item)
})
}
})
},
changeType(item) {
this.type = item.value
this.page = 1
this.resetList()
this.fetchList()
},
resetList() {
this.leftList = []
this.rightList = []
this.leftHeight = 0
this.rightHeight = 0
},
async fetchList() {
if (this.isWait) return
this.isWait = true
const params = {
type: this.type,
page: this.page,
limit: this.limit
}
try {
const res = await getVideoList(params)
if (res.status === 200) {
const items = res.data
for (let i = 0; i < items.length; i++) {
items[i].hide = true
}
// 并行获取所有封面高度
const heights = await Promise.all(items.map(item => this.getImageHeight(item.cover)))
items.forEach((item, i) => {
this.pushToColumn(item, heights[i] + TEXT_HEIGHT)
})
}
} catch (e) {
// 忽略请求或图片尺寸获取失败
} finally {
this.isWait = false
}
},
getImageHeight(src) {
return new Promise(resolve => {
uni.getImageInfo({
src,
success: res => {
resolve(res.height / res.width * COVER_WIDTH)
},
fail: () => {
resolve(COVER_WIDTH)
}
})
})
},
pushToColumn(item, height) {
if (this.leftHeight <= this.rightHeight) {
this.leftList.push(item)
this.leftHeight += height
} else {
this.rightList.push(item)
this.rightHeight += height
}
},
goDetail(item) {
this.$yrouter.push("/pages/VideoPlayBackList/VideoPlayBackDetail?videoUrl=" + item.video + '&id=' + item.id + '&click=1')
}
}
}
</script>
<style lang="less">
.type-list {
margin: 28rpx 32rpx;
.item {
margin-right: 20rpx;
padding: 12rpx 16rpx;
border-radius: 20rpx;
background: #fff;
font-size: 26rpx;
white-space: nowrap;
}
.active {
background: #f66;
color: #fff;
}
}
.list {
margin: 28rpx 32rpx;
.video-waterfalls-wrap {
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.waterfalls-column {
width: 332rpx;
}
.item {
margin-bottom: 20rpx;
border-radius: 4rpx;
background: #fff;
.cover {
width: 332rpx;
vertical-align: middle;
}
.title {
padding: 12rpx 16rpx;
font-size: 26rpx;
font-weight: bold;
line-height: 38rpx;
color: #333;
}
.mark {
margin: 14rpx 16rpx;
font-size: 22rpx;
line-height: 32rpx;
color: #999;
}
.footer {
padding: 12rpx 16rpx 16rpx;
border-top: 1rpx solid #E1E1E1;
font-size: 22rpx;
}
.icon {
width: 40rpx;
height: 40rpx;
vertical-align: middle;
border-radius: 50%;
}
.visit {
width: 100%;
color: #333;
overflow: hidden;
}
.time {
color: #999;
}
}
}
</style>