zbH5/src/views/VideoPlay/components/VideoFooter.vue
2025-04-07 16:55:52 +08:00

488 lines
11 KiB
Vue

<template>
<div class="opt-wrap">
<div class="msg-content">
<ChatFrame
className="hp"
@sendMsg="sendMsg"
:informMsgList="informMsgList"
:detail="detail" />
<div class="recommend-img" v-show="showRecommend" @click="toActivityPage">
<img :src="activityObj.imgUrl" alt="" srcset="" />
<i @click.stop="closeActivity"></i>
</div>
</div>
<div class="input-area">
<input
type="text"
maxlength="200"
:placeholder="
detail.liveStatus === $liveStatusObj.FinishPlay
? '直播结束,暂不支持互动哟~'
: isSpeak
? '互动已关闭...'
: '与老师互动...'
"
v-model.trim="text"
@focus="inputMsg"
:disabled="
isSpeak || [$liveStatusObj.FinishPlay].includes(detail.liveStatus)
"
@keyup.enter="sendMsg(1, { text })" />
<button
class="send"
:disabled="!text || sendTextLoading"
@click="sendMsg(1, { text })">
发送
</button>
<button class="share" @click="sendMsg(5)"></button>
<button
class="clear"
v-if="detail.liveStatus === $liveStatusObj.InLive"
@click.stop="clearScreenFn"></button>
<button class="shop" @click.stop="openProductList"></button>
<button
v-if="detail.liveStatus !== $liveStatusObj.NotStart"
:class="['star', detail.isFavor === 1 ? 'active' : '']"
@click.stop="sendMsg(4)">
<span v-if="detail.favorUserCount">{{
bigNumberTransform(detail.favorUserCount)
}}</span>
</button>
</div>
</div>
<Share ref="shareRef" :detail="detail" />
<ProductList
ref="productListRef"
:tgId="detail.advisorBasic?.id"
:detail="detail" />
</template>
<script setup>
import { ref, defineProps, watch, defineEmits } from "vue"
import { useStore } from "vuex"
import { showToast } from "vant"
import BScroll from "@better-scroll/core"
import PullDown from "@better-scroll/pull-down"
import Share from "@/components/Share.vue"
import ProductList from "./ProductList.vue"
import { likeVideo } from "@/api/video"
import emitter from "@/utils/emitter"
import useGetLiveStatusObj from "@/hooks/useGetLiveStatusObj"
import ChatFrame from "./ChatFrame.vue"
import { userLogin } from "@/utils/login"
const $liveStatusObj = useGetLiveStatusObj()
BScroll.use(PullDown)
const store = useStore()
const props = defineProps({
detail: {
// 视频详情
ype: Object,
default: () => ({}),
},
activityObj: {
// 活动内容
type: Object,
default: () => ({}),
},
informMsgList: {
// 聊天互动信息
type: Array,
default: () => [],
},
isSpeak: {
// 是否关闭互动
type: Boolean,
default: false,
},
})
const showRecommend = ref(false) // 展示活动模块
watch(
() => props.activityObj,
() => {
if (props.activityObj && Object.keys(props.activityObj).length) {
showRecommend.value = true
}
}
)
function toActivityPage() {
location.href = props.activityObj.url
}
const text = ref()
const shareRef = ref()
const sendTextLoading = ref(false)
const emit = defineEmits(["sendMsg", "clearScreenFn", "closeActivity"])
const sendMsg = (type, params = {}) => {
if (![1, 4].includes(type)) {
// 不是聊天互动
emit("sendMsg", type, params)
}
switch (type) {
case 1:
if (text.value) {
sendTextLoading.value = true
emit("sendMsg", type, {
...params,
callBack: () => {
sendTextLoading.value = false
text.value = ""
},
errorBack: () => {
sendTextLoading.value = false
},
})
} else {
showToast("请输入互动内容!")
}
break
case 4:
dblclickLive()
break
case 5:
shareRef.value.showPopup = true
break
default:
break
}
}
function inputMsg() {
if (!store.state.token) {
userLogin()
}
}
const productListRef = ref()
const openProductList = () => {
// 购物车列表弹窗
productListRef.value.showPopup = true
}
// 清屏
const clearScreenFn = () => {
emit("clearScreenFn")
}
// 关闭活动弹窗
const closeActivity = () => {
showRecommend.value = false
emit("closeActivity")
}
let liveIndex = 0
const liveIcon = [
require("@/assets/images/liveIcon/icon1.png"),
require("@/assets/images/liveIcon/icon2.png"),
require("@/assets/images/liveIcon/icon3.png"),
require("@/assets/images/liveIcon/icon4.png"),
]
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,
})
}
}
let sendLiveTime = null
const dblclickLive = () => {
const img = document.createElement("img")
img.setAttribute("src", liveIcon[liveIndex % 4])
img.setAttribute("class", "live-icon")
document.querySelector(".star").appendChild(img)
liveIndex++
;((img) => {
setTimeout(() => {
let star = document.querySelector(".star")
star && star.removeChild(img)
}, 2000)
})(img)
clearTimeout(sendLiveTime)
sendLiveTime = setTimeout(() => {
sendLikeVideo(liveIndex)
liveIndex = 0
}, 1000)
}
function bigNumberTransform(value) {
let param = {}
let k = 10000,
sizes = ["", "万", "亿", "万亿"],
i
if (value < k) {
param.value = value
param.unit = ""
} else {
i = Math.floor(Math.log(value) / Math.log(k))
param.value = value / Math.pow(k, i)
param.unit = `${sizes[i]}+`
}
let number = param.value + param.unit
return number
}
</script>
<style scoped lang="scss">
.opt-wrap {
position: absolute;
bottom: 40px;
padding: 20px 20px;
width: 100%;
box-sizing: border-box;
z-index: 2;
}
.input-area {
display: flex;
align-items: center;
input {
height: 64px;
background: rgba(0, 0, 0, 0.3);
border-radius: 32px;
font-weight: 500;
font-size: 24px;
letter-spacing: 0;
line-height: 24px;
padding: 0 16px;
flex: 1;
color: #cccccc;
}
input::placeholder {
color: #cccccc; /* 设置颜色为灰色 */
}
button {
width: 64px;
height: 64px;
margin-left: 20px;
}
button.send {
width: auto;
height: 64px;
padding: 0 20px;
font-size: 28px;
border-radius: 32px;
color: #fff;
background-image: linear-gradient(270deg, #2e78fa 0%, #45acff 100%);
white-space: nowrap;
&[disabled] {
opacity: 0.6;
}
}
.star {
position: relative;
background: url(../../../assets/images/like-icon1.png) no-repeat center;
background-size: cover;
&.active {
background: url(../../../assets/images/like-icon2.png) no-repeat center;
background-size: cover;
}
span {
position: absolute;
top: 0;
right: 0;
min-width: 20px;
transform: translateX(18px) translateY(-50%);
display: flex;
align-items: center;
justify-content: center;
padding: 4px;
flex-direction: column;
border-radius: 13px 13px 13px 4px;
background: linear-gradient(
128deg,
#fff2dc -25.5%,
#ffd9a7 89.14%,
#605a52 89.14%
);
color: rgb(142, 81, 5);
font-size: 18px;
font-style: normal;
font-weight: 500;
}
}
.clear {
background: url(../../../assets/images/clear.png) no-repeat center;
background-size: cover;
}
.share {
background: url(../../../assets/images/share.png) no-repeat center;
background-size: cover;
}
.shop {
background: url(../../../assets/images/shop.png) no-repeat center;
background-size: cover;
}
}
.interact-scroll {
position: relative;
max-height: 360px;
overflow: hidden;
text-align: left;
width: calc(100% - 238px);
margin-right: 20px;
li > div {
display: flex;
flex-wrap: wrap;
align-items: center;
font-size: 24px;
font-weight: 500;
letter-spacing: 0;
text-align: left;
color: #fff;
margin-bottom: 12px;
label {
color: rgba(154, 191, 255, 1);
}
&.product-item {
flex-direction: column;
align-items: flex-start;
}
}
p,
.reply-content {
line-height: 28px;
border-radius: 20px;
background: rgba(0, 0, 0, 0.3);
padding: 8px 16px;
word-break: break-all;
}
.reply {
line-height: 40px;
margin-right: 10px;
}
button {
height: 44px;
line-height: 44px;
border: none;
border-radius: 20px;
background-color: rgba(0, 0, 0, 0.3);
background-repeat: no-repeat;
background-position: left 10px center;
background-size: 20px auto;
padding-left: 32px;
font-size: 24px;
padding: 0 20px 0 30px;
&.share {
color: #ff3d36;
background-image: url(../../../assets/images/share-icon2.png);
}
&.attention {
color: #ff7d26;
background-image: url(../../../assets/images/attention.png);
}
}
}
.msg-content {
display: flex;
align-items: flex-end;
margin-bottom: 20px;
.recommend-img {
position: relative;
width: 208px;
height: 280px;
margin-right: 10px;
img {
width: 100%;
height: 100%;
}
i {
position: absolute;
width: 40px;
height: 40px;
border-radius: 50%;
top: 0;
right: 0;
transform: translateX(50%) translateY(-50%);
background: url(../../../assets/images/close-icon.png) no-repeat center;
background-size: 100%;
}
}
}
.top-tip {
color: #fff;
font-size: 24px;
text-align: center;
line-height: 28px;
border-radius: 20px;
// background: rgba(0, 0, 0, 0.3);
padding: 8px 8px;
animation-delay: 2s;
}
::v-deep .live-icon {
position: absolute;
left: 50%;
top: 0;
width: 60px;
height: auto;
z-index: 2;
transform: translateX(-50%) translateY(-75%);
animation: mymove 2.5s;
-webkit-animation: mymove 2.5s; /*Safari and Chrome*/
}
@keyframes mymove {
from {
top: 0;
opacity: 1;
}
to {
top: -200px;
opacity: 0;
}
}
@-webkit-keyframes mymove /*Safari and Chrome*/ {
from {
top: 0;
opacity: 1;
}
to {
top: -200px;
opacity: 0;
}
}
.question {
width: 100%;
background: #fff;
border-radius: 8px;
color: #000;
padding: 16px;
h5 {
font-size: 30px;
margin-bottom: 20px;
}
span {
color: #ff3d36;
font-size: 28px;
}
}
::v-deep .item-wrap {
margin-bottom: 0;
}
.pulldown-wrapper {
position: absolute;
width: 100%;
padding: 20px;
box-sizing: border-box;
transform: translateY(-100%) translateZ(0);
text-align: center;
color: #999;
font-size: 24px;
}
</style>