zbH5/src/views/VideoPlay/hComponents/Information.vue
2025-03-09 15:06:29 +08:00

411 lines
10 KiB
Vue

<template>
<div class="scroll-wrap">
<div class="detail-desc">
<div class="detail-title fw-5" @click="$egg(3, 1000)">
<h4>{{ detail.title }}</h4>
<div class="play-count">{{ detail.readCount }}次播放</div>
</div>
<div class="tag-count flex-ac-sb">
<div v-show="detail.infoVO" class="tag">
{{ `${detail.infoVO?.productName} 专属服务` }}
</div>
<!-- <div class="count flex-ac">
<div class="play-count">{{ detail.readCount }}次播放</div>
<div class="star-count flex-ac" v-if="!$shieldConfig.tgLive">
<img
v-if="detail.isFavor === 1"
src="@/assets/images/like-icon3.png"
alt="" />
<img
v-else
src="@/assets/images/like-icon.png"
alt=""
@click="sendLikeVideo(1)" />
<div
class="text-18 fw-5"
:class="detail.isFavor === 1 ? 'tc-f13721' : 'tc-1B2330'">
{{ detail.favorUserCount ? detail.favorUserCount : "" }}
</div>
</div>
</div> -->
</div>
<div class="author">
<div>
<div class="author-desc flex-ac">
<img
class="avatar"
:src="
detail.advisorBasic && detail.advisorBasic.avatar
? detail.advisorBasic.avatar
: defaultPhoto
"
alt="" />
<label>主讲</label>
<div>
<div class="text-28 tc-606877">
{{ detail.advisorBasic?.showName }}
</div>
</div>
</div>
<div class="handle flex-ac no-wrap">
<button
class="add"
@click.stop="subAdvisor"
v-if="!$shieldConfig.tgLive">
{{ detail.isSubAdvisor === 1 ? "取消关注" : "关注" }}
</button>
</div>
</div>
<div class="author-desc flex-ac" v-if="detail.guestInfo">
<img class="avatar" :src="detail.guestInfo.avatar" alt="" />
<label>嘉宾</label>
<div>
<div class="text-28 tc-606877">
{{ detail.guestInfo.showName }}
</div>
</div>
</div>
</div>
</div>
<div class="line"></div>
<div
v-if="detail.liveStatus === $liveStatusObj.NotStart"
class="countdown-wrapper">
<!-- <img class="coupon" src="@/assets/image/coupon@2x.png" alt="" @click="toTicket()" /> -->
<div class="title-time flex-ac-sb">
<div class="text-36 fw-5 tc-1B2330">
{{ `预计${detail.playType == 1 ? "直" : "录"}播开始时间` }}
</div>
<div class="text-28 tc-606877 fw-5">{{ detail.startTime }}</div>
</div>
<div class="from-start flex-ac text-28 tc-606877">
{{ `距离${detail.playType == 1 ? "直" : "录"}播开始` }}
</div>
<CountDown :deadline="detail.startTime" />
<div
class="status-btn text-32 flex-ac"
:class="
detail.isSubscribe !== 1 && detail.allowSubscribe !== 2
? 'to-preview'
: 'previewd'
">
<div
v-if="detail.isSubscribe !== 1 && detail.allowSubscribe !== 2"
class="flex-ac"
v-preReClick="setSubLiveVideo">
<img class="status-icon" src="@/assets/images/status2.png" alt="" />
<div class="desc tc-2E78FA">
{{ detail.playType == 1 ? "预约直播" : "预约视频" }}
</div>
</div>
<div v-if="detail.isSubscribe == 1" class="flex-ac">
<img class="status-icon" src="@/assets/images/status7.png" alt="" />
<div class="desc tc-606877">已预约</div>
</div>
</div>
<div class="preview-count">
{{ `${detail.subscribeUserCount}人已预约` }}
</div>
</div>
<div class="line"></div>
<div class="watch-focus">
<div class="text-36 tc-1B2330 fw-5">视频简介</div>
<div class="watch-content tc-1B2330">
{{ detail.viewPoint }}
</div>
<div class="detail" v-if="detail.detail" v-html="detail.detail"></div>
</div>
</div>
</template>
<script setup>
import { defineProps, onMounted } from "vue"
import { useRoute } from "vue-router"
import { sendFollowMessage } from "@/api/video"
import { attentionTg } from "@/api/index"
import emitter from "@/utils/emitter"
import CountDown from "./components/CountDown.vue"
import useGetLiveStatusObj from "@/hooks/useGetLiveStatusObj"
import useDisableScroll from "@/hooks/useDisableScroll"
import { subLiveVideo } from "@/api/video"
import useShieldConfig from "@/hooks/useShieldConfig"
import useLoadConsole from "@/hooks/useLoadConsole"
const $egg = useLoadConsole()
const $liveStatusObj = useGetLiveStatusObj()
const route = useRoute()
const $shieldConfig = useShieldConfig()
const { addScrollEvent } = useDisableScroll()
onMounted(() => {
addScrollEvent(".scroll-wrap")
})
const props = defineProps({
detail: {
// 视频详情
ype: Object,
default: () => ({}),
},
})
const defaultPhoto = require("@/assets/images/default-photo.png")
// 关注投顾
async function subAdvisor() {
let ret = await attentionTg({
advisorId: props.detail.advisorBasic?.id,
channel: 2,
option: props.detail.isSubAdvisor === 1 ? 2 : 1,
videoId: props.detail.id,
})
if (ret.code === 0) {
emitter.emit("updateVideoDetail", {
isSubAdvisor: props.detail.isSubAdvisor === 1 ? 2 : 1,
})
props.detail.isSubAdvisor === 1 &&
[
$liveStatusObj.InLive,
$liveStatusObj.PausePlay,
$liveStatusObj.FinishPlay,
].includes(props.detail.liveStatus) &&
sendFollowMessage({
id: props.detail.id,
option: props.detail.isSubAdvisor === 1 ? 2 : 1,
})
}
}
// const sendLikeVideo = async (liveNum) => {
// const ret = await likeVideo({
// id: props.detail.id,
// option: 1,
// num: liveNum,
// })
// if (ret.code === 0) {
// emitter.emit("updateVideoDetail", {
// isFavor: 1,
// favorUserCount: ret.data.count,
// })
// }
// }
const setSubLiveVideo = async () => {
let ret = await subLiveVideo({
id: props.detail.id,
option: props.detail.isSubscribe === 1 ? 2 : 1,
saleUserId: route.query.saleUserId,
})
if (ret.code === 0) {
emitter.emit("updateVideoDetail", {
isSubscribe: props.detail.isSubscribe === 1 ? 2 : 1,
subscribeUserCount: ret.data.count,
})
}
}
</script>
<style scoped lang="scss">
.mb20 {
margin-bottom: 20px;
}
.text-36 {
font-size: 36px;
}
.tc-1B2330 {
color: #1b2330;
}
.fw-5 {
font-weight: 500;
}
.text-28 {
font-size: 28px;
}
.tc-606877 {
color: #606877;
}
.tc-f13721 {
color: #f13721;
}
.tc-1B2330 {
color: #1b2330;
}
.flex-bl {
display: flex;
align-items: baseline;
}
.flex-ac {
display: flex;
align-items: center;
}
.line {
height: 12px;
background: #f5f6fa;
}
.flex-ac-sb {
display: flex;
align-items: center;
justify-content: space-between;
}
.scroll-wrap {
height: 100%;
overflow-y: scroll;
}
.detail-desc {
padding: 32px;
background-color: #fff;
text-align: left;
.detail-title {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 36px;
line-height: 54px;
margin-bottom: 8px;
color: #1b2330;
font-weight: 500;
h4 {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex: 1;
}
.play-count {
margin: 0 20px 0 16px;
color: #9aa4b6;
font-size: 24px;
}
}
.tag {
padding: 6px 8px;
border: 1px solid rgba($color: #2e78fa, $alpha: 0.2);
border-radius: 8px;
}
.tag-count {
justify-content: flex-end;
color: #9aa4b6;
font-size: 24px;
}
// .play-count {
// margin: 0 20px 0 16px;
// }
.star-count {
img {
width: 32px;
height: 32px;
}
}
.author {
margin-top: 24px;
padding: 24px;
background: #f8f9fa;
border-radius: 12px;
& > div {
margin-bottom: 20px;
}
& > div:last-child {
margin-bottom: 0;
}
.avatar {
margin-right: 12px;
width: 60px;
height: 60px;
border: 1px solid rgba(0, 0, 0, 0.07);
border-radius: 50%;
}
.depart {
margin-top: 12px;
}
.add {
height: 54px;
line-height: 54px;
border-radius: 28px;
border: 0.5px solid rgba(240, 46, 24, 0.5);
color: rgb(240, 46, 24);
font-size: 24px;
font-style: normal;
font-weight: 400;
background: none;
padding: 0 20px;
}
.author-desc {
label {
font-size: 22px;
line-height: 22px;
margin-right: 10px;
background: linear-gradient(90deg, #66adff, #1472ff);
padding: 6px 8px;
border-radius: 4px;
color: #fff;
}
}
}
}
.countdown-wrapper {
position: relative;
background-color: #fff;
margin-top: 12px;
padding: 32px;
.coupon {
position: absolute;
width: 120px;
height: 120px;
top: 114px;
right: 12px;
}
.from-start {
margin: 56px 0 16px;
justify-content: center;
}
.status-btn {
margin: 40px auto 16px;
width: 248px;
height: 80px;
justify-content: center;
// padding: 16px 32px;
border: 1px solid;
border-radius: 40px;
.status-icon {
width: 48px;
height: 48px;
margin-right: 8px;
}
.desc {
line-height: 48px;
font-size: 32px;
font-weight: 500;
}
}
.to-preview {
color: #2e78fa;
border-color: #2e78fa;
}
.previewd {
color: #606877;
border-color: #606877;
}
.preview-count {
justify-content: center;
color: #9aa4b6;
font-size: 24px;
font-weight: 500;
line-height: 24px;
}
}
.watch-focus {
padding: 32px;
background: #fff;
text-align: left;
.watch-content {
font-size: 28px;
line-height: 44px;
margin-top: 24px;
}
}
.detail {
font-size: 28px;
line-height: 44px;
padding-top: 40px;
::v-deep img {
max-width: 100%;
}
}
</style>