uniapp-app/pages_app/videoDetail/videoDetail.vue
haomingming ad85572062 789
2025-08-25 14:24:59 +08:00

390 lines
8.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<uni-nav-bar
left-icon="left"
title="视频详情"
@clickLeft="goBack"
fixed
color="#8B2316"
height="140rpx"
:border="false"
backgroundColor="#eeeeee"
>
<template #right>
<view class="nav-actions">
<uni-icons type="share" size="22" color="#8B2316" />
<uni-icons type="heart" size="22" color="#8B2316" />
</view>
</template>
</uni-nav-bar>
<view class="video-detail-page">
<scroll-view class="content-scroll" scroll-y :show-scrollbar="false" @scrolltolower="onScrollToLower" lower-threshold="60">
<!-- 视频区域 -->
<view class="player-wrapper">
<!-- #ifdef APP -->
<uniVideo></uniVideo>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<video class="player" :src="videoSrc" :poster="poster" controls objectFit="contain"></video>
<!-- #endif -->
</view>
<!-- 标签切换 -->
<view class="tabs">
<view class="tab" :class="{ active: activeTab === 'info' }" @click="switchTab('info')">视频简介</view>
<view class="tab" :class="{ active: activeTab === 'comment' }" @click="switchTab('comment')">评论</view>
</view>
<!-- 内容区 -->
<view v-if="activeTab === 'info'" class="intro">
<view class="speaker">陈煜 教授</view>
<text class="intro-text">{{ introText }}</text>
</view>
<view v-else class="comments">
<view v-if="commentList.length === 0" class="empty">暂无评论</view>
<view v-else>
<view class="comment-item" v-for="(c, idx) in commentList" :key="idx">
<image class="avatar" :src="c.avatar" mode="aspectFill" />
<view class="meta">
<view class="name">{{ c.name }}</view>
<view class="content">{{ c.content }}</view>
<view class="time">{{ c.time }}</view>
</view>
<view class="reply-btn" @click="onReply(c)">回复</view>
</view>
<!-- 加载状态/没有更多 -->
<view v-if="loading" class="list-loading">加载中...</view>
<view v-if="noMore" class="list-no-more">没有更多了</view>
</view>
</view>
<!-- 留白避免被底部按钮遮挡 -->
<!-- <view class="bottom-spacer"></view> -->
</scroll-view>
</view>
<!-- 底部区域信息页为下载条评论页为上传图片+输入+发送 -->
<view v-if="activeTab === 'info'" class="bottom-download" @click="onDownload">
<text class="download-text">点击下载(限时<text class="discount">5</text>仅需50积分)</text>
</view>
<view v-else class="bottom-comment">
<input class="comment-input" v-model="commentText" placeholder="我也说一句" confirm-type="send" @confirm="sendComment" />
<view class="send-btn" @click="sendComment">发送</view>
</view>
</template>
<script setup>
import { ref } from 'vue';
import uniVideo from '@/components/uniVideo/uniVideo.vue';
const videoSrc = ref('');
const poster = ref('/static/livebg.png');
const activeTab = ref('info');
const introText = ref(
'首都医科大学附属北京佑安医院肝病中心四科主任疑难肝病与人工肝中心主任主任医师教授博士生导师。中华医学会肝病学分会副秘书长、委员、终末期肝病学组副组长北京医学会肝病学分会常委肝衰竭及人工肝学组副组长北京肝胆相照公益基金会副理事长等。发表论文500余篇累计SCI论文150余篇出版专著20余部获得科研奖项10余项获得发明专利7项。'
);
// 示例评论数据
const commentList = ref([
{
avatar: '/static/icon_home_my_public.png',
name: '肝胆相照测试号4',
content: 'hhjh',
time: '2025-07-01 17:17:13'
},
{
avatar: '/static/icon_home_my_public.png',
name: '肝胆相照测试号4',
content: 'kkkk',
time: '2025-07-01 17:17:18'
},
{
avatar: '/static/icon_home_my_public.png',
name: '肝胆相照测试号4',
content: 'nnj',
time: '2025-07-01 17:17:22'
}
]);
const switchTab = (tab) => {
activeTab.value = tab;
};
const onDownload = () => {
uni.showToast({ title: '前往下载页', icon: 'none' });
};
const goBack = () => {
uni.navigateBack();
};
const onReply = (c) => {
uni.showToast({ title: `回复:${c.name}`, icon: 'none' });
};
// 评论输入
const commentText = ref('');
const sendComment = () => {
if (!commentText.value.trim()) {
uni.showToast({ title: '请输入内容', icon: 'none' });
return;
}
commentList.value.unshift({
avatar: '/static/icon_home_my_public.png',
name: '我',
content: commentText.value,
time: new Date().toISOString().slice(0, 19).replace('T', ' ')
});
commentText.value = '';
};
// 上拉加载
const page = ref(1);
const pageSize = ref(10);
const loading = ref(false);
const noMore = ref(false);
const mockMore = Array.from({ length: 30 }).map((_, i) => ({
avatar: '/static/icon_home_my_public.png',
name: '肝胆相照测试号4',
content: `更多评论 ${i + 1}`,
time: `2025-07-01 17:${20 + Math.floor(i / 2)}:${10 + (i % 2) * 5}`
}));
const onScrollToLower = async () => {
if (activeTab.value !== 'comment' || loading.value || noMore.value) return;
loading.value = true;
try {
await new Promise(r => setTimeout(r, 600));
const start = (page.value - 1) * pageSize.value;
const chunk = mockMore.slice(start, start + pageSize.value);
if (!chunk.length) {
noMore.value = true;
} else {
commentList.value.push(...chunk);
page.value += 1;
}
} finally {
loading.value = false;
}
};
</script>
<style lang="scss" scoped>
$nav-h: 140rpx;
$bottom-h: 100rpx;
$bg-color: #f7f7f7;
$text-primary: #333;
$text-secondary: #666;
$theme-color: #8B2316;
.nav-actions {
display: flex;
align-items: center;
gap: 20rpx;
}
.video-detail-page {
height: calc(100vh - #{$nav-h} - #{$bottom-h});
background: $bg-color;
overflow: hidden;
}
.content-scroll {
height: 100%;
}
.player-wrapper {
background: #fff;
}
.player {
width: 100%;
height: 420rpx;
background: #000;
border-bottom: 1rpx solid #eee;
}
.tabs {
background: #fff;
display: flex;
justify-content: center;
gap: 240rpx;
padding: 24rpx 0 0;
position: sticky;
border-bottom:2rpx solid #cccccc;
top: 0;
z-index: 5;
.tab {
position: relative;
padding: 16rpx 0 24rpx;
color: $text-secondary;
font-size: 28rpx;
&.active {
color: $theme-color;
}
&.active::after {
content: '';
position: absolute;
left: 50%;
bottom: 0;
transform: translateX(-50%);
width: 64rpx;
height: 6rpx;
border-radius: 6rpx;
background: $theme-color;
}
}
}
.intro {
background: #fff;
padding: 24rpx 28rpx 40rpx;
.speaker {
font-size: 32rpx;
color: $text-primary;
margin: 12rpx 0 20rpx;
}
.intro-text {
font-size: 30rpx;
line-height: 1.8;
color: $text-primary;
}
}
.comments {
background: #fff;
min-height: 300rpx;
padding: 20rpx 20rpx 40rpx;
.empty {
text-align: center;
color: $text-secondary;
padding: 60rpx 0;
}
.comment-item {
display: flex;
align-items: flex-start;
padding: 24rpx 10rpx;
border-bottom: 2rpx solid #f0f0f0;
.avatar {
width: 100rpx;
height: 100rpx;
border-radius: 20rpx;
margin-right: 20rpx;
background: #eee;
}
.meta {
flex: 1;
min-width: 0;
.name {
font-size: 30rpx;
color: #1f1f1f;
margin-bottom: 6rpx;
}
.content {
font-size: 30rpx;
color: #666;
line-height: 1.6;
margin-bottom: 12rpx;
word-break: break-word;
}
.time {
font-size: 24rpx;
color: #909399;
}
}
.reply-btn {
margin-left: 16rpx;
border: 2rpx solid #8B2316;
color: #8B2316;
border-radius: 36rpx;
padding: 10rpx 24rpx;
font-size: 26rpx;
white-space: nowrap;
}
}
.list-loading,
.list-no-more {
text-align: center;
color: #9aa0a6;
padding: 20rpx 0;
font-size: 26rpx;
}
}
.bottom-spacer {
height: 40rpx;
}
.bottom-download {
position: fixed;
left: 0;
right: 0;
bottom: 0;
height: $bottom-h;
background: #00cac1;
display: flex;
align-items: center;
justify-content: center;
z-index: 10;
.discount{
color:#d4ff00;
font-size: 40rpx;
}
.download-text {
color: #fff;
font-size: 30rpx;
}
}
.bottom-comment {
position: fixed;
left: 0;
right: 0;
bottom: 0;
height: 100rpx;
background: #ffffff;
display: flex;
align-items: center;
padding: 0 20rpx;
gap: 16rpx;
z-index: 10;
.comment-input {
flex: 1;
height: 72rpx;
border-radius: 10rpx;
background: #ffffff;
border: 2rpx solid #cacaca;
padding: 0 24rpx;
font-size: 28rpx;
color: #333;
}
.send-btn {
padding: 0 28rpx;
height: 72rpx;
border-radius: 36rpx;
background: #8B2316;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
}
}
</style>