360 lines
10 KiB
Vue
360 lines
10 KiB
Vue
<template>
|
|
<view class="pkg-video-watch" v-if="ready">
|
|
|
|
<cover-view class="fixed-header flex ai-start">
|
|
<cover-view class="bold">推荐</cover-view>
|
|
<cover-view class="flex ai-center" style="margin-left: 100rpx" @click="navToCity">
|
|
<cover-view>{{ cityName }}</cover-view>
|
|
<cover-image style="width: 48rpx;height: 48rpx" :src="webUrl+'/20240113230523321737.png'" mode="scaleToFill"/>
|
|
</cover-view>
|
|
</cover-view>
|
|
|
|
<swiper style="height:100%" vertical @change="onChange">
|
|
<swiper-item v-for="(item,index) in list" :key="index">
|
|
<view class="item">
|
|
<video :id="`video-${index}`" :src="item['video']" loop :controls="false" :show-center-play-btn="false"/>
|
|
|
|
<view class="btn-play flex jc-center ai-center" @click="controlVideo">
|
|
<image style="width:57rpx;height:65rpx" :src="webUrl+'/20240123093125710999.png'" mode="scaleToFill"
|
|
v-if="showPlay"/>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="fixed-footer flex jc-between ai-end"
|
|
:style="{'bottom':systemInfo['safeAreaInsets']['bottom']+'px'}" v-if="!showDialog">
|
|
<view class="flex ai-center">
|
|
<cover-image style="width: 80rpx;height: 80rpx;border-radius: 50%;z-index: 10" :src="item['hotelLogo']"
|
|
@click="navToStore(item['hotelId'])"/>
|
|
<cover-view class="more-t">{{ item['hotelName'] }}</cover-view>
|
|
</view>
|
|
|
|
<cover-view class="flex ai-center">
|
|
<cover-view class="flex flex-col ai-center" style="width:78rpx;margin-right: 16rpx;"
|
|
@click="changeLike(item)">
|
|
<cover-image style="width: 60rpx;height: 60rpx" :src="webUrl+'/20240113230547221591.png'"
|
|
v-if="item['hasLike']"/>
|
|
<cover-image style="width: 60rpx;height: 60rpx" :src="webUrl+'/20240113230552152511.png'" v-else/>
|
|
<cover-view class="one-t tc">{{ item['likeCount'] }}</cover-view>
|
|
</cover-view>
|
|
<cover-view class="flex flex-col ai-center" style="width:78rpx;margin-right: 16rpx;"
|
|
@click="changeFav(item)">
|
|
<cover-image style="width: 60rpx;height: 60rpx" :src="webUrl+'/20240113230535491918.png'"
|
|
v-if="item['hasFavorite']"/>
|
|
<cover-image style="width: 60rpx;height: 60rpx" :src="webUrl+'/20240113230541207016.png'" v-else/>
|
|
<cover-view class="one-t tc">{{ item['favoriteCount'] }}</cover-view>
|
|
</cover-view>
|
|
<cover-view class="flex flex-col ai-center" style="width:78rpx" @click="showDialog=true">
|
|
<cover-image style="width: 60rpx;height: 60rpx" :src="webUrl+'/20240113230529202260.png'"/>
|
|
<cover-view class="one-t tc">{{ item['replyCount'] }}</cover-view>
|
|
</cover-view>
|
|
</cover-view>
|
|
</view>
|
|
</swiper-item>
|
|
</swiper>
|
|
|
|
<u-popup :show="showDialog" :round="10" mode="bottom" overlay overlayOpacity="0"
|
|
closeOnClickOverlay
|
|
@close="dialogClose" @open="dialogOpen">
|
|
<view style="z-index: 100">
|
|
<cover-view class="tc" style="padding: 20rpx 0 40rpx;font-size: 28rpx">{{
|
|
list[current]['replyCount']
|
|
}}条评论
|
|
</cover-view>
|
|
<scroll-view style="max-height: 740rpx" scroll-y @scrolltolower="fetchReply">
|
|
<view class="flex" style="margin: 0 30rpx 30rpx" v-for="(item,index) in replyList" :key="index">
|
|
<cover-image class="flex-0" style="width: 64rpx;height: 64rpx;margin-right: 18rpx;border-radius: 50%"
|
|
:src="item['userAvatar']"/>
|
|
<cover-view>
|
|
<cover-view style="color:#999999;font-size: 28rpx">{{ item['userNickname'] }}</cover-view>
|
|
<cover-view class="more-t" style="font-size: 32rpx;line-height: 48rpx">{{ item['comment'] }}</cover-view>
|
|
<cover-view style="color:#999999;font-size: 28rpx">{{ item['time'] }}</cover-view>
|
|
</cover-view>
|
|
</view>
|
|
</scroll-view>
|
|
<view class="flex jc-between ai-center" style="padding: 20rpx;border-top:2rpx solid #DCDCDC;">
|
|
<u-input :customStyle="{'border':'none','background': '#F6F6F6'}" v-model="comment"
|
|
placeholder="请输入评论..." maxlength="200" shape="circle"/>
|
|
<cover-view class="btn-submit flex jc-center ai-center" @click="onSubmit">发布</cover-view>
|
|
</view>
|
|
</view>
|
|
</u-popup>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import {ref} from '@vue/composition-api'
|
|
import {onLoad, onShow} from '@dcloudio/uni-app'
|
|
import {VUE_APP_RESOURCES_URL as webUrl} from '../../config/index'
|
|
import {getReplyList, likeVideo, randomList, removeFavoriteVideo, removeLikeVideo, submitReply} from "@/api/video";
|
|
import {addVideo} from "@/api/favorite";
|
|
import {getCurAddress, getLocation} from "@/utils/common";
|
|
|
|
const systemInfo = ref()
|
|
|
|
onLoad((options) => {
|
|
uni.getSystemInfo({
|
|
success(res) {
|
|
systemInfo.value = res
|
|
}
|
|
})
|
|
|
|
videoId.value = options.videoId || ''
|
|
const name = options.name
|
|
if (name) {
|
|
cityName.value = name
|
|
fetchList()
|
|
} else {
|
|
getMapData()
|
|
}
|
|
})
|
|
|
|
onShow(() => {
|
|
ready.value = false
|
|
setTimeout(() => {
|
|
if (cityName.value) fetchList()
|
|
}, 1000)
|
|
})
|
|
|
|
const ready = ref(false)
|
|
const cityName = ref('')
|
|
const videoId = ref('')
|
|
|
|
const navToCity = () => {
|
|
uni.redirectTo({url: '/pkg-video/views/city'})
|
|
}
|
|
|
|
const navToHome = () => {
|
|
uni.switchTab({url: '/pages/home/index'})
|
|
}
|
|
|
|
const navToStore = (id) => {
|
|
console.log(typeof id, id)
|
|
uni.navigateTo({url: '/pagesInn/inn/innHome?id=' + id})
|
|
}
|
|
|
|
const getMapData = async () => {
|
|
const map = await getLocation();
|
|
if (map.length > 1) {
|
|
const {latitude, longitude} = map[1];
|
|
const address = await getCurAddress(latitude, longitude);
|
|
cityName.value = address[1].data.result['ad_info']['city']
|
|
}
|
|
|
|
await fetchList()
|
|
}
|
|
|
|
const list = ref([])
|
|
const fetchList = async () => {
|
|
let param
|
|
if (videoId.value) {
|
|
param = {
|
|
videoId: videoId.value,
|
|
limit: 2
|
|
}
|
|
} else {
|
|
param = {
|
|
cityName: cityName.value,
|
|
limit: 2
|
|
}
|
|
}
|
|
const res = await randomList(param)
|
|
if (res.success) {
|
|
res.data?.forEach(item => list.value.push(item))
|
|
if (!ready.value && list.value.length === 0) {
|
|
uni.showModal({
|
|
title: '',
|
|
content: '当前城市还没有视频,可以先看看其他城市的喔~',
|
|
cancelText: '返回',
|
|
cancelColor: '#3A87FC',
|
|
confirmText: '选择城市',
|
|
confirmColor: '#3A87FC',
|
|
success(res) {
|
|
if (res.confirm) {
|
|
navToCity()
|
|
} else if (res.cancel) {
|
|
navToHome()
|
|
}
|
|
}
|
|
})
|
|
}
|
|
ready.value = true
|
|
if (list.value.length > 0) handleVideoPlay()
|
|
}
|
|
}
|
|
|
|
const changeLike = async (item) => {
|
|
const videoId = item['id']
|
|
if (item['hasLike']) {
|
|
const res = await removeLikeVideo(videoId)
|
|
if (res.success) {
|
|
item['hasLike'] = false
|
|
item['likeCount'] = res.data['likeCount']
|
|
}
|
|
} else {
|
|
const res = await likeVideo(videoId)
|
|
if (res.success) {
|
|
item['hasLike'] = true
|
|
item['likeCount'] = res.data['likeCount']
|
|
}
|
|
}
|
|
}
|
|
|
|
const changeFav = async (item) => {
|
|
const videoId = item['id']
|
|
if (item['hasFavorite']) {
|
|
const res = await removeFavoriteVideo(videoId)
|
|
if (res.success) {
|
|
item['hasFavorite'] = false
|
|
item['favoriteCount'] = res.data['favoriteCount']
|
|
}
|
|
} else {
|
|
const res = await addVideo(videoId)
|
|
if (res.success) {
|
|
item['hasFavorite'] = true
|
|
item['favoriteCount'] = res.data['favoriteCount']
|
|
}
|
|
}
|
|
}
|
|
|
|
const current = ref(0)
|
|
const onChange = (event) => {
|
|
current.value = event.detail.current
|
|
if (current.value + 2 >= list.value.length) fetchList()
|
|
handleVideoPlay()
|
|
}
|
|
|
|
const showPlay = ref(false)
|
|
const currentContext = ref()
|
|
const handleVideoPlay = () => {
|
|
for (let i = 0; i < list.value.length; i++) {
|
|
let id = `video-${i}`
|
|
let videoContext = uni.createVideoContext(id)
|
|
videoContext.pause()
|
|
if (current.value === i) videoContext.play()
|
|
}
|
|
}
|
|
const controlVideo = () => {
|
|
let id = `video-${current.value}`
|
|
currentContext.value = uni.createVideoContext(id)
|
|
if (showPlay.value) {
|
|
currentContext.value.play()
|
|
} else {
|
|
currentContext.value.pause()
|
|
}
|
|
showPlay.value = !showPlay.value
|
|
}
|
|
|
|
const showDialog = ref(false)
|
|
const dialogClose = () => {
|
|
showDialog.value = false
|
|
}
|
|
const dialogOpen = () => {
|
|
comment.value = ''
|
|
page.value = 1
|
|
replyList.value = []
|
|
fetchReply()
|
|
}
|
|
const comment = ref('')
|
|
const page = ref(1)
|
|
|
|
const replyList = ref([])
|
|
const fetchReply = async () => {
|
|
const id = list.value[current.value]['id']
|
|
const res = await getReplyList(id, page.value)
|
|
if (res.success && res.data['records']?.length > 0) {
|
|
res.data['records']?.forEach(item => {
|
|
item.time = uni.$u.timeFrom(Date.parse(item.createTime))
|
|
replyList.value.push(item)
|
|
})
|
|
page.value++
|
|
}
|
|
}
|
|
|
|
const onSubmit = async () => {
|
|
if (comment.value.trim().length === 0) return
|
|
const videoId = list.value[current.value]['id']
|
|
const res = await submitReply(videoId, comment.value)
|
|
if (res.success) {
|
|
uni.showToast({
|
|
title: '评论已发布',
|
|
icon: 'none',
|
|
success() {
|
|
list.value[current.value]['replyCount']++
|
|
showDialog.value = false
|
|
}
|
|
})
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="less">
|
|
.pkg-video-watch {
|
|
position: relative;
|
|
height: 100vh;
|
|
box-sizing: border-box;
|
|
background: #000000;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.fixed-header {
|
|
position: absolute;
|
|
left: 200rpx;
|
|
top: 32rpx;
|
|
color: #FFFFFF;
|
|
font-size: 44rpx;
|
|
z-index: 10;
|
|
|
|
.bold {
|
|
border-bottom: 10rpx solid #FFFFFF;
|
|
}
|
|
}
|
|
|
|
video {
|
|
width: 100vw;
|
|
height: 100vh;
|
|
}
|
|
|
|
.fixed-footer {
|
|
position: absolute;
|
|
left: 0;
|
|
width: 100vw;
|
|
box-sizing: border-box;
|
|
padding: 20rpx 32rpx;
|
|
z-index: 10;
|
|
|
|
.more-t {
|
|
width: 216rpx;
|
|
margin-left: 10rpx;
|
|
color: #FFFFFF;
|
|
font-size: 36rpx;
|
|
line-height: 52rpx;
|
|
z-index: 10;
|
|
}
|
|
|
|
.one-t {
|
|
width: 100%;
|
|
margin-top: 8rpx;
|
|
color: #FFFFFF;
|
|
font-size: 28rpx;
|
|
}
|
|
}
|
|
|
|
.btn-submit {
|
|
width: 120rpx;
|
|
height: 64rpx;
|
|
margin-left: 20rpx;
|
|
border-radius: 12rpx;
|
|
background: #FD5749;
|
|
color: #FFFFFF;
|
|
font-size: 32rpx;
|
|
}
|
|
|
|
.btn-play {
|
|
position: absolute;
|
|
left: 0;
|
|
top: 50%;
|
|
transform: translate(0, -50%);
|
|
width: 100vw;
|
|
height: 50vh;
|
|
}
|
|
</style> |