new_app/components/my-video-list/my-video-list.vue

1338 lines
31 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>
<list
v-if="showAndriod"
:bounce="false"
:loadmoreoffset="wHeight * 3"
:show-scrollbar="false"
ref="listBox"
:pagingEnabled="true"
@loadmore="loadmore"
:scrollable="scrollable"
>
<cell v-for="(item, index) in list" :key="item.courseDetailsId" :ref="setRefList(index)">
<view class="swipers-items" :style="boxStyle" @longpress="popupShow('speed')">
<list-item-vue
:total="list.length"
:item="item"
:current="current"
:isCollect="isCollect"
:isAndriod="isAndriod"
:showAndriod="showAndriod"
:isIos="isIos"
:isH5="isH5"
:isTabbar="isTabbar"
@playStatusChange="playStatusChange"
:height="wHeight"
:isCommand="isCommand"
:showControls="control.showControls"
@toDetail="toDetail(item, index)"
@itemMounted="itemMounted"
@controlstoggles="controlstoggles"
:index="index"
:instance="instance"
:nowIndex="nowIndex"
@appear="appear($event, item, index)"
:playSpeeds="playSpeeds"
@disappear="disappear($event, item, index)"
@dianzanClick="dianzanClick(item, index)"
@share="share(item)"
@zhuijuClick="zhuijuClick(item)"
@progressScroll="progressScroll"
@progressScrollEnd="progressScrollEnd"
@popupShow="popupShow($event, item, index)"
></list-item-vue>
</view>
</cell>
</list>
<view v-if="isH5 || isIos" class="w-full box" style="width: 100vw">
<swiper
@longpress="popupShow('speed')"
:style="{ height: wHeight + 'px' }"
v-if="videoList.length"
@change="swiperChange"
:current="current"
:circular="true"
vertical
class="u-flex-1"
@transition="transition"
:indicator-dots="false"
:autoplay="false"
:interval="0"
:duration="200"
>
<swiper-item v-for="(item, index) in videoList" :key="index">
<list-item-vue
:total="list.length"
:item="item"
:isCommand="isCommand"
:height="wHeight"
:isAndriod="isAndriod"
:showAndriod="showAndriod"
:isIos="isIos"
:isH5="isH5"
:isTabbar="isTabbar"
@playStatusChange="playStatusChange"
:showControls="control.showControls"
:current="current"
:isCollect="isCollect"
@toDetail="toDetail(item, index)"
@controlstoggles="controlstoggles"
:playSpeeds="playSpeeds"
:index="index"
:nowIndex="nowIndex"
@dianzanClick="dianzanClick(item, index)"
@share="share(item)"
@zhuijuClick="zhuijuClick(item)"
@popupShow="popupShow($event, item, index)"
></list-item-vue>
</swiper-item>
</swiper>
</view>
<!-- 返回按钮 -->
<view class="back-icon" v-if="!isTabbar && control.showBack">
<u-icon name="arrow-left" color="#fff" :size="28" @click="back"></u-icon>
</view>
<!-- 选集 -->
<up-overlay :show="popup.show" @click="popupClose('show')">
<view class="u-p-30 bg-fff xuanji-box">
<view class="u-flex u-flex-row u-row-between">
<view class="u-flex u-flex-row" style="align-items: baseline">
<text class="color-333 u-font-32">{{ info.title }}</text>
<text class="u-font-28 color-666 u-m-l-20">共{{ list.length }}集</text>
</view>
<up-icon name="close" :size="16" color="#333" bold @click="popupClose('show')"></up-icon>
</view>
<scroll-view scroll-y="true" class="u-m-t-30 xuanji-scroll" :style="{ height: xuanjiData.height + 'px' }" :scroll-top="xuanjiData.scrollTop" :show-scrollbar="false">
<view class="ji-list u-flex u-flex-row u-flex-wrap">
<view
class="ji-item u-flex-xy-center u-text-center"
@click="jiClick(item, index)"
:class="[nowIndex == index ? 'active' : '', (index + 1) % 3 == 0 ? 'mr-0' : '', 'ji-item' + index]"
v-for="(item, index) in list"
:key="index"
>
<text class="u-font-28" :class="{ 'color-fff': nowIndex == index }">第{{ index + 1 }}集</text>
<view class="lock u-flex-xy-center" v-if="!item.videoUrl">
<up-icon name="lock" :size="14" color="#fff"></up-icon>
<!-- <image class="lock-icon" src="@/static/images/lock.png" mode=""></image> -->
</view>
<image v-if="nowIndex == index" class="playing" src="@/static/images/playIng.png" mode=""></image>
</view>
</view>
</scroll-view>
</view>
</up-overlay>
<!-- 暂时舍弃因为在ios上会有奇怪问题导致经常不出现 -->
<!-- 选集-->
<!-- <view class="mask" :class="{'mask-show':popup.show}">
<view class="u-p-30 bg-fff box">
<view class="u-flex u-flex-row u-row-between">
<view class="u-flex u-flex-row" style="align-items: baseline;">
<text class="color-333 u-font-32 ">{{info.title}}</text>
<text class="u-font-28 color-666 u-m-l-20">共{{list.length}}集</text>
</view>
<up-icon name="close" :size="16" color="#333" bold @click="popupClose('show')"></up-icon>
</view>
<view :style="{height:xuanjiData.height+'px',overflow:'hidden'}">
<scroll-view scroll-y="true" class="u-m-t-30 xuanji-scroll" :style="{height:xuanjiData.height+'px'}"
:scroll-top="xuanjiData.scrollTop" :show-scrollbar="false">
<view class="ji-list u-flex u-flex-row u-flex-wrap">
<view class="ji-item u-flex-xy-center u-text-center" @click="jiClick(item,index)"
:class="[nowIndex==index?'active':'',(index+1)%3==0?'mr-0':'','ji-item'+index]"
v-for="(item,index) in list" :key="index">
<text class="u-font-28" :class="{'color-fff':nowIndex==index}">第{{index+1}}集</text>
<view class="lock u-flex-xy-center" v-if="!item.videoUrl">
<up-icon name="lock" :size="14" color="#fff"></up-icon>
</view>
<image v-if="nowIndex==index" class="playing" src="@/static/images/playIng.png" mode="">
</image>
</view>
</view>
</scroll-view>
</view>
</view>
</view> -->
<up-popup :show="popup.show1" :round="10" @close="popupClose('show')" :customStyle="customStyle">
<view class="u-p-30">
<view class="u-flex u-flex-row u-row-between">
<view class="u-flex u-flex-row" style="align-items: baseline">
<text class="color-333 u-font-32">{{ info.title }}</text>
<text class="u-font-28 color-666 u-m-l-20">共{{ list.length }}集</text>
</view>
<up-icon name="close" :size="16" color="#333" bold @click="popupClose('show')"></up-icon>
</view>
<view :style="{ height: xuanjiData.height + 'px', overflow: 'hidden' }">
<scroll-view
scroll-y="true"
class="u-m-t-30 xuanji-scroll"
:style="{ height: xuanjiData.height + 'px' }"
:scroll-top="xuanjiData.scrollTop"
:show-scrollbar="false"
>
<view class="ji-list u-flex u-flex-row u-flex-wrap">
<view
class="ji-item u-flex-xy-center u-text-center"
@click="jiClick(item, index)"
:class="[nowIndex == index ? 'active' : '', (index + 1) % 3 == 0 ? 'mr-0' : '', 'ji-item' + index]"
v-for="(item, index) in list"
:key="index"
>
<text class="u-font-28" :class="{ 'color-fff': nowIndex == index }">第{{ index + 1 }}集</text>
<view class="lock u-flex-xy-center" v-if="!item.videoUrl">
<up-icon name="lock" :size="14" color="#fff"></up-icon>
<!-- <image class="lock-icon" src="@/static/images/lock.png" mode=""></image> -->
</view>
<image v-if="nowIndex == index" class="playing" src="@/static/images/playIng.png" mode=""></image>
</view>
</view>
</scroll-view>
</view>
</view>
</up-popup>
<!-- 支付 -->
<up-popup :show="popup.pay" :round="10" @close="popupClose('pay')" :customStyle="customStyle">
<view class="u-p-30">
<view class="u-flex u-flex-row u-row-between">
<view class="u-flex u-flex-row" style="align-items: baseline">
<text class="color-333 u-font-32">当前视频 没有播放权限</text>
</view>
<up-icon name="close" :size="16" color="#333" bold @click="popupClose('pay')"></up-icon>
</view>
<view class="u-m-t-30">
<text class="color-999 u-font-24">{{ paytips }}</text>
</view>
<view class="u-m-t-30">
<text class="color-999 u-font-24">注:抽奖机会仅当日可用,次日作废</text>
</view>
<view class="colo-333 pay-list font-bold u-font-28 u-m-t-20">
<view class="pay-list-item" v-if="info && info.price" @click="payBtnClick('money', 'all')">
<image class="hot" src="@/static/images/hot.png" mode=""></image>
<text class="u-font-28 font-bold">{{ info.price }}元解锁全剧</text>
</view>
<view class="pay-list-item" v-if="info && info.wholesalePrice" @click="payBtnClick('money', 10)">
<image class="hot" src="@/static/images/hot.png" mode=""></image>
<text class="u-font-28 font-bold">{{ info.price }}元解锁全剧</text>
</view>
<view class="pay-list-item" @click="payBtnClick('gold', 1)" v-if="nowDanjiPrice * goldBili > 0">
<image class="hot" src="@/static/images/hot.png" mode=""></image>
<text class="u-font-28 font-bold">{{ to2(nowDanjiPrice * goldBili)}}金币解锁单集视频</text>
</view>
<view class="pay-list-item" @click="payBtnClick('money', 1)">
<!-- <image class="hot" src="@/static/images/hot.png" mode=""></image> -->
<text class="u-font-28 font-bold">{{ nowDanjiPrice }}元解锁单集视频</text>
</view>
</view>
</view>
</up-popup>
<!-- 支付确认 -->
<up-popup :show="popup.payTips" :round="10" @close="popupClose('payTips')" :customStyle="customStyle">
<view class="u-p-30">
<view class="u-flex u-flex-row u-row-between">
<view class="u-flex u-flex-row" style="align-items: baseline">
<text class="color-333 u-font-32">购买后继续观看</text>
</view>
<up-icon name="close" :size="16" color="#333" bold @click="popupClose('payTips')"></up-icon>
</view>
<view class="u-flex u-m-t-24 u-flex-row u-row-between u-font-28">
<view class="u-flex u-flex-row u-flex-y-center">
<image src="@/static/images/zhifubao.png" class="zhifubao" mode=""></image>
<text class="u-m-l-20 u-flex-xy-center u-font-28">支付宝</text>
</view>
<view>
<up-radio-group>
<up-radio :icon-size="20" :size="26" :activeColor="color.main"></up-radio>
</up-radio-group>
</view>
</view>
<view class="u-m-t-10">
<text class="font-bold u-font-26 color-333">温馨提示</text>
<text class="u-m-t-10 u-font-24 color-999">{{ $common.payTips }}</text>
</view>
<view class="u-flex u-flex-row u-m-t-30 u-flex-y-center u-font-28">
<view class="u-flex-y-center">
<up-checkbox usedAlone shape="circle" v-model:checked="isAgree" :activeColor="color.main"></up-checkbox>
</view>
<view class="u-flex u-flex-row u-flex-y-center">
<text class="u-font-28 color-333">我已经阅读并同意</text>
<text class="color-main u-font-28">《付费须知说明》</text>
</view>
</view>
<view class="u-m-t-30 my-bg-main payConfirm" @click="payConfirm">
<text class="u-font-28 color-fff">确认支付</text>
</view>
</view>
</up-popup>
<!-- 倍速 -->
<up-popup :show="popup.speed" :round="0" @close="popupClose('speed')" :customStyle="customStyle">
<view class="u-p-20 u-flex u-flex-row u-row-between u-flex-y-center">
<text class="font-bold color-333 u-font-28">倍速:</text>
<view class="u-flex u-flex-row speed-list">
<text class="speed-list-item u-font-28" @click="changeSpeed(index)" :class="{ active: index == speeds.active }" v-for="(item, index) in speeds.list">
{{ item.num }}x
</text>
</view>
</view>
</up-popup>
<!-- 达到每天支付赠送抽奖次数上限时弹窗确认 -->
<up-popup :show="popup.payConfirm" mode="center" :round="22" @close="popupClose('payConfirm')" :customStyle="payConfirmCustomStyle">
<view class="u-p-32">
<text class="u-font-32 color-333 font-bold u-text-center">付款确认</text>
<view class="u-p-l-14 u-p-r-14">
<view class="color-333 u-font-28 u-m-t-28 u-m-b-28">
<view class="u-flex u-flex-row">
<text class="u-font-28">今日已付款解锁{{ payCount.canGetRedPackMax }}次,本次解锁后将</text>
<text class="no-get">不会获得</text>
</view>
<text class="u-font-28">抽奖机会,请确认是否继续付款</text>
</view>
<view class="u-flex u-flex-row u-row-between gap-20 u-p-l-28 u-p-r-28">
<text class="cancel-btn" @click="popupClose('payConfirm')">取消</text>
<text class="confirm-btn" @click="continuePay()">继续付款</text>
</view>
</view>
</view>
</up-popup>
<!-- 绑定微信 -->
<up-popup :show="popup.bindWx" mode="center" :round="22" @close="popupClose('bindWx')" :customStyle="payConfirmCustomStyle">
<view class="u-p-32">
<text class="u-font-32 color-333 font-bold u-text-center">绑定微信</text>
<view class="u-p-l-14 u-p-r-14">
<text class="u-text-center color-333 u-font-28 u-m-t-28 u-m-b-28">请先绑定微信再继续完成支付</text>
<view class="u-flex u-flex-row u-row-between gap-20 u-p-l-28 u-p-r-28">
<text class="cancel-btn" @click="popupClose('bindWx')">取消</text>
<text class="confirm-btn" @click="bindWx()">立即绑定</text>
</view>
</view>
</view>
</up-popup>
<!-- #ifdef H5 -->
<my-poster ref="refPoster"></my-poster>
<!-- #endif -->
</template>
<script setup>
import { toBindWx } from '@/utils/wx.js';
import { useCommonStore } from '@/store/common.js';
import { getElRect } from '@/utils/util.js';
const $common = useCommonStore();
// #ifdef APP
const domModule = uni.requireNativePlugin('dom');
// #endif
import listItemVue from './list-item.vue';
import { returnShareUrl } from '@/commons/config.js';
import color from '@/commons/color.js';
import { debounce, throttle } from 'lodash';
import * as Api from '@/api/video/index.js';
import infoBox from '@/utils/infoBox.js';
import { computed, reactive, ref, watch, nextTick, onMounted, getCurrentInstance, onUnmounted } from 'vue';
function to2(n){
if(n){
return n.toFixed(2)
}
}
//绑定微信
function bindWx() {
popupClose('bindWx');
toBindWx();
}
const payConfirmCustomStyle = {
width: '694rpx'
};
let scrollable = ref(true);
function progressScroll() {
scrollable.value = false;
}
function progressScrollEnd() {
scrollable.value = true;
}
let isH5 = false;
// #ifdef H5
isH5 = true;
// #endif
const sysinfo = uni.getSystemInfoSync();
const isIos = sysinfo.platform == 'ios' ? true : false;
const isAndriod = sysinfo.platform == 'android' ? true : false;
const showAndriod = !isH5 && isAndriod ? true : false;
let initing = true;
const refPoster = ref(null);
let paytips = ref('');
const props = defineProps({
list: {
type: Array,
default: () => {
[];
}
},
options: {
tpye: Object,
default: () => {
return {
courseDetailsId: ''
};
}
},
isCommand: {
type: Boolean,
default: false
},
isTabbar: {
type: Boolean,
default: false
},
info: {
tpye: Object,
default: () => {
return {
collect: 0,
current: {},
list: [],
price: 0,
title: ''
};
}
}
});
const control = reactive({
showBack: true,
showControls: true
});
// #ifdef APP
control.showControls = false;
// #endif
const customStyle = computed(() => {
// #ifdef H5
return {
bottom: props.isTabbar ? '50px' : '0'
};
// #endif
// #ifndef H5
return {};
// #endif
});
function controlstoggles(e) {
control.showControls = e.detail.show;
control.showBack = control.showControls;
}
const speeds = reactive({
list: [
{
name: '0.5x',
num: 0.5
},
{
name: '1x',
num: 1
},
{
name: '1.25x',
num: 1.25
},
{
name: '1.5x',
num: 1.5
}
],
active: 1
});
const $mountedComponents = {};
function itemMounted(index) {
$mountedComponents[index] = true;
}
function back() {
const arr = getCurrentPages();
if (arr.length < 2) {
uni.switchTab({
url: '/pages/index/index'
});
return;
}
uni.navigateBack();
}
function changeSpeed(index) {
speeds.active = index;
uni.showToast({
title: '已切换' + speeds.list[index].num + '倍播放',
icon: 'none',
duration: 2000
});
}
const playSpeeds = computed(() => {
return speeds.list[speeds.active].num;
});
const instance = getCurrentInstance();
let isAgree = ref(false);
const cutomStyle = {
background: 'rgb(255, 117, 129)',
height: '100rpx',
'border-radius': '100px'
};
const popup = reactive({
show: false,
pay: false,
bindWx: false,
payTips: false,
speed: false,
data: null,
payConfirm: false,
payType: null
});
//选集数据
const xuanjiData = reactive({
scrollTop: 0,
items: [],
scrollHeight: 0,
height: 300
});
const refXuanjiList = ref(null);
function xuanjiScroll(e) {
console.log(e);
}
async function xuanjiInit() {
const height = 44;
const marginBottom = 10;
const oneItemHeight = height + marginBottom;
const scrollTop = Math.ceil((nowIndex.value + 1) / 3) * oneItemHeight - xuanjiData.height / 2 + oneItemHeight / 2;
if (props.list.length <= 15) {
xuanjiData.scrollTop = 0;
return;
}
xuanjiData.scrollTop = scrollTop * 1 < 0 ? 0 : scrollTop;
// #ifdef H5
if (!xuanjiData.items[props.list.length - 1]) {
const res = await getElRect('ji-list', instance, {
rect: true
});
xuanjiData.scrollHeight = res.height;
let firstItemTop = 0;
for (let i in props.list) {
const res1 = await getElRect('ji-item' + i, instance, {
rect: true
});
if (i == 0) {
firstItemTop = res1.top;
}
xuanjiData.items[i] = {
height: res1.height,
top: i == 0 ? 0 : res1.top - firstItemTop
};
}
}
xuanjiData.scrollTop = xuanjiData.items[nowIndex.value].top - xuanjiData.height / 2 + xuanjiData.items[nowIndex.value].height / 2;
console.log(xuanjiData);
// #endif
}
function openBs() {}
let cacheIndex = null;
function appear(isFirst, item, index) {
if (isFirst) {
$mountedComponents[index] = true;
}
if (!initing) {
cacheIndex = index;
}
}
function disappear(e, item, index) {
if (index == nowIndex.value && cacheIndex !== null && !initing) {
console.log('disappear' + index);
console.log('disappear nowIndex' + nowIndex.value);
console.log('cacheIndex' + cacheIndex);
nowIndex.value = cacheIndex;
const item = props.list[nowIndex.value];
if (!item.videoUrl) {
popupShow('pay', item, nowIndex.value);
}
cacheIndex = null;
}
}
//非金币支付
async function payOrder(data) {
const res = await Api.payOrder(data);
if (res) {
uni.setStorageSync('nobuyCourseId', popup.data.courseDetailsId);
// #ifdef APP
uni.navigateTo({
url: '/pages/pays/pays?orderId=' + data.orderId + '&url=' + res.h5Url
});
// #endif
// #ifdef H5
window.location.href = res.h5Url;
// #endif
popupClose();
}
}
//金币支付
async function goldPay(data) {
console.log(popup.index);
const res = await Api.goldPay(data);
if (res) {
uni.showToast({
title: '解锁成功',
icon: 'none'
});
popupClose();
emits('update', {
index: popup.index
});
}
}
//确认支付
async function payConfirm() {
const [type, num] = popup.payType.split('-');
if (type != 'gold') {
if (!isAgree.value) {
return infoBox.showToast('请阅读并同意 《付费须知说明》');
}
}
console.log(type, num);
let data = {
courseId: popup.data.courseId
};
if (num == 1) {
data.courseDetailsId = popup.data.courseDetailsId;
}
try {
const res = num == '10' ? await Api.buyTenVideo(data) : await Api.buyVideo(data);
if (res && res.code == 407) {
popupShow('bindWx');
return;
}
if (!res || !res.orders) {
return uni.showToast({
title: '创建订单失败',
icon: 'none'
});
}
if (res) {
if (type == 'gold') {
goldPay({
orderId: res.orders.ordersId
});
} else {
payOrder({
orderId: res.orders.ordersId
});
}
} else {
}
} catch (error) {
console.log(error);
}
}
async function payBtnClick(type, num) {
console.log(type, num);
popup.payType = `${type}-${num}`;
if (type == 'gold') {
return payConfirm();
}
try {
if (payCount.now > payCount.canGetRedPackMax) {
popupShow('payConfirm');
return;
}
popupClose('show');
popupShow('payTips');
} catch (error) {}
}
function continuePay() {
popupClose('payConfirm');
popupClose('show');
popupShow('payTips');
}
function jiClick(item, index) {
initing = false;
let newCurrent = (current.value + 1) % 3;
videoList.value[newCurrent] = item;
current.value = newCurrent;
popupClose('show');
if (showAndriod) {
goListPosition(index);
}
}
let refList = ref([]);
function setRefList(index) {
refList.value[index] = null;
return (el) => {
if (el) {
refList.value[index] = el;
}
};
}
//滚动到指定位置
let positonmer = null;
function goListPosition(index) {
clearTimeout(positonmer);
const el = refList.value[index];
if (initing) {
if (!$mountedComponents[index]) {
positonmer = setTimeout(() => {
goListPosition(index);
}, 200);
return;
}
}
domModule.scrollToElement(el, {
animated: false
});
initing = false;
const item = props.list[index];
setVideoList(item);
insertHistory();
}
function popupClose(key) {
console.log('popupClose:' + key);
if (key == 'show') {
// xuanjiData.scrollTop = 0
}
if (key) {
popup[key] = false;
return;
}
for (let i in popup) {
if (!i.includes(['data', 'payType'])) {
popup[i] = false;
}
}
}
const payCount = reactive({
canGetRedPackMax: 0,
now: 1
});
function extractNumbers(str) {
const numbers = str.match(/\d+/g);
if (numbers) {
return numbers.map((num) => parseInt(num, 10));
}
return [];
}
async function popupShow(key = 'show', item, index) {
console.log(key, item, 'debug');
console.log('key' + popup[key]);
console.log('popupShow');
if (key == 'show') {
// #ifdef H5
nextTick(() => {
xuanjiInit();
});
// #endif
// #ifdef APP
xuanjiInit();
// #endif
}
if (key == 'pay') {
const res = await Api.getPayTips();
const numbers = extractNumbers(res);
console.log(numbers);
if (numbers.length >= 2) {
payCount.canGetRedPackMax = numbers[0];
payCount.now = numbers[1];
console.log(payCount);
}
paytips.value = res;
}
popup[key] = true;
if (item) {
popup.data = item;
popup.index = index;
}
}
let goldBili = ref($common.goldBili || 0);
let wHeight = ref(0);
async function configInit() {
goldBili.value = $common.goldBili;
const sysInfo = uni.getSystemInfoSync();
wHeight.value = sysInfo.windowHeight;
// wHeight.value = sysInfo.screenHeight
}
let isCollect = ref(props.info.collect);
watch(
() => props.collect,
(newval) => {
isCollect.value = newval;
}
);
function toDetail(item, index) {
uni.navigateTo({
url: '/pages/video/detail?courseId=' + item.courseId
});
}
function posterError() {}
function posterSuccess() {}
let nowIndex = ref(0);
let current = ref(0);
let videoList = ref([]);
function init() {
let item = props.list.find((v) => props.options.courseDetailsId == v.courseDetailsId);
item = item ? item : props.info.current;
if (JSON.stringify(item) !== '{}') {
if (showAndriod) {
nextTick(() => {
const index = props.list.findIndex((v) => v.courseDetailsId == item.courseDetailsId);
goListPosition(index);
});
} else {
setVideoList(item);
}
}
}
const emits = defineEmits(['zhuijuClick', 'swiperChange', 'share', 'update', 'errorHandle']);
function zhuijuClick(item) {
isCollect.value = !isCollect.value;
zhuiju({
courseId: item.courseId,
type: isCollect.value ? 1 : 0
});
emits('zhuijuClick');
}
const zhuiju = debounce((data) => {
Api.zhuiju(data);
}, 500);
let dianZanTimer = null;
function dianzanClick(item, index) {
item.isGood = !item.isGood;
const newval = item.goodNum + (item.isGood ? 1 : -1);
item.goodNum = newval < 0 ? 0 : newval;
emits('update', {
index,
item
});
dianzan(item, index);
}
const dianzan = debounce((item, index) => {
Api.dianzan({
courseId: item.courseId,
courseDetailsId: item.courseDetailsId,
type: item.isGood ? 1 : 0
}).then((res) => {
if (res) {
uni.showToast({
title: '操作成功!',
icon: 'none'
});
}
});
}, 500);
let showControls = ref(false);
function openShowPay(current, index, videoUrl) {
showControls.value = true;
}
function videoPlay(videoId, courseDetailsId) {}
function ended() {}
function share(item) {
const { qdCode } = uni.getStorageSync('userInfo') || {};
const urls =
returnShareUrl() +
'/me/detail/detail?id=' +
item.courseId +
'&courseDetailsId=' +
item.courseDetailsId +
'&invitation=' +
uni.getStorageSync('invitationCode') +
'&qdCode=' +
qdCode;
console.log(urls);
// #ifdef H5
refPoster.value.make({
qrcode: urls,
title: props.info.title,
bigImg: item.titleImg,
tips: '长按或扫描识别二维码观看'
});
// #endif
// #ifndef H5
uni.setClipboardData({
data: urls,
success() {
uni.showToast({
title: '邀请链接已复制到剪贴板',
icon: 'none'
});
}
});
// #endif
}
const insertHistory = debounce(async () => {
try {
if (uni.getStorageSync('token')) {
const item = videoList.value[current.value];
const res = await Api.insertHistory({
courseId: item.courseId,
courseDetailsId: item.courseDetailsId
});
console.log('insertHistory===', res);
}
} catch (error) {
console.log('insertHistory.error===', error);
emits('errorHandle', error);
}
}, 1000);
async function swiperChange(e) {
console.log('e.detail.current');
console.log(e.detail.current);
current.value = e.detail.current;
const item = videoList.value[e.detail.current];
await insertHistory();
setVideoList(item);
}
const refPopup = ref(null);
function setVideoList(item) {
const listLen = props.list.length;
const lastIndex = listLen - 1;
const index = props.list.findIndex((v) => v.courseDetailsId == item.courseDetailsId);
nowIndex.value = index;
let position = '';
if (index === 0) {
position = 'start';
}
if (index === props.list.length - 1) {
position = 'end';
}
if (current.value == 0) {
if (position === 'start') {
videoList.value = [item, props.list[index + 1], props.list[lastIndex]];
} else if (position === 'end') {
videoList.value = [item, props.list[0], props.list[lastIndex]];
} else {
videoList.value = [item, props.list[index + 1], props.list[index - 1]];
}
}
if (current.value == 1) {
if (position === 'start') {
videoList.value = [props.list[lastIndex], item, props.list[index + 1]];
} else if (position === 'end') {
videoList.value = [props.list[lastIndex - 1], item, props.list[0]];
} else {
videoList.value = [props.list[index - 1], item, props.list[index + 1]];
}
}
if (current.value == 2) {
if (position === 'start') {
videoList.value = [props.list[1], props.list[lastIndex], item];
} else if (position === 'end') {
videoList.value = [props.list[0], props.list[lastIndex - 1], item];
} else {
videoList.value = [props.list[index + 1], props.list[index - 1], item];
}
}
if (!item.videoUrl) {
nextTick(() => {
setTimeout(() => {
popupShow('pay', item, index);
}, 100);
});
}
}
function transition(e) {
if (e.detail.dy > 0) {
//down
} else {
//up
}
}
function waiting() {}
configInit();
onMounted(() => {
init();
// setTimeout(()=>{
// },500)
});
watch(
() => props.list.length,
(newval) => {
console.log('props.list.length change' + newval);
if (!showAndriod) {
init();
}
}
);
watch(
() => nowIndex.value,
(newval) => {}
);
const nowDanjiPrice = computed(() => {
return videoList.value[current.value].price;
});
function loadmore() {
console.log('loadmore');
}
const boxStyle = computed(() => {
return {
height: wHeight.value + 'px',
width: '750rpx'
};
});
function videoListUpdata() {
videoList.value = videoList.value.map((v) => {
const item = props.list.find((listItem) => listItem.courseDetailsId == v.courseDetailsId);
return item ? item : v;
});
}
/**
* @param {type} = [start,end]
*/
const playStatusChange = debounce(async (data) => {
try {
const res = await Api.playStatus(data);
console.log('playStatusChange.res', res);
} catch (error) {
console.log('playStatusChange.error', error);
emits('errorHandle', error);
}
}, 2000);
defineExpose({
videoListUpdata
});
</script>
<style lang="scss" scoped>
.box {
/* #ifdef H5 */
flex: 1;
/* #endif */
}
.u-flex-1 {
flex: 1;
width: 100%;
height: 100%;
}
.u-popup {
position: fixed !important;
}
::v-deep .u-popup {
position: fixed !important;
}
.video {
width: 100%;
height: 100%;
}
.poster {
/* #ifdef H5 */
position: absolute;
width: 100%;
height: 90%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
/* #endif */
/* #ifdef APP */
width: 750rpx;
flex: 1;
/* #endif */
}
.u-text-center {
text-align: center;
}
.u-flex-row {
flex-direction: row !important;
}
.info {
width: 80%;
height: auto;
position: absolute !important;
bottom: 50px;
left: 10px;
color: #ffffff;
font-size: 15px;
z-index: 9999;
}
.u-flex-y-center {
align-items: center !important;
}
.swipers-items {
width: 750rpx;
flex: 1;
position: relative;
background-color: #000;
}
.right {
width: 60rpx;
position: absolute !important;
right: 20rpx;
top: 50%;
transform: translate(0, -50%);
z-index: 999;
color: #fff;
font-size: 24rpx;
.icon {
width: 60rpx;
height: 60rpx;
}
.share {
.text {
white-space: nowrap;
}
}
.zhuiju {
}
}
.poster-popup {
position: fixed !important;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.6);
z-index: 9999;
justify-content: center;
align-items: center;
}
.ji-list {
.ji-item {
width: 208rpx;
margin-bottom: 20rpx;
margin-right: 30rpx;
height: 88rpx;
font-size: 28rpx;
color: #333;
border-radius: 12rpx;
background-color: #f5f7ff;
position: relative;
&.active {
background-color: $my-main-color;
color: #fff;
}
&.mr-0 {
margin-right: 0;
}
.lock {
position: absolute;
border-radius: 0px 6px 0px 6px;
background-color: #ccc;
padding: 2rpx 4rpx;
top: 0;
right: 0;
.lock-icon {
width: 24rpx;
height: 24rpx;
}
}
.playing {
position: absolute;
width: 32rpx;
height: 24rpx;
bottom: 5px;
right: 7px;
}
}
}
.ji-item:nth-of-type(3n) {
margin-right: 0;
}
.hot {
width: 40rpx;
height: 40rpx;
}
.back-icon {
position: fixed;
z-index: 9999;
left: 30rpx;
top: 100rpx;
}
.pay-list {
.pay-list-item {
flex-direction: row;
justify-content: center;
background-color: #f2f2f2;
padding: 24rpx;
border-radius: 20rpx;
margin-bottom: 40rpx;
}
}
.payConfirm {
border-radius: 100px;
height: 100rpx;
line-height: 100rpx;
text-align: center;
justify-content: center;
align-items: center;
}
.zhifubao {
width: 56rpx;
height: 56rpx;
}
.qrcode {
position: fixed;
top: -9999px;
left: -9999px;
opacity: 0;
}
.speed-list {
align-items: center;
background-color: #eeeeef;
padding: 5px 10px;
border-radius: 5px;
.speed-list-item {
border-radius: 3px;
width: 50px;
padding: 8px 0;
justify-content: center;
align-items: center;
text-align: center;
.playing {
}
&.active {
background-color: #ffffff;
.playing {
}
}
}
}
.mask {
position: fixed;
z-index: 2000;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
justify-content: end;
transition: transform 0.3s ease-in-out;
transform: translateY(100vh);
&.mask-show {
transform: translateY(0);
}
.box {
position: absolute;
left: 0;
right: 0;
bottom: 0;
border-radius: 10px 10px 0 0;
background-color: #fff;
}
}
.xuanji-box {
position: absolute;
left: 0;
right: 0;
bottom: 0;
border-radius: 10px 10px 0 0;
background-color: #fff;
}
.cancel-btn,
.confirm-btn {
width: 210rpx;
height: 70rpx;
line-height: 70rpx;
text-align: center;
font-size: 32rpx;
color: #fff;
background: #ed838a;
box-shadow: inset 0rpx -6rpx 12rpx 0rpx rgba(255, 255, 255, 0.77);
border-radius: 40rpx 40rpx 40rpx 40rpx;
}
.no-get {
color: #ff5560;
font-size: 32rpx;
}
</style>