488 lines
11 KiB
Vue
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>
|