对接后端 hgmjapi.mfcg.me: - 接口解密 key 更新为 resKey360 - 登录 sysType 使用原生 getDevType(后端已放开 pc/android) - 修正榜单接口路径 /vid/rangking → /vid/ranking,方法改为 GET Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
585 lines
17 KiB
Vue
585 lines
17 KiB
Vue
<template>
|
||
<div class="post-box" @click="$router.push({ path: '/postDetail', query: { postid: props.postInfo.id } })">
|
||
<!-- header-->
|
||
<div class="post-top" v-if="!props.isHiddenAvatar">
|
||
<div class="post-top-left flex-center-center" @click.stop="toUserpage">
|
||
<div class="post-avatar">
|
||
<lazyImg
|
||
:src="props.postInfo.publisher?.portrait"
|
||
round
|
||
:key="props.postInfo.publisher?.portrait"
|
||
/>
|
||
</div>
|
||
<div class="post-info">
|
||
<div class="username_box ellipsis">
|
||
<span>{{ props.postInfo.publisher?.name }}</span>
|
||
<span v-if="props.postInfo.publisher.vipLevel > 0" class="vipLevel">
|
||
LV.{{ props.postInfo.publisher.vipLevel }}
|
||
</span>
|
||
<!-- <img v-if="props.postInfo.publisher?.superUser" src="@/assets/images/png/isCentral.png" alt="" />-->
|
||
<!-- <SvgIcon class="vipIcon icon" name="vipIcon" v-if="state.publisher?.vipLevel > 0" />-->
|
||
</div>
|
||
<!--显示时间-->
|
||
<div class="location-box flex-vcenter">
|
||
<!-- <span v-if="props.postInfo.publisher?.vipLevel != 0">
|
||
{{
|
||
props.postInfo.publisher?.vipLevel == 1
|
||
? '月卡用户'
|
||
: props.postInfo.publisher?.vipLevel == 2
|
||
? '季卡用户'
|
||
: props.postInfo.publisher?.vipLevel == 3
|
||
? '月卡用户'
|
||
: ''
|
||
}}
|
||
</span> -->
|
||
<span v-if="props.postInfo.publisher?.vipName">{{ props.postInfo.publisher?.vipName }}</span>
|
||
{{ fromNowTime(props.postInfo.reviewAt) }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- 关注 -->
|
||
<div
|
||
@click.stop="followUp"
|
||
v-if="userStore.userInfo.uid != props.postInfo.publisher?.uid && route.path != '/personal'"
|
||
>
|
||
<div class="post-top-right-follow flex-center-center" v-if="props.postInfo.publisher?.hasFollowed">已关注</div>
|
||
<div class="post-top-right flex-center-center" v-else>
|
||
<svgIcon name="follow_add"></svgIcon>
|
||
关注
|
||
</div>
|
||
</div>
|
||
<!-- 审核状态 -->
|
||
<div
|
||
class="statusClass"
|
||
v-if="userStore.userInfo.uid == props.postInfo.publisher?.uid && route.path == '/myPublish'"
|
||
>
|
||
<div @click.stop="props.postInfo?.status == 2 ? showReason() : ''">
|
||
{{ setText(props.postInfo?.status) }}
|
||
</div>
|
||
<!-- <div v-else>-->
|
||
<!-- 被拒原因:-->
|
||
<!-- <p>{{ props.postInfo?.reason }}</p>-->
|
||
<!-- </div>-->
|
||
</div>
|
||
</div>
|
||
<div class="post-time" v-else>发布时间:1小时前</div>
|
||
<!--content -->
|
||
<div class="post-text">
|
||
<TextOverflow :text="props.postInfo.title" :maxLines="3" :isTopping="props.postInfo.isTopping">
|
||
<template #default="{ clickToggle, expanded }">
|
||
<div @click.stop="clickToggle" class="text-btn">
|
||
{{ expanded ? '收起' : '全文' }}
|
||
</div>
|
||
</template>
|
||
</TextOverflow>
|
||
</div>
|
||
<!-- 图片+视频 -->
|
||
<div class="post-media">
|
||
<!-- 如果只有图片 没有视频 -->
|
||
<template v-if="props.postInfo.seriesCover && props.postInfo.seriesCover.length && !props.postInfo.sourceURL">
|
||
<lazyImg
|
||
:src="src"
|
||
v-for="(src, index) in props.postInfo.seriesCover.slice(0, 3)"
|
||
:key="src + index"
|
||
class="img_item"
|
||
>
|
||
<div v-if="index == 2 && props.postInfo.seriesCover.length > 3" class="filter">
|
||
+{{ props.postInfo.seriesCover.length - 3 }}
|
||
</div>
|
||
</lazyImg>
|
||
</template>
|
||
<!-- 如果有图片 也有有视频 -->
|
||
<template v-if="props.postInfo.seriesCover && props.postInfo.seriesCover.length && props.postInfo.sourceURL">
|
||
<!-- 图片第一张为封面 -->
|
||
<!-- 如果图片第一张地址和封面图一样-->
|
||
<template v-if="props.postInfo.seriesCover[0] == props.postInfo.cover">
|
||
<!-- 如果图片大于4张 只展示图片 不用展示视频 -->
|
||
<template v-if="props.postInfo.seriesCover.length >= 4">
|
||
<lazyImg
|
||
:src="src"
|
||
v-for="(src, index) in props.postInfo.seriesCover.slice(1, 4)"
|
||
:key="src + index"
|
||
class="img_item"
|
||
>
|
||
<!-- <div v-if="index == 2 && props.postInfo.seriesCover.length >= 4 && !props.postInfo.sourceURL" class="filter">
|
||
+{{ props.postInfo.seriesCover.length -1 - 3 }}
|
||
</div> -->
|
||
<div
|
||
v-if="index == 2 && props.postInfo.seriesCover.length >= 4 && props.postInfo.sourceURL"
|
||
class="filter"
|
||
>
|
||
+{{ props.postInfo.seriesCover.length - 4 + 1 }}
|
||
</div>
|
||
</lazyImg>
|
||
</template>
|
||
<!-- 否则图片+视频 -->
|
||
<template v-else>
|
||
<lazyImg
|
||
:src="src"
|
||
v-for="(src, index) in props.postInfo.seriesCover.slice(1)"
|
||
:key="src + index"
|
||
class="img_item"
|
||
></lazyImg>
|
||
<lazyImg :src="props.postInfo.cover" :key="props.postInfo.cover" class="img_item">
|
||
<div class="play_box">
|
||
<img class="icon" src="@/assets/images/png/playIcon.png" alt="" />
|
||
">
|
||
</div>
|
||
</lazyImg>
|
||
</template>
|
||
</template>
|
||
<!-- 图片不一样正常展示 -->
|
||
<template v-else>
|
||
<template v-if="props.postInfo.seriesCover.length >= 3">
|
||
<lazyImg
|
||
:src="src"
|
||
v-for="(src, index) in props.postInfo.seriesCover.slice(0, 3)"
|
||
:key="src + index"
|
||
class="img_item"
|
||
>
|
||
<div
|
||
v-if="index == 2 && props.postInfo.seriesCover.length > 3 && !props.postInfo.sourceURL"
|
||
class="filter"
|
||
>
|
||
+{{ props.postInfo.seriesCover.length - 3 }}
|
||
</div>
|
||
<div
|
||
v-if="index == 2 && props.postInfo.seriesCover.length > 3 && props.postInfo.sourceURL"
|
||
class="filter"
|
||
>
|
||
+{{ props.postInfo.seriesCover.length + 1 - 3 }}
|
||
</div>
|
||
</lazyImg>
|
||
</template>
|
||
<!-- 否则图片+视频 -->
|
||
<template v-else>
|
||
<lazyImg
|
||
:src="src"
|
||
v-for="(src, index) in props.postInfo.seriesCover"
|
||
:key="src + index"
|
||
class="img_item"
|
||
></lazyImg>
|
||
<lazyImg :src="props.postInfo.cover" :key="props.postInfo.cover" class="img_item">
|
||
<div class="play_box">
|
||
<img class="icon" src="@/assets/images/png/playIcon.png" alt="" />
|
||
">
|
||
</div>
|
||
</lazyImg>
|
||
</template>
|
||
</template>
|
||
</template>
|
||
<!-- 只有视频 没有图片 -->
|
||
<template v-if="props.postInfo.seriesCover && !props.postInfo.seriesCover.length && props.postInfo.sourceURL">
|
||
<lazyImg :src="props.postInfo.cover" :key="props.postInfo.cover" class="video_item">
|
||
<div class="play_box">
|
||
<img class="icon" src="@/assets/images/png/playIcon.png" alt="" />
|
||
">
|
||
</div>
|
||
</lazyImg>
|
||
</template>
|
||
<!-- 如果有图片且图片大于三张 有无视频都无所谓-->
|
||
<!-- <template v-if="props.postInfo.seriesCover && props.postInfo.seriesCover.length >= 3">
|
||
<lazyImg
|
||
:src="src"
|
||
v-for="(src, index) in props.postInfo.seriesCover.slice(0, 3)"
|
||
:key="src + index"
|
||
class="img_item"
|
||
>
|
||
<div v-if="index == 2 && props.postInfo.seriesCover.length > 3 && !props.postInfo.sourceURL" class="filter">
|
||
+{{ props.postInfo.seriesCover.length - 3 }}
|
||
</div>
|
||
<div v-if="index == 2 && props.postInfo.seriesCover.length > 3 && props.postInfo.sourceURL" class="filter">
|
||
+{{ props.postInfo.seriesCover.length + 1 - 3 }}
|
||
</div>
|
||
</lazyImg>
|
||
</template> -->
|
||
<!-- 有图片 并且图片小于三张 或者没有图片 且 有视频 -->
|
||
<!-- <template v-if="props.postInfo.seriesCover && props.postInfo.seriesCover.length < 3 && props.postInfo.sourceURL">
|
||
<lazyImg
|
||
:src="src"
|
||
v-for="(src, index) in props.postInfo.seriesCover"
|
||
:key="src + index"
|
||
class="img_item"
|
||
></lazyImg>
|
||
<lazyImg :src="props.postInfo.cover" :key="props.postInfo.cover" class="img_item">
|
||
<div class="play_box">
|
||
<SvgIcon name="playIcon" />
|
||
</div>
|
||
</lazyImg>
|
||
</template> -->
|
||
</div>
|
||
<!-- 操作栏 -->
|
||
<div class="post_menu">
|
||
<div class="post_menu_left">
|
||
<div class="item">
|
||
<img class="icon" src="@/assets/images/png/post_eye.png" />
|
||
<span class="ellipsis">{{ watchCountText(props.postInfo.playCount) }}</span>
|
||
</div>
|
||
|
||
<div class="item">
|
||
<img class="icon" src="@/assets/images/png/post_commit.png" />
|
||
<span class="ellipsis">{{ watchCountText(props.postInfo.commentCount) }}</span>
|
||
</div>
|
||
|
||
<div class="item" @click.stop="clickLike">
|
||
<img class="icon" v-if="props.postInfo.vidStatus?.hasLiked" src="@/assets/images/png/post_inheart.png" />
|
||
<img class="icon" v-else src="@/assets/images/png/post_heart.png" />
|
||
<span class="ellipsis">{{ watchCountText(props.postInfo.likeCount) }}</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="post_menu_right" @click.stop="goTagPage">
|
||
{{ props.postInfo.tags && props.postInfo.tags.length ? '#' + props.postInfo.tags[0].name : '' }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script lang="ts" setup>
|
||
import { reactive, inject, onActivated } from 'vue';
|
||
import { watchCountText, watchCount, fromNowTime } from '@/utils/index';
|
||
import { useRouter, useRoute } from 'vue-router';
|
||
import { showToast } from 'vant';
|
||
import { useUserStore } from '@/stores/user';
|
||
import CommunityApi from '@/service/community';
|
||
import VideoApi from '@/service/video';
|
||
|
||
const router = useRouter();
|
||
const route = useRoute();
|
||
const userStore = useUserStore();
|
||
const userInfo = userStore.userInfo;
|
||
|
||
const props = defineProps<{
|
||
postInfo: any;
|
||
currentIndex: any;
|
||
list: Array<Types.Video.VInfosItem>;
|
||
isHiddenAvatar?: boolean;
|
||
}>();
|
||
const state = reactive({
|
||
info: props.postInfo,
|
||
});
|
||
onActivated(() => {
|
||
const userStore = useUserStore();
|
||
const userInfo = userStore.userInfo;
|
||
});
|
||
|
||
// 关注
|
||
const followUp = async () => {
|
||
try {
|
||
let req = {
|
||
isFollow: !props.postInfo.publisher.hasFollowed,
|
||
followUID: props.postInfo.publisher?.uid,
|
||
};
|
||
await CommunityApi.careOrcancle(req);
|
||
props.postInfo.publisher.hasFollowed = !props.postInfo.publisher.hasFollowed;
|
||
showToast(`${props.postInfo.publisher.hasFollowed ? '关注' : '取消'}成功`);
|
||
} catch (e) {
|
||
console.log(e);
|
||
}
|
||
};
|
||
|
||
// 点赞
|
||
const clickLike = async () => {
|
||
localStorage.removeItem('operateData');
|
||
try {
|
||
let req = {
|
||
type: 'image',
|
||
objID: props.postInfo.id,
|
||
};
|
||
if (!props.postInfo.vidStatus.hasLiked) {
|
||
await CommunityApi.zan(req);
|
||
props.postInfo.vidStatus.hasLiked = true;
|
||
// getDetails(props.postInfo.id)
|
||
props.postInfo.likeCount++;
|
||
showToast('点赞成功');
|
||
} else {
|
||
await CommunityApi.cancleZan(req);
|
||
props.postInfo.vidStatus.hasLiked = false;
|
||
props.postInfo.likeCount--;
|
||
showToast('取消成功');
|
||
// getDetails(props.postInfo.id)
|
||
}
|
||
} catch (e) {
|
||
console.log(e);
|
||
}
|
||
};
|
||
|
||
const emit = defineEmits(['showReason', 'setNewData']);
|
||
// 获取帖子详情
|
||
const getDetails = async (id: any) => {
|
||
try {
|
||
let req = {
|
||
videoID: id,
|
||
};
|
||
let res: any = await VideoApi.queryVideoInfo(req);
|
||
emit('setNewData', res);
|
||
} catch (e) {
|
||
console.log(e);
|
||
}
|
||
};
|
||
|
||
const goTagPage = () => {
|
||
if (route.path == '/communityTagDeatil') {
|
||
router.replace({ path: '/communityTagDeatil', query: { id: props.postInfo.tags[0].id } });
|
||
} else {
|
||
router.push({ path: '/communityTagDeatil', query: { id: props.postInfo.tags[0].id } });
|
||
}
|
||
};
|
||
|
||
const toUserpage = () => {
|
||
router.push({ path: '/userInfo', query: { uid: props.postInfo.publisher.uid } });
|
||
localStorage.removeItem('isChange');
|
||
};
|
||
|
||
const setText = (data: any) => {
|
||
if (data == 0) {
|
||
return '待审核';
|
||
} else if (data == 1) {
|
||
return '已通过';
|
||
} else if (data == 2) {
|
||
return '查看原因';
|
||
}
|
||
};
|
||
|
||
const showReason = () => {
|
||
emit('showReason', props.postInfo?.reason);
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.post-box {
|
||
width: 100%;
|
||
//background: rgba(65, 55, 72, 0.3);
|
||
padding: 10px 16px;
|
||
box-sizing: border-box;
|
||
border-radius: 8px;
|
||
|
||
.post-top {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: flex-end;
|
||
|
||
.post-top-left {
|
||
.post-avatar {
|
||
width: 40px;
|
||
height: 40px;
|
||
border-radius: 50%;
|
||
margin-right: 8px;
|
||
:deep(.loading) {
|
||
background-size: 28px 21px;
|
||
}
|
||
}
|
||
.post-info {
|
||
width: 200px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
.username_box {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 5px;
|
||
span {
|
||
display: inline-block;
|
||
font-size: 14px;
|
||
font-weight: 600;
|
||
letter-spacing: 0.36px;
|
||
margin-right: 5px;
|
||
color: #ffffff;
|
||
}
|
||
img {
|
||
width: 20px;
|
||
}
|
||
|
||
.vipLevel {
|
||
padding: 1px 4px;
|
||
//width: 30px;
|
||
//height: 14px;
|
||
background: #f1a100;
|
||
border-radius: 8px;
|
||
font-size: 10px;
|
||
color: #000;
|
||
//display: flex;
|
||
//align-items: center;
|
||
//justify-content: center;
|
||
}
|
||
}
|
||
.location-box {
|
||
padding-top: 5px;
|
||
font-size: 12px;
|
||
color: rgb(172, 186, 191);
|
||
span {
|
||
font-size: 10px;
|
||
color: rgb(102, 56, 0);
|
||
display: inline-block;
|
||
border-radius: 3px;
|
||
background: linear-gradient(to right, rgb(238, 217, 180), rgb(174, 138, 95));
|
||
padding: 2px 5px;
|
||
box-sizing: border-box;
|
||
margin: 0 5px 0 0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.post-top-right {
|
||
svg {
|
||
width: 12px;
|
||
height: 12px;
|
||
margin: 0 3px 0 0;
|
||
}
|
||
border: solid 1px #f1a100;
|
||
border-radius: 20px;
|
||
font-size: 12px;
|
||
color: #f1a100;
|
||
width: 60px;
|
||
height: 24px;
|
||
}
|
||
.post-top-right-follow {
|
||
width: 60px;
|
||
height: 24px;
|
||
color: #fff;
|
||
background: #333;
|
||
border-radius: 20px;
|
||
font-size: 12px;
|
||
}
|
||
}
|
||
|
||
.post-time {
|
||
font-size: 12px;
|
||
color: #ffffff;
|
||
font-weight: 400;
|
||
}
|
||
|
||
.post-text {
|
||
padding-top: 6px;
|
||
padding-bottom: 6px;
|
||
display: flex;
|
||
align-items: center;
|
||
width: 100%;
|
||
}
|
||
|
||
.post-media {
|
||
width: 100%;
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr 1fr;
|
||
grid-row-gap: 8px;
|
||
grid-column-gap: 5px;
|
||
.img_item {
|
||
width: 111px;
|
||
height: 111px;
|
||
border-radius: 8px;
|
||
overflow: hidden;
|
||
position: relative;
|
||
z-index: 1;
|
||
.filter {
|
||
position: absolute;
|
||
bottom: 5px;
|
||
right: 5px;
|
||
background: rgba(0, 0, 0, 0.6);
|
||
color: #f1f1f1;
|
||
padding: 3px 12px;
|
||
box-sizing: border-box;
|
||
font-size: 12px;
|
||
border-radius: 8px;
|
||
}
|
||
.play_box {
|
||
position: absolute;
|
||
width: 100%;
|
||
height: 100%;
|
||
top: 0;
|
||
left: 0;
|
||
z-index: 1;
|
||
> svg {
|
||
width: 20px;
|
||
height: 20px;
|
||
}
|
||
|
||
.icon {
|
||
width: 30px;
|
||
height: 30px;
|
||
position: absolute;
|
||
left: 50%;
|
||
top: 50%;
|
||
transform: translate(-50%, -50%);
|
||
}
|
||
}
|
||
}
|
||
|
||
.video_item {
|
||
width: 230px;
|
||
height: 130px;
|
||
border-radius: 8px;
|
||
overflow: hidden;
|
||
position: relative;
|
||
z-index: 1;
|
||
|
||
.play_box {
|
||
position: absolute;
|
||
width: 100%;
|
||
height: 100%;
|
||
top: 0;
|
||
left: 0;
|
||
z-index: 1;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
> svg {
|
||
width: 30px;
|
||
height: 30px;
|
||
}
|
||
|
||
.icon {
|
||
width: 30px;
|
||
height: 30px;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.post_menu {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-top: 15px;
|
||
.post_menu_left {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
|
||
.item {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-right: 22px;
|
||
|
||
.icon {
|
||
width: 20px;
|
||
height: 20px;
|
||
margin-right: 5px;
|
||
}
|
||
|
||
.ellipsis {
|
||
font-size: 12px;
|
||
color: rgb(172, 186, 191);
|
||
}
|
||
}
|
||
}
|
||
.post_menu_right {
|
||
font-size: 14px;
|
||
color: #246bfd;
|
||
}
|
||
}
|
||
.statusClass {
|
||
box-sizing: border-box;
|
||
width: 72px;
|
||
height: 24px;
|
||
color: #fff;
|
||
background: #333;
|
||
border-radius: 12px;
|
||
font-size: 12px;
|
||
text-align: center;
|
||
line-height: 24px;
|
||
p {
|
||
margin: 6px 0 0 0;
|
||
}
|
||
}
|
||
}
|
||
</style>
|