757 lines
16 KiB
Vue
757 lines
16 KiB
Vue
|
|
<template>
|
||
|
|
<div class="video-detail-page">
|
||
|
|
<!-- 左侧导航栏 -->
|
||
|
|
<aside class="sidebar">
|
||
|
|
<!-- Logo -->
|
||
|
|
<div class="logo">logo</div>
|
||
|
|
|
||
|
|
<!-- 导航菜单 -->
|
||
|
|
<nav class="nav-menu">
|
||
|
|
<div class="nav-item" @click="goToProfile">
|
||
|
|
<el-icon><User /></el-icon>
|
||
|
|
<span>个人主页</span>
|
||
|
|
</div>
|
||
|
|
<div class="nav-item" @click="goToSubscription">
|
||
|
|
<el-icon><Compass /></el-icon>
|
||
|
|
<span>会员订阅</span>
|
||
|
|
</div>
|
||
|
|
<div class="nav-item active">
|
||
|
|
<el-icon><Document /></el-icon>
|
||
|
|
<span>我的作品</span>
|
||
|
|
</div>
|
||
|
|
</nav>
|
||
|
|
</aside>
|
||
|
|
|
||
|
|
<!-- 主内容区域 -->
|
||
|
|
<main class="main-content">
|
||
|
|
<!-- 左侧视频播放器区域 -->
|
||
|
|
<div class="video-player-section">
|
||
|
|
<div class="video-container">
|
||
|
|
<video
|
||
|
|
ref="videoPlayer"
|
||
|
|
class="video-player"
|
||
|
|
:src="videoData.videoUrl"
|
||
|
|
:poster="videoData.cover"
|
||
|
|
@loadedmetadata="onVideoLoaded"
|
||
|
|
@timeupdate="onTimeUpdate"
|
||
|
|
@ended="onVideoEnded"
|
||
|
|
>
|
||
|
|
您的浏览器不支持视频播放
|
||
|
|
</video>
|
||
|
|
|
||
|
|
<!-- 视频文字叠加 -->
|
||
|
|
<div class="video-overlay" v-if="videoData.overlayText">
|
||
|
|
<div class="overlay-text">{{ videoData.overlayText }}</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 播放控制栏 -->
|
||
|
|
<div class="video-controls">
|
||
|
|
<div class="control-left">
|
||
|
|
<button class="play-btn" @click="togglePlay">
|
||
|
|
<el-icon v-if="!isPlaying"><VideoPlay /></el-icon>
|
||
|
|
<el-icon v-else><Pause /></el-icon>
|
||
|
|
</button>
|
||
|
|
<div class="progress-container">
|
||
|
|
<div class="progress-bar" @click="seekTo">
|
||
|
|
<div class="progress-fill" :style="{ width: progressPercent + '%' }"></div>
|
||
|
|
</div>
|
||
|
|
<div class="time-display">{{ formatTime(currentTime) }} / {{ formatTime(duration) }}</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="control-right">
|
||
|
|
<button class="control-btn" @click="toggleFullscreen">
|
||
|
|
<el-icon><FullScreen /></el-icon>
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 右上角操作按钮 -->
|
||
|
|
<div class="video-actions">
|
||
|
|
<el-tooltip content="分享" placement="bottom">
|
||
|
|
<button class="action-btn" @click="shareVideo">
|
||
|
|
<el-icon><Share /></el-icon>
|
||
|
|
</button>
|
||
|
|
</el-tooltip>
|
||
|
|
<el-tooltip content="下载" placement="bottom">
|
||
|
|
<button class="action-btn" @click="downloadVideo">
|
||
|
|
<el-icon><Download /></el-icon>
|
||
|
|
</button>
|
||
|
|
</el-tooltip>
|
||
|
|
<el-tooltip content="删除" placement="bottom">
|
||
|
|
<button class="action-btn delete-btn" @click="deleteVideo">
|
||
|
|
<el-icon><Delete /></el-icon>
|
||
|
|
</button>
|
||
|
|
</el-tooltip>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 右侧详情侧边栏 -->
|
||
|
|
<div class="detail-sidebar">
|
||
|
|
<!-- 用户信息头部 -->
|
||
|
|
<div class="sidebar-header">
|
||
|
|
<div class="user-info">
|
||
|
|
<div class="avatar">
|
||
|
|
<el-icon><User /></el-icon>
|
||
|
|
</div>
|
||
|
|
<div class="username">{{ videoData.username }}</div>
|
||
|
|
</div>
|
||
|
|
<button class="close-btn" @click="goBack">
|
||
|
|
<el-icon><Close /></el-icon>
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 标签页 -->
|
||
|
|
<div class="tabs">
|
||
|
|
<div class="tab active">视频详情</div>
|
||
|
|
<div class="tab">文生视频</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 描述区域 -->
|
||
|
|
<div class="description-section">
|
||
|
|
<h3 class="section-title">描述</h3>
|
||
|
|
<p class="description-text">{{ videoData.description }}</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 元数据区域 -->
|
||
|
|
<div class="metadata-section">
|
||
|
|
<div class="metadata-item">
|
||
|
|
<span class="label">创建时间</span>
|
||
|
|
<span class="value">{{ videoData.createTime }}</span>
|
||
|
|
</div>
|
||
|
|
<div class="metadata-item">
|
||
|
|
<span class="label">视频 ID</span>
|
||
|
|
<span class="value">{{ videoData.id }}</span>
|
||
|
|
</div>
|
||
|
|
<div class="metadata-item">
|
||
|
|
<span class="label">时长</span>
|
||
|
|
<span class="value">{{ videoData.duration }}s</span>
|
||
|
|
</div>
|
||
|
|
<div class="metadata-item">
|
||
|
|
<span class="label">清晰度</span>
|
||
|
|
<span class="value">{{ videoData.resolution }}</span>
|
||
|
|
</div>
|
||
|
|
<div class="metadata-item">
|
||
|
|
<span class="label">分类</span>
|
||
|
|
<span class="value">{{ videoData.category }}</span>
|
||
|
|
</div>
|
||
|
|
<div class="metadata-item">
|
||
|
|
<span class="label">宽高比</span>
|
||
|
|
<span class="value">{{ videoData.aspectRatio }}</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 操作按钮 -->
|
||
|
|
<div class="action-section">
|
||
|
|
<button class="create-similar-btn" @click="createSimilar">
|
||
|
|
做同款
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</main>
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script setup>
|
||
|
|
import { ref, onMounted, onUnmounted } from 'vue'
|
||
|
|
import { useRoute, useRouter } from 'vue-router'
|
||
|
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||
|
|
import {
|
||
|
|
VideoPlay,
|
||
|
|
VideoPause as Pause,
|
||
|
|
FullScreen,
|
||
|
|
Share,
|
||
|
|
Download,
|
||
|
|
Delete,
|
||
|
|
User,
|
||
|
|
Compass,
|
||
|
|
Document,
|
||
|
|
Close
|
||
|
|
} from '@element-plus/icons-vue'
|
||
|
|
|
||
|
|
const route = useRoute()
|
||
|
|
const router = useRouter()
|
||
|
|
|
||
|
|
// 视频播放器相关
|
||
|
|
const videoPlayer = ref(null)
|
||
|
|
const isPlaying = ref(false)
|
||
|
|
const currentTime = ref(0)
|
||
|
|
const duration = ref(0)
|
||
|
|
const progressPercent = ref(0)
|
||
|
|
|
||
|
|
// 视频数据
|
||
|
|
const videoData = ref({
|
||
|
|
id: '2995697841305810',
|
||
|
|
username: 'mingzi_FBx7foZYDS7inL',
|
||
|
|
title: 'What Does it Mean To You',
|
||
|
|
overlayText: 'What Does it Mean To You',
|
||
|
|
description: '影片捕捉了暴风雪中的午夜时分,坐落在积雪覆盖的悬崖顶上的孤立灯塔。相机逐渐放大灯塔的灯光,穿透飞舞的雪花,投射出幽幽的光芒。在白茫茫的环境中,灯塔的黑色轮廓显得格外醒目,呼啸的风声和远处海浪的撞击声增强了孤独的氛围。这一场景展示了灯塔的孤独力量。',
|
||
|
|
createTime: '2025/10/17 13:41',
|
||
|
|
duration: 5,
|
||
|
|
resolution: '1080p',
|
||
|
|
category: '文生视频',
|
||
|
|
aspectRatio: '16:9',
|
||
|
|
videoUrl: '/images/backgrounds/welcome.jpg', // 临时使用图片作为视频
|
||
|
|
cover: '/images/backgrounds/welcome.jpg'
|
||
|
|
})
|
||
|
|
|
||
|
|
// 根据ID获取视频数据
|
||
|
|
const getVideoData = (id) => {
|
||
|
|
// 模拟不同ID对应不同的分类
|
||
|
|
const videoConfigs = {
|
||
|
|
'2995000000001': { category: '参考图', title: '图片作品 #1' },
|
||
|
|
'2995000000002': { category: '参考图', title: '图片作品 #2' },
|
||
|
|
'2995000000003': { category: '文生视频', title: '视频作品 #3' },
|
||
|
|
'2995000000004': { category: '图生视频', title: '视频作品 #4' }
|
||
|
|
}
|
||
|
|
|
||
|
|
const config = videoConfigs[id] || videoConfigs['2995000000003']
|
||
|
|
|
||
|
|
return {
|
||
|
|
id: id,
|
||
|
|
username: 'mingzi_FBx7foZYDS7inL',
|
||
|
|
title: config.title,
|
||
|
|
overlayText: config.title,
|
||
|
|
description: '影片捕捉了暴风雪中的午夜时分,坐落在积雪覆盖的悬崖顶上的孤立灯塔。相机逐渐放大灯塔的灯光,穿透飞舞的雪花,投射出幽幽的光芒。在白茫茫的环境中,灯塔的黑色轮廓显得格外醒目,呼啸的风声和远处海浪的撞击声增强了孤独的氛围。这一场景展示了灯塔的孤独力量。',
|
||
|
|
createTime: '2025/10/17 13:41',
|
||
|
|
duration: 5,
|
||
|
|
resolution: '1080p',
|
||
|
|
category: config.category,
|
||
|
|
aspectRatio: '16:9',
|
||
|
|
videoUrl: '/images/backgrounds/welcome.jpg',
|
||
|
|
cover: '/images/backgrounds/welcome.jpg'
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 视频播放控制
|
||
|
|
const togglePlay = () => {
|
||
|
|
if (!videoPlayer.value) return
|
||
|
|
|
||
|
|
if (isPlaying.value) {
|
||
|
|
videoPlayer.value.pause()
|
||
|
|
} else {
|
||
|
|
videoPlayer.value.play()
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
const onVideoLoaded = () => {
|
||
|
|
duration.value = videoPlayer.value.duration
|
||
|
|
}
|
||
|
|
|
||
|
|
const onTimeUpdate = () => {
|
||
|
|
currentTime.value = videoPlayer.value.currentTime
|
||
|
|
progressPercent.value = (currentTime.value / duration.value) * 100
|
||
|
|
}
|
||
|
|
|
||
|
|
const onVideoEnded = () => {
|
||
|
|
isPlaying.value = false
|
||
|
|
}
|
||
|
|
|
||
|
|
const seekTo = (event) => {
|
||
|
|
if (!videoPlayer.value) return
|
||
|
|
|
||
|
|
const rect = event.currentTarget.getBoundingClientRect()
|
||
|
|
const clickX = event.clientX - rect.left
|
||
|
|
const percentage = clickX / rect.width
|
||
|
|
const newTime = percentage * duration.value
|
||
|
|
|
||
|
|
videoPlayer.value.currentTime = newTime
|
||
|
|
}
|
||
|
|
|
||
|
|
const formatTime = (time) => {
|
||
|
|
const minutes = Math.floor(time / 60)
|
||
|
|
const seconds = Math.floor(time % 60)
|
||
|
|
return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`
|
||
|
|
}
|
||
|
|
|
||
|
|
const toggleFullscreen = () => {
|
||
|
|
if (!videoPlayer.value) return
|
||
|
|
|
||
|
|
if (document.fullscreenElement) {
|
||
|
|
document.exitFullscreen()
|
||
|
|
} else {
|
||
|
|
videoPlayer.value.requestFullscreen()
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 操作功能
|
||
|
|
const shareVideo = () => {
|
||
|
|
ElMessage.info('分享功能开发中')
|
||
|
|
}
|
||
|
|
|
||
|
|
const downloadVideo = () => {
|
||
|
|
ElMessage.success('开始下载视频')
|
||
|
|
}
|
||
|
|
|
||
|
|
const deleteVideo = async () => {
|
||
|
|
try {
|
||
|
|
await ElMessageBox.confirm('确定删除这个视频吗?', '删除确认', {
|
||
|
|
type: 'warning',
|
||
|
|
confirmButtonText: '删除',
|
||
|
|
cancelButtonText: '取消'
|
||
|
|
})
|
||
|
|
ElMessage.success('视频已删除')
|
||
|
|
router.back()
|
||
|
|
} catch (_) {}
|
||
|
|
}
|
||
|
|
|
||
|
|
const createSimilar = () => {
|
||
|
|
ElMessage.info('跳转到文生视频创作页面')
|
||
|
|
// router.push('/create-video')
|
||
|
|
}
|
||
|
|
|
||
|
|
// 导航函数
|
||
|
|
const goToProfile = () => {
|
||
|
|
router.push('/profile')
|
||
|
|
}
|
||
|
|
|
||
|
|
const goToSubscription = () => {
|
||
|
|
router.push('/subscription')
|
||
|
|
}
|
||
|
|
|
||
|
|
const goBack = () => {
|
||
|
|
router.back()
|
||
|
|
}
|
||
|
|
|
||
|
|
// 监听视频播放状态变化
|
||
|
|
const handlePlay = () => {
|
||
|
|
isPlaying.value = true
|
||
|
|
}
|
||
|
|
|
||
|
|
const handlePause = () => {
|
||
|
|
isPlaying.value = false
|
||
|
|
}
|
||
|
|
|
||
|
|
onMounted(() => {
|
||
|
|
// 根据路由参数更新视频数据
|
||
|
|
const videoId = route.params.id
|
||
|
|
if (videoId) {
|
||
|
|
videoData.value = getVideoData(videoId)
|
||
|
|
}
|
||
|
|
|
||
|
|
if (videoPlayer.value) {
|
||
|
|
videoPlayer.value.addEventListener('play', handlePlay)
|
||
|
|
videoPlayer.value.addEventListener('pause', handlePause)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
onUnmounted(() => {
|
||
|
|
if (videoPlayer.value) {
|
||
|
|
videoPlayer.value.removeEventListener('play', handlePlay)
|
||
|
|
videoPlayer.value.removeEventListener('pause', handlePause)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<style scoped>
|
||
|
|
.video-detail-page {
|
||
|
|
display: flex;
|
||
|
|
height: 100vh;
|
||
|
|
background: #0a0a0a;
|
||
|
|
color: #fff;
|
||
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 左侧导航栏 */
|
||
|
|
.sidebar {
|
||
|
|
width: 280px;
|
||
|
|
background: #1a1a1a;
|
||
|
|
padding: 24px 0;
|
||
|
|
border-right: 1px solid #1a1a1a;
|
||
|
|
flex-shrink: 0;
|
||
|
|
display: block;
|
||
|
|
position: relative;
|
||
|
|
}
|
||
|
|
|
||
|
|
.logo {
|
||
|
|
padding: 0 24px 32px;
|
||
|
|
font-size: 20px;
|
||
|
|
font-weight: 500;
|
||
|
|
color: white;
|
||
|
|
}
|
||
|
|
|
||
|
|
.nav-menu {
|
||
|
|
padding: 0 20px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.nav-item {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
padding: 14px 18px;
|
||
|
|
margin-bottom: 4px;
|
||
|
|
border-radius: 8px;
|
||
|
|
cursor: pointer;
|
||
|
|
transition: all 0.3s ease;
|
||
|
|
position: relative;
|
||
|
|
}
|
||
|
|
|
||
|
|
.nav-item:hover {
|
||
|
|
background: #2a2a2a;
|
||
|
|
}
|
||
|
|
|
||
|
|
.nav-item.active {
|
||
|
|
background: #1e3a8a;
|
||
|
|
}
|
||
|
|
|
||
|
|
.nav-item .el-icon {
|
||
|
|
margin-right: 14px;
|
||
|
|
font-size: 20px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.nav-item span {
|
||
|
|
font-size: 15px;
|
||
|
|
flex: 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 主内容区域 */
|
||
|
|
.main-content {
|
||
|
|
flex: 1;
|
||
|
|
display: flex;
|
||
|
|
background: #0a0a0a;
|
||
|
|
overflow: hidden;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 左侧视频播放器区域 */
|
||
|
|
.video-player-section {
|
||
|
|
flex: 2;
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: center;
|
||
|
|
background: #000;
|
||
|
|
position: relative;
|
||
|
|
}
|
||
|
|
|
||
|
|
.video-container {
|
||
|
|
position: relative;
|
||
|
|
width: 100%;
|
||
|
|
height: 100%;
|
||
|
|
max-width: 100%;
|
||
|
|
max-height: 100%;
|
||
|
|
}
|
||
|
|
|
||
|
|
.video-player {
|
||
|
|
width: 100%;
|
||
|
|
height: 100%;
|
||
|
|
object-fit: contain;
|
||
|
|
background: #000;
|
||
|
|
}
|
||
|
|
|
||
|
|
.video-overlay {
|
||
|
|
position: absolute;
|
||
|
|
bottom: 80px;
|
||
|
|
left: 20px;
|
||
|
|
z-index: 10;
|
||
|
|
}
|
||
|
|
|
||
|
|
.overlay-text {
|
||
|
|
font-family: 'Brush Script MT', cursive;
|
||
|
|
font-size: 24px;
|
||
|
|
color: #8b5cf6;
|
||
|
|
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.8);
|
||
|
|
font-weight: bold;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 视频控制栏 */
|
||
|
|
.video-controls {
|
||
|
|
position: absolute;
|
||
|
|
bottom: 0;
|
||
|
|
left: 0;
|
||
|
|
right: 0;
|
||
|
|
background: linear-gradient(transparent, rgba(0, 0, 0, 0.8));
|
||
|
|
padding: 20px;
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: space-between;
|
||
|
|
}
|
||
|
|
|
||
|
|
.control-left {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
gap: 15px;
|
||
|
|
flex: 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
.play-btn {
|
||
|
|
background: none;
|
||
|
|
border: none;
|
||
|
|
color: #fff;
|
||
|
|
font-size: 20px;
|
||
|
|
cursor: pointer;
|
||
|
|
padding: 8px;
|
||
|
|
border-radius: 50%;
|
||
|
|
transition: background-color 0.3s;
|
||
|
|
}
|
||
|
|
|
||
|
|
.play-btn:hover {
|
||
|
|
background: rgba(255, 255, 255, 0.1);
|
||
|
|
}
|
||
|
|
|
||
|
|
.progress-container {
|
||
|
|
flex: 1;
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
gap: 10px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.progress-bar {
|
||
|
|
flex: 1;
|
||
|
|
height: 4px;
|
||
|
|
background: rgba(255, 255, 255, 0.3);
|
||
|
|
border-radius: 2px;
|
||
|
|
cursor: pointer;
|
||
|
|
position: relative;
|
||
|
|
}
|
||
|
|
|
||
|
|
.progress-fill {
|
||
|
|
height: 100%;
|
||
|
|
background: #409eff;
|
||
|
|
border-radius: 2px;
|
||
|
|
transition: width 0.1s;
|
||
|
|
}
|
||
|
|
|
||
|
|
.time-display {
|
||
|
|
color: #fff;
|
||
|
|
font-size: 14px;
|
||
|
|
white-space: nowrap;
|
||
|
|
}
|
||
|
|
|
||
|
|
.control-right {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
}
|
||
|
|
|
||
|
|
.control-btn {
|
||
|
|
background: none;
|
||
|
|
border: none;
|
||
|
|
color: #fff;
|
||
|
|
font-size: 18px;
|
||
|
|
cursor: pointer;
|
||
|
|
padding: 8px;
|
||
|
|
border-radius: 4px;
|
||
|
|
transition: background-color 0.3s;
|
||
|
|
}
|
||
|
|
|
||
|
|
.control-btn:hover {
|
||
|
|
background: rgba(255, 255, 255, 0.1);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 右上角操作按钮 */
|
||
|
|
.video-actions {
|
||
|
|
position: absolute;
|
||
|
|
top: 20px;
|
||
|
|
right: 20px;
|
||
|
|
display: flex;
|
||
|
|
gap: 10px;
|
||
|
|
z-index: 10;
|
||
|
|
}
|
||
|
|
|
||
|
|
.action-btn {
|
||
|
|
background: rgba(0, 0, 0, 0.6);
|
||
|
|
border: none;
|
||
|
|
color: #fff;
|
||
|
|
width: 40px;
|
||
|
|
height: 40px;
|
||
|
|
border-radius: 50%;
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: center;
|
||
|
|
cursor: pointer;
|
||
|
|
transition: all 0.3s;
|
||
|
|
}
|
||
|
|
|
||
|
|
.action-btn:hover {
|
||
|
|
background: rgba(0, 0, 0, 0.8);
|
||
|
|
transform: scale(1.1);
|
||
|
|
}
|
||
|
|
|
||
|
|
.delete-btn:hover {
|
||
|
|
background: rgba(220, 38, 38, 0.8);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 右侧详情侧边栏 */
|
||
|
|
.detail-sidebar {
|
||
|
|
flex: 1;
|
||
|
|
background: #1a1a1a;
|
||
|
|
border-radius: 12px 0 0 0;
|
||
|
|
padding: 24px;
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
gap: 24px;
|
||
|
|
overflow-y: auto;
|
||
|
|
}
|
||
|
|
|
||
|
|
.sidebar-header {
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
gap: 16px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.user-info {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
gap: 12px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.avatar {
|
||
|
|
width: 40px;
|
||
|
|
height: 40px;
|
||
|
|
background: #409eff;
|
||
|
|
border-radius: 50%;
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: center;
|
||
|
|
color: #fff;
|
||
|
|
font-size: 18px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.username {
|
||
|
|
font-size: 16px;
|
||
|
|
font-weight: 500;
|
||
|
|
color: #fff;
|
||
|
|
}
|
||
|
|
|
||
|
|
.tabs {
|
||
|
|
display: flex;
|
||
|
|
gap: 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
.tab {
|
||
|
|
padding: 8px 16px;
|
||
|
|
background: transparent;
|
||
|
|
color: #9ca3af;
|
||
|
|
cursor: pointer;
|
||
|
|
border-radius: 6px;
|
||
|
|
transition: all 0.3s;
|
||
|
|
font-size: 14px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.tab.active {
|
||
|
|
background: #409eff;
|
||
|
|
color: #fff;
|
||
|
|
}
|
||
|
|
|
||
|
|
.tab:hover:not(.active) {
|
||
|
|
background: rgba(255, 255, 255, 0.1);
|
||
|
|
color: #fff;
|
||
|
|
}
|
||
|
|
|
||
|
|
.description-section {
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
gap: 12px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.section-title {
|
||
|
|
font-size: 16px;
|
||
|
|
font-weight: 600;
|
||
|
|
color: #fff;
|
||
|
|
margin: 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
.description-text {
|
||
|
|
font-size: 14px;
|
||
|
|
line-height: 1.6;
|
||
|
|
color: #d1d5db;
|
||
|
|
margin: 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
.metadata-section {
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
gap: 12px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.metadata-item {
|
||
|
|
display: flex;
|
||
|
|
justify-content: space-between;
|
||
|
|
align-items: center;
|
||
|
|
padding: 8px 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
.label {
|
||
|
|
font-size: 14px;
|
||
|
|
color: #9ca3af;
|
||
|
|
}
|
||
|
|
|
||
|
|
.value {
|
||
|
|
font-size: 14px;
|
||
|
|
color: #fff;
|
||
|
|
font-weight: 500;
|
||
|
|
}
|
||
|
|
|
||
|
|
.action-section {
|
||
|
|
margin-top: auto;
|
||
|
|
padding-top: 20px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.create-similar-btn {
|
||
|
|
width: 100%;
|
||
|
|
background: #409eff;
|
||
|
|
color: #fff;
|
||
|
|
border: none;
|
||
|
|
border-radius: 8px;
|
||
|
|
padding: 12px 24px;
|
||
|
|
font-size: 16px;
|
||
|
|
font-weight: 500;
|
||
|
|
cursor: pointer;
|
||
|
|
transition: all 0.3s;
|
||
|
|
}
|
||
|
|
|
||
|
|
.create-similar-btn:hover {
|
||
|
|
background: #337ecc;
|
||
|
|
transform: translateY(-2px);
|
||
|
|
}
|
||
|
|
|
||
|
|
.create-similar-btn:active {
|
||
|
|
transform: translateY(0);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 响应式设计 */
|
||
|
|
@media (max-width: 1024px) {
|
||
|
|
.video-detail-page {
|
||
|
|
flex-direction: column;
|
||
|
|
}
|
||
|
|
|
||
|
|
.video-player-section {
|
||
|
|
flex: 1;
|
||
|
|
min-height: 50vh;
|
||
|
|
}
|
||
|
|
|
||
|
|
.detail-sidebar {
|
||
|
|
flex: 1;
|
||
|
|
border-radius: 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@media (max-width: 768px) {
|
||
|
|
.video-overlay {
|
||
|
|
bottom: 60px;
|
||
|
|
left: 10px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.overlay-text {
|
||
|
|
font-size: 18px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.video-controls {
|
||
|
|
padding: 15px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.video-actions {
|
||
|
|
top: 15px;
|
||
|
|
right: 15px;
|
||
|
|
gap: 8px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.action-btn {
|
||
|
|
width: 35px;
|
||
|
|
height: 35px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.detail-sidebar {
|
||
|
|
padding: 16px;
|
||
|
|
gap: 16px;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
</style>
|