2025-12-01 22:27:50 +08:00
|
|
|
|
<template>
|
2026-01-17 19:54:57 +08:00
|
|
|
|
<FullWidthLayout :show-padding="false">
|
2026-02-12 23:35:39 +08:00
|
|
|
|
<div class="digital-human-page">
|
|
|
|
|
|
<!-- 左侧配置区 -->
|
|
|
|
|
|
<section class="config-panel">
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 步骤1:输入文案 -->
|
|
|
|
|
|
<div class="config-card">
|
|
|
|
|
|
<div class="step-indicator">1</div>
|
|
|
|
|
|
<h3 class="card-title">输入播文案</h3>
|
|
|
|
|
|
|
|
|
|
|
|
<a-textarea
|
2026-02-26 18:52:09 +08:00
|
|
|
|
v-model:value="store.text"
|
|
|
|
|
|
:placeholder="placeholder"
|
2026-02-12 23:35:39 +08:00
|
|
|
|
:rows="4"
|
2026-02-26 18:52:09 +08:00
|
|
|
|
:maxlength="4000"
|
2026-02-12 23:35:39 +08:00
|
|
|
|
:show-count="true"
|
|
|
|
|
|
class="text-input"
|
|
|
|
|
|
:bordered="false"
|
|
|
|
|
|
/>
|
2025-12-01 22:27:50 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
<div class="input-meta">
|
2026-02-26 18:52:09 +08:00
|
|
|
|
<span>当前字数:{{ store.text?.length || 0 }}字</span>
|
2026-01-17 19:54:57 +08:00
|
|
|
|
</div>
|
2026-02-12 23:35:39 +08:00
|
|
|
|
</div>
|
2025-12-01 22:27:50 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
<!-- 步骤2:语音设置 -->
|
|
|
|
|
|
<div class="config-card">
|
|
|
|
|
|
<div class="step-indicator">2</div>
|
|
|
|
|
|
<h3 class="card-title">语音设置</h3>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="voice-settings">
|
|
|
|
|
|
<div class="setting-group">
|
|
|
|
|
|
<label class="setting-label">选择音色</label>
|
|
|
|
|
|
<VoiceSelector
|
2026-02-26 18:52:09 +08:00
|
|
|
|
:synth-text="store.text"
|
|
|
|
|
|
:speech-rate="store.speechRate"
|
|
|
|
|
|
@select="store.setVoice"
|
2026-02-12 23:35:39 +08:00
|
|
|
|
/>
|
2025-12-01 22:27:50 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2026-01-17 19:54:57 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
<!-- 步骤3:上传视频 -->
|
|
|
|
|
|
<div class="config-card">
|
|
|
|
|
|
<div class="step-indicator">3</div>
|
|
|
|
|
|
<h3 class="card-title">上传/选择视频素材</h3>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="video-options">
|
|
|
|
|
|
<!-- 上传新视频 -->
|
|
|
|
|
|
<div
|
|
|
|
|
|
class="video-option-card"
|
2026-02-26 18:52:09 +08:00
|
|
|
|
:class="{ 'video-option-card--selected': store.videoSource === 'upload' }"
|
|
|
|
|
|
@click="store.selectUploadMode"
|
2026-02-12 23:35:39 +08:00
|
|
|
|
>
|
|
|
|
|
|
<div class="video-option-icon">
|
|
|
|
|
|
<CloudUploadOutlined />
|
2025-12-28 00:19:17 +08:00
|
|
|
|
</div>
|
2026-02-12 23:35:39 +08:00
|
|
|
|
<div class="video-option-content">
|
|
|
|
|
|
<h4>点击上传新视频</h4>
|
|
|
|
|
|
<p>支持 MP4、MOV (需 >3秒)</p>
|
2025-12-28 00:19:17 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
<!-- 从素材库选择 -->
|
2025-12-28 00:19:17 +08:00
|
|
|
|
<div
|
2026-02-12 23:35:39 +08:00
|
|
|
|
class="video-option-card"
|
2026-02-26 18:52:09 +08:00
|
|
|
|
:class="{ 'video-option-card--selected': store.videoSource === 'select' }"
|
|
|
|
|
|
@click="store.selectLibraryMode"
|
2025-12-28 00:19:17 +08:00
|
|
|
|
>
|
2026-02-12 23:35:39 +08:00
|
|
|
|
<div class="video-option-icon">
|
|
|
|
|
|
<PictureOutlined />
|
2025-12-28 00:19:17 +08:00
|
|
|
|
</div>
|
2026-02-12 23:35:39 +08:00
|
|
|
|
<div class="video-option-content">
|
|
|
|
|
|
<h4>从素材库选择</h4>
|
|
|
|
|
|
<p>选择已上传的视频</p>
|
2025-12-28 00:19:17 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
<!-- 已选择视频预览 -->
|
2026-02-26 18:52:09 +08:00
|
|
|
|
<div v-if="store.selectedVideo" class="selected-video">
|
2026-02-12 23:35:39 +08:00
|
|
|
|
<div class="video-preview-thumb">
|
|
|
|
|
|
<img
|
2026-02-26 18:52:09 +08:00
|
|
|
|
:src="getVideoPreviewUrl(store.selectedVideo)"
|
|
|
|
|
|
:alt="store.selectedVideo.fileName"
|
2026-02-12 23:35:39 +08:00
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="video-preview-info">
|
2026-02-26 18:52:09 +08:00
|
|
|
|
<div class="video-name">{{ store.selectedVideo.fileName }}</div>
|
|
|
|
|
|
<div class="video-meta">{{ formatDuration(store.selectedVideo.duration) }}</div>
|
2026-02-12 23:35:39 +08:00
|
|
|
|
</div>
|
2026-02-26 18:52:09 +08:00
|
|
|
|
<button class="change-video-btn" @click="store.reset">更换</button>
|
2026-02-12 23:35:39 +08:00
|
|
|
|
</div>
|
2025-12-28 00:19:17 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
<!-- 上传区域 -->
|
|
|
|
|
|
<div
|
2026-02-26 18:52:09 +08:00
|
|
|
|
v-if="store.videoSource === 'upload'"
|
2026-02-12 23:35:39 +08:00
|
|
|
|
class="upload-zone"
|
|
|
|
|
|
:class="{ 'upload-zone--dragover': dragOver }"
|
|
|
|
|
|
@drop.prevent="handleDrop"
|
|
|
|
|
|
@dragover.prevent="dragOver = true"
|
|
|
|
|
|
@dragleave.prevent="dragOver = false"
|
|
|
|
|
|
>
|
2026-02-26 18:52:09 +08:00
|
|
|
|
<input ref="fileInput" type="file" accept=".mp4,.mov" class="file-input" @change="handleFileSelect" />
|
2026-02-12 23:35:39 +08:00
|
|
|
|
|
2026-02-26 18:52:09 +08:00
|
|
|
|
<div v-if="!store.videoPreviewUrl" class="upload-placeholder">
|
2026-02-12 23:35:39 +08:00
|
|
|
|
<CloudUploadOutlined class="upload-icon" />
|
|
|
|
|
|
<span class="upload-text">点击上传新视频</span>
|
|
|
|
|
|
<span class="upload-hint">支持 MP4、MOV (需 >3秒)</span>
|
|
|
|
|
|
<button class="select-file-btn" @click="triggerFileSelect">选择文件</button>
|
|
|
|
|
|
</div>
|
2026-02-04 01:46:55 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
<div v-else class="upload-preview">
|
2026-02-25 14:56:39 +08:00
|
|
|
|
<video
|
2026-02-26 18:52:09 +08:00
|
|
|
|
:src="store.videoPreviewUrl"
|
2026-02-25 14:56:39 +08:00
|
|
|
|
controls
|
|
|
|
|
|
playsinline
|
|
|
|
|
|
preload="metadata"
|
|
|
|
|
|
class="preview-video-player"
|
|
|
|
|
|
></video>
|
2026-02-26 18:52:09 +08:00
|
|
|
|
<p class="upload-filename">{{ store.videoFile?.name }}</p>
|
|
|
|
|
|
<button class="change-video-btn" @click="store.reset">更换</button>
|
2025-12-28 00:19:17 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2026-02-12 23:35:39 +08:00
|
|
|
|
</div>
|
2025-12-02 01:55:57 +08:00
|
|
|
|
|
2026-02-26 18:52:09 +08:00
|
|
|
|
<!-- 进度显示 -->
|
|
|
|
|
|
<div v-if="store.isBusy || store.isFailed || store.isDone" class="progress-card">
|
|
|
|
|
|
<div class="progress-header">
|
|
|
|
|
|
<span class="progress-label">{{ store.stepLabel }}</span>
|
|
|
|
|
|
<span class="progress-percent">{{ store.progress }}%</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<a-progress :percent="store.progress" :status="progressStatus" :show-info="false" />
|
|
|
|
|
|
|
|
|
|
|
|
<div v-if="store.isFailed" class="error-actions">
|
|
|
|
|
|
<span class="error-text">{{ store.error }}</span>
|
|
|
|
|
|
<a-button size="small" @click="store.retry">重试</a-button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div v-if="store.isDone" class="success-actions">
|
|
|
|
|
|
<span class="success-text">任务已提交成功</span>
|
|
|
|
|
|
<a-button size="small" @click="store.reset">重新生成</a-button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2026-02-12 23:35:39 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- 操作按钮 -->
|
|
|
|
|
|
<div class="action-section">
|
|
|
|
|
|
<a-button
|
2026-02-26 18:52:09 +08:00
|
|
|
|
v-if="!store.isDone"
|
2026-02-12 23:35:39 +08:00
|
|
|
|
type="primary"
|
|
|
|
|
|
size="large"
|
2026-02-26 18:52:09 +08:00
|
|
|
|
:disabled="!store.canGenerate"
|
|
|
|
|
|
:loading="store.isBusy"
|
2026-02-12 23:35:39 +08:00
|
|
|
|
block
|
2026-02-26 18:52:09 +08:00
|
|
|
|
@click="store.generate"
|
2026-02-12 23:35:39 +08:00
|
|
|
|
class="action-btn"
|
|
|
|
|
|
>
|
2026-02-26 18:52:09 +08:00
|
|
|
|
{{ store.isBusy ? store.stepLabel + '...' : '生成数字人视频' }}
|
2026-02-12 23:35:39 +08:00
|
|
|
|
</a-button>
|
|
|
|
|
|
</div>
|
2026-02-04 01:18:16 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 右侧预览区 -->
|
|
|
|
|
|
<aside class="preview-panel">
|
|
|
|
|
|
<div class="preview-card">
|
|
|
|
|
|
<h3 class="preview-title">合成预览</h3>
|
2025-12-02 01:55:57 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
<div class="preview-screen">
|
|
|
|
|
|
<ResultPanel @videoLoaded="handleVideoLoaded" />
|
2025-12-02 01:55:57 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
<div class="preview-meta">
|
|
|
|
|
|
<div class="meta-row">
|
|
|
|
|
|
<span class="meta-label">预计消耗积分</span>
|
2026-02-26 20:04:09 +08:00
|
|
|
|
<span class="meta-value">{{ estimatedPoints }} 积分</span>
|
2026-02-12 23:35:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="meta-row">
|
|
|
|
|
|
<span class="meta-label">当前余额</span>
|
2026-02-24 22:11:30 +08:00
|
|
|
|
<span class="meta-value">{{ userStore.remainingPoints.toLocaleString() }} 积分</span>
|
2026-02-12 23:35:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</aside>
|
2025-12-01 22:27:50 +08:00
|
|
|
|
|
|
|
|
|
|
</div>
|
2026-02-12 23:35:39 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- 视频选择器弹窗 -->
|
2026-02-26 18:52:09 +08:00
|
|
|
|
<VideoSelector
|
|
|
|
|
|
v-model:open="store.videoSelectorVisible"
|
|
|
|
|
|
@select="store.selectVideo"
|
|
|
|
|
|
/>
|
2026-01-17 19:54:57 +08:00
|
|
|
|
</FullWidthLayout>
|
2025-12-01 22:27:50 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
|
2025-12-28 13:49:45 +08:00
|
|
|
|
<script setup lang="ts">
|
2026-02-26 18:52:09 +08:00
|
|
|
|
import { ref, computed, onMounted } from 'vue'
|
|
|
|
|
|
import { CloudUploadOutlined, CrownFilled, PictureOutlined } from '@ant-design/icons-vue'
|
2025-12-01 22:27:50 +08:00
|
|
|
|
import { useVoiceCopyStore } from '@/stores/voiceCopy'
|
2026-02-24 22:11:30 +08:00
|
|
|
|
import { useUserStore } from '@/stores/user'
|
2026-02-26 20:04:09 +08:00
|
|
|
|
import { usePointsConfigStore } from '@/stores/pointsConfig'
|
2025-12-28 00:19:17 +08:00
|
|
|
|
import VideoSelector from '@/components/VideoSelector.vue'
|
|
|
|
|
|
import VoiceSelector from '@/components/VoiceSelector.vue'
|
|
|
|
|
|
import ResultPanel from '@/components/ResultPanel.vue'
|
2026-01-17 19:54:57 +08:00
|
|
|
|
import FullWidthLayout from '@/layouts/components/FullWidthLayout.vue'
|
2026-02-26 18:52:09 +08:00
|
|
|
|
import { useDigitalHumanStore } from './stores/useDigitalHumanStore'
|
2025-12-22 00:15:02 +08:00
|
|
|
|
|
2026-02-26 18:52:09 +08:00
|
|
|
|
// ==================== Store ====================
|
|
|
|
|
|
const store = useDigitalHumanStore()
|
2025-12-28 13:49:45 +08:00
|
|
|
|
const voiceStore = useVoiceCopyStore()
|
2026-02-24 22:11:30 +08:00
|
|
|
|
const userStore = useUserStore()
|
2026-02-26 20:04:09 +08:00
|
|
|
|
const pointsConfigStore = usePointsConfigStore()
|
2025-12-28 00:19:17 +08:00
|
|
|
|
|
2026-02-26 18:52:09 +08:00
|
|
|
|
// ==================== 本地状态 ====================
|
|
|
|
|
|
const dragOver = ref(false)
|
|
|
|
|
|
const fileInput = ref<HTMLInputElement | null>(null)
|
2025-12-28 13:49:45 +08:00
|
|
|
|
|
2026-02-26 18:52:09 +08:00
|
|
|
|
// ==================== 计算属性 ====================
|
|
|
|
|
|
const placeholder = computed(() => {
|
|
|
|
|
|
if (store.faceDurationMs > 0) {
|
|
|
|
|
|
const maxChars = Math.floor(store.faceDurationMs / 1000 * 4)
|
|
|
|
|
|
return `请输入文案,建议不超过${maxChars}字以确保与视频匹配`
|
|
|
|
|
|
}
|
|
|
|
|
|
return '请输入你想让角色说话的内容'
|
|
|
|
|
|
})
|
2025-12-01 22:27:50 +08:00
|
|
|
|
|
2026-02-26 18:52:09 +08:00
|
|
|
|
const progressStatus = computed(() => {
|
|
|
|
|
|
if (store.isFailed) return 'exception'
|
|
|
|
|
|
if (store.isDone) return 'success'
|
|
|
|
|
|
return 'active'
|
|
|
|
|
|
})
|
2026-02-12 23:35:39 +08:00
|
|
|
|
|
2026-02-26 20:04:09 +08:00
|
|
|
|
// 预计消耗积分(从配置获取 kling 模型积分)
|
|
|
|
|
|
const estimatedPoints = computed(() => {
|
|
|
|
|
|
const points = pointsConfigStore.getConsumePoints('kling')
|
|
|
|
|
|
return points ?? 150 // 默认 150 积分
|
|
|
|
|
|
})
|
|
|
|
|
|
|
2026-02-26 18:52:09 +08:00
|
|
|
|
// ==================== 方法 ====================
|
|
|
|
|
|
function triggerFileSelect() {
|
2026-02-12 23:35:39 +08:00
|
|
|
|
fileInput.value?.click()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-26 18:52:09 +08:00
|
|
|
|
function handleFileSelect(e: Event) {
|
|
|
|
|
|
const file = (e.target as HTMLInputElement).files?.[0]
|
|
|
|
|
|
if (file) store.handleFileUpload(file)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function handleDrop(e: DragEvent) {
|
|
|
|
|
|
dragOver.value = false
|
|
|
|
|
|
const file = e.dataTransfer?.files[0]
|
|
|
|
|
|
if (file) store.handleFileUpload(file)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function handleVideoLoaded(_url: string) {
|
|
|
|
|
|
// 可用于更新预览
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function formatDuration(seconds: number): string {
|
|
|
|
|
|
if (!seconds) return '--:--'
|
|
|
|
|
|
const mins = Math.floor(seconds / 60)
|
|
|
|
|
|
const secs = Math.floor(seconds % 60)
|
|
|
|
|
|
return `${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function getVideoPreviewUrl(video: any): string {
|
|
|
|
|
|
if (video.coverBase64) {
|
|
|
|
|
|
return video.coverBase64.startsWith('data:')
|
|
|
|
|
|
? video.coverBase64
|
|
|
|
|
|
: `data:image/jpeg;base64,${video.coverBase64}`
|
|
|
|
|
|
}
|
|
|
|
|
|
return video.previewUrl || video.coverUrl || ''
|
2026-02-12 23:35:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-26 18:52:09 +08:00
|
|
|
|
// ==================== 生命周期 ====================
|
2025-12-01 22:27:50 +08:00
|
|
|
|
onMounted(async () => {
|
2026-02-25 18:21:25 +08:00
|
|
|
|
await Promise.all([
|
|
|
|
|
|
voiceStore.refresh(),
|
2026-02-26 20:04:09 +08:00
|
|
|
|
userStore.fetchUserProfile(),
|
|
|
|
|
|
pointsConfigStore.loadConfig()
|
2026-02-25 18:21:25 +08:00
|
|
|
|
])
|
2025-12-01 22:27:50 +08:00
|
|
|
|
})
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
2025-12-28 13:49:45 +08:00
|
|
|
|
<style scoped lang="less">
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.digital-human-page {
|
2026-01-18 00:34:04 +08:00
|
|
|
|
min-height: 100vh;
|
2026-02-12 23:35:39 +08:00
|
|
|
|
background: #F8FAFC;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
|
gap: 24px;
|
|
|
|
|
|
padding: 24px;
|
2026-01-18 00:34:04 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.config-panel {
|
|
|
|
|
|
flex: 1;
|
2026-02-26 18:52:09 +08:00
|
|
|
|
padding: 0 20px;
|
2026-02-12 23:35:39 +08:00
|
|
|
|
max-width: 100%;
|
2025-12-28 13:49:45 +08:00
|
|
|
|
}
|
2026-01-18 00:34:04 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.preview-panel {
|
|
|
|
|
|
width: 400px;
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
border-left: 1px solid #E2E8F0;
|
|
|
|
|
|
padding: 20px;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
flex-shrink: 0;
|
2026-01-18 00:34:04 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
@media (max-width: 1200px) {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
border-left: none;
|
|
|
|
|
|
border-top: 1px solid #E2E8F0;
|
|
|
|
|
|
order: -1;
|
2026-01-18 00:34:04 +08:00
|
|
|
|
}
|
2025-12-28 13:49:45 +08:00
|
|
|
|
}
|
2025-12-01 22:27:50 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.config-card {
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
border: 1px solid #E2E8F0;
|
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
|
padding: 20px;
|
|
|
|
|
|
margin-bottom: 16px;
|
|
|
|
|
|
overflow: hidden;
|
2025-12-28 13:49:45 +08:00
|
|
|
|
}
|
2026-01-18 00:34:04 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.step-indicator {
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
left: 0;
|
|
|
|
|
|
top: 0;
|
|
|
|
|
|
width: 32px;
|
|
|
|
|
|
height: 32px;
|
|
|
|
|
|
background: linear-gradient(135deg, #3B82F6 0%, #2563EB 100%);
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
border-radius: 8px 0 12px 0;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
2026-01-18 00:34:04 +08:00
|
|
|
|
font-size: 14px;
|
2026-02-12 23:35:39 +08:00
|
|
|
|
font-weight: 700;
|
|
|
|
|
|
box-shadow: 0 2px 8px rgba(59, 130, 246, 0.3);
|
2026-01-18 00:34:04 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.card-title {
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
color: #1E293B;
|
|
|
|
|
|
margin: 0 0 12px 12px;
|
|
|
|
|
|
padding-left: 44px;
|
2026-01-18 00:34:04 +08:00
|
|
|
|
}
|
2025-12-01 22:27:50 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.text-input {
|
|
|
|
|
|
width: 100%;
|
2026-01-18 00:34:04 +08:00
|
|
|
|
|
|
|
|
|
|
:deep(.ant-input) {
|
|
|
|
|
|
border: none;
|
2026-02-12 23:35:39 +08:00
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
padding: 16px 12px;
|
|
|
|
|
|
background: #F8FAFC;
|
|
|
|
|
|
|
|
|
|
|
|
&:focus {
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
box-shadow: 0 0 0 1px #E2E8F0;
|
|
|
|
|
|
}
|
2026-01-18 00:34:04 +08:00
|
|
|
|
}
|
2025-12-01 22:27:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.input-meta {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
color: #94A3B8;
|
|
|
|
|
|
margin-top: 12px;
|
2026-01-18 00:34:04 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.voice-settings {
|
|
|
|
|
|
display: grid;
|
|
|
|
|
|
grid-template-columns: 1fr 1fr;
|
|
|
|
|
|
gap: 12px;
|
|
|
|
|
|
|
|
|
|
|
|
@media (max-width: 640px) {
|
|
|
|
|
|
grid-template-columns: 1fr;
|
|
|
|
|
|
}
|
2025-12-01 22:27:50 +08:00
|
|
|
|
}
|
2026-01-18 00:34:04 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.setting-group {
|
2025-12-01 22:27:50 +08:00
|
|
|
|
display: flex;
|
2026-02-12 23:35:39 +08:00
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 8px;
|
2025-12-01 22:27:50 +08:00
|
|
|
|
}
|
2026-01-18 00:34:04 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.setting-label {
|
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
color: #64748B;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.model-options {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
background: #F1F5F9;
|
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
|
padding: 2px;
|
|
|
|
|
|
gap: 2px;
|
2025-12-01 22:27:50 +08:00
|
|
|
|
}
|
2026-01-18 00:34:04 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.model-btn {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
padding: 8px 10px;
|
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
color: #64748B;
|
|
|
|
|
|
border: none;
|
|
|
|
|
|
background: transparent;
|
2025-12-01 22:27:50 +08:00
|
|
|
|
cursor: pointer;
|
2026-02-12 23:35:39 +08:00
|
|
|
|
transition: all 0.2s ease;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
gap: 4px;
|
|
|
|
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
|
|
background: rgba(255, 255, 255, 0.5);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
&--active {
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
color: #22C55E;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.pro-icon {
|
2025-12-01 22:27:50 +08:00
|
|
|
|
font-size: 12px;
|
2026-02-12 23:35:39 +08:00
|
|
|
|
color: #EAB308;
|
2025-12-01 22:27:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.video-options {
|
2025-12-28 00:19:17 +08:00
|
|
|
|
display: grid;
|
|
|
|
|
|
grid-template-columns: 1fr 1fr;
|
2026-01-18 00:34:04 +08:00
|
|
|
|
gap: 12px;
|
2025-12-28 00:19:17 +08:00
|
|
|
|
margin-bottom: 16px;
|
2026-02-12 23:35:39 +08:00
|
|
|
|
|
|
|
|
|
|
@media (max-width: 480px) {
|
|
|
|
|
|
grid-template-columns: 1fr;
|
|
|
|
|
|
}
|
2025-12-28 00:19:17 +08:00
|
|
|
|
}
|
2026-01-18 00:34:04 +08:00
|
|
|
|
|
2025-12-28 00:19:17 +08:00
|
|
|
|
.video-option-card {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
2026-01-18 00:34:04 +08:00
|
|
|
|
gap: 12px;
|
2026-02-12 23:35:39 +08:00
|
|
|
|
padding: 14px 16px;
|
|
|
|
|
|
border: 2px dashed #E2E8F0;
|
|
|
|
|
|
border-radius: 10px;
|
|
|
|
|
|
background: #F8FAFC;
|
2025-12-28 00:19:17 +08:00
|
|
|
|
cursor: pointer;
|
2026-02-12 23:35:39 +08:00
|
|
|
|
transition: all 0.2s ease;
|
2026-01-18 00:34:04 +08:00
|
|
|
|
|
|
|
|
|
|
&:hover {
|
2026-02-13 00:21:21 +08:00
|
|
|
|
border-color: #3B82F6;
|
|
|
|
|
|
background: #EFF6FF;
|
2026-01-18 00:34:04 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
&--selected {
|
|
|
|
|
|
border-style: solid;
|
2026-02-13 00:21:21 +08:00
|
|
|
|
border-color: #2563EB;
|
|
|
|
|
|
background: #EFF6FF;
|
2026-01-18 00:34:04 +08:00
|
|
|
|
}
|
2025-12-28 00:19:17 +08:00
|
|
|
|
}
|
2026-01-18 00:34:04 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.video-option-icon {
|
|
|
|
|
|
font-size: 20px;
|
|
|
|
|
|
color: #94A3B8;
|
2025-12-28 00:19:17 +08:00
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
2026-02-12 23:35:39 +08:00
|
|
|
|
width: 36px;
|
|
|
|
|
|
height: 36px;
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
border-radius: 6px;
|
2026-01-18 00:34:04 +08:00
|
|
|
|
flex-shrink: 0;
|
2025-12-28 00:19:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.video-option-content {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
|
2026-02-26 18:52:09 +08:00
|
|
|
|
h4 {
|
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
color: #1E293B;
|
|
|
|
|
|
margin: 0 0 4px 0;
|
|
|
|
|
|
}
|
2026-02-12 23:35:39 +08:00
|
|
|
|
|
2026-02-26 18:52:09 +08:00
|
|
|
|
p {
|
|
|
|
|
|
font-size: 11px;
|
|
|
|
|
|
color: #94A3B8;
|
|
|
|
|
|
margin: 0;
|
|
|
|
|
|
}
|
2026-02-12 23:35:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.selected-video {
|
2025-12-28 00:19:17 +08:00
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
2026-02-12 23:35:39 +08:00
|
|
|
|
gap: 10px;
|
|
|
|
|
|
padding: 10px;
|
|
|
|
|
|
background: #F1F5F9;
|
2025-12-28 00:19:17 +08:00
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
}
|
2026-02-12 23:35:39 +08:00
|
|
|
|
|
|
|
|
|
|
.video-preview-thumb {
|
|
|
|
|
|
width: 70px;
|
|
|
|
|
|
height: 40px;
|
2025-12-28 00:19:17 +08:00
|
|
|
|
border-radius: 6px;
|
|
|
|
|
|
overflow: hidden;
|
2026-02-12 23:35:39 +08:00
|
|
|
|
background: #1E293B;
|
2025-12-28 00:19:17 +08:00
|
|
|
|
flex-shrink: 0;
|
2026-02-12 23:35:39 +08:00
|
|
|
|
|
|
|
|
|
|
img {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
object-fit: cover;
|
|
|
|
|
|
}
|
2025-12-28 00:19:17 +08:00
|
|
|
|
}
|
2026-02-12 23:35:39 +08:00
|
|
|
|
|
|
|
|
|
|
.video-preview-info {
|
2025-12-28 00:19:17 +08:00
|
|
|
|
flex: 1;
|
|
|
|
|
|
min-width: 0;
|
|
|
|
|
|
}
|
2026-02-12 23:35:39 +08:00
|
|
|
|
|
|
|
|
|
|
.video-name {
|
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
color: #1E293B;
|
2026-02-25 00:38:19 +08:00
|
|
|
|
width: 160px;
|
2025-12-28 00:19:17 +08:00
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
|
}
|
2026-02-12 23:35:39 +08:00
|
|
|
|
|
2025-12-28 00:19:17 +08:00
|
|
|
|
.video-meta {
|
2026-02-12 23:35:39 +08:00
|
|
|
|
font-size: 11px;
|
|
|
|
|
|
color: #94A3B8;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.change-video-btn {
|
|
|
|
|
|
padding: 4px 10px;
|
|
|
|
|
|
font-size: 11px;
|
|
|
|
|
|
color: #64748B;
|
|
|
|
|
|
border: none;
|
|
|
|
|
|
background: transparent;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
text-decoration: underline;
|
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
|
|
|
|
|
|
&:hover {
|
2026-02-13 00:21:21 +08:00
|
|
|
|
color: #3B82F6;
|
2026-02-12 23:35:39 +08:00
|
|
|
|
}
|
2025-12-28 00:19:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-28 13:49:45 +08:00
|
|
|
|
.upload-zone {
|
2026-02-12 23:35:39 +08:00
|
|
|
|
min-height: 160px;
|
2025-12-28 13:49:45 +08:00
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
2026-02-12 23:35:39 +08:00
|
|
|
|
border: 2px dashed #E2E8F0;
|
|
|
|
|
|
border-radius: 10px;
|
|
|
|
|
|
background: #F8FAFC;
|
|
|
|
|
|
transition: all 0.2s ease;
|
|
|
|
|
|
|
|
|
|
|
|
&--dragover {
|
2026-02-13 00:21:21 +08:00
|
|
|
|
border-color: #3B82F6;
|
|
|
|
|
|
background: #EFF6FF;
|
2026-01-18 00:34:04 +08:00
|
|
|
|
}
|
2025-12-28 13:49:45 +08:00
|
|
|
|
}
|
2026-01-18 00:34:04 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.file-input {
|
|
|
|
|
|
display: none;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-28 13:49:45 +08:00
|
|
|
|
.upload-placeholder {
|
2026-01-18 00:34:04 +08:00
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: center;
|
2026-02-12 23:35:39 +08:00
|
|
|
|
gap: 8px;
|
|
|
|
|
|
}
|
2026-01-18 00:34:04 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.upload-icon {
|
|
|
|
|
|
font-size: 28px;
|
|
|
|
|
|
color: #94A3B8;
|
|
|
|
|
|
}
|
2026-01-18 00:34:04 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.upload-text {
|
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
color: #1E293B;
|
|
|
|
|
|
}
|
2026-01-18 00:34:04 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.upload-hint {
|
|
|
|
|
|
font-size: 11px;
|
|
|
|
|
|
color: #94A3B8;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.select-file-btn {
|
|
|
|
|
|
margin-top: 12px;
|
|
|
|
|
|
padding: 6px 16px;
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
font-weight: 500;
|
2026-02-13 00:21:21 +08:00
|
|
|
|
color: #3B82F6;
|
2026-02-26 18:52:09 +08:00
|
|
|
|
border: 1px solid #3B82F6;
|
2026-02-12 23:35:39 +08:00
|
|
|
|
background: transparent;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
|
transition: all 0.2s ease;
|
|
|
|
|
|
|
|
|
|
|
|
&:hover {
|
2026-02-13 00:21:21 +08:00
|
|
|
|
background: rgba(59, 130, 246, 0.1);
|
2026-01-18 00:34:04 +08:00
|
|
|
|
}
|
2025-12-28 13:49:45 +08:00
|
|
|
|
}
|
2026-01-18 00:34:04 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.upload-preview {
|
2026-01-18 00:34:04 +08:00
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: center;
|
2026-02-12 23:35:39 +08:00
|
|
|
|
gap: 10px;
|
|
|
|
|
|
padding: 12px;
|
2025-12-28 13:49:45 +08:00
|
|
|
|
}
|
2026-01-18 00:34:04 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.preview-video-player {
|
2025-12-28 13:49:45 +08:00
|
|
|
|
width: 100%;
|
2026-02-12 23:35:39 +08:00
|
|
|
|
max-height: 140px;
|
2025-12-28 13:49:45 +08:00
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.upload-filename {
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
color: #64748B;
|
|
|
|
|
|
max-width: 100%;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
|
padding: 6px 10px;
|
|
|
|
|
|
background: #F1F5F9;
|
|
|
|
|
|
border-radius: 6px;
|
2025-12-28 00:19:17 +08:00
|
|
|
|
}
|
2026-01-18 00:34:04 +08:00
|
|
|
|
|
2026-02-26 18:52:09 +08:00
|
|
|
|
// 进度卡片
|
|
|
|
|
|
.progress-card {
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
border: 1px solid #E2E8F0;
|
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
|
padding: 16px;
|
|
|
|
|
|
margin-bottom: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.progress-header {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.progress-label {
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
color: #1E293B;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.progress-percent {
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
color: #64748B;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.error-actions {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
margin-top: 12px;
|
|
|
|
|
|
padding-top: 12px;
|
|
|
|
|
|
border-top: 1px solid #FEE2E2;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.error-text {
|
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
color: #DC2626;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.success-actions {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
margin-top: 12px;
|
|
|
|
|
|
padding-top: 12px;
|
|
|
|
|
|
border-top: 1px solid #86EFAC;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.success-text {
|
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
color: #166534;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 操作按钮
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.action-section {
|
|
|
|
|
|
margin-top: 20px;
|
|
|
|
|
|
padding-top: 16px;
|
|
|
|
|
|
border-top: 1px solid #E2E8F0;
|
2025-12-28 00:19:17 +08:00
|
|
|
|
}
|
2026-01-18 00:34:04 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.action-btn {
|
|
|
|
|
|
height: 44px;
|
|
|
|
|
|
font-size: 15px;
|
2025-12-28 00:19:17 +08:00
|
|
|
|
font-weight: 600;
|
2026-02-12 23:35:39 +08:00
|
|
|
|
border-radius: 8px;
|
2026-01-18 00:34:04 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
&.ant-btn-primary {
|
2026-02-13 00:21:21 +08:00
|
|
|
|
background: linear-gradient(135deg, #3B82F6 0%, #2563EB 100%);
|
2026-02-12 23:35:39 +08:00
|
|
|
|
border: none;
|
|
|
|
|
|
|
|
|
|
|
|
&:hover:not(:disabled) {
|
2026-02-13 00:21:21 +08:00
|
|
|
|
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.35);
|
2026-02-12 23:35:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
&:disabled {
|
|
|
|
|
|
background: #D1D5DB;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-12-28 00:19:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
// 预览面板
|
|
|
|
|
|
.preview-card {
|
|
|
|
|
|
position: sticky;
|
|
|
|
|
|
top: 24px;
|
2025-12-28 00:19:17 +08:00
|
|
|
|
}
|
2026-01-18 00:34:04 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.preview-title {
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
color: #1E293B;
|
|
|
|
|
|
margin: 0 0 16px 0;
|
2025-12-28 00:19:17 +08:00
|
|
|
|
}
|
2026-01-18 00:34:04 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.preview-screen {
|
|
|
|
|
|
aspect-ratio: 9/16;
|
|
|
|
|
|
background: #1E293B;
|
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
position: relative;
|
2026-01-18 00:34:04 +08:00
|
|
|
|
display: flex;
|
2026-02-12 23:35:39 +08:00
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
2025-12-28 00:19:17 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
&::after {
|
|
|
|
|
|
content: '预览画面不可用';
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
inset: 0;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
background: rgba(0, 0, 0, 0.6);
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
}
|
2026-01-18 00:34:04 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
:deep(.result-panel) {
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
}
|
2026-01-18 00:34:04 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.preview-meta {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 10px;
|
|
|
|
|
|
padding: 16px;
|
|
|
|
|
|
background: #F8FAFC;
|
2025-12-28 13:49:45 +08:00
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
}
|
2026-01-18 00:34:04 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.meta-row {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
font-size: 12px;
|
2026-01-18 00:34:04 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.meta-label {
|
|
|
|
|
|
color: #64748B;
|
2026-01-18 00:34:04 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-26 18:52:09 +08:00
|
|
|
|
.meta-value {
|
2026-01-18 00:34:04 +08:00
|
|
|
|
font-weight: 600;
|
2026-02-12 23:35:39 +08:00
|
|
|
|
color: #1E293B;
|
2025-12-28 13:49:45 +08:00
|
|
|
|
}
|
2026-01-18 00:34:04 +08:00
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
// 响应式
|
2025-12-28 13:49:45 +08:00
|
|
|
|
@media (max-width: 1024px) {
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.digital-human-page {
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.config-panel {
|
|
|
|
|
|
max-width: 100%;
|
2026-01-18 00:34:04 +08:00
|
|
|
|
padding: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.preview-panel {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
border-left: none;
|
|
|
|
|
|
border-top: 1px solid #E2E8F0;
|
|
|
|
|
|
order: -1;
|
|
|
|
|
|
padding: 16px;
|
2026-01-18 00:34:04 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.preview-card {
|
|
|
|
|
|
position: static;
|
2026-01-18 00:34:04 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-12 23:35:39 +08:00
|
|
|
|
.preview-screen {
|
|
|
|
|
|
min-height: 200px;
|
2025-12-28 13:49:45 +08:00
|
|
|
|
}
|
2025-12-28 00:19:17 +08:00
|
|
|
|
}
|
2025-12-01 22:27:50 +08:00
|
|
|
|
</style>
|