Files
huangguo_dhz/src/components/HorizontalVideoVerticalBox/index.vue
T
谢宇宁andClaude Opus 4.8 c957b45bad 初始化黄果短剧 H5 客户端
对接后端 hgmjapi.mfcg.me:
- 接口解密 key 更新为 resKey360
- 登录 sysType 使用原生 getDevType(后端已放开 pc/android)
- 修正榜单接口路径 /vid/rangking → /vid/ranking,方法改为 GET

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-08 19:41:43 +07:00

297 lines
8.6 KiB
Vue

<template>
<div class="horizontalVideoBox" @click="openVideo">
<div class="coverBox">
<lazyImg class="cover" v-if="!state.videoInfo.type" :src="state.videoInfo?.verticalCover" />
<lazyImg class="cover" v-else :src="state.videoInfo?.cover" />
<!-- <div class="videoInfo flex-center-between" v-if="!state.videoInfo.type">-->
<!-- <div class="playCount flex-center-center">-->
<!-- <SvgIcon class="icon" name="playIcon" />-->
<!-- <div class="count">{{ watchCount(state.videoInfo?.playCount) }}</div>-->
<!-- </div>-->
<!-- <div class="playDuration">{{ videoTime(state.videoInfo?.playTime) }}</div>-->
<!-- </div>-->
<!-- <div class="subscriptInfo" v-if="!state.videoInfo.type">-->
<!-- &lt;!&ndash; <div class="label freeLabel" v-if="state.videoInfo?.coins == 0">免费</div> &ndash;&gt;-->
<!-- &lt;!&ndash; <div class="label" v-if="state.videoInfo?.originCoins == 0 && !state.videoInfo?.freeArea">-->
<!-- <img src="./../../assets/images/png/vip.png" />-->
<!-- VIP-->
<!-- </div> &ndash;&gt;-->
<!-- <div class="goldCoinLabel flex-center-center" v-if="state.videoInfo?.coins != 0">-->
<!-- <img src="./../../assets/images/png/icon.png" />-->
<!-- <span>{{ state.videoInfo?.originCoins }}</span>-->
<!-- </div>-->
<!-- </div>-->
<div class="subscriptInfo" v-if="!state.videoInfo.type && state.videoInfo.tagNames.length > 0">
<!-- <div class="label freeLabel" v-if="state.videoInfo?.coins == 0">免费</div> -->
<!-- <div class="label" v-if="state.videoInfo?.originCoins == 0 && !state.videoInfo?.freeArea">
<img src="./../../assets/images/png/vip.png" />
VIP
</div> -->
<!-- <div class="goldCoinLabel flex-center-center" v-if="state.videoInfo?.coins != 0">-->
<!-- <img src="./../../assets/images/png/icon.png" />-->
<!-- <span>{{ state.videoInfo?.originCoins }}</span>-->
<!-- </div>-->
<div class="goldCoinLabel flex-center-center" v-if="state.videoInfo?.coins != 0">
<span>{{ state.videoInfo.tagNames[0] }}</span>
</div>
</div>
</div>
<div :class="state.isOneLine ? 'videoTitle1' : 'videoTitle'">
<div class="title">
{{ state.videoInfo?.title ? state.videoInfo?.title : '无标题' }}
</div>
</div>
<div class="bloggerBox" v-if="state.videoInfo.publisher">
<div class="bloggerInfo">
<lazyImg round class="bloggerAvatar" :src="state.videoInfo?.publisher?.portrait" />
<span>{{ state.videoInfo.publisher?.name }}</span>
</div>
<div class="likeBox" v-if="state.videoInfo.publisher?.officialCert">
<SvgIcon name="isVip" class="like" />
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { watchCount, videoTime, addVideoHistory } from '@/utils/index';
import { useRouter } from 'vue-router';
import { useVideoStore } from '@/stores/video';
import { jumpAdv } from '@/utils/index';
import { HistoryVideoType } from '@/enums/app';
const router = useRouter();
const videoStore = useVideoStore();
const props = withDefaults(
defineProps<{
videoInfo: Types.Video.VInfosItem;
videoList: Types.Video.VInfosItem[];
isMovie?: boolean;
queryPath?: string;
isOneLine?: boolean;
}>(),
{
videoInfo: () => <Types.Video.VInfosItem>{},
videoList: () => [],
isMovie: () => false,
queryPath: () => '',
isOneLine: () => false,
},
);
const emit = defineEmits(['changeVideo']);
const state = {
videoInfo: props.videoInfo,
videoList: props.videoList,
isMovie: props.isMovie,
queryPath: props.queryPath,
isOneLine: props.isOneLine,
};
const openVideo = () => {
if (state.videoInfo.type) {
jumpAdv(state.videoInfo);
return;
}
router.push({
path: '/novelDetailsPage',
query: {
id: state.videoInfo.id,
// uid: state.videoInfo.publisher?.uid,
// queryPath: state.queryPath,
},
});
// if (state.isMovie) {
// emit('changeVideo', state.videoInfo);
// } else {
// router.push({
// path: '/movieDetails',
// query: {
// vid: state.videoInfo.id,
// uid: state.videoInfo.publisher?.uid,
// queryPath: state.queryPath,
// },
// });
// }
// if (state.videoInfo.newsType == 'COVER') {
// // router.push({
// // path: '/postDetails',
// // query: {
// // postId: state.videoInfo.id,
// // },
// // });
// } else {
// if (state.videoInfo.playTime > 300) {
// if (state.isMovie) {
// emit('changeVideo', state.videoInfo);
// } else {
// router.push({
// path: '/movieDetails',
// query: {
// vid: state.videoInfo.id,
// uid: state.videoInfo.publisher?.uid,
// queryPath: state.queryPath,
// },
// });
// }
// return;
// } else {
// videoStore.deleteVideoList();
// videoStore.saveVideoList(state.videoList, state.videoInfo);
// router.push('/shortVideoDetails');
// }
// }
};
</script>
<style lang="scss" scoped>
.horizontalVideoBox {
height: 100%;
width: 100%;
margin-bottom: 10px;
.coverBox {
height: 94px;
border-radius: 6px;
overflow: hidden;
transform: translateZ(0px);
position: relative;
.videoInfo {
height: 24px;
width: 100%;
background: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.6));
position: absolute;
left: 0;
bottom: 0;
padding: 0 10px 0 12px;
transform: translateZ(0px);
.playCount {
.icon {
height: 10px;
width: 10px;
}
.count {
font-size: 10px;
color: rgb(248, 248, 248);
margin-left: 5px;
}
}
.playDuration {
font-size: 11px;
color: rgb(248, 248, 248);
}
}
.subscriptInfo {
transform: translateZ(0px);
position: absolute;
top: 5px;
right: 0px;
z-index: 1;
.label {
padding: 0 5px;
box-sizing: border-box;
height: 18px;
min-width: 34px;
// background-image:linear-gradient(to right,#ffe247 ,#ffd4a3,#ffd4a3) ;
// color: #c87426;
// border-radius: 2px 2px 0 0;
font-size: 8px;
text-align: center;
line-height: 18px;
> img {
height: 10px;
width: 10px;
}
}
.goldCoinLabel {
padding: 0 4px;
box-sizing: border-box;
// background: rgba(0, 0, 0, 0.6);
//border: 0.5px solid #ffad00;
background: linear-gradient(0deg, #ff0000, #ff0000);
height: 16px;
min-width: 27px;
// border-radius: 0 0 6px 0;
border-radius: 2px 0 0 2px;
> img {
height: 10px;
width: 10px;
margin-right: 3.3px;
}
span {
font-size: 12px;
font-weight: 700;
color: rgb(248, 248, 248);
}
}
.freeLabel {
color: #598300;
background-color: #d8ffa6;
}
}
}
.videoTitle {
padding: 2px 0px 8px;
box-sizing: border-box;
height: 26px;
margin-top: 8px;
.title {
font-size: 12px;
// color: rgba(248, 248, 248, 0.8);
color: #ffffff;
line-height: 18px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
}
}
.videoTitle1 {
padding: 2px 0px 8px;
box-sizing: border-box;
height: 30px;
margin-top: 8px;
.title {
font-size: 14px;
// color: rgba(248, 248, 248, 0.8);
color: rgb(38, 38, 38);
line-height: 18px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
}
}
.bloggerBox {
display: flex;
align-items: center;
font-size: 12px;
color: rgba(166, 166, 166, 1);
.likeBox {
display: flex;
justify-content: center;
align-items: center;
background: $themeColor;
width: 16px;
height: 10px;
border-radius: 2px;
margin-left: 8px;
.like {
width: 8px;
height: 8px;
}
}
.bloggerInfo {
display: flex;
align-items: center;
}
.bloggerAvatar {
width: 18px;
height: 18px;
border-radius: 50%;
margin-right: 8px;
}
}
}
</style>