6433 lines
308 KiB
HTML
Executable File
6433 lines
308 KiB
HTML
Executable File
<!doctype html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="utf-8"/>
|
||
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
||
<title>小虾智剪 - AI智能视频创作平台</title>
|
||
<style>
|
||
:root{
|
||
--primary:#4f46e5;
|
||
--primary-dark:#4338ca;
|
||
--primary-soft:#eef2ff;
|
||
--primary-light:#818cf8;
|
||
--slate:#0f172a;
|
||
--muted:#64748b;
|
||
--line:#e2e8f0;
|
||
--bg:#f8fafc;
|
||
--green:#10b981;
|
||
--amber:#f59e0b;
|
||
--red:#ef4444;
|
||
--shadow-sm:0 10px 30px rgba(15,23,42,.06);
|
||
--shadow-md:0 24px 70px rgba(15,23,42,.09);
|
||
--radius-sm:14px;
|
||
--radius-md:18px;
|
||
--radius-lg:24px;
|
||
--radius-xl:28px;
|
||
}
|
||
*{box-sizing:border-box;margin:0;padding:0}
|
||
body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Microsoft YaHei",Arial,sans-serif;color:var(--slate);background:var(--bg);line-height:1.6;min-height:100vh}
|
||
|
||
/* 背景装饰 */
|
||
.bg{position:fixed;inset:0;z-index:-2;background:radial-gradient(circle at 18% 20%,rgba(79,70,229,.11),transparent 30%),radial-gradient(circle at 86% 14%,rgba(16,185,129,.08),transparent 28%),radial-gradient(circle at 48% 80%,rgba(99,102,241,.08),transparent 34%),#f8fafc}
|
||
.dots{position:fixed;inset:0;z-index:-1;background-image:radial-gradient(circle,rgba(79,70,229,.1) 1px,transparent 1px);background-size:38px 38px;opacity:.32}
|
||
|
||
/* 通用组件 */
|
||
.tag{display:inline-flex;padding:6px 12px;border-radius:999px;border:1px solid #c7d2fe;background:#eef2ff;color:#4338ca;font-weight:700;font-size:13px}
|
||
.card{background:rgba(255,255,255,.94);border:1px solid rgba(226,232,240,.95);border-radius:var(--radius-xl);box-shadow:var(--shadow-md);padding:28px}
|
||
.btn{border:0;border-radius:var(--radius-sm);padding:11px 18px;font-weight:700;cursor:pointer;transition:.18s ease;display:inline-flex;align-items:center;justify-content:center;gap:7px;font-size:14px}
|
||
.btn.primary{background:linear-gradient(135deg,#6366f1,#4f46e5);color:#fff;box-shadow:0 14px 26px rgba(79,70,229,.22)}
|
||
.btn.primary:hover{transform:translateY(-2px);box-shadow:0 18px 34px rgba(79,70,229,.28)}
|
||
.btn.ghost{background:#fff;border:1px solid var(--line);color:#475569}
|
||
.btn.ghost:hover{border-color:#c7d2fe;color:#4338ca;background:#f8faff}
|
||
.btn.sm{padding:8px 14px;font-size:13px}
|
||
.btn:active{transform:translateY(0)}
|
||
.pill{font-size:11px;padding:4px 8px;border-radius:999px;font-weight:700;display:inline-block}
|
||
.pill.ok{background:#dcfce7;color:#166534}
|
||
.pill.warn{background:#ffedd5;color:#c2410c}
|
||
.pill.bad{background:#ffe4e6;color:#be123c}
|
||
.pill.info{background:#dbeafe;color:#1d4ed8}
|
||
.pill.muted{background:#f1f5f9;color:#64748b}
|
||
.icon{width:44px;height:44px;border-radius:16px;display:grid;place-items:center;font-size:20px}
|
||
|
||
/* 页面视图 */
|
||
.view{display:none}
|
||
.view.active{display:block}
|
||
.wrap{max-width:1440px;margin:0 auto;padding:0 24px 60px}
|
||
.page-head{display:flex;justify-content:space-between;align-items:flex-start;gap:18px;margin-bottom:22px;padding-top:32px}
|
||
.page-head h2{font-size:26px;margin:0 0 6px;letter-spacing:-.02em}
|
||
.page-head p{margin:0;color:var(--muted);line-height:1.7}
|
||
.section{padding:24px 0;border-top:1px solid #edf2f7}
|
||
.section:first-child{border-top:0;padding-top:0}
|
||
.section-title{display:flex;justify-content:space-between;align-items:center;margin-bottom:14px}
|
||
.section-title h3{margin:0;font-size:18px;font-weight:700}
|
||
.hint{border:1px solid var(--line);background:#f8fafc;color:var(--muted);border-radius:999px;padding:6px 10px;font-size:12px}
|
||
|
||
/* 顶部导航(公开页面) */
|
||
.nav{height:68px;position:sticky;top:0;z-index:50;background:rgba(255,255,255,.86);backdrop-filter:blur(18px);border-bottom:1px solid rgba(226,232,240,.92);box-shadow:0 8px 28px rgba(15,23,42,.04)}
|
||
.nav-in{max-width:1440px;margin:0 auto;height:100%;padding:0 24px;display:flex;align-items:center;justify-content:space-between}
|
||
.brand{display:flex;gap:10px;align-items:center;font-size:20px;font-weight:900}
|
||
.logo{width:38px;height:38px;border-radius:14px;background:linear-gradient(135deg,#818cf8,#4f46e5);display:grid;place-items:center;color:#fff;box-shadow:0 12px 26px rgba(79,70,229,.24);font-size:20px}
|
||
.nav-links{display:flex;gap:22px;color:var(--muted);font-weight:600}
|
||
.nav-links span{cursor:pointer;padding:8px 0;position:relative}
|
||
.nav-links .active{color:var(--primary)}
|
||
.nav-links .active::after{content:"";position:absolute;left:0;right:0;bottom:-18px;height:3px;border-radius:999px;background:var(--primary)}
|
||
.avatar-btn{width:36px;height:36px;border-radius:50%;background:var(--primary-soft);color:var(--primary-dark);display:grid;place-items:center;font-weight:800;cursor:pointer;position:relative}
|
||
.avatar-menu{position:absolute;top:48px;right:0;background:#fff;border:1px solid var(--line);border-radius:var(--radius-md);box-shadow:var(--shadow-md);padding:8px;min-width:180px;display:none;z-index:100}
|
||
.avatar-btn:hover .avatar-menu{display:block}
|
||
.avatar-menu span{display:block;padding:10px 12px;border-radius:10px;cursor:pointer;font-size:14px}
|
||
.avatar-menu span:hover{background:var(--primary-soft);color:var(--primary-dark)}
|
||
|
||
/* 用户下拉菜单 */
|
||
.user-dropdown{display:flex;align-items:center;gap:10px;position:relative;cursor:pointer}
|
||
.user-dropdown .name{font-weight:600;font-size:14px}
|
||
.user-dropdown .role{font-size:12px;color:var(--muted)}
|
||
|
||
/* Hero区域 */
|
||
.hero{display:grid;grid-template-columns:1fr 420px;gap:48px;align-items:center;padding:60px 0 50px}
|
||
.hero h1{font-size:44px;line-height:1.1;margin:16px 0 14px;letter-spacing:-.04em}
|
||
.hero p{font-size:17px;line-height:1.8;color:var(--muted);margin:0 0 22px}
|
||
.hero-actions{display:flex;gap:12px;margin-top:8px}
|
||
.hero-actions .btn{padding:14px 24px;font-size:15px}
|
||
.hero-visual{border-radius:28px;background:#fff;border:1px solid var(--line);box-shadow:0 30px 90px rgba(15,23,42,.15);padding:18px;position:relative;overflow:hidden}
|
||
.hero-video{height:260px;border-radius:22px;background:linear-gradient(135deg,#111827,#312e81);position:relative;overflow:hidden;display:grid;place-items:center;color:#fff}
|
||
.hero-video::before{content:"";position:absolute;inset:0;background:radial-gradient(circle at 72% 28%,rgba(255,255,255,.22),transparent 24%),linear-gradient(0deg,rgba(0,0,0,.42),transparent)}
|
||
.play-btn{position:relative;z-index:1;width:72px;height:72px;border-radius:50%;display:grid;place-items:center;background:rgba(255,255,255,.18);border:1px solid rgba(255,255,255,.25);backdrop-filter:blur(8px);font-size:28px}
|
||
.hero-info{margin-top:14px;display:flex;justify-content:space-between;align-items:center}
|
||
.hero-badge{display:flex;gap:10px}
|
||
.demo-badge{background:linear-gradient(135deg,#fef3c7,#fde68a);color:#92400e;padding:5px 10px;border-radius:8px;font-size:12px;font-weight:600}
|
||
|
||
/* 功能卡片 */
|
||
.feature-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin:30px 0}
|
||
.feature{background:#fff;border:1px solid var(--line);border-radius:var(--radius-lg);padding:22px;transition:.18s ease}
|
||
.feature:hover{transform:translateY(-3px);box-shadow:var(--shadow-sm)}
|
||
.feature .icon{margin-bottom:14px}
|
||
.feature h3{margin:0 0 8px;font-size:16px}
|
||
.feature p{margin:0;color:var(--muted);line-height:1.6;font-size:13px}
|
||
|
||
/* 工作流程 */
|
||
.workflow{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin:30px 0}
|
||
.workflow-step{background:#fff;border:1px solid var(--line);border-radius:var(--radius-md);padding:18px;text-align:center;position:relative}
|
||
.workflow-step:not(:last-child)::after{content:"→";position:absolute;right:-18px;top:50%;transform:translateY(-50%);color:var(--primary-light);font-size:20px;font-weight:700}
|
||
.workflow-step .step-num{width:32px;height:32px;border-radius:10px;background:var(--primary);color:#fff;display:inline-grid;place-items:center;font-weight:800;margin-bottom:10px}
|
||
.workflow-step h4{margin:0 0 6px;font-size:15px}
|
||
.workflow-step p{margin:0;color:var(--muted);font-size:12px}
|
||
|
||
/* 定价卡片 */
|
||
.pricing-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:18px;margin:30px 0}
|
||
.pricing-card{background:#fff;border:2px solid var(--line);border-radius:var(--radius-lg);padding:26px;text-align:center;transition:.18s ease;position:relative}
|
||
.pricing-card:hover{transform:translateY(-3px);box-shadow:var(--shadow-sm)}
|
||
.pricing-card.popular{border-color:var(--primary);background:linear-gradient(180deg,#fff,#f5f7ff)}
|
||
.pricing-card .icon{margin:0 auto 14px}
|
||
.pricing-card h3{margin:0 0 4px;font-size:18px}
|
||
.pricing-card .desc{color:var(--muted);font-size:13px;margin:0 0 16px}
|
||
.pricing-card .price{font-size:32px;font-weight:800;color:var(--slate)}
|
||
.pricing-card .price span{font-size:14px;font-weight:400;color:var(--muted)}
|
||
.pricing-card .features{text-align:left;margin:18px 0;color:#475569;font-size:13px;line-height:2}
|
||
.pricing-card .features div{padding:2px 0}
|
||
.pricing-card .btn{width:100%;margin-top:16px}
|
||
.pricing-card .popular-tag{position:absolute;top:-12px;left:50%;transform:translateX(-50%);background:var(--primary);color:#fff;padding:4px 14px;border-radius:999px;font-size:12px;font-weight:700}
|
||
|
||
/* KPI卡片 */
|
||
.kpi-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:16px}
|
||
.kpi{background:linear-gradient(180deg,#fff,#f8fafc);border:1px solid var(--line);border-radius:var(--radius-lg);padding:20px;transition:.18s ease}
|
||
.kpi:hover{transform:translateY(-2px);box-shadow:var(--shadow-sm)}
|
||
.kpi .value{font-size:30px;font-weight:800;color:var(--slate)}
|
||
.kpi .label{color:var(--muted);font-size:13px;margin-top:4px}
|
||
.kpi .trend{font-size:12px;margin-top:8px}
|
||
.kpi .trend.up{color:var(--green)}
|
||
.kpi .trend.down{color:var(--red)}
|
||
|
||
/* 侧边栏布局 */
|
||
.app-layout{display:grid;grid-template-columns:240px 1fr;gap:24px;min-height:calc(100vh - 68px)}
|
||
.sidebar{background:rgba(255,255,255,.88);backdrop-filter:blur(18px);border-right:1px solid rgba(226,232,240,.9);padding:24px 16px;position:sticky;top:68px;height:calc(100vh - 68px);overflow-y:auto}
|
||
.sidebar-logo{display:flex;gap:10px;align-items:center;font-size:18px;font-weight:800;margin-bottom:28px;padding:0 8px}
|
||
.sidebar-nav{display:flex;flex-direction:column;gap:4px}
|
||
.sidebar-item{display:flex;align-items:center;gap:12px;padding:12px 14px;border-radius:var(--radius-sm);color:var(--muted);cursor:pointer;font-weight:600;font-size:14px;transition:.15s ease}
|
||
.sidebar-item:hover{background:var(--primary-soft);color:var(--primary)}
|
||
.sidebar-item.active{background:var(--primary-soft);color:var(--primary);font-weight:700}
|
||
.sidebar-item .icon{width:36px;height:36px;border-radius:10px;display:grid;place-items:center;font-size:18px;background:#f1f5f9}
|
||
.sidebar-item.active .icon{background:var(--primary);color:#fff}
|
||
.sidebar-divider{height:1px;background:var(--line);margin:16px 0}
|
||
.sidebar-bottom{margin-top:auto;padding-top:20px;border-top:1px solid var(--line)}
|
||
|
||
/* 主内容区 */
|
||
.main-content{padding:0}
|
||
.main-content .page-head{padding-top:24px}
|
||
|
||
/* 标题库 */
|
||
.titles-layout{display:grid;grid-template-columns:220px 1fr;gap:20px}
|
||
.category-list{display:flex;flex-direction:column;gap:8px}
|
||
.category-item{border:1px solid var(--line);background:#fff;border-radius:var(--radius-sm);padding:14px;cursor:pointer;transition:.15s ease}
|
||
.category-item:hover{transform:translateX(4px)}
|
||
.category-item.active{border-color:var(--primary);background:var(--primary-soft)}
|
||
.category-item h4{margin:0 0 4px;font-size:14px}
|
||
.category-item span{font-size:12px;color:var(--muted)}
|
||
.titles-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
|
||
.title-card{background:#fff;border:1px solid var(--line);border-radius:var(--radius-md);padding:16px;cursor:pointer;transition:.18s ease}
|
||
.title-card:hover{transform:translateY(-2px);box-shadow:var(--shadow-sm)}
|
||
.title-card .content{font-size:14px;font-weight:600;margin-bottom:10px;line-height:1.5}
|
||
.title-card .meta{display:flex;justify-content:space-between;align-items:center}
|
||
.title-card .stats{font-size:12px;color:var(--muted)}
|
||
.favorite{color:var(--amber);font-size:16px;cursor:pointer}
|
||
|
||
/* 素材库 */
|
||
.assets-layout{display:grid;grid-template-columns:260px 1fr;gap:20px}
|
||
.asset-library-list{display:flex;flex-direction:column;gap:8px}
|
||
.asset-library-item{border:1px solid var(--line);background:#fff;border-radius:var(--radius-sm);padding:14px;cursor:pointer;transition:.15s ease}
|
||
.asset-library-item.active{border-color:var(--primary);background:var(--primary-soft)}
|
||
.asset-library-item h4{margin:0 0 4px;font-size:14px}
|
||
.asset-library-item span{font-size:12px;color:var(--muted)}
|
||
.asset-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:14px}
|
||
.asset-card{border:1px solid var(--line);background:#fff;border-radius:var(--radius-md);overflow:hidden;cursor:pointer;transition:.18s ease}
|
||
.asset-card:hover{transform:translateY(-3px);box-shadow:var(--shadow-sm)}
|
||
.asset-thumb{aspect-ratio:9/16;border-radius:var(--radius-sm) var(--radius-sm) 0 0;position:relative;overflow:hidden;display:grid;place-items:center;color:#fff}
|
||
.asset-thumb .play{position:absolute;width:40px;height:40px;border-radius:50%;background:rgba(255,255,255,.25);display:grid;place-items:center;backdrop-filter:blur(4px)}
|
||
.asset-info{padding:12px}
|
||
.asset-info h4{margin:0 0 6px;font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||
.asset-info .meta{display:flex;justify-content:space-between;align-items:center;font-size:11px;color:var(--muted)}
|
||
|
||
/* 配音库 */
|
||
.voices-layout{display:grid;grid-template-columns:220px 1fr;gap:20px}
|
||
.voice-list{display:flex;flex-direction:column;gap:10px}
|
||
.voice-card{background:#fff;border:1px solid var(--line);border-radius:var(--radius-md);padding:16px;display:grid;grid-template-columns:50px 1fr auto;gap:14px;align-items:center;transition:.18s ease}
|
||
.voice-card:hover{transform:translateY(-2px);box-shadow:var(--shadow-sm)}
|
||
.voice-icon{width:50px;height:50px;border-radius:50%;display:grid;place-items:center;color:#fff;font-size:22px}
|
||
.voice-info h4{margin:0 0 4px;font-size:14px;font-weight:600}
|
||
.voice-info .meta{font-size:12px;color:var(--muted)}
|
||
.voice-wave{height:24px;width:120px;border-radius:999px;background:repeating-linear-gradient(90deg,#c7d2fe 0 5px,transparent 5px 10px)}
|
||
.voice-actions{display:flex;gap:8px}
|
||
|
||
/* 模板库 */
|
||
.template-toolbar{display:flex;justify-content:space-between;align-items:center;gap:16px;margin-bottom:20px}
|
||
.search-box{display:flex;align-items:center;gap:10px;background:#fff;border:1px solid var(--line);border-radius:var(--radius-sm);padding:0 14px;flex:1;max-width:400px}
|
||
.search-box input{border:0;outline:0;padding:12px 0;font-size:14px;width:100%}
|
||
.template-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:16px}
|
||
.template-card{background:#fff;border:1px solid var(--line);border-radius:var(--radius-md);overflow:hidden;cursor:pointer;transition:.18s ease}
|
||
.template-card:hover{transform:translateY(-3px);box-shadow:var(--shadow-sm)}
|
||
.template-thumb{aspect-ratio:16/9;display:grid;place-items:center;color:#fff;font-size:28px;font-weight:700;position:relative}
|
||
.template-thumb::after{content:"";position:absolute;inset:0;background:linear-gradient(0deg,rgba(0,0,0,.3),transparent)}
|
||
.template-thumb span{position:relative;z-index:1}
|
||
.template-info{padding:14px}
|
||
.template-info h4{margin:0 0 6px;font-size:14px;font-weight:600}
|
||
.template-info .meta{font-size:12px;color:var(--muted);display:flex;justify-content:space-between}
|
||
|
||
/* 一键生成 */
|
||
.generate-layout{display:grid;grid-template-columns:1fr 320px;gap:24px}
|
||
.steps-bar{display:flex;justify-content:center;gap:8px;margin-bottom:28px}
|
||
.step-item{display:flex;align-items:center;gap:8px;padding:10px 16px;border-radius:var(--radius-sm);color:var(--muted);font-weight:600;font-size:14px}
|
||
.step-item.active{background:var(--primary-soft);color:var(--primary)}
|
||
.step-item.done{color:var(--green)}
|
||
.step-item .num{width:26px;height:26px;border-radius:50%;background:#f1f5f9;display:grid;place-items:center;font-size:12px;font-weight:700}
|
||
.step-item.active .num{background:var(--primary);color:#fff}
|
||
.step-item.done .num{background:var(--green);color:#fff}
|
||
.step-item .arrow{color:#cbd5e1}
|
||
|
||
.generate-form{display:flex;flex-direction:column;gap:16px}
|
||
.form-section{background:#fff;border:1px solid var(--line);border-radius:var(--radius-md);padding:20px}
|
||
.form-section h3{margin:0 0 14px;font-size:15px}
|
||
.form-row{display:grid;grid-template-columns:1fr 1fr;gap:14px}
|
||
.form-field label{display:block;font-weight:600;margin-bottom:8px;font-size:13px}
|
||
.form-field input,.form-field select{width:100%;height:44px;border:1px solid var(--line);border-radius:var(--radius-sm);background:#fff;padding:0 14px;font-size:14px;outline:0;transition:.15s ease}
|
||
.form-field input:focus,.form-field select:focus{border-color:var(--primary);box-shadow:0 0 0 3px rgba(79,70,229,.1)}
|
||
|
||
.choice-list{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
|
||
.choice-item{background:#fff;border:2px solid var(--line);border-radius:var(--radius-md);padding:14px;cursor:pointer;transition:.18s ease;text-align:center}
|
||
.choice-item:hover{border-color:#c7d2fe}
|
||
.choice-item.selected{border-color:var(--primary);background:var(--primary-soft)}
|
||
.choice-item .thumb{height:60px;border-radius:var(--radius-sm);display:grid;place-items:center;color:#fff;font-size:24px;margin-bottom:10px}
|
||
.choice-item h4{margin:0 0 4px;font-size:13px;font-weight:600}
|
||
.choice-item p{margin:0;font-size:11px;color:var(--muted)}
|
||
.choice-item .check-icon{width:22px;height:22px;border-radius:50%;background:var(--primary);color:#fff;display:none;place-items:center;font-size:12px;position:absolute;right:-6px;top:-6px}
|
||
.choice-item{position:relative}
|
||
.choice-item.selected .check-icon{display:grid}
|
||
|
||
.generate-preview{background:#fff;border:1px solid var(--line);border-radius:var(--radius-md);padding:20px;position:sticky;top:92px}
|
||
.preview-video{aspect-ratio:9/16;max-height:400px;border-radius:var(--radius-md);background:linear-gradient(135deg,#111827,#312e81);display:grid;place-items:center;color:#fff;font-size:36px;position:relative;overflow:hidden;margin-bottom:16px}
|
||
.preview-video::before{content:"";position:absolute;inset:0;background:radial-gradient(circle at 72% 28%,rgba(255,255,255,.2),transparent 40%)}
|
||
.preview-video .play{position:relative;z-index:1;width:60px;height:60px;border-radius:50%;background:rgba(255,255,255,.2);display:grid;place-items:center;backdrop-filter:blur(8px)}
|
||
.preview-caption{background:rgba(255,255,255,.95);color:var(--slate);border-radius:10px;padding:10px;text-align:center;font-weight:600;font-size:14px;margin-bottom:14px}
|
||
.preview-title{font-weight:600;margin-bottom:10px}
|
||
.preview-timeline{display:flex;flex-direction:column;gap:8px}
|
||
.timeline-item{display:flex;align-items:center;gap:10px;padding:10px;background:#f8fafc;border-radius:10px;font-size:13px}
|
||
.timeline-item .num{width:24px;height:24px;border-radius:8px;background:var(--primary-soft);color:var(--primary);display:grid;place-items:center;font-weight:700;font-size:11px}
|
||
.timeline-item span{color:var(--muted);margin-left:auto;font-size:12px}
|
||
.generate-actions{display:flex;gap:10px;margin-top:16px}
|
||
.generate-actions .btn{flex:1}
|
||
|
||
/* 成片库 */
|
||
.products-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:16px}
|
||
.product-card{background:#fff;border:1px solid var(--line);border-radius:var(--radius-md);overflow:hidden;cursor:pointer;transition:.18s ease;position:relative}
|
||
.product-card:hover{transform:translateY(-3px);box-shadow:var(--shadow-sm)}
|
||
.product-card.selected{border-color:var(--primary);box-shadow:0 0 0 2px var(--primary-soft)}
|
||
.product-thumb{aspect-ratio:9/16;position:relative;overflow:hidden;display:grid;place-items:center;color:#fff}
|
||
.product-thumb .play{position:absolute;width:48px;height:48px;border-radius:50%;background:rgba(255,255,255,.25);display:grid;place-items:center;backdrop-filter:blur(4px)}
|
||
.product-thumb .duration{position:absolute;bottom:8px;right:8px;background:rgba(0,0,0,.6);padding:2px 8px;border-radius:6px;font-size:11px}
|
||
.product-info{padding:14px}
|
||
.product-info h4{margin:0 0 8px;font-size:14px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||
.product-info .status{display:flex;justify-content:space-between;align-items:center}
|
||
.product-select-checkbox{position:absolute;top:12px;left:12px;z-index:10}
|
||
|
||
/* 任务历史 */
|
||
.tabs{display:flex;gap:6px;margin-bottom:20px;border-bottom:1px solid var(--line);padding-bottom:12px}
|
||
.tab{padding:8px 16px;border-radius:var(--radius-sm);cursor:pointer;font-weight:600;font-size:14px;color:var(--muted);transition:.15s ease}
|
||
.tab:hover{background:#f1f5f9}
|
||
.tab.active{background:var(--primary-soft);color:var(--primary)}
|
||
.task-list{display:flex;flex-direction:column;gap:10px}
|
||
.task-item{background:#fff;border:1px solid var(--line);border-radius:var(--radius-md);padding:16px;display:grid;grid-template-columns:1fr auto auto auto;gap:16px;align-items:center;transition:.15s ease}
|
||
.task-item:hover{box-shadow:var(--shadow-sm)}
|
||
.task-info h4{margin:0 0 4px;font-size:14px;font-weight:600}
|
||
.task-info .meta{font-size:12px;color:var(--muted)}
|
||
.task-time{text-align:right;font-size:12px;color:var(--muted)}
|
||
.task-time .date{display:block;margin-bottom:2px}
|
||
|
||
/* 查重检测 */
|
||
.duplication-layout{display:grid;grid-template-columns:1fr 1fr;gap:24px}
|
||
.upload-zone{border:2px dashed var(--line);border-radius:var(--radius-lg);padding:60px;text-align:center;background:linear-gradient(180deg,#fff,#f8fafc);transition:.18s ease;cursor:pointer}
|
||
.upload-zone:hover{border-color:var(--primary-light);background:linear-gradient(180deg,#fff,var(--primary-soft))}
|
||
.upload-zone .icon{width:64px;height:64px;border-radius:20px;background:var(--primary-soft);margin:0 auto 16px;display:grid;place-items:center;font-size:28px;color:var(--primary)}
|
||
.upload-zone h3{margin:0 0 8px;font-size:18px}
|
||
.upload-zone p{margin:0;color:var(--muted);font-size:13px}
|
||
.upload-zone .formats{margin-top:12px;font-size:12px;color:var(--muted)}
|
||
.result-zone{background:#fff;border:1px solid var(--line);border-radius:var(--radius-lg);padding:24px}
|
||
.result-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px}
|
||
.result-score{text-align:center;padding:30px}
|
||
.result-circle{width:140px;height:140px;border-radius:50%;margin:0 auto 16px;display:grid;place-items:center;flex-direction:column}
|
||
.result-circle .percent{font-size:36px;font-weight:800}
|
||
.result-circle .label{font-size:14px;opacity:.8}
|
||
.result-circle.low{background:linear-gradient(135deg,#dcfce7,#bbf7d0);color:#15803d}
|
||
.result-circle.mid{background:linear-gradient(135deg,#fef3c7,#fde68a);color:#92400e}
|
||
.result-circle.high{background:linear-gradient(135deg,#fee2e2,#fecaca);color:#dc2626}
|
||
.result-list{margin-top:20px}
|
||
.result-item{display:flex;align-items:center;gap:14px;padding:14px;background:#f8fafc;border-radius:var(--radius-sm);margin-bottom:10px}
|
||
.result-item .thumb{width:60px;height:80px;border-radius:8px;background:linear-gradient(135deg,#64748b,#334155);display:grid;place-items:center;color:#fff}
|
||
.result-item .info h4{margin:0 0 4px;font-size:14px;font-weight:600}
|
||
.result-item .info p{font-size:12px;color:var(--muted);margin:0}
|
||
.result-item .similarity{margin-left:auto;font-weight:700;color:var(--amber)}
|
||
|
||
/* 空状态 */
|
||
.empty-state{border:1px dashed #cbd5e1;background:linear-gradient(180deg,#fff,#f8fafc);border-radius:var(--radius-lg);padding:48px;text-align:center;color:var(--muted)}
|
||
.empty-state .icon{width:60px;height:60px;border-radius:18px;background:var(--primary-soft);margin:0 auto 16px;display:grid;place-items:center;color:var(--primary);font-size:28px;font-weight:800}
|
||
.empty-state h3{color:var(--slate);margin:0 0 8px;font-size:16px}
|
||
.empty-state p{margin:0 0 16px;font-size:14px}
|
||
|
||
/* 登录页 */
|
||
.login-page{min-height:100vh;display:grid;place-items:center;padding:40px 24px}
|
||
.login-card{background:rgba(255,255,255,.95);border:1px solid var(--line);border-radius:var(--radius-xl);box-shadow:var(--shadow-md);padding:48px;width:100%;max-width:420px}
|
||
.login-header{text-align:center;margin-bottom:32px}
|
||
.login-header .brand{display:flex;gap:10px;align-items:center;justify-content:center;font-size:24px;font-weight:900;margin-bottom:12px}
|
||
.login-header p{color:var(--muted);font-size:14px}
|
||
.login-form{display:flex;flex-direction:column;gap:16px}
|
||
.login-form .form-field label{display:block;font-weight:600;margin-bottom:8px;font-size:13px}
|
||
.login-form .form-field input{width:100%;height:48px;border:1px solid var(--line);border-radius:var(--radius-sm);background:#fff;padding:0 16px;font-size:14px;outline:0;transition:.15s ease}
|
||
.login-form .form-field input:focus{border-color:var(--primary);box-shadow:0 0 0 3px rgba(79,70,229,.1)}
|
||
.login-form .btn{width:100%;padding:14px;margin-top:8px}
|
||
.login-footer{text-align:center;margin-top:20px;font-size:14px;color:var(--muted)}
|
||
.login-footer a{color:var(--primary);font-weight:600;text-decoration:none}
|
||
.login-divider{display:flex;align-items:center;gap:16px;margin:20px 0;color:var(--muted);font-size:13px}
|
||
.login-divider::before,.login-divider::after{content:"";flex:1;height:1px;background:var(--line)}
|
||
|
||
/* 订阅页 */
|
||
.subscription-page{}
|
||
|
||
/* 模态框 */
|
||
.modal-overlay{display:none;position:fixed;inset:0;z-index:200;background:rgba(15,23,42,.5);backdrop-filter:blur(8px);place-items:center;padding:24px}
|
||
.modal-overlay.show{display:grid}
|
||
.modal{background:#fff;border-radius:var(--radius-xl);padding:32px;width:min(480px,100%);box-shadow:0 40px 120px rgba(15,23,42,.3);text-align:center}
|
||
.modal h3{font-size:22px;margin:0 0 8px}
|
||
.modal p{color:var(--muted);margin:0 0 20px;line-height:1.7}
|
||
.progress-bar{height:8px;background:#e2e8f0;border-radius:999px;overflow:hidden;margin:16px 0}
|
||
.progress-bar .fill{height:100%;background:linear-gradient(90deg,#6366f1,#4f46e5);border-radius:999px;transition:width .4s ease}
|
||
.spinner{width:64px;height:64px;border-radius:50%;margin:0 auto 18px;border:5px solid #e0e7ff;border-top-color:var(--primary);animation:spin 1s linear infinite}
|
||
.success-icon{width:64px;height:64px;border-radius:50%;background:var(--green);color:#fff;font-size:32px;display:none;place-items:center;margin:0 auto 18px}
|
||
.modal.done .spinner{display:none}
|
||
.modal.done .success-icon{display:grid}
|
||
.modal-step{font-size:13px;color:var(--muted);margin-top:12px}
|
||
|
||
@keyframes spin{to{transform:rotate(360deg)}}
|
||
|
||
/* 响应式 */
|
||
@media(max-width:1200px){
|
||
.hero{grid-template-columns:1fr}
|
||
.feature-grid,.pricing-grid,.kpi-grid{grid-template-columns:repeat(2,1fr)}
|
||
.template-grid{grid-template-columns:repeat(3,1fr)}
|
||
.products-grid{grid-template-columns:repeat(3,1fr)}
|
||
}
|
||
@media(max-width:980px){
|
||
.app-layout{grid-template-columns:1fr}
|
||
.sidebar{position:fixed;left:0;top:68px;width:260px;height:calc(100vh - 68px);transform:translateX(-100%);z-index:40}
|
||
.sidebar.open{transform:translateX(0)}
|
||
.titles-layout,.assets-layout,.voices-layout,.generate-layout,.duplication-layout{grid-template-columns:1fr}
|
||
.feature-grid,.pricing-grid,.kpi-grid,.template-grid,.products-grid{grid-template-columns:repeat(2,1fr)}
|
||
.workflow{grid-template-columns:repeat(2,1fr)}
|
||
.workflow-step:not(:last-child)::after{display:none}
|
||
}
|
||
@media(max-width:720px){
|
||
.wrap{padding:0 16px 60px}
|
||
.hero h1{font-size:32px}
|
||
.feature-grid,.pricing-grid,.kpi-grid,.template-grid,.products-grid,.workflow{grid-template-columns:1fr}
|
||
.choice-list{grid-template-columns:repeat(2,1fr)}
|
||
.task-item{grid-template-columns:1fr;gap:10px}
|
||
.tabs{flex-wrap:wrap}
|
||
.form-row{grid-template-columns:1fr}
|
||
.step-item .label{display:none}
|
||
}
|
||
|
||
/* 隐藏导航 */
|
||
.nav-hidden{display:none}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="bg"></div>
|
||
<div class="dots"></div>
|
||
|
||
<!-- 顶部导航 -->
|
||
<nav class="nav" id="topNav">
|
||
<div class="nav-in">
|
||
<div class="brand">
|
||
<div class="logo">🦐</div>
|
||
<span>小虾智剪</span>
|
||
</div>
|
||
<div class="nav-links" id="navLinks">
|
||
<span class="active" data-view="home">首页</span>
|
||
<span data-view="subscription">订阅</span>
|
||
<span>帮助中心</span>
|
||
<span>联系我们</span>
|
||
</div>
|
||
<div id="authButtons">
|
||
<button class="btn ghost" onclick="showView('login')">登录</button>
|
||
<button class="btn primary" onclick="showView('login')">免费开始</button>
|
||
</div>
|
||
<div id="userMenu" class="user-dropdown" style="display:none">
|
||
<div class="avatar-btn">虾
|
||
<div class="avatar-menu">
|
||
<span>个人设置</span>
|
||
<span>工作空间</span>
|
||
<span onclick="logout()">退出登录</span>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<div class="name">演示用户</div>
|
||
<div class="role">标准版</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
|
||
<!-- 主内容 -->
|
||
<main>
|
||
<!-- 首页 -->
|
||
<section id="view-home" class="view active">
|
||
<div class="wrap">
|
||
<div class="hero">
|
||
<div>
|
||
<span class="tag">🦐 小虾智剪 · AI智能视频创作平台</span>
|
||
<h1>上传素材,AI自动剪辑<br/>一键生成短视频</h1>
|
||
<p>面向口播、产品介绍、直播切片和企业宣传的智能视频创作平台。素材管理、智能分类、一键生成、成片查重,全流程自动化处理。</p>
|
||
<div class="hero-actions">
|
||
<button class="btn primary" onclick="login()">立即免费开始</button>
|
||
<button class="btn ghost" onclick="showView('subscription')">查看定价方案</button>
|
||
</div>
|
||
</div>
|
||
<div class="hero-visual">
|
||
<div class="hero-video">
|
||
<div class="play-btn">▶</div>
|
||
</div>
|
||
<div class="hero-info">
|
||
<div class="hero-badge">
|
||
<span class="demo-badge">✨ AI智能剪辑</span>
|
||
<span class="demo-badge">⚡ 30秒生成</span>
|
||
</div>
|
||
<span class="pill ok">可发布</span>
|
||
</div>
|
||
<p style="color:#64748b;line-height:1.6;margin:12px 0 0;font-size:13px">小虾智剪 让视频创作变得简单高效</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="feature-grid">
|
||
<div class="feature">
|
||
<div class="icon" style="background:linear-gradient(135deg,#0ea5e9,#0284c7)">🎬</div>
|
||
<h3>AI智能剪辑</h3>
|
||
<p>智能分析素材内容,自动匹配最佳剪辑方案,一键生成专业级短视频。</p>
|
||
</div>
|
||
<div class="feature">
|
||
<div class="icon" style="background:linear-gradient(135deg,#10b981,#059669)">📦</div>
|
||
<h3>素材自动分类</h3>
|
||
<p>AI自动识别素材内容,智能打标签,支持视频、音频、图片统一管理。</p>
|
||
</div>
|
||
<div class="feature">
|
||
<div class="icon" style="background:linear-gradient(135deg,#6366f1,#4f46e5)">✨</div>
|
||
<h3>一键生成视频</h3>
|
||
<p>选择模板和素材,系统自动完成剪辑、配音、字幕,30秒快速出片。</p>
|
||
</div>
|
||
<div class="feature">
|
||
<div class="icon" style="background:linear-gradient(135deg,#f59e0b,#d97706)">🔍</div>
|
||
<h3>成片查重检测</h3>
|
||
<p>智能检测视频相似度,支持MP4/AVI/MOV/MKV格式,确保内容原创性。</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<div class="section-title">
|
||
<h3>工作流程</h3>
|
||
</div>
|
||
<div class="workflow">
|
||
<div class="workflow-step">
|
||
<div class="step-num">1</div>
|
||
<h4>上传素材</h4>
|
||
<p>上传视频、音频、图片素材</p>
|
||
</div>
|
||
<div class="workflow-step">
|
||
<div class="step-num">2</div>
|
||
<h4>AI分析</h4>
|
||
<p>智能识别内容自动分类</p>
|
||
</div>
|
||
<div class="workflow-step">
|
||
<div class="step-num">3</div>
|
||
<h4>智能剪辑</h4>
|
||
<p>选择模板自动生成剪辑方案</p>
|
||
</div>
|
||
<div class="workflow-step">
|
||
<div class="step-num">4</div>
|
||
<h4>一键导出</h4>
|
||
<p>快速导出高质量成片</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="section" id="pricing-home">
|
||
<div class="section-title">
|
||
<h3>定价方案</h3>
|
||
<button class="btn ghost sm" onclick="showView('subscription')">查看全部方案 →</button>
|
||
</div>
|
||
<div class="pricing-grid">
|
||
<div class="pricing-card">
|
||
<div class="icon" style="background:linear-gradient(135deg,#94a3b8,#64748b);margin:0 auto">入</div>
|
||
<h3>体验版</h3>
|
||
<p class="desc">免费体验基础功能</p>
|
||
<div class="price">¥0 <span>/ 永久</span></div>
|
||
<div class="features">
|
||
<div>✓ 1个工作空间</div>
|
||
<div>✓ 基础素材库管理</div>
|
||
<div>✓ 每月10次视频生成</div>
|
||
</div>
|
||
<button class="btn ghost" onclick="login()">开始体验</button>
|
||
</div>
|
||
<div class="pricing-card popular">
|
||
<span class="popular-tag">推荐</span>
|
||
<div class="icon" style="background:linear-gradient(135deg,#6366f1,#4f46e5);margin:0 auto">标</div>
|
||
<h3>标准版</h3>
|
||
<p class="desc">适合个人创作者</p>
|
||
<div class="price">¥99 <span>/ 月</span></div>
|
||
<div class="features">
|
||
<div>✓ 3个项目空间</div>
|
||
<div>✓ 500条素材管理</div>
|
||
<div>✓ 每月200次视频生成</div>
|
||
</div>
|
||
<button class="btn primary" onclick="login()">立即开通</button>
|
||
</div>
|
||
<div class="pricing-card">
|
||
<div class="icon" style="background:linear-gradient(135deg,#10b981,#059669);margin:0 auto">专</div>
|
||
<h3>专业版</h3>
|
||
<p class="desc">适合团队高频创作</p>
|
||
<div class="price">¥299 <span>/ 月</span></div>
|
||
<div class="features">
|
||
<div>✓ 20个项目空间</div>
|
||
<div>✓ 5000条素材管理</div>
|
||
<div>✓ 每月1000次视频生成</div>
|
||
</div>
|
||
<button class="btn ghost" onclick="login()">了解详情</button>
|
||
</div>
|
||
<div class="pricing-card">
|
||
<div class="icon" style="background:linear-gradient(135deg,#f59e0b,#d97706);margin:0 auto">企</div>
|
||
<h3>企业版</h3>
|
||
<p class="desc">专属定制服务</p>
|
||
<div class="price">定制 <span>/ 方案</span></div>
|
||
<div class="features">
|
||
<div>✓ 无限项目空间</div>
|
||
<div>✓ 私有化部署</div>
|
||
<div>✓ 专属技术支持</div>
|
||
</div>
|
||
<button class="btn ghost" onclick="login()">联系销售</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="section" style="text-align:center;padding:40px 0">
|
||
<h2 style="font-size:28px;margin-bottom:12px">准备好开始了吗?</h2>
|
||
<p style="color:var(--muted);margin-bottom:24px">立即注册,体验AI智能视频创作的便捷</p>
|
||
<button class="btn primary" style="padding:16px 32px;font-size:16px" onclick="login()">免费开始使用 →</button>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 登录页 -->
|
||
<section id="view-login" class="view">
|
||
<div class="login-page">
|
||
<div class="login-card">
|
||
<div class="login-header">
|
||
<div class="brand">
|
||
<div class="logo">🦐</div>
|
||
<span>小虾智剪</span>
|
||
</div>
|
||
<p>登录到您的账户,开始智能视频创作</p>
|
||
</div>
|
||
<div class="login-form">
|
||
<div class="form-field">
|
||
<label>邮箱地址</label>
|
||
<input type="email" placeholder="请输入邮箱"/>
|
||
</div>
|
||
<div class="form-field">
|
||
<label>密码</label>
|
||
<input type="password" placeholder="请输入密码"/>
|
||
</div>
|
||
<button class="btn primary" onclick="doLogin()">登录</button>
|
||
</div>
|
||
<div class="login-divider">或</div>
|
||
<button class="btn ghost" style="width:100%" onclick="doLogin()">微信登录</button>
|
||
<div class="login-footer">
|
||
还没有账户?<a href="#" onclick="doLogin()">立即注册</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 订阅页 -->
|
||
<section id="view-subscription" class="view">
|
||
<div class="wrap subscription-page">
|
||
<div class="page-head">
|
||
<div>
|
||
<span class="tag">订阅与定价</span>
|
||
<h2>选择适合你的方案</h2>
|
||
<p>从个人试用到团队批量生产,灵活选择,按需升级</p>
|
||
</div>
|
||
</div>
|
||
<div class="pricing-grid">
|
||
<div class="pricing-card">
|
||
<div class="icon" style="background:linear-gradient(135deg,#94a3b8,#64748b);margin:0 auto">入</div>
|
||
<h3>体验版</h3>
|
||
<p class="desc">适合先体验基础功能</p>
|
||
<div class="price">¥0 <span>/ 永久免费</span></div>
|
||
<div class="features">
|
||
<div>✓ 1个工作空间</div>
|
||
<div>✓ 基础素材库 / 标题库</div>
|
||
<div>✓ 每月10次视频生成</div>
|
||
<div>✓ 成片预览与下载</div>
|
||
<div>✓ 不含团队协作</div>
|
||
</div>
|
||
<button class="btn ghost" onclick="showView('login')">开始体验</button>
|
||
</div>
|
||
<div class="pricing-card popular">
|
||
<span class="popular-tag">推荐</span>
|
||
<div class="icon" style="background:linear-gradient(135deg,#6366f1,#4f46e5);margin:0 auto">标</div>
|
||
<h3>标准版</h3>
|
||
<p class="desc">适合个人创作者</p>
|
||
<div class="price">¥99 <span>/ 月</span></div>
|
||
<div class="features">
|
||
<div>✓ 3个项目空间</div>
|
||
<div>✓ 500条素材管理</div>
|
||
<div>✓ 每月200次视频生成</div>
|
||
<div>✓ 标题库 / 配音库 / 成片库</div>
|
||
<div>✓ 签名下载与批量地址</div>
|
||
</div>
|
||
<button class="btn primary" onclick="showView('login')">选择标准版</button>
|
||
</div>
|
||
<div class="pricing-card">
|
||
<div class="icon" style="background:linear-gradient(135deg,#10b981,#059669);margin:0 auto">专</div>
|
||
<h3>专业版</h3>
|
||
<p class="desc">适合高频创作团队</p>
|
||
<div class="price">¥299 <span>/ 月</span></div>
|
||
<div class="features">
|
||
<div>✓ 20个项目空间</div>
|
||
<div>✓ 5000条素材管理</div>
|
||
<div>✓ 每月1000次视频生成</div>
|
||
<div>✓ 高风险素材诊断</div>
|
||
<div>✓ 失败任务重试与协作</div>
|
||
</div>
|
||
<button class="btn ghost" onclick="showView('login')">选择专业版</button>
|
||
</div>
|
||
<div class="pricing-card">
|
||
<div class="icon" style="background:linear-gradient(135deg,#f59e0b,#d97706);margin:0 auto">企</div>
|
||
<h3>企业版</h3>
|
||
<p class="desc">适合品牌和机构</p>
|
||
<div class="price">定制 <span>/ 专属报价</span></div>
|
||
<div class="features">
|
||
<div>✓ 无限项目与团队席位</div>
|
||
<div>✓ 私有化部署 / 专属存储</div>
|
||
<div>✓ 专属模板与品牌素材库</div>
|
||
<div>✓ API对接与权限审计</div>
|
||
<div>✓ 运维支持与SLA</div>
|
||
</div>
|
||
<button class="btn ghost" onclick="showView('login')">联系销售</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Dashboard -->
|
||
<section id="view-dashboard" class="view">
|
||
<div class="app-layout">
|
||
<aside class="sidebar">
|
||
<div class="sidebar-logo">
|
||
<div class="logo" style="width:34px;height:34px;font-size:18px">🦐</div>
|
||
<span>小虾智剪</span>
|
||
</div>
|
||
<nav class="sidebar-nav">
|
||
<div class="sidebar-item active" data-view="dashboard">
|
||
<div class="icon" style="background:var(--primary);color:#fff">📊</div>
|
||
<span>控制台</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="titles">
|
||
<div class="icon">📝</div>
|
||
<span>标题库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="assets">
|
||
<div class="icon">📦</div>
|
||
<span>素材库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="voices">
|
||
<div class="icon">🎙️</div>
|
||
<span>配音库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="templates">
|
||
<div class="icon">🎨</div>
|
||
<span>模板库</span>
|
||
</div>
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-item" data-view="editing-planner">
|
||
<div class="icon">✂️</div>
|
||
<span>剪辑计划</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="generate">
|
||
<div class="icon" style="background:var(--primary);color:#fff">✨</div>
|
||
<span>一键生成</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="products">
|
||
<div class="icon">🎬</div>
|
||
<span>成片库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="history">
|
||
<div class="icon">📋</div>
|
||
<span>任务历史</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="duplication">
|
||
<div class="icon">🔍</div>
|
||
<span>查重检测</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="editing-planner">
|
||
<div class="icon">✂️</div>
|
||
<span>剪辑计划</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="voiceClone">
|
||
<div class="icon">🎤</div>
|
||
<span>我的音色</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="accounts">
|
||
<div class="icon">🔑</div>
|
||
<span>账号管理</span>
|
||
</div>
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-item" data-view="subscription-logged">
|
||
<div class="icon">💎</div>
|
||
<span>订阅管理</span>
|
||
</div>
|
||
</nav>
|
||
<div class="sidebar-bottom">
|
||
<div class="sidebar-item" onclick="logout()">
|
||
<div class="icon">🚪</div>
|
||
<span>退出登录</span>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
<div class="main-content">
|
||
<div class="page-head">
|
||
<div>
|
||
<h2>欢迎回来,演示用户 👋</h2>
|
||
<p>今天是2024年,您有3个任务正在进行中</p>
|
||
</div>
|
||
<button class="btn primary" onclick="showView('generate')">✨ 一键生成视频</button>
|
||
</div>
|
||
|
||
<div class="kpi-grid">
|
||
<div class="kpi">
|
||
<div class="value">12</div>
|
||
<div class="label">项目总数</div>
|
||
<div class="trend up">↑ 2 本月新增</div>
|
||
</div>
|
||
<div class="kpi">
|
||
<div class="value">486</div>
|
||
<div class="label">素材总数</div>
|
||
<div class="trend up">↑ 38 本月上传</div>
|
||
</div>
|
||
<div class="kpi">
|
||
<div class="value">156</div>
|
||
<div class="label">本月生成数</div>
|
||
<div class="trend up">↑ 23% vs 上月</div>
|
||
</div>
|
||
<div class="kpi">
|
||
<div class="value">2.4GB</div>
|
||
<div class="label">存储空间</div>
|
||
<div class="trend">已用 24%</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<div class="section-title">
|
||
<h3>最近任务</h3>
|
||
<button class="btn ghost sm" onclick="showView('history')">查看全部 →</button>
|
||
</div>
|
||
<div class="task-list">
|
||
<div class="task-item">
|
||
<div class="task-info">
|
||
<h4>产品卖点混剪视频</h4>
|
||
<div class="meta">一键生成 · 模板:画中画混剪</div>
|
||
</div>
|
||
<span class="pill ok">已完成</span>
|
||
<div class="task-time">
|
||
<span class="date">今天 14:32</span>
|
||
耗时 28秒
|
||
</div>
|
||
</div>
|
||
<div class="task-item">
|
||
<div class="task-info">
|
||
<h4>直播切片成片</h4>
|
||
<div class="meta">一键生成 · 模板:人物口播</div>
|
||
</div>
|
||
<span class="pill warn">进行中</span>
|
||
<div class="task-time">
|
||
<span class="date">今天 14:28</span>
|
||
已耗时 2分钟
|
||
</div>
|
||
</div>
|
||
<div class="task-item">
|
||
<div class="task-info">
|
||
<h4>新品上市宣传片</h4>
|
||
<div class="meta">一键生成 · 模板:品牌宣传</div>
|
||
</div>
|
||
<span class="pill ok">已完成</span>
|
||
<div class="task-time">
|
||
<span class="date">昨天 16:45</span>
|
||
耗时 35秒
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<div class="section-title">
|
||
<h3>快速入口</h3>
|
||
</div>
|
||
<div class="feature-grid" style="margin:0">
|
||
<div class="feature" style="cursor:pointer" onclick="showView('titles')">
|
||
<div class="icon" style="background:linear-gradient(135deg,#6366f1,#4f46e5)">📝</div>
|
||
<h3>标题库</h3>
|
||
<p>24条标题 · 5个分类</p>
|
||
</div>
|
||
<div class="feature" style="cursor:pointer" onclick="showView('assets')">
|
||
<div class="icon" style="background:linear-gradient(135deg,#0ea5e9,#0284c7)">📦</div>
|
||
<h3>素材库</h3>
|
||
<p>486个素材 · 3个素材库</p>
|
||
</div>
|
||
<div class="feature" style="cursor:pointer" onclick="showView('generate')">
|
||
<div class="icon" style="background:linear-gradient(135deg,#10b981,#059669)">✨</div>
|
||
<h3>一键生成</h3>
|
||
<p>开始创作新视频</p>
|
||
</div>
|
||
<div class="feature" style="cursor:pointer" onclick="showView('products')">
|
||
<div class="icon" style="background:linear-gradient(135deg,#f59e0b,#d97706)">🎬</div>
|
||
<h3>成片库</h3>
|
||
<p>89个成片 · 3个待复核</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 标题库 -->
|
||
<section id="view-titles" class="view">
|
||
<div class="app-layout">
|
||
<aside class="sidebar">
|
||
<div class="sidebar-logo">
|
||
<div class="logo" style="width:34px;height:34px;font-size:18px">🦐</div>
|
||
<span>小虾智剪</span>
|
||
</div>
|
||
<nav class="sidebar-nav">
|
||
<div class="sidebar-item" data-view="dashboard">
|
||
<div class="icon">📊</div>
|
||
<span>控制台</span>
|
||
</div>
|
||
<div class="sidebar-item active" data-view="titles">
|
||
<div class="icon" style="background:var(--primary);color:#fff">📝</div>
|
||
<span>标题库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="assets">
|
||
<div class="icon">📦</div>
|
||
<span>素材库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="voices">
|
||
<div class="icon">🎙️</div>
|
||
<span>配音库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="templates">
|
||
<div class="icon">🎨</div>
|
||
<span>模板库</span>
|
||
</div>
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-item" data-view="generate">
|
||
<div class="icon">✨</div>
|
||
<span>一键生成</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="products">
|
||
<div class="icon">🎬</div>
|
||
<span>成片库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="history">
|
||
<div class="icon">📋</div>
|
||
<span>任务历史</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="duplication">
|
||
<div class="icon">🔍</div>
|
||
<span>查重检测</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="editing-planner">
|
||
<div class="icon">✂️</div>
|
||
<span>剪辑计划</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="voiceClone">
|
||
<div class="icon">🎤</div>
|
||
<span>我的音色</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="accounts">
|
||
<div class="icon">🔑</div>
|
||
<span>账号管理</span>
|
||
</div>
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-item" data-view="subscription-logged">
|
||
<div class="icon">💎</div>
|
||
<span>订阅管理</span>
|
||
</div>
|
||
</nav>
|
||
<div class="sidebar-bottom">
|
||
<div class="sidebar-item" onclick="logout()">
|
||
<div class="icon">🚪</div>
|
||
<span>退出登录</span>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
<div class="main-content">
|
||
<div class="page-head">
|
||
<div>
|
||
<h2>标题库</h2>
|
||
<p>管理常用标题,生成时直接选择使用</p>
|
||
</div>
|
||
<div style="display:flex;gap:10px">
|
||
<button class="btn ghost" onclick="openBatchImportModal()">批量导入</button>
|
||
<button class="btn primary" onclick="openNewTitleModal()">+ 新增标题</button>
|
||
</div>
|
||
</div>
|
||
<div class="titles-layout">
|
||
<div class="category-list">
|
||
<div class="category-item active">
|
||
<h4>全部标题</h4>
|
||
<span>24 条</span>
|
||
</div>
|
||
<div class="category-item">
|
||
<h4>口播开场</h4>
|
||
<span>8 条</span>
|
||
</div>
|
||
<div class="category-item">
|
||
<h4>产品介绍</h4>
|
||
<span>6 条</span>
|
||
</div>
|
||
<div class="category-item">
|
||
<h4>教程类</h4>
|
||
<span>5 条</span>
|
||
</div>
|
||
<div class="category-item">
|
||
<h4>种草推荐</h4>
|
||
<span>3 条</span>
|
||
</div>
|
||
<div class="category-item">
|
||
<h4>直播引流</h4>
|
||
<span>2 条</span>
|
||
</div>
|
||
</div>
|
||
<div class="titles-grid">
|
||
<div class="title-card">
|
||
<div class="content">3秒抓住注意力,30秒讲清卖点</div>
|
||
<div class="meta">
|
||
<div>
|
||
<span class="pill info" style="margin-right:6px">口播开场</span>
|
||
<span class="stats">使用 6 次</span>
|
||
</div>
|
||
<div style="display:flex;align-items:center;gap:8px">
|
||
<button class="btn ghost sm" onclick="event.stopPropagation();openEditTitleModal(this.parentElement.parentElement.parentElement)">✏️ 编辑</button>
|
||
<button class="btn ghost sm" onclick="event.stopPropagation();openDeleteTitleModal(this.parentElement.parentElement.parentElement)" style="color:var(--red)">🗑️</button>
|
||
<span class="favorite favorited" onclick="event.stopPropagation();toggleFavorite(this)">★</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="title-card">
|
||
<div class="content">新手也能看懂的自动剪辑教程</div>
|
||
<div class="meta">
|
||
<div>
|
||
<span class="pill info" style="margin-right:6px">教程类</span>
|
||
<span class="stats">使用 3 次</span>
|
||
</div>
|
||
<span class="favorite" onclick="event.stopPropagation();toggleFavorite(this)">☆</span>
|
||
</div>
|
||
</div>
|
||
<div class="title-card">
|
||
<div class="content">这款产品让效率提升10倍的秘密</div>
|
||
<div class="meta">
|
||
<div>
|
||
<span class="pill ok" style="margin-right:6px">种草推荐</span>
|
||
<span class="stats">使用 4 次</span>
|
||
</div>
|
||
<span class="favorite favorited" onclick="event.stopPropagation();toggleFavorite(this)">★</span>
|
||
</div>
|
||
</div>
|
||
<div class="title-card">
|
||
<div class="content">直播预告:今晚8点准时开始</div>
|
||
<div class="meta">
|
||
<div>
|
||
<span class="pill warn" style="margin-right:6px">直播引流</span>
|
||
<span class="stats">使用 2 次</span>
|
||
</div>
|
||
<span class="favorite" onclick="event.stopPropagation();toggleFavorite(this)">☆</span>
|
||
</div>
|
||
</div>
|
||
<div class="title-card">
|
||
<div class="content">产品功能详解,看这一期就够了</div>
|
||
<div class="meta">
|
||
<div>
|
||
<span class="pill info" style="margin-right:6px">产品介绍</span>
|
||
<span class="stats">使用 5 次</span>
|
||
</div>
|
||
<span class="favorite favorited" onclick="event.stopPropagation();toggleFavorite(this)">★</span>
|
||
</div>
|
||
</div>
|
||
<div class="title-card">
|
||
<div class="content">揭秘!达人都在用的剪辑技巧</div>
|
||
<div class="meta">
|
||
<div>
|
||
<span class="pill info" style="margin-right:6px">口播开场</span>
|
||
<span class="stats">使用 3 次</span>
|
||
</div>
|
||
<span class="favorite" onclick="event.stopPropagation();toggleFavorite(this)">☆</span>
|
||
</div>
|
||
</div>
|
||
<div class="title-card">
|
||
<div class="content">实测对比:传统方法VS智能剪辑</div>
|
||
<div class="meta">
|
||
<div>
|
||
<span class="pill ok" style="margin-right:6px">种草推荐</span>
|
||
<span class="stats">使用 2 次</span>
|
||
</div>
|
||
<span class="favorite favorited" onclick="event.stopPropagation();toggleFavorite(this)">★</span>
|
||
</div>
|
||
</div>
|
||
<div class="title-card">
|
||
<div class="content">如何使用小虾智剪快速生成视频</div>
|
||
<div class="meta">
|
||
<div>
|
||
<span class="pill info" style="margin-right:6px">教程类</span>
|
||
<span class="stats">使用 4 次</span>
|
||
</div>
|
||
<span class="favorite" onclick="event.stopPropagation();toggleFavorite(this)">☆</span>
|
||
</div>
|
||
</div>
|
||
<div class="title-card">
|
||
<div class="content">限时福利!今天下单立减100元</div>
|
||
<div class="meta">
|
||
<div>
|
||
<span class="pill warn" style="margin-right:6px">直播引流</span>
|
||
<span class="stats">使用 1 次</span>
|
||
</div>
|
||
<span class="favorite" onclick="event.stopPropagation();toggleFavorite(this)">☆</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 素材库 -->
|
||
<section id="view-assets" class="view">
|
||
<div class="app-layout">
|
||
<aside class="sidebar">
|
||
<div class="sidebar-logo">
|
||
<div class="logo" style="width:34px;height:34px;font-size:18px">🦐</div>
|
||
<span>小虾智剪</span>
|
||
</div>
|
||
<nav class="sidebar-nav">
|
||
<div class="sidebar-item" data-view="dashboard">
|
||
<div class="icon">📊</div>
|
||
<span>控制台</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="titles">
|
||
<div class="icon">📝</div>
|
||
<span>标题库</span>
|
||
</div>
|
||
<div class="sidebar-item active" data-view="assets">
|
||
<div class="icon" style="background:var(--primary);color:#fff">📦</div>
|
||
<span>素材库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="voices">
|
||
<div class="icon">🎙️</div>
|
||
<span>配音库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="templates">
|
||
<div class="icon">🎨</div>
|
||
<span>模板库</span>
|
||
</div>
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-item" data-view="generate">
|
||
<div class="icon">✨</div>
|
||
<span>一键生成</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="products">
|
||
<div class="icon">🎬</div>
|
||
<span>成片库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="history">
|
||
<div class="icon">📋</div>
|
||
<span>任务历史</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="duplication">
|
||
<div class="icon">🔍</div>
|
||
<span>查重检测</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="editing-planner">
|
||
<div class="icon">✂️</div>
|
||
<span>剪辑计划</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="voiceClone">
|
||
<div class="icon">🎤</div>
|
||
<span>我的音色</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="accounts">
|
||
<div class="icon">🔑</div>
|
||
<span>账号管理</span>
|
||
</div>
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-item" data-view="subscription-logged">
|
||
<div class="icon">💎</div>
|
||
<span>订阅管理</span>
|
||
</div>
|
||
</nav>
|
||
<div class="sidebar-bottom">
|
||
<div class="sidebar-item" onclick="logout()">
|
||
<div class="icon">🚪</div>
|
||
<span>退出登录</span>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
<div class="main-content">
|
||
<div class="page-head">
|
||
<div>
|
||
<h2>素材库</h2>
|
||
<p>管理视频、音频、图片素材,AI自动分类</p>
|
||
</div>
|
||
<div style="display:flex;gap:10px">
|
||
<button class="btn ghost" onclick="openNewAssetLibModal()">+ 新建素材库</button>
|
||
<button class="btn primary" onclick="openUploadModal()">上传素材</button>
|
||
</div>
|
||
</div>
|
||
<div class="assets-layout">
|
||
<div class="asset-library-list">
|
||
<div class="asset-library-item active">
|
||
<h4>直播切片素材库</h4>
|
||
<span>186 个素材 · 1.2GB</span>
|
||
</div>
|
||
<div class="asset-library-item">
|
||
<h4>产品展示素材库</h4>
|
||
<span>156 个素材 · 980MB</span>
|
||
</div>
|
||
<div class="asset-library-item">
|
||
<h4>用户反馈素材库</h4>
|
||
<span>144 个素材 · 320MB</span>
|
||
</div>
|
||
</div>
|
||
<div class="asset-grid">
|
||
<div class="asset-card">
|
||
<div class="asset-thumb" style="background:linear-gradient(135deg,#0ea5e9,#0284c7)">
|
||
<div class="play">▶</div>
|
||
</div>
|
||
<div class="asset-info">
|
||
<h4>主播口播开场.mp4</h4>
|
||
<div class="meta">
|
||
<span class="pill info">视频</span>
|
||
<span>00:32</span>
|
||
</div>
|
||
<button class="btn ghost sm" onclick="event.stopPropagation();openDiagnoseModal(this.closest('.asset-card'))" style="width:100%;margin-top:8px;padding:6px;font-size:12px">🔍 诊断</button>
|
||
</div>
|
||
</div>
|
||
<div class="asset-card">
|
||
<div class="asset-thumb" style="background:linear-gradient(135deg,#f59e0b,#d97706)">
|
||
<div class="play">▶</div>
|
||
</div>
|
||
<div class="asset-info">
|
||
<h4>产品特写镜头.mp4</h4>
|
||
<div class="meta">
|
||
<span class="pill warn">待复核</span>
|
||
<span>00:18</span>
|
||
</div>
|
||
<button class="btn ghost sm" onclick="event.stopPropagation();openDiagnoseModal(this.closest('.asset-card'))" style="width:100%;margin-top:8px;padding:6px;font-size:12px">🔍 诊断</button>
|
||
</div>
|
||
</div>
|
||
<div class="asset-card">
|
||
<div class="asset-thumb" style="background:linear-gradient(135deg,#10b981,#059669)">
|
||
<div class="play">▶</div>
|
||
</div>
|
||
<div class="asset-info">
|
||
<h4>用户评价片段.mp4</h4>
|
||
<div class="meta">
|
||
<span class="pill ok">已通过</span>
|
||
<span>00:25</span>
|
||
</div>
|
||
<button class="btn ghost sm" onclick="event.stopPropagation();openDiagnoseModal(this.closest('.asset-card'))" style="width:100%;margin-top:8px;padding:6px;font-size:12px">🔍 诊断</button>
|
||
</div>
|
||
</div>
|
||
<div class="asset-card">
|
||
<div class="asset-thumb" style="background:linear-gradient(135deg,#6366f1,#4f46e5)">
|
||
<div class="play">▶</div>
|
||
</div>
|
||
<div class="asset-info">
|
||
<h4>开箱展示.mp4</h4>
|
||
<div class="meta">
|
||
<span class="pill info">视频</span>
|
||
<span>00:16</span>
|
||
</div>
|
||
<button class="btn ghost sm" onclick="event.stopPropagation();openDiagnoseModal(this.closest('.asset-card'))" style="width:100%;margin-top:8px;padding:6px;font-size:12px">🔍 诊断</button>
|
||
</div>
|
||
</div>
|
||
<div class="asset-card">
|
||
<div class="asset-thumb" style="background:linear-gradient(135deg,#ec4899,#db2777)">
|
||
<div class="play">▶</div>
|
||
</div>
|
||
<div class="asset-info">
|
||
<h4>使用场景演示.mp4</h4>
|
||
<div class="meta">
|
||
<span class="pill ok">已通过</span>
|
||
<span>00:22</span>
|
||
</div>
|
||
<button class="btn ghost sm" onclick="event.stopPropagation();openDiagnoseModal(this.closest('.asset-card'))" style="width:100%;margin-top:8px;padding:6px;font-size:12px">🔍 诊断</button>
|
||
</div>
|
||
</div>
|
||
<div class="asset-card">
|
||
<div class="asset-thumb" style="background:linear-gradient(135deg,#64748b,#475569)">
|
||
<div class="play">▶</div>
|
||
</div>
|
||
<div class="asset-info">
|
||
<h4>低清素材片段.mp4</h4>
|
||
<div class="meta">
|
||
<span class="pill bad">高风险</span>
|
||
<span>00:09</span>
|
||
</div>
|
||
<button class="btn ghost sm" onclick="event.stopPropagation();openDiagnoseModal(this.closest('.asset-card'))" style="width:100%;margin-top:8px;padding:6px;font-size:12px">🔍 诊断</button>
|
||
</div>
|
||
</div>
|
||
<div class="asset-card">
|
||
<div class="asset-thumb" style="background:linear-gradient(135deg,#14b8a6,#0d9488)">
|
||
<div class="play">▶</div>
|
||
</div>
|
||
<div class="asset-info">
|
||
<h4>直播高光时刻.mp4</h4>
|
||
<div class="meta">
|
||
<span class="pill ok">已通过</span>
|
||
<span>01:15</span>
|
||
</div>
|
||
<button class="btn ghost sm" onclick="event.stopPropagation();openDiagnoseModal(this.closest('.asset-card'))" style="width:100%;margin-top:8px;padding:6px;font-size:12px">🔍 诊断</button>
|
||
</div>
|
||
</div>
|
||
<div class="asset-card">
|
||
<div class="asset-thumb" style="background:linear-gradient(135deg,#8b5cf6,#7c3aed)">
|
||
<div class="play">▶</div>
|
||
</div>
|
||
<div class="asset-info">
|
||
<h4>产品细节特写.mp4</h4>
|
||
<div class="meta">
|
||
<span class="pill info">视频</span>
|
||
<span>00:14</span>
|
||
</div>
|
||
<button class="btn ghost sm" onclick="event.stopPropagation();openDiagnoseModal(this.closest('.asset-card'))" style="width:100%;margin-top:8px;padding:6px;font-size:12px">🔍 诊断</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 配音库 -->
|
||
<section id="view-voices" class="view">
|
||
<div class="app-layout">
|
||
<aside class="sidebar">
|
||
<div class="sidebar-logo">
|
||
<div class="logo" style="width:34px;height:34px;font-size:18px">🦐</div>
|
||
<span>小虾智剪</span>
|
||
</div>
|
||
<nav class="sidebar-nav">
|
||
<div class="sidebar-item" data-view="dashboard">
|
||
<div class="icon">📊</div>
|
||
<span>控制台</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="titles">
|
||
<div class="icon">📝</div>
|
||
<span>标题库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="assets">
|
||
<div class="icon">📦</div>
|
||
<span>素材库</span>
|
||
</div>
|
||
<div class="sidebar-item active" data-view="voices">
|
||
<div class="icon" style="background:var(--primary);color:#fff">🎙️</div>
|
||
<span>配音库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="templates">
|
||
<div class="icon">🎨</div>
|
||
<span>模板库</span>
|
||
</div>
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-item" data-view="generate">
|
||
<div class="icon">✨</div>
|
||
<span>一键生成</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="products">
|
||
<div class="icon">🎬</div>
|
||
<span>成片库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="history">
|
||
<div class="icon">📋</div>
|
||
<span>任务历史</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="duplication">
|
||
<div class="icon">🔍</div>
|
||
<span>查重检测</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="editing-planner">
|
||
<div class="icon">✂️</div>
|
||
<span>剪辑计划</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="voiceClone">
|
||
<div class="icon">🎤</div>
|
||
<span>我的音色</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="accounts">
|
||
<div class="icon">🔑</div>
|
||
<span>账号管理</span>
|
||
</div>
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-item" data-view="subscription-logged">
|
||
<div class="icon">💎</div>
|
||
<span>订阅管理</span>
|
||
</div>
|
||
</nav>
|
||
<div class="sidebar-bottom">
|
||
<div class="sidebar-item" onclick="logout()">
|
||
<div class="icon">🚪</div>
|
||
<span>退出登录</span>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
<div class="main-content">
|
||
<div class="page-head">
|
||
<div>
|
||
<h2>配音库</h2>
|
||
<p>管理配音素材,支持AI生成和手动创建</p>
|
||
</div>
|
||
<div style="display:flex;gap:10px">
|
||
<button class="btn ghost" onclick="openNewVoiceModal()">+ 新建配音库</button>
|
||
<button class="btn ghost" onclick="openAIGenerateModal()">🎙️ AI生成配音</button>
|
||
<button class="btn primary" onclick="openManualVoiceModal()">+ 上传配音</button>
|
||
</div>
|
||
</div>
|
||
<div class="voices-layout">
|
||
<div class="asset-library-list">
|
||
<div class="asset-library-item active">
|
||
<h4>短视频带货配音</h4>
|
||
<span>8 条配音</span>
|
||
</div>
|
||
<div class="asset-library-item">
|
||
<h4>知识分享配音</h4>
|
||
<span>5 条配音</span>
|
||
</div>
|
||
<div class="asset-library-item">
|
||
<h4>品牌宣传配音</h4>
|
||
<span>3 条配音</span>
|
||
</div>
|
||
</div>
|
||
<div class="voice-list">
|
||
<div class="voice-card">
|
||
<div class="voice-icon" style="background:linear-gradient(135deg,#ec4899,#db2777)">🎙️</div>
|
||
<div class="voice-info">
|
||
<h4>温柔女声 - 轻松种草</h4>
|
||
<div class="meta">短视频带货配音 · 00:28 · 女声</div>
|
||
</div>
|
||
<div class="voice-wave"></div>
|
||
<div class="voice-actions">
|
||
<button class="btn ghost sm">▶ 试听</button>
|
||
</div>
|
||
</div>
|
||
<div class="voice-card">
|
||
<div class="voice-icon" style="background:linear-gradient(135deg,#6366f1,#4f46e5)">🎙️</div>
|
||
<div class="voice-info">
|
||
<h4>专业男声 - 产品介绍</h4>
|
||
<div class="meta">品牌宣传配音 · 00:35 · 男声</div>
|
||
</div>
|
||
<div class="voice-wave"></div>
|
||
<div class="voice-actions">
|
||
<button class="btn ghost sm">▶ 试听</button>
|
||
</div>
|
||
</div>
|
||
<div class="voice-card">
|
||
<div class="voice-icon" style="background:linear-gradient(135deg,#0ea5e9,#0284c7)">🎙️</div>
|
||
<div class="voice-info">
|
||
<h4>活力女声 - 直播预告</h4>
|
||
<div class="meta">短视频带货配音 · 00:15 · 女声</div>
|
||
</div>
|
||
<div class="voice-wave"></div>
|
||
<div class="voice-actions">
|
||
<button class="btn ghost sm">▶ 试听</button>
|
||
</div>
|
||
</div>
|
||
<div class="voice-card">
|
||
<div class="voice-icon" style="background:linear-gradient(135deg,#10b981,#059669)">🎙️</div>
|
||
<div class="voice-info">
|
||
<h4>知性女声 - 知识讲解</h4>
|
||
<div class="meta">知识分享配音 · 00:42 · 女声</div>
|
||
</div>
|
||
<div class="voice-wave"></div>
|
||
<div class="voice-actions">
|
||
<button class="btn ghost sm">▶ 试听</button>
|
||
</div>
|
||
</div>
|
||
<div class="voice-card">
|
||
<div class="voice-icon" style="background:linear-gradient(135deg,#f59e0b,#d97706)">🎙️</div>
|
||
<div class="voice-info">
|
||
<h4>磁性男声 - 深度测评</h4>
|
||
<div class="meta">知识分享配音 · 00:55 · 男声</div>
|
||
</div>
|
||
<div class="voice-wave"></div>
|
||
<div class="voice-actions">
|
||
<button class="btn ghost sm">▶ 试听</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 模板库 -->
|
||
<section id="view-templates" class="view">
|
||
<div class="app-layout">
|
||
<aside class="sidebar">
|
||
<div class="sidebar-logo">
|
||
<div class="logo" style="width:34px;height:34px;font-size:18px">🦐</div>
|
||
<span>小虾智剪</span>
|
||
</div>
|
||
<nav class="sidebar-nav">
|
||
<div class="sidebar-item" data-view="dashboard">
|
||
<div class="icon">📊</div>
|
||
<span>控制台</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="titles">
|
||
<div class="icon">📝</div>
|
||
<span>标题库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="assets">
|
||
<div class="icon">📦</div>
|
||
<span>素材库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="voices">
|
||
<div class="icon">🎙️</div>
|
||
<span>配音库</span>
|
||
</div>
|
||
<div class="sidebar-item active" data-view="templates">
|
||
<div class="icon" style="background:var(--primary);color:#fff">🎨</div>
|
||
<span>模板库</span>
|
||
</div>
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-item" data-view="generate">
|
||
<div class="icon">✨</div>
|
||
<span>一键生成</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="products">
|
||
<div class="icon">🎬</div>
|
||
<span>成片库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="history">
|
||
<div class="icon">📋</div>
|
||
<span>任务历史</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="duplication">
|
||
<div class="icon">🔍</div>
|
||
<span>查重检测</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="voiceClone">
|
||
<div class="icon">🎤</div>
|
||
<span>我的音色</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="editing-planner">
|
||
<div class="icon">✂️</div>
|
||
<span>剪辑计划</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="accounts">
|
||
<div class="icon">🔑</div>
|
||
<span>账号管理</span>
|
||
</div>
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-item" data-view="subscription-logged">
|
||
<div class="icon">💎</div>
|
||
<span>订阅管理</span>
|
||
</div>
|
||
</nav>
|
||
<div class="sidebar-bottom">
|
||
<div class="sidebar-item" onclick="logout()">
|
||
<div class="icon">🚪</div>
|
||
<span>退出登录</span>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
<div class="main-content">
|
||
<div class="page-head">
|
||
<div>
|
||
<h2>模板库</h2>
|
||
<p>选择适合的模板,快速生成专业视频</p>
|
||
</div>
|
||
<button class="btn ghost" onclick="showView('editing-planner')">+ 创建模板</button>
|
||
</div>
|
||
<div class="template-toolbar">
|
||
<div class="search-box">
|
||
<span>🔍</span>
|
||
<input type="text" placeholder="搜索模板..."/>
|
||
</div>
|
||
<div style="display:flex;gap:8px">
|
||
<button class="btn ghost sm active">全部</button>
|
||
<button class="btn ghost sm">口播</button>
|
||
<button class="btn ghost sm">种草</button>
|
||
<button class="btn ghost sm">产品</button>
|
||
<button class="btn ghost sm">品牌</button>
|
||
</div>
|
||
</div>
|
||
<div class="template-grid">
|
||
<div class="template-card">
|
||
<div class="template-thumb" style="background:linear-gradient(135deg,#fbbf24,#f59e0b)">
|
||
<span>PIP</span>
|
||
</div>
|
||
<div class="template-info">
|
||
<h4>画中画混剪</h4>
|
||
<div class="meta">
|
||
<span class="pill muted">产品展示</span>
|
||
<span>使用 56 次</span>
|
||
</div>
|
||
<button class="btn primary sm" style="width:100%;margin-top:10px" onclick="event.stopPropagation();useTemplate(this.parentElement.parentElement)">使用此模板</button>
|
||
</div>
|
||
</div>
|
||
<div class="template-card">
|
||
<div class="template-thumb" style="background:linear-gradient(135deg,#3b82f6,#1d4ed8)">
|
||
<span>ONE</span>
|
||
</div>
|
||
<div class="template-info">
|
||
<h4>一镜到底</h4>
|
||
<div class="meta">
|
||
<span class="pill info">口播</span>
|
||
<span>使用 42 次</span>
|
||
</div>
|
||
<button class="btn primary sm" style="width:100%;margin-top:10px" onclick="event.stopPropagation();useTemplate(this.parentElement.parentElement)">使用此模板</button>
|
||
</div>
|
||
</div>
|
||
<div class="template-card">
|
||
<div class="template-thumb" style="background:linear-gradient(135deg,#6366f1,#4f46e5)">
|
||
<span>PER</span>
|
||
</div>
|
||
<div class="template-info">
|
||
<h4>人物口播</h4>
|
||
<div class="meta">
|
||
<span class="pill info">口播</span>
|
||
<span>使用 38 次</span>
|
||
</div>
|
||
<button class="btn primary sm" style="width:100%;margin-top:10px" onclick="event.stopPropagation();useTemplate(this.parentElement.parentElement)">使用此模板</button>
|
||
</div>
|
||
</div>
|
||
<div class="template-card">
|
||
<div class="template-thumb" style="background:linear-gradient(135deg,#10b981,#059669)">
|
||
<span>SUP</span>
|
||
</div>
|
||
<div class="template-info">
|
||
<h4>种草推荐</h4>
|
||
<div class="meta">
|
||
<span class="pill ok">种草</span>
|
||
<span>使用 35 次</span>
|
||
</div>
|
||
<button class="btn primary sm" style="width:100%;margin-top:10px" onclick="event.stopPropagation();useTemplate(this.parentElement.parentElement)">使用此模板</button>
|
||
</div>
|
||
</div>
|
||
<div class="template-card">
|
||
<div class="template-thumb" style="background:linear-gradient(135deg,#ec4899,#db2777)">
|
||
<span>REV</span>
|
||
</div>
|
||
<div class="template-info">
|
||
<h4>产品评测</h4>
|
||
<div class="meta">
|
||
<span class="pill warn">产品</span>
|
||
<span>使用 28 次</span>
|
||
</div>
|
||
<button class="btn primary sm" style="width:100%;margin-top:10px" onclick="event.stopPropagation();useTemplate(this.parentElement.parentElement)">使用此模板</button>
|
||
</div>
|
||
</div>
|
||
<div class="template-card">
|
||
<div class="template-thumb" style="background:linear-gradient(135deg,#8b5cf6,#7c3aed)">
|
||
<span>BRD</span>
|
||
</div>
|
||
<div class="template-info">
|
||
<h4>品牌宣传</h4>
|
||
<div class="meta">
|
||
<span class="pill muted">品牌</span>
|
||
<span>使用 22 次</span>
|
||
</div>
|
||
<button class="btn primary sm" style="width:100%;margin-top:10px" onclick="event.stopPropagation();useTemplate(this.parentElement.parentElement)">使用此模板</button>
|
||
</div>
|
||
</div>
|
||
<div class="template-card">
|
||
<div class="template-thumb" style="background:linear-gradient(135deg,#f97316,#ea580c)">
|
||
<span>LIV</span>
|
||
</div>
|
||
<div class="template-info">
|
||
<h4>直播切片</h4>
|
||
<div class="meta">
|
||
<span class="pill warn">直播</span>
|
||
<span>使用 48 次</span>
|
||
</div>
|
||
<button class="btn primary sm" style="width:100%;margin-top:10px" onclick="event.stopPropagation();useTemplate(this.parentElement.parentElement)">使用此模板</button>
|
||
</div>
|
||
</div>
|
||
<div class="template-card">
|
||
<div class="template-thumb" style="background:linear-gradient(135deg,#64748b,#475569)">
|
||
<span>TIP</span>
|
||
</div>
|
||
<div class="template-info">
|
||
<h4>技巧教程</h4>
|
||
<div class="meta">
|
||
<span class="pill info">教程</span>
|
||
<span>使用 18 次</span>
|
||
</div>
|
||
<button class="btn primary sm" style="width:100%;margin-top:10px" onclick="event.stopPropagation();useTemplate(this.parentElement.parentElement)">使用此模板</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 一键生成 -->
|
||
<section id="view-generate" class="view">
|
||
<div class="app-layout">
|
||
<aside class="sidebar">
|
||
<div class="sidebar-logo">
|
||
<div class="logo" style="width:34px;height:34px;font-size:18px">🦐</div>
|
||
<span>小虾智剪</span>
|
||
</div>
|
||
<nav class="sidebar-nav">
|
||
<div class="sidebar-item" data-view="dashboard">
|
||
<div class="icon">📊</div>
|
||
<span>控制台</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="titles">
|
||
<div class="icon">📝</div>
|
||
<span>标题库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="assets">
|
||
<div class="icon">📦</div>
|
||
<span>素材库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="voices">
|
||
<div class="icon">🎙️</div>
|
||
<span>配音库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="templates">
|
||
<div class="icon">🎨</div>
|
||
<span>模板库</span>
|
||
</div>
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-item active" data-view="generate">
|
||
<div class="icon" style="background:var(--primary);color:#fff">✨</div>
|
||
<span>一键生成</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="products">
|
||
<div class="icon">🎬</div>
|
||
<span>成片库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="history">
|
||
<div class="icon">📋</div>
|
||
<span>任务历史</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="duplication">
|
||
<div class="icon">🔍</div>
|
||
<span>查重检测</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="voiceClone">
|
||
<div class="icon">🎤</div>
|
||
<span>我的音色</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="editing-planner">
|
||
<div class="icon">✂️</div>
|
||
<span>剪辑计划</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="accounts">
|
||
<div class="icon">🔑</div>
|
||
<span>账号管理</span>
|
||
</div>
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-item" data-view="subscription-logged">
|
||
<div class="icon">💎</div>
|
||
<span>订阅管理</span>
|
||
</div>
|
||
</nav>
|
||
<div class="sidebar-bottom">
|
||
<div class="sidebar-item" onclick="logout()">
|
||
<div class="icon">🚪</div>
|
||
<span>退出登录</span>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
<div class="main-content">
|
||
<div class="page-head">
|
||
<div>
|
||
<h2>一键生成视频</h2>
|
||
<p>选择模板和素材,系统自动完成剪辑</p>
|
||
</div>
|
||
<button class="btn ghost">💾 保存草稿</button>
|
||
</div>
|
||
|
||
<div class="steps-bar">
|
||
<div class="step-item active" data-step="1">
|
||
<div class="num">1</div>
|
||
<span class="label">选择模板</span>
|
||
</div>
|
||
<span class="arrow">→</span>
|
||
<div class="step-item" data-step="2">
|
||
<div class="num">2</div>
|
||
<span class="label">选择素材</span>
|
||
</div>
|
||
<span class="arrow">→</span>
|
||
<div class="step-item" data-step="3">
|
||
<div class="num">3</div>
|
||
<span class="label">选择标题</span>
|
||
</div>
|
||
<span class="arrow">→</span>
|
||
<div class="step-item" data-step="4">
|
||
<div class="num">4</div>
|
||
<span class="label">选择配音</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="generate-layout">
|
||
<div class="generate-form">
|
||
<div class="form-section" id="step-1">
|
||
<h3>🎨 选择模板</h3>
|
||
<div class="choice-list">
|
||
<div class="choice-item selected" onclick="selectChoice(this)">
|
||
<span class="check-icon">✓</span>
|
||
<div class="thumb" style="background:linear-gradient(135deg,#fbbf24,#f59e0b)">PIP</div>
|
||
<h4>画中画混剪</h4>
|
||
<p>产品展示 · 30秒</p>
|
||
</div>
|
||
<div class="choice-item" onclick="selectChoice(this)">
|
||
<span class="check-icon">✓</span>
|
||
<div class="thumb" style="background:linear-gradient(135deg,#3b82f6,#1d4ed8)">ONE</div>
|
||
<h4>一镜到底</h4>
|
||
<p>口播 · 45秒</p>
|
||
</div>
|
||
<div class="choice-item" onclick="selectChoice(this)">
|
||
<span class="check-icon">✓</span>
|
||
<div class="thumb" style="background:linear-gradient(135deg,#6366f1,#4f46e5)">PER</div>
|
||
<h4>人物口播</h4>
|
||
<p>知识分享 · 60秒</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-section" id="step-2" style="display:none">
|
||
<h3>📦 选择素材</h3>
|
||
<div class="form-field">
|
||
<label>选择素材库</label>
|
||
<select>
|
||
<option>直播切片素材库</option>
|
||
<option>产品展示素材库</option>
|
||
<option>用户反馈素材库</option>
|
||
</select>
|
||
</div>
|
||
<div style="margin-top:14px">
|
||
<span class="pill ok" style="margin-right:8px">已选 12 个素材</span>
|
||
<span style="color:var(--muted);font-size:13px">系统将自动选择最合适的素材</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-section" id="step-3" style="display:none">
|
||
<h3>📝 选择标题</h3>
|
||
<div class="form-field">
|
||
<label>选择标题</label>
|
||
<select>
|
||
<option>3秒抓住注意力,30秒讲清卖点</option>
|
||
<option>新手也能看懂的自动剪辑教程</option>
|
||
<option>这款产品让效率提升10倍的秘密</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-section" id="step-4" style="display:none">
|
||
<h3>🎙️ 选择配音</h3>
|
||
<div class="choice-list" id="voice-choice-list" style="grid-template-columns:repeat(4,1fr);margin-bottom:16px">
|
||
<div class="choice-item" onclick="selectVoiceChoice(this, 'douyin')">
|
||
<span class="check-icon">✓</span>
|
||
<div class="thumb" style="background:linear-gradient(135deg,#ec4899,#db2777)">🎙️</div>
|
||
<h4>温柔女声</h4>
|
||
<p>轻松种草</p>
|
||
</div>
|
||
<div class="choice-item" onclick="selectVoiceChoice(this, 'male1')">
|
||
<span class="check-icon">✓</span>
|
||
<div class="thumb" style="background:linear-gradient(135deg,#6366f1,#4f46e5)">🎙️</div>
|
||
<h4>专业男声</h4>
|
||
<p>产品介绍</p>
|
||
</div>
|
||
<div class="choice-item" onclick="selectVoiceChoice(this, 'female2')">
|
||
<span class="check-icon">✓</span>
|
||
<div class="thumb" style="background:linear-gradient(135deg,#0ea5e9,#0284c7)">🎙️</div>
|
||
<h4>活力女声</h4>
|
||
<p>直播预告</p>
|
||
</div>
|
||
<div class="choice-item" onclick="selectVoiceChoice(this, 'clone')" id="clone-voice-option">
|
||
<span class="check-icon">✓</span>
|
||
<div class="thumb" style="background:linear-gradient(135deg,#f59e0b,#d97706)">🎤</div>
|
||
<h4>克隆我的声音</h4>
|
||
<p>上传/录制</p>
|
||
</div>
|
||
</div>
|
||
<!-- 克隆声音展开区域 -->
|
||
<div id="clone-voice-expand" style="display:none;margin-top:16px;padding:20px;background:#fff;border:1px solid var(--line);border-radius:var(--radius-md)">
|
||
<h4 style="margin:0 0 12px;font-size:14px">🎤 克隆我的声音</h4>
|
||
<p style="margin:0 0 12px;font-size:12px;color:var(--muted)">上传你的声音,AI将用你的音色生成配音</p>
|
||
<div id="clone-voice-upload-area" style="border:2px dashed var(--line);border-radius:var(--radius-sm);padding:30px;text-align:center;background:#f8fafc;cursor:pointer;margin-bottom:12px" onclick="document.getElementById('clone-audio-input').click()">
|
||
<div style="font-size:28px;margin-bottom:8px">🎵</div>
|
||
<p style="margin:0;font-size:13px">拖拽或点击上传音频文件(MP3/WAV,10秒以上)</p>
|
||
<p style="margin:8px 0 0;font-size:11px;color:var(--muted)">支持格式:MP3、WAV · 建议时长:10秒~3分钟</p>
|
||
<input type="file" id="clone-audio-input" accept=".mp3,.wav" style="display:none" onchange="handleCloneAudioUpload(this)"/>
|
||
</div>
|
||
<div style="display:flex;gap:10px;margin-bottom:12px">
|
||
<button class="btn ghost" style="flex:1" onclick="openRecordModal()">🎙️ 直接录制</button>
|
||
</div>
|
||
<p style="margin:0;font-size:11px;color:var(--muted);background:#f8fafc;padding:8px 12px;border-radius:8px">💡 建议上传10秒~3分钟的清晰语音,环境安静、语速均匀效果最佳</p>
|
||
<!-- 音频预览区域 -->
|
||
<div id="clone-audio-preview" style="display:none;margin-top:12px;padding:16px;background:#f8fafc;border-radius:var(--radius-sm)">
|
||
<div style="display:flex;align-items:center;gap:12px;margin-bottom:10px">
|
||
<button class="btn ghost sm" onclick="playCloneAudio()">▶ 播放</button>
|
||
<div style="flex:1">
|
||
<div style="height:6px;background:#e2e8f0;border-radius:3px;overflow:hidden">
|
||
<div id="clone-audio-progress" style="height:100%;background:var(--primary);width:0%;transition:width .3s"></div>
|
||
</div>
|
||
</div>
|
||
<span id="clone-audio-duration" style="font-size:12px;color:var(--muted)">00:00 / 00:00</span>
|
||
</div>
|
||
<p id="clone-audio-name" style="margin:0;font-size:12px;color:var(--muted)">已上传音频.mp3</p>
|
||
</div>
|
||
<!-- 已克隆音色选择区域 -->
|
||
<div id="cloned-voices-select" style="margin-top:16px">
|
||
<p style="margin:0 0 8px;font-size:12px;font-weight:600;color:var(--muted)">或选择已克隆的音色:</p>
|
||
<div id="cloned-voice-list-step4" style="display:flex;flex-direction:column;gap:8px">
|
||
<!-- 动态渲染已克隆音色 -->
|
||
</div>
|
||
<button class="btn ghost sm" style="margin-top:8px" onclick="showView('voiceClone')">➕ 克隆新音色</button>
|
||
</div>
|
||
<button id="start-clone-btn" class="btn primary" style="width:100%;margin-top:16px" onclick="startVoiceClone()">🎤 开始克隆</button>
|
||
<!-- 克隆进度 -->
|
||
<div id="clone-progress-area" style="display:none;margin-top:16px;text-align:center">
|
||
<div style="font-size:13px;color:var(--muted);margin-bottom:8px">正在克隆音色...</div>
|
||
<div style="height:8px;background:#f1f5f9;border-radius:999px;overflow:hidden;margin-bottom:8px">
|
||
<div id="clone-progress-bar" style="height:100%;background:linear-gradient(90deg,var(--primary),var(--primary-light));width:0%;transition:width .4s"></div>
|
||
</div>
|
||
<p id="clone-progress-text" style="margin:0;font-size:12px;color:var(--primary)">准备就绪</p>
|
||
</div>
|
||
<!-- 克隆成功提示 -->
|
||
<div id="clone-success-area" style="display:none;margin-top:16px;text-align:center;padding:16px;background:#dcfce7;border-radius:var(--radius-sm)">
|
||
<p style="margin:0;font-size:14px;color:#166534">✅ 音色克隆成功,可继续使用</p>
|
||
</div>
|
||
</div>
|
||
<div id="selected-voice-display" style="display:none;font-size:13px;color:var(--green);margin-bottom:12px">已选择配音</div>
|
||
</div>
|
||
|
||
<div style="display:flex;gap:12px;margin-top:8px">
|
||
<button class="btn ghost" onclick="prevStep()">← 上一步</button>
|
||
<button class="btn primary" style="flex:1" onclick="nextStep()">下一步 →</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="generate-preview">
|
||
<div class="preview-video">
|
||
<div class="play">▶</div>
|
||
</div>
|
||
<div id="preview-caption" class="preview-caption">3秒抓住注意力,30秒讲清卖点</div>
|
||
<div class="preview-title">剪辑计划预览</div>
|
||
<div id="preview-timeline" class="preview-timeline">
|
||
<div class="timeline-item">
|
||
<div class="num">1</div>
|
||
<span>主讲口播 · 开场钩子</span>
|
||
<span>0-8s</span>
|
||
</div>
|
||
<div class="timeline-item">
|
||
<div class="num">2</div>
|
||
<span>产品特写 · B-roll</span>
|
||
<span>8-20s</span>
|
||
</div>
|
||
<div class="timeline-item">
|
||
<div class="num">3</div>
|
||
<span>用户反馈 · 结尾</span>
|
||
<span>20-30s</span>
|
||
</div>
|
||
</div>
|
||
<div class="generate-actions">
|
||
<button class="btn ghost">重新生成</button>
|
||
<button class="btn primary" onclick="startGeneration()">✨ 确认生成</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 成片库 -->
|
||
<section id="view-products" class="view">
|
||
<div class="app-layout">
|
||
<aside class="sidebar">
|
||
<div class="sidebar-logo">
|
||
<div class="logo" style="width:34px;height:34px;font-size:18px">🦐</div>
|
||
<span>小虾智剪</span>
|
||
</div>
|
||
<nav class="sidebar-nav">
|
||
<div class="sidebar-item" data-view="dashboard">
|
||
<div class="icon">📊</div>
|
||
<span>控制台</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="titles">
|
||
<div class="icon">📝</div>
|
||
<span>标题库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="assets">
|
||
<div class="icon">📦</div>
|
||
<span>素材库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="voices">
|
||
<div class="icon">🎙️</div>
|
||
<span>配音库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="templates">
|
||
<div class="icon">🎨</div>
|
||
<span>模板库</span>
|
||
</div>
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-item" data-view="generate">
|
||
<div class="icon">✨</div>
|
||
<span>一键生成</span>
|
||
</div>
|
||
<div class="sidebar-item active" data-view="products">
|
||
<div class="icon" style="background:var(--primary);color:#fff">🎬</div>
|
||
<span>成片库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="history">
|
||
<div class="icon">📋</div>
|
||
<span>任务历史</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="duplication">
|
||
<div class="icon">🔍</div>
|
||
<span>查重检测</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="voiceClone">
|
||
<div class="icon">🎤</div>
|
||
<span>我的音色</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="editing-planner">
|
||
<div class="icon">✂️</div>
|
||
<span>剪辑计划</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="accounts">
|
||
<div class="icon">🔑</div>
|
||
<span>账号管理</span>
|
||
</div>
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-item" data-view="subscription-logged">
|
||
<div class="icon">💎</div>
|
||
<span>订阅管理</span>
|
||
</div>
|
||
</nav>
|
||
<div class="sidebar-bottom">
|
||
<div class="sidebar-item" onclick="logout()">
|
||
<div class="icon">🚪</div>
|
||
<span>退出登录</span>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
<div class="main-content">
|
||
<div class="page-head">
|
||
<div>
|
||
<h2>成片库</h2>
|
||
<p>查看和管理生成的视频成品</p>
|
||
</div>
|
||
<div style="display:flex;align-items:center;gap:12px">
|
||
<label style="display:flex;align-items:center;gap:8px;cursor:pointer;font-size:14px;font-weight:600;color:var(--muted)">
|
||
<input type="checkbox" id="select-all-products" onchange="toggleSelectAllProducts()" style="width:16px;height:16px;accent-color:var(--primary)"/>
|
||
全选
|
||
</label>
|
||
<span id="selected-count" style="font-size:13px;color:var(--muted)">已选 <span style="color:var(--primary);font-weight:700">0</span> 个视频</span>
|
||
<button id="batch-publish-btn" class="btn primary" onclick="openBatchPublishModal()" disabled style="opacity:0.5;cursor:not-allowed">📢 批量发布</button>
|
||
<button class="btn ghost">批量下载</button>
|
||
</div>
|
||
</div>
|
||
<div class="products-grid">
|
||
<div class="product-card" data-product-id="2" data-product-name="产品卖点混剪">
|
||
<label class="product-select-checkbox" onclick="event.stopPropagation()">
|
||
<input type="checkbox" onchange="toggleProductSelect(this.closest('.product-card'))" style="width:18px;height:18px;accent-color:var(--primary);position:absolute;top:12px;left:12px;z-index:10"/>
|
||
</label>
|
||
<div class="product-thumb" style="background:linear-gradient(135deg,#f59e0b,#d97706)">
|
||
<div class="play">▶</div>
|
||
<span class="duration">00:28</span>
|
||
</div>
|
||
<div class="product-info">
|
||
<h4>产品卖点混剪</h4>
|
||
<div class="status">
|
||
<span class="pill warn">待复核</span>
|
||
<span style="font-size:12px;color:var(--muted)">今天 14:28</span>
|
||
</div>
|
||
<div style="display:flex;gap:6px;margin-top:8px">
|
||
<button class="btn ghost sm" onclick="event.stopPropagation();downloadProduct(this.closest('.product-card'))" style="flex:1;padding:6px 4px;font-size:12px">📥 下载</button>
|
||
<button class="btn primary sm" onclick="event.stopPropagation();openPublishModal(this.closest('.product-card'))" style="flex:1;padding:6px 4px;font-size:12px">📢 发布</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="product-card" data-product-id="3" data-product-name="种草推荐视频">
|
||
<label class="product-select-checkbox" onclick="event.stopPropagation()">
|
||
<input type="checkbox" onchange="toggleProductSelect(this.closest('.product-card'))" style="width:18px;height:18px;accent-color:var(--primary);position:absolute;top:12px;left:12px;z-index:10"/>
|
||
</label>
|
||
<div class="product-thumb" style="background:linear-gradient(135deg,#10b981,#059669)">
|
||
<div class="play">▶</div>
|
||
<span class="duration">00:35</span>
|
||
</div>
|
||
<div class="product-info">
|
||
<h4>种草推荐视频</h4>
|
||
<div class="status">
|
||
<span class="pill ok">可发布</span>
|
||
<span style="font-size:12px;color:var(--muted)">昨天 16:45</span>
|
||
</div>
|
||
<div style="display:flex;gap:6px;margin-top:8px">
|
||
<button class="btn ghost sm" onclick="event.stopPropagation();downloadProduct(this.closest('.product-card'))" style="flex:1;padding:6px 4px;font-size:12px">📥 下载</button>
|
||
<button class="btn primary sm" onclick="event.stopPropagation();openPublishModal(this.closest('.product-card'))" style="flex:1;padding:6px 4px;font-size:12px">📢 发布</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="product-card" data-product-id="4" data-product-name="品牌宣传片">
|
||
<label class="product-select-checkbox" onclick="event.stopPropagation()">
|
||
<input type="checkbox" onchange="toggleProductSelect(this.closest('.product-card'))" style="width:18px;height:18px;accent-color:var(--primary);position:absolute;top:12px;left:12px;z-index:10"/>
|
||
</label>
|
||
<div class="product-thumb" style="background:linear-gradient(135deg,#6366f1,#4f46e5)">
|
||
<div class="play">▶</div>
|
||
<span class="duration">00:45</span>
|
||
</div>
|
||
<div class="product-info">
|
||
<h4>品牌宣传片</h4>
|
||
<div class="status">
|
||
<span class="pill ok">可发布</span>
|
||
<span style="font-size:12px;color:var(--muted)">昨天 11:20</span>
|
||
</div>
|
||
<div style="display:flex;gap:6px;margin-top:8px">
|
||
<button class="btn ghost sm" onclick="event.stopPropagation();downloadProduct(this.closest('.product-card'))" style="flex:1;padding:6px 4px;font-size:12px">📥 下载</button>
|
||
<button class="btn primary sm" onclick="event.stopPropagation();openPublishModal(this.closest('.product-card'))" style="flex:1;padding:6px 4px;font-size:12px">📢 发布</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="product-card" data-product-id="5" data-product-name="新品上市预告">
|
||
<label class="product-select-checkbox" onclick="event.stopPropagation()">
|
||
<input type="checkbox" onchange="toggleProductSelect(this.closest('.product-card'))" style="width:18px;height:18px;accent-color:var(--primary);position:absolute;top:12px;left:12px;z-index:10"/>
|
||
</label>
|
||
<div class="product-thumb" style="background:linear-gradient(135deg,#ec4899,#db2777)">
|
||
<div class="play">▶</div>
|
||
<span class="duration">00:30</span>
|
||
</div>
|
||
<div class="product-info">
|
||
<h4>新品上市预告</h4>
|
||
<div class="status">
|
||
<span class="pill bad">已下载</span>
|
||
<span style="font-size:12px;color:var(--muted)">3天前</span>
|
||
</div>
|
||
<div style="display:flex;gap:6px;margin-top:8px">
|
||
<button class="btn ghost sm" onclick="event.stopPropagation();downloadProduct(this.closest('.product-card'))" style="flex:1;padding:6px 4px;font-size:12px">📥 下载</button>
|
||
<button class="btn primary sm" onclick="event.stopPropagation();openPublishModal(this.closest('.product-card'))" style="flex:1;padding:6px 4px;font-size:12px">📢 发布</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="product-card" data-product-id="6" data-product-name="技巧教程第一期">
|
||
<label class="product-select-checkbox" onclick="event.stopPropagation()">
|
||
<input type="checkbox" onchange="toggleProductSelect(this.closest('.product-card'))" style="width:18px;height:18px;accent-color:var(--primary);position:absolute;top:12px;left:12px;z-index:10"/>
|
||
</label>
|
||
<div class="product-thumb" style="background:linear-gradient(135deg,#8b5cf6,#7c3aed)">
|
||
<div class="play">▶</div>
|
||
<span class="duration">00:22</span>
|
||
</div>
|
||
<div class="product-info">
|
||
<h4>技巧教程第一期</h4>
|
||
<div class="status">
|
||
<span class="pill ok">可发布</span>
|
||
<span style="font-size:12px;color:var(--muted)">5天前</span>
|
||
</div>
|
||
<div style="display:flex;gap:6px;margin-top:8px">
|
||
<button class="btn ghost sm" onclick="event.stopPropagation();downloadProduct(this.closest('.product-card'))" style="flex:1;padding:6px 4px;font-size:12px">📥 下载</button>
|
||
<button class="btn primary sm" onclick="event.stopPropagation();openPublishModal(this.closest('.product-card'))" style="flex:1;padding:6px 4px;font-size:12px">📢 发布</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="product-card" data-product-id="7" data-product-name="产品评测视频">
|
||
<label class="product-select-checkbox" onclick="event.stopPropagation()">
|
||
<input type="checkbox" onchange="toggleProductSelect(this.closest('.product-card'))" style="width:18px;height:18px;accent-color:var(--primary);position:absolute;top:12px;left:12px;z-index:10"/>
|
||
</label>
|
||
<div class="product-thumb" style="background:linear-gradient(135deg,#64748b,#475569)">
|
||
<div class="play">▶</div>
|
||
<span class="duration">00:18</span>
|
||
</div>
|
||
<div class="product-info">
|
||
<h4>产品评测视频</h4>
|
||
<div class="status">
|
||
<span class="pill bad">已下载</span>
|
||
<span style="font-size:12px;color:var(--muted)">1周前</span>
|
||
</div>
|
||
<div style="display:flex;gap:6px;margin-top:8px">
|
||
<button class="btn ghost sm" onclick="event.stopPropagation();downloadProduct(this.closest('.product-card'))" style="flex:1;padding:6px 4px;font-size:12px">📥 下载</button>
|
||
<button class="btn primary sm" onclick="event.stopPropagation();openPublishModal(this.closest('.product-card'))" style="flex:1;padding:6px 4px;font-size:12px">📢 发布</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="product-card" data-product-id="1" data-product-name="直播切片成片_v2" data-published="true" style="opacity:0.65">
|
||
<label class="product-select-checkbox" onclick="event.stopPropagation()">
|
||
<input type="checkbox" disabled style="width:18px;height:18px;accent-color:var(--primary);position:absolute;top:12px;left:12px;z-index:10;opacity:0.4"/>
|
||
</label>
|
||
<div style="position:absolute;top:12px;right:12px;background:var(--green);color:#fff;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;z-index:10">已发布</div>
|
||
<div class="product-thumb" style="background:linear-gradient(135deg,#0ea5e9,#0284c7)">
|
||
<div class="play">▶</div>
|
||
<span class="duration">00:32</span>
|
||
</div>
|
||
<div class="product-info">
|
||
<h4>直播切片成片_v2</h4>
|
||
<div class="status">
|
||
<span class="pill ok">可发布</span>
|
||
<span style="font-size:12px;color:var(--muted)">今天 14:32</span>
|
||
</div>
|
||
<div style="display:flex;gap:6px;margin-top:8px">
|
||
<button class="btn ghost sm" onclick="event.stopPropagation();downloadProduct(this.closest('.product-card'))" style="flex:1;padding:6px 4px;font-size:12px">📥 下载</button>
|
||
<span class="pill ok" style="flex:1;padding:6px 4px;font-size:12px;text-align:center;display:inline-block">✅ 已发布</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="product-card">
|
||
<div class="product-thumb" style="background:linear-gradient(135deg,#14b8a6,#0d9488)">
|
||
<div class="play">▶</div>
|
||
<span class="duration">00:40</span>
|
||
</div>
|
||
<div class="product-info">
|
||
<h4>直播高光合集</h4>
|
||
<div class="status">
|
||
<span class="pill ok">可发布</span>
|
||
<span style="font-size:12px;color:var(--muted)">1周前</span>
|
||
</div>
|
||
<div style="display:flex;gap:6px;margin-top:8px">
|
||
<button class="btn ghost sm" onclick="event.stopPropagation();downloadProduct(this.closest('.product-card'))" style="flex:1;padding:6px 4px;font-size:12px">📥 下载</button>
|
||
<button class="btn primary sm" onclick="event.stopPropagation();openPublishModal(this.closest('.product-card'))" style="flex:1;padding:6px 4px;font-size:12px">📢 发布</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 任务历史 -->
|
||
<section id="view-history" class="view">
|
||
<div class="app-layout">
|
||
<aside class="sidebar">
|
||
<div class="sidebar-logo">
|
||
<div class="logo" style="width:34px;height:34px;font-size:18px">🦐</div>
|
||
<span>小虾智剪</span>
|
||
</div>
|
||
<nav class="sidebar-nav">
|
||
<div class="sidebar-item" data-view="dashboard">
|
||
<div class="icon">📊</div>
|
||
<span>控制台</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="titles">
|
||
<div class="icon">📝</div>
|
||
<span>标题库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="assets">
|
||
<div class="icon">📦</div>
|
||
<span>素材库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="voices">
|
||
<div class="icon">🎙️</div>
|
||
<span>配音库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="templates">
|
||
<div class="icon">🎨</div>
|
||
<span>模板库</span>
|
||
</div>
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-item" data-view="generate">
|
||
<div class="icon">✨</div>
|
||
<span>一键生成</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="products">
|
||
<div class="icon">🎬</div>
|
||
<span>成片库</span>
|
||
</div>
|
||
<div class="sidebar-item active" data-view="history">
|
||
<div class="icon" style="background:var(--primary);color:#fff">📋</div>
|
||
<span>任务历史</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="duplication">
|
||
<div class="icon">🔍</div>
|
||
<span>查重检测</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="voiceClone">
|
||
<div class="icon">🎤</div>
|
||
<span>我的音色</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="editing-planner">
|
||
<div class="icon">✂️</div>
|
||
<span>剪辑计划</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="accounts">
|
||
<div class="icon">🔑</div>
|
||
<span>账号管理</span>
|
||
</div>
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-item" data-view="subscription-logged">
|
||
<div class="icon">💎</div>
|
||
<span>订阅管理</span>
|
||
</div>
|
||
</nav>
|
||
<div class="sidebar-bottom">
|
||
<div class="sidebar-item" onclick="logout()">
|
||
<div class="icon">🚪</div>
|
||
<span>退出登录</span>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
<div class="main-content">
|
||
<div class="page-head">
|
||
<div>
|
||
<h2>任务历史</h2>
|
||
<p>查看所有视频生成任务的执行记录</p>
|
||
</div>
|
||
</div>
|
||
<div class="tabs">
|
||
<div class="tab active" onclick="filterTasks('all')">全部 (156)</div>
|
||
<div class="tab" onclick="filterTasks('running')">进行中 (3)</div>
|
||
<div class="tab" onclick="filterTasks('done')">已完成 (150)</div>
|
||
<div class="tab" onclick="filterTasks('failed')">失败 (3)</div>
|
||
</div>
|
||
<div class="task-list">
|
||
<div class="task-item">
|
||
<div class="task-info">
|
||
<h4>产品卖点混剪视频</h4>
|
||
<div class="meta">一键生成 · 模板:画中画混剪</div>
|
||
</div>
|
||
<span class="pill ok">已完成</span>
|
||
<div class="task-time">
|
||
<span class="date">今天 14:32</span>
|
||
耗时 28秒
|
||
</div>
|
||
<button class="btn ghost sm">查看</button>
|
||
</div>
|
||
<div class="task-item">
|
||
<div class="task-info">
|
||
<h4>直播切片成片</h4>
|
||
<div class="meta">一键生成 · 模板:人物口播</div>
|
||
</div>
|
||
<span class="pill warn">进行中</span>
|
||
<div class="task-time">
|
||
<span class="date">今天 14:28</span>
|
||
已耗时 2分钟
|
||
</div>
|
||
<button class="btn ghost sm">查看</button>
|
||
</div>
|
||
<div class="task-item">
|
||
<div class="task-info">
|
||
<h4>新品上市宣传片</h4>
|
||
<div class="meta">一键生成 · 模板:品牌宣传</div>
|
||
</div>
|
||
<span class="pill ok">已完成</span>
|
||
<div class="task-time">
|
||
<span class="date">昨天 16:45</span>
|
||
耗时 35秒
|
||
</div>
|
||
<button class="btn ghost sm">查看</button>
|
||
</div>
|
||
<div class="task-item">
|
||
<div class="task-info">
|
||
<h4>产品评测视频</h4>
|
||
<div class="meta">一键生成 · 模板:产品评测</div>
|
||
</div>
|
||
<span class="pill bad">失败</span>
|
||
<div class="task-time">
|
||
<span class="date">昨天 10:30</span>
|
||
失败
|
||
</div>
|
||
<button class="btn ghost sm">重试</button>
|
||
</div>
|
||
<div class="task-item">
|
||
<div class="task-info">
|
||
<h4>技巧教程第一期</h4>
|
||
<div class="meta">一键生成 · 模板:技巧教程</div>
|
||
</div>
|
||
<span class="pill ok">已完成</span>
|
||
<div class="task-time">
|
||
<span class="date">3天前 15:20</span>
|
||
耗时 42秒
|
||
</div>
|
||
<button class="btn ghost sm">查看</button>
|
||
</div>
|
||
<div class="task-item">
|
||
<div class="task-info">
|
||
<h4>直播高光合集</h4>
|
||
<div class="meta">一键生成 · 模板:直播切片</div>
|
||
</div>
|
||
<span class="pill ok">已完成</span>
|
||
<div class="task-time">
|
||
<span class="date">5天前 11:15</span>
|
||
耗时 55秒
|
||
</div>
|
||
<button class="btn ghost sm">查看</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 查重检测 -->
|
||
<section id="view-duplication" class="view">
|
||
<div class="app-layout">
|
||
<aside class="sidebar">
|
||
<div class="sidebar-logo">
|
||
<div class="logo" style="width:34px;height:34px;font-size:18px">🦐</div>
|
||
<span>小虾智剪</span>
|
||
</div>
|
||
<nav class="sidebar-nav">
|
||
<div class="sidebar-item" data-view="dashboard">
|
||
<div class="icon">📊</div>
|
||
<span>控制台</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="titles">
|
||
<div class="icon">📝</div>
|
||
<span>标题库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="assets">
|
||
<div class="icon">📦</div>
|
||
<span>素材库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="voices">
|
||
<div class="icon">🎙️</div>
|
||
<span>配音库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="templates">
|
||
<div class="icon">🎨</div>
|
||
<span>模板库</span>
|
||
</div>
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-item" data-view="generate">
|
||
<div class="icon">✨</div>
|
||
<span>一键生成</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="products">
|
||
<div class="icon">🎬</div>
|
||
<span>成片库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="history">
|
||
<div class="icon">📋</div>
|
||
<span>任务历史</span>
|
||
</div>
|
||
<div class="sidebar-item active" data-view="duplication">
|
||
<div class="icon" style="background:var(--primary);color:#fff">🔍</div>
|
||
<span>查重检测</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="voiceClone">
|
||
<div class="icon">🎤</div>
|
||
<span>我的音色</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="accounts">
|
||
<div class="icon">🔑</div>
|
||
<span>账号管理</span>
|
||
</div>
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-item" data-view="subscription-logged">
|
||
<div class="icon">💎</div>
|
||
<span>订阅管理</span>
|
||
</div>
|
||
</nav>
|
||
<div class="sidebar-bottom">
|
||
<div class="sidebar-item" onclick="logout()">
|
||
<div class="icon">🚪</div>
|
||
<span>退出登录</span>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
<div class="main-content">
|
||
<div class="page-head">
|
||
<div>
|
||
<h2>视频查重检测</h2>
|
||
<p>上传视频文件,检测与现有视频的相似度</p>
|
||
</div>
|
||
</div>
|
||
<div class="duplication-layout">
|
||
<div>
|
||
<div class="upload-zone" onclick="simulateUpload()">
|
||
<div class="icon">📤</div>
|
||
<h3>拖拽上传视频文件</h3>
|
||
<p>或点击选择文件上传</p>
|
||
<div class="formats">支持格式:MP4 / AVI / MOV / MKV,单文件 ≤ 2GB</div>
|
||
</div>
|
||
<div style="margin-top:16px;display:flex;gap:10px">
|
||
<button class="btn primary" style="flex:1" onclick="simulateUpload()">📤 选择文件</button>
|
||
<button class="btn ghost">📷 摄像头录制</button>
|
||
</div>
|
||
</div>
|
||
<div class="result-zone">
|
||
<div class="result-header">
|
||
<h3 style="margin:0">查重结果</h3>
|
||
<span class="pill warn">待检测</span>
|
||
</div>
|
||
<div class="result-score">
|
||
<div class="result-circle low">
|
||
<div class="percent">12%</div>
|
||
<div class="label">相似度</div>
|
||
</div>
|
||
<p style="color:var(--muted);font-size:14px;margin-top:12px">该视频相似度较低,原创性良好</p>
|
||
</div>
|
||
<div class="result-list">
|
||
<h4 style="margin:0 0 12px;font-size:14px">匹配的视频片段</h4>
|
||
<div class="result-item">
|
||
<div class="thumb">▶</div>
|
||
<div class="info">
|
||
<h4>直播切片成片_v1.mp4</h4>
|
||
<p>相似片段:0:08-0:12</p>
|
||
</div>
|
||
<span class="similarity">8%</span>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="thumb" style="background:linear-gradient(135deg,#0ea5e9,#0284c7)">▶</div>
|
||
<div class="info">
|
||
<h4>产品卖点混剪.mp4</h4>
|
||
<p>相似片段:0:22-0:25</p>
|
||
</div>
|
||
<span class="similarity">4%</span>
|
||
</div>
|
||
</div>
|
||
<button class="btn primary" style="width:100%;margin-top:16px">📥 下载检测报告</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
|
||
|
||
<!-- 我的音色库 -->
|
||
<section id="view-voiceClone" class="view">
|
||
<div class="app-layout">
|
||
<aside class="sidebar">
|
||
<div class="sidebar-logo">
|
||
<div class="logo" style="width:34px;height:34px;font-size:18px">🦐</div>
|
||
<span>小虾智剪</span>
|
||
</div>
|
||
<nav class="sidebar-nav">
|
||
<div class="sidebar-item" data-view="dashboard">
|
||
<div class="icon">📊</div>
|
||
<span>控制台</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="titles">
|
||
<div class="icon">📝</div>
|
||
<span>标题库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="assets">
|
||
<div class="icon">📦</div>
|
||
<span>素材库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="voices">
|
||
<div class="icon">🎙️</div>
|
||
<span>配音库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="templates">
|
||
<div class="icon">🎨</div>
|
||
<span>模板库</span>
|
||
</div>
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-item" data-view="generate">
|
||
<div class="icon">✨</div>
|
||
<span>一键生成</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="products">
|
||
<div class="icon">🎬</div>
|
||
<span>成片库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="history">
|
||
<div class="icon">📋</div>
|
||
<span>任务历史</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="duplication">
|
||
<div class="icon">🔍</div>
|
||
<span>查重检测</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="voiceClone">
|
||
<div class="icon" style="background:var(--primary);color:#fff">🎤</div>
|
||
<span>我的音色</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="accounts">
|
||
<div class="icon">🔑</div>
|
||
<span>账号管理</span>
|
||
</div>
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-item" data-view="subscription-logged">
|
||
<div class="icon">💎</div>
|
||
<span>订阅管理</span>
|
||
</div>
|
||
</nav>
|
||
<div class="sidebar-bottom">
|
||
<div class="sidebar-item" onclick="logout()">
|
||
<div class="icon">🚪</div>
|
||
<span>退出登录</span>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
<div class="main-content">
|
||
<div class="page-head">
|
||
<div>
|
||
<h2>🎤 我的音色库</h2>
|
||
<p>克隆和管理你的专属音色,用AI生成个性化配音</p>
|
||
</div>
|
||
<button class="btn primary" onclick="openCloneVoiceModal()">✨ 克隆新音色</button>
|
||
</div>
|
||
|
||
<!-- 音色卡片列表 -->
|
||
<div id="voice-clone-list" style="display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:16px;margin-top:20px">
|
||
<!-- 示例音色卡片 -->
|
||
<div class="voice-clone-card" style="background:#fff;border:1px solid var(--line);border-radius:var(--radius-lg);padding:20px;position:relative">
|
||
<div style="position:absolute;top:16px;right:16px">
|
||
<button class="btn ghost sm" onclick="deleteVoiceClone(this)" style="padding:4px 8px;font-size:11px">🗑️</button>
|
||
<button class="btn ghost sm" onclick="renameVoiceClone(this)" style="padding:4px 8px;font-size:11px">✏️</button>
|
||
</div>
|
||
<div style="display:flex;align-items:center;gap:14px;margin-bottom:14px">
|
||
<div style="width:56px;height:56px;border-radius:50%;background:linear-gradient(135deg,#f59e0b,#d97706);display:grid;place-items:center;color:#fff;font-size:24px">🎤</div>
|
||
<div>
|
||
<h4 style="margin:0 0 4px;font-size:15px;font-weight:600">我的默认音色</h4>
|
||
<span class="pill ok">已就绪</span>
|
||
</div>
|
||
</div>
|
||
<div style="font-size:13px;color:var(--muted);margin-bottom:12px">
|
||
<div style="margin-bottom:4px">🎵 时长:15秒</div>
|
||
<div>📅 创建于:2024年6月15日</div>
|
||
</div>
|
||
<div style="display:flex;align-items:center;gap:10px;padding:10px;background:#f8fafc;border-radius:10px">
|
||
<button class="btn ghost sm" onclick="playVoiceClone(this)" style="flex:1">▶ 试听</button>
|
||
<button class="btn primary sm" onclick="useVoiceClone(this)" style="flex:1">✨ 使用此音色</button>
|
||
</div>
|
||
</div>
|
||
<!-- 更多音色卡片可通过JS动态添加 -->
|
||
</div>
|
||
|
||
<!-- 空状态 -->
|
||
<div id="voice-clone-empty" style="display:none;margin-top:40px;text-align:center;padding:48px">
|
||
<div style="font-size:64px;margin-bottom:16px">🎤</div>
|
||
<h3 style="margin:0 0 8px;font-size:18px">还没有克隆音色</h3>
|
||
<p style="margin:0 0 20px;color:var(--muted)">上传你的声音,AI将克隆你的专属音色</p>
|
||
<button class="btn primary" onclick="openCloneVoiceModal()">✨ 立即克隆</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
|
||
<!-- 订阅管理(登录后版本) -->
|
||
<section id="view-subscription-logged" class="view">
|
||
<div class="app-layout">
|
||
<aside class="sidebar">
|
||
<div class="sidebar-logo">
|
||
<div class="logo" style="width:34px;height:34px;font-size:18px">🦐</div>
|
||
<span>小虾智剪</span>
|
||
</div>
|
||
<nav class="sidebar-nav">
|
||
<div class="sidebar-item" data-view="dashboard">
|
||
<div class="icon">📊</div>
|
||
<span>控制台</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="titles">
|
||
<div class="icon">📝</div>
|
||
<span>标题库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="assets">
|
||
<div class="icon">📦</div>
|
||
<span>素材库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="voices">
|
||
<div class="icon">🎙️</div>
|
||
<span>配音库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="templates">
|
||
<div class="icon">🎨</div>
|
||
<span>模板库</span>
|
||
</div>
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-item" data-view="generate">
|
||
<div class="icon">✨</div>
|
||
<span>一键生成</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="products">
|
||
<div class="icon">🎬</div>
|
||
<span>成片库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="history">
|
||
<div class="icon">📋</div>
|
||
<span>任务历史</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="duplication">
|
||
<div class="icon">🔍</div>
|
||
<span>查重检测</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="voiceClone">
|
||
<div class="icon">🎤</div>
|
||
<span>我的音色</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="accounts">
|
||
<div class="icon">🔑</div>
|
||
<span>账号管理</span>
|
||
</div>
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-item active" data-view="subscription-logged">
|
||
<div class="icon" style="background:var(--primary);color:#fff">💎</div>
|
||
<span>订阅管理</span>
|
||
</div>
|
||
</nav>
|
||
<div class="sidebar-bottom">
|
||
<div class="sidebar-item" onclick="logout()">
|
||
<div class="icon">🚪</div>
|
||
<span>退出登录</span>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
<div class="main-content">
|
||
<div class="page-head">
|
||
<div>
|
||
<h2>订阅管理</h2>
|
||
<p>查看和管理您的订阅套餐</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 当前套餐信息 -->
|
||
<div class="card" style="margin-bottom:24px">
|
||
<div style="display:flex;justify-content:space-between;align-items:center">
|
||
<div>
|
||
<div style="display:flex;align-items:center;gap:12px;margin-bottom:8px">
|
||
<span class="tag">专业版</span>
|
||
<span class="pill ok">已激活</span>
|
||
</div>
|
||
<p style="margin:0;color:var(--muted);font-size:14px">到期时间:2025年6月15日 · 自动续费</p>
|
||
</div>
|
||
<div style="display:flex;gap:10px">
|
||
<button class="btn ghost" onclick="openRenewModal()">续费</button>
|
||
<button class="btn ghost" onclick="openDowngradeModal()">降级</button>
|
||
<button class="btn primary" onclick="openUpgradeModal('旗舰版')">升级</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 套餐卡片 -->
|
||
<div class="pricing-grid">
|
||
<div class="pricing-card">
|
||
<div class="icon" style="background:#f1f5f9;margin:0 auto 14px">🆓</div>
|
||
<h3>免费版</h3>
|
||
<p class="desc">入门体验</p>
|
||
<div class="price">¥0<span>/月</span></div>
|
||
<div class="features">
|
||
<div>✓ 5个视频/月</div>
|
||
<div>✓ 基础剪辑功能</div>
|
||
<div>✓ 标准画质导出</div>
|
||
<div>✗ 无AI高级功能</div>
|
||
</div>
|
||
<button class="btn ghost" onclick="alert('当前已是免费版')">当前版本</button>
|
||
</div>
|
||
<div class="pricing-card">
|
||
<div class="icon" style="background:var(--primary-soft);margin:0 auto 14px">⭐</div>
|
||
<h3>个人进阶版</h3>
|
||
<p class="desc">创作者首选</p>
|
||
<div class="price">¥299<span>/月</span></div>
|
||
<div class="features">
|
||
<div>✓ 50个视频/月</div>
|
||
<div>✓ 高级剪辑功能</div>
|
||
<div>✓ 1080P高清导出</div>
|
||
<div>✓ AI智能剪辑</div>
|
||
</div>
|
||
<button class="btn ghost" onclick="openUpgradeModal('个人进阶版')">升级</button>
|
||
</div>
|
||
<div class="pricing-card popular">
|
||
<div class="popular-tag">推荐</div>
|
||
<div class="icon" style="background:var(--primary);color:#fff;margin:0 auto 14px">💎</div>
|
||
<h3>个人旗舰版</h3>
|
||
<p class="desc">专业创作者</p>
|
||
<div class="price">¥599<span>/月</span></div>
|
||
<div class="features">
|
||
<div>✓ 无限视频生成</div>
|
||
<div>✓ 4K超清导出</div>
|
||
<div>✓ 全AI功能</div>
|
||
<div>✓ 优先处理队列</div>
|
||
</div>
|
||
<button class="btn ghost" onclick="openUpgradeModal('个人旗舰版')">升级</button>
|
||
</div>
|
||
<div class="pricing-card">
|
||
<div class="icon" style="background:#fef3c7;margin:0 auto 14px">🏢</div>
|
||
<h3>企业版</h3>
|
||
<p class="desc">团队协作</p>
|
||
<div class="price">¥1999<span>/月</span></div>
|
||
<div class="features">
|
||
<div>✓ 无限视频生成</div>
|
||
<div>✓ 团队协作空间</div>
|
||
<div>✓ API接口调用</div>
|
||
<div>✓ 专属客服支持</div>
|
||
</div>
|
||
<button class="btn ghost" onclick="openUpgradeModal('企业版')">升级</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 账单记录 -->
|
||
<div class="section">
|
||
<div class="section-title">
|
||
<h3>账单记录</h3>
|
||
</div>
|
||
<div style="background:#fff;border:1px solid var(--line);border-radius:var(--radius-lg);overflow:hidden">
|
||
<table style="width:100%;border-collapse:collapse">
|
||
<thead>
|
||
<tr style="background:#f8fafc">
|
||
<th style="padding:14px 16px;text-align:left;font-size:13px;color:var(--muted)">订单号</th>
|
||
<th style="padding:14px 16px;text-align:left;font-size:13px;color:var(--muted)">套餐</th>
|
||
<th style="padding:14px 16px;text-align:left;font-size:13px;color:var(--muted)">金额</th>
|
||
<th style="padding:14px 16px;text-align:left;font-size:13px;color:var(--muted)">支付方式</th>
|
||
<th style="padding:14px 16px;text-align:left;font-size:13px;color:var(--muted)">时间</th>
|
||
<th style="padding:14px 16px;text-align:left;font-size:13px;color:var(--muted)">状态</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr style="border-top:1px solid var(--line)">
|
||
<td style="padding:14px 16px;font-size:13px;color:var(--muted)">ORD20240615001</td>
|
||
<td style="padding:14px 16px;font-size:13px">专业版(年付)</td>
|
||
<td style="padding:14px 16px;font-size:13px;font-weight:600">¥1,299</td>
|
||
<td style="padding:14px 16px;font-size:13px">支付宝</td>
|
||
<td style="padding:14px 16px;font-size:13px;color:var(--muted)">2024-06-15</td>
|
||
<td style="padding:14px 16px"><span class="pill ok">已支付</span></td>
|
||
</tr>
|
||
<tr style="border-top:1px solid var(--line)">
|
||
<td style="padding:14px 16px;font-size:13px;color:var(--muted)">ORD20240615001</td>
|
||
<td style="padding:14px 16px;font-size:13px">专业版(年付)</td>
|
||
<td style="padding:14px 16px;font-size:13px;font-weight:600">¥1,299</td>
|
||
<td style="padding:14px 16px;font-size:13px">支付宝</td>
|
||
<td style="padding:14px 16px;font-size:13px;color:var(--muted)">2024-06-15</td>
|
||
<td style="padding:14px 16px"><span class="pill ok">已支付</span></td>
|
||
</tr>
|
||
<tr style="border-top:1px solid var(--line)">
|
||
<td style="padding:14px 16px;font-size:13px;color:var(--muted)">ORD20230615001</td>
|
||
<td style="padding:14px 16px;font-size:13px">专业版(年付)</td>
|
||
<td style="padding:14px 16px;font-size:13px;font-weight:600">¥1,199</td>
|
||
<td style="padding:14px 16px;font-size:13px">微信支付</td>
|
||
<td style="padding:14px 16px;font-size:13px;color:var(--muted)">2023-06-15</td>
|
||
<td style="padding:14px 16px"><span class="pill ok">已支付</span></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 账号管理 -->
|
||
<section id="view-accounts" class="view">
|
||
<div class="app-layout">
|
||
<aside class="sidebar">
|
||
<div class="sidebar-logo">
|
||
<div class="logo" style="width:34px;height:34px;font-size:18px">🦐</div>
|
||
<span>小虾智剪</span>
|
||
</div>
|
||
<nav class="sidebar-nav">
|
||
<div class="sidebar-item" data-view="dashboard">
|
||
<div class="icon">📊</div>
|
||
<span>控制台</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="titles">
|
||
<div class="icon">📝</div>
|
||
<span>标题库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="assets">
|
||
<div class="icon">📦</div>
|
||
<span>素材库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="voices">
|
||
<div class="icon">🎙️</div>
|
||
<span>配音库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="templates">
|
||
<div class="icon">🎨</div>
|
||
<span>模板库</span>
|
||
</div>
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-item" data-view="generate">
|
||
<div class="icon">✨</div>
|
||
<span>一键生成</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="products">
|
||
<div class="icon">🎬</div>
|
||
<span>成片库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="history">
|
||
<div class="icon">📋</div>
|
||
<span>任务历史</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="duplication">
|
||
<div class="icon">🔍</div>
|
||
<span>查重检测</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="editing-planner">
|
||
<div class="icon">✂️</div>
|
||
<span>剪辑计划</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="voiceClone">
|
||
<div class="icon">🎤</div>
|
||
<span>我的音色</span>
|
||
</div>
|
||
<div class="sidebar-item active" data-view="accounts">
|
||
<div class="icon" style="background:var(--primary);color:#fff">🔑</div>
|
||
<span>账号管理</span>
|
||
</div>
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-item" data-view="subscription-logged">
|
||
<div class="icon">💎</div>
|
||
<span>订阅管理</span>
|
||
</div>
|
||
</nav>
|
||
<div class="sidebar-bottom">
|
||
<div class="sidebar-item" onclick="logout()">
|
||
<div class="icon">🚪</div>
|
||
<span>退出登录</span>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
<div class="main-content">
|
||
<div class="page-head">
|
||
<div>
|
||
<h2>🔑 账号管理</h2>
|
||
<p>绑定您的社交平台账号,用于视频一键发布到各平台</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<div style="display:grid;grid-template-columns:repeat(2,1fr);gap:20px">
|
||
<!-- 抖音 -->
|
||
<div style="background:#fff;border:1px solid var(--line);border-radius:var(--radius-lg);padding:24px">
|
||
<div style="display:flex;align-items:center;gap:12px;margin-bottom:20px">
|
||
<span style="font-size:28px">📱</span>
|
||
<div>
|
||
<h3 style="margin:0;font-size:18px">抖音</h3>
|
||
<p style="margin:4px 0 0;font-size:13px;color:var(--muted)">Douyin</p>
|
||
</div>
|
||
</div>
|
||
<div id="accounts-douyin-list" style="display:flex;flex-direction:column;gap:10px;margin-bottom:16px">
|
||
<!-- 账号1 -->
|
||
<div style="display:flex;align-items:center;gap:10px;padding:12px;background:#f8fafc;border-radius:12px">
|
||
<div style="width:36px;height:36px;border-radius:50%;background:linear-gradient(135deg,#fe2c55,#25f4ee);display:grid;place-items:center;color:#fff;font-weight:700;font-size:14px">🎬</div>
|
||
<div style="flex:1">
|
||
<div style="font-weight:600;font-size:14px">小虾智剪-官方号</div>
|
||
<span class="pill ok" style="font-size:10px;padding:2px 6px">已连接</span>
|
||
</div>
|
||
<button class="btn ghost sm" onclick="openUnbindModal('douyin', '小虾智剪-官方号')" style="padding:6px 10px;font-size:12px">解绑</button>
|
||
</div>
|
||
<!-- 账号2 -->
|
||
<div style="display:flex;align-items:center;gap:10px;padding:12px;background:#f8fafc;border-radius:12px">
|
||
<div style="width:36px;height:36px;border-radius:50%;background:linear-gradient(135deg,#fe2c55,#25f4ee);display:grid;place-items:center;color:#fff;font-weight:700;font-size:14px">物</div>
|
||
<div style="flex:1">
|
||
<div style="font-weight:600;font-size:14px">小虾智剪-好物推荐</div>
|
||
<span class="pill ok" style="font-size:10px;padding:2px 6px">已连接</span>
|
||
</div>
|
||
<button class="btn ghost sm" onclick="openUnbindModal('douyin', '小虾智剪-好物推荐')" style="padding:6px 10px;font-size:12px">解绑</button>
|
||
</div>
|
||
</div>
|
||
<button class="btn ghost" onclick="openBindAccountModal('douyin')" style="width:100%">+ 绑定新账号</button>
|
||
</div>
|
||
|
||
<!-- 快手 -->
|
||
<div style="background:#fff;border:1px solid var(--line);border-radius:var(--radius-lg);padding:24px">
|
||
<div style="display:flex;align-items:center;gap:12px;margin-bottom:20px">
|
||
<span style="font-size:28px">🎬</span>
|
||
<div>
|
||
<h3 style="margin:0;font-size:18px">快手</h3>
|
||
<p style="margin:4px 0 0;font-size:13px;color:var(--muted)">Kuaishou</p>
|
||
</div>
|
||
</div>
|
||
<div id="accounts-kuaishou-list" style="display:flex;flex-direction:column;gap:10px;margin-bottom:16px">
|
||
<!-- 账号1 -->
|
||
<div style="display:flex;align-items:center;gap:10px;padding:12px;background:#f8fafc;border-radius:12px">
|
||
<div style="width:36px;height:36px;border-radius:50%;background:linear-gradient(135deg,#ff4906,#ffba00);display:grid;place-items:center;color:#fff;font-weight:700;font-size:14px">快</div>
|
||
<div style="flex:1">
|
||
<div style="font-weight:600;font-size:14px">小虾智剪-快手</div>
|
||
<span class="pill ok" style="font-size:10px;padding:2px 6px">已连接</span>
|
||
</div>
|
||
<button class="btn ghost sm" onclick="openUnbindModal('kuaishou', '小虾智剪-快手')" style="padding:6px 10px;font-size:12px">解绑</button>
|
||
</div>
|
||
</div>
|
||
<button class="btn ghost" onclick="openBindAccountModal('kuaishou')" style="width:100%">+ 绑定新账号</button>
|
||
</div>
|
||
|
||
<!-- 小红书 -->
|
||
<div style="background:#fff;border:1px solid var(--line);border-radius:var(--radius-lg);padding:24px">
|
||
<div style="display:flex;align-items:center;gap:12px;margin-bottom:20px">
|
||
<span style="font-size:28px">📕</span>
|
||
<div>
|
||
<h3 style="margin:0;font-size:18px">小红书</h3>
|
||
<p style="margin:4px 0 0;font-size:13px;color:var(--muted)">Xiaohongshu</p>
|
||
</div>
|
||
</div>
|
||
<div id="accounts-xiaohongshu-list" style="display:flex;flex-direction:column;gap:10px;margin-bottom:16px">
|
||
<!-- 账号1 -->
|
||
<div style="display:flex;align-items:center;gap:10px;padding:12px;background:#f8fafc;border-radius:12px">
|
||
<div style="width:36px;height:36px;border-radius:50%;background:linear-gradient(135deg,#ff2442,#ff6b6b);display:grid;place-items:center;color:#fff;font-weight:700;font-size:14px">📕</div>
|
||
<div style="flex:1">
|
||
<div style="font-weight:600;font-size:14px">小虾智剪-种草号</div>
|
||
<span class="pill ok" style="font-size:10px;padding:2px 6px">已连接</span>
|
||
</div>
|
||
<button class="btn ghost sm" onclick="openUnbindModal('xiaohongshu', '小虾智剪-种草号')" style="padding:6px 10px;font-size:12px">解绑</button>
|
||
</div>
|
||
</div>
|
||
<button class="btn ghost" onclick="openBindAccountModal('xiaohongshu')" style="width:100%">+ 绑定新账号</button>
|
||
</div>
|
||
|
||
<!-- 微信视频号 -->
|
||
<div style="background:#fff;border:1px solid var(--line);border-radius:var(--radius-lg);padding:24px">
|
||
<div style="display:flex;align-items:center;gap:12px;margin-bottom:20px">
|
||
<span style="font-size:28px">💬</span>
|
||
<div>
|
||
<h3 style="margin:0;font-size:18px">微信视频号</h3>
|
||
<p style="margin:4px 0 0;font-size:13px;color:var(--muted)">WeChat Channels</p>
|
||
</div>
|
||
</div>
|
||
<div id="accounts-wechat-list" style="display:flex;flex-direction:column;gap:10px;margin-bottom:16px">
|
||
<!-- 空状态 -->
|
||
<div style="padding:20px;text-align:center;color:var(--muted);font-size:14px">
|
||
<div style="font-size:32px;margin-bottom:8px">🔓</div>
|
||
<p style="margin:0">暂未绑定账号</p>
|
||
</div>
|
||
</div>
|
||
<button class="btn ghost" onclick="openBindAccountModal('wechat')" style="width:100%">+ 绑定新账号</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 底部统计 -->
|
||
<div style="margin-top:24px;padding:16px 20px;background:#f8fafc;border-radius:var(--radius-md);display:flex;align-items:center;justify-content:center;gap:8px">
|
||
<span style="font-size:16px">📊</span>
|
||
<span style="font-weight:600">已绑定 <span style="color:var(--primary)">4</span> 个账号 / 支持 <span style="color:var(--primary)">4</span> 个平台</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ==================== 音色克隆模态框 ==================== -->
|
||
<div id="modal-cloneVoice" class="modal-overlay">
|
||
<div class="modal" style="max-width:520px;max-height:90vh;overflow-y:auto;text-align:left">
|
||
<h3 style="margin:0 0 20px;font-size:20px">🎤 克隆新音色</h3>
|
||
|
||
<!-- 音色名称 -->
|
||
<div style="margin-bottom:20px">
|
||
<label style="display:block;margin-bottom:8px;font-weight:600;font-size:14px">音色名称</label>
|
||
<input type="text" id="clone-voice-name" value="我的声音 1" placeholder="输入音色名称" style="width:100%;height:44px;border:1px solid var(--line);border-radius:var(--radius-sm);padding:0 14px;font-size:14px"/>
|
||
</div>
|
||
|
||
<!-- 上传音频区域 -->
|
||
<div style="margin-bottom:20px">
|
||
<label style="display:block;margin-bottom:8px;font-weight:600;font-size:14px">上传音频</label>
|
||
<div id="clone-upload-area" style="border:2px dashed var(--line);border-radius:var(--radius-md);padding:30px;text-align:center;background:#f8fafc;cursor:pointer;transition:all .2s" onclick="document.getElementById('clone-upload-input').click()">
|
||
<div style="font-size:36px;margin-bottom:10px">🎵</div>
|
||
<p style="margin:0;font-size:14px;font-weight:600">拖拽音频文件到此处</p>
|
||
<p style="margin:8px 0 0;font-size:13px;color:var(--muted)">或点击选择文件</p>
|
||
<p style="margin:6px 0 0;font-size:11px;color:var(--muted)">支持 MP3、WAV 格式,建议时长 10秒~3分钟</p>
|
||
<input type="file" id="clone-upload-input" accept=".mp3,.wav" style="display:none" onchange="handleCloneFileUpload(this)"/>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 或分隔符 -->
|
||
<div style="display:flex;align-items:center;gap:16px;margin:20px 0">
|
||
<div style="flex:1;height:1px;background:var(--line)"></div>
|
||
<span style="font-size:13px;color:var(--muted)">或</span>
|
||
<div style="flex:1;height:1px;background:var(--line)"></div>
|
||
</div>
|
||
|
||
<!-- 直接录制 -->
|
||
<div style="margin-bottom:20px">
|
||
<label style="display:block;margin-bottom:8px;font-weight:600;font-size:14px">直接录制</label>
|
||
<div id="clone-record-area" style="border:1px solid var(--line);border-radius:var(--radius-md);padding:24px;text-align:center;background:#fff">
|
||
<div id="clone-record-idle">
|
||
<p style="margin:0 0 12px;font-size:13px;color:var(--muted)">点击按钮开始录制你的声音</p>
|
||
<button id="clone-record-btn" class="btn primary" onclick="startCloneRecording()" style="width:80px;height:80px;border-radius:50%;font-size:32px;padding:0;background:linear-gradient(135deg,#ef4444,#dc2626)">🎙️</button>
|
||
<p style="margin:12px 0 0;font-size:12px;color:var(--muted)">建议录制10秒以上</p>
|
||
</div>
|
||
<div id="clone-record-recording" style="display:none">
|
||
<p style="margin:0 0 12px;font-size:14px;color:var(--red);font-weight:600">🔴 录音中...</p>
|
||
<div style="font-size:36px;font-weight:700;color:var(--red);margin-bottom:12px" id="clone-record-timer">00:00</div>
|
||
<button class="btn" onclick="stopCloneRecording()" style="width:80px;height:80px;border-radius:50%;font-size:32px;padding:0;background:var(--red);color:#fff;border:none">⏹</button>
|
||
</div>
|
||
<div id="clone-record-preview" style="display:none">
|
||
<p style="margin:0 0 12px;font-size:14px;color:var(--green);font-weight:600">✅ 录制完成</p>
|
||
<div style="display:flex;align-items:center;justify-content:center;gap:12px">
|
||
<button class="btn ghost" onclick="reRecordClone()">🔄 重新录制</button>
|
||
<button class="btn primary" onclick="useCloneRecording()">✓ 使用此录音</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 音频预览 -->
|
||
<div id="clone-audio-preview-modal" style="display:none;margin-bottom:20px;padding:16px;background:#f8fafc;border-radius:var(--radius-md)">
|
||
<div style="display:flex;align-items:center;gap:12px;margin-bottom:10px">
|
||
<button class="btn ghost sm" onclick="playClonePreview()">▶ 播放</button>
|
||
<div style="flex:1">
|
||
<div style="height:6px;background:#e2e8f0;border-radius:3px;overflow:hidden">
|
||
<div id="clone-preview-progress" style="height:100%;background:var(--primary);width:0%;transition:width .3s"></div>
|
||
</div>
|
||
</div>
|
||
<span id="clone-preview-duration" style="font-size:12px;color:var(--muted)">00:00 / 00:00</span>
|
||
</div>
|
||
<p id="clone-preview-name" style="margin:0;font-size:12px;color:var(--muted)">已上传音频.mp3</p>
|
||
<button onclick="removeCloneAudio()" style="margin-top:8px;background:none;border:none;color:var(--red);font-size:12px;cursor:pointer">🗑️ 移除</button>
|
||
</div>
|
||
|
||
<!-- 提示 -->
|
||
<div style="padding:12px 16px;background:#fef3c7;border-radius:var(--radius-sm);margin-bottom:20px;font-size:13px;color:#92400e">
|
||
💡 建议上传10秒~3分钟的清晰语音,环境安静、语速均匀效果最佳
|
||
</div>
|
||
|
||
<!-- 克隆进度 -->
|
||
<div id="clone-modal-progress" style="display:none;margin-bottom:20px;text-align:center">
|
||
<div style="font-size:14px;color:var(--muted);margin-bottom:12px">正在克隆音色...</div>
|
||
<div style="height:8px;background:#f1f5f9;border-radius:999px;overflow:hidden;margin-bottom:12px">
|
||
<div id="clone-modal-progress-bar" style="height:100%;background:linear-gradient(90deg,var(--primary),var(--primary-light));width:0%;transition:width .4s"></div>
|
||
</div>
|
||
<p id="clone-modal-progress-text" style="margin:0;font-size:12px;color:var(--primary)">准备就绪</p>
|
||
</div>
|
||
|
||
<!-- 克隆成功 -->
|
||
<div id="clone-modal-success" style="display:none;margin-bottom:20px;text-align:center;padding:20px;background:#dcfce7;border-radius:var(--radius-md)">
|
||
<p style="margin:0;font-size:16px;color:#166534">🎉 音色克隆成功!</p>
|
||
<p style="margin:8px 0 0;font-size:13px;color:#15803d">你的专属音色已保存到音色库</p>
|
||
</div>
|
||
|
||
<!-- 按钮 -->
|
||
<div style="display:flex;gap:12px" id="clone-modal-buttons">
|
||
<button class="btn ghost" onclick="closeModal('modal-cloneVoice')" style="flex:1">取消</button>
|
||
<button id="clone-start-btn" class="btn primary" onclick="startCloneVoiceProcess()" style="flex:1" disabled>🎤 开始克隆</button>
|
||
</div>
|
||
<div style="display:flex;gap:12px" id="clone-modal-done" style="display:none">
|
||
<button class="btn primary" onclick="closeModal('modal-cloneVoice')" style="flex:1">完成</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<!-- 生成进度模态框 -->
|
||
<div id="modalOverlay" class="modal-overlay">
|
||
<div id="generationModal" class="modal">
|
||
<div class="spinner"></div>
|
||
<div class="success-icon">✓</div>
|
||
<h3 id="modalTitle">正在生成视频</h3>
|
||
<p id="modalText">小虾智剪正在按剪辑计划合成成片,生成完成后会自动进入成片库。</p>
|
||
<div class="progress-bar">
|
||
<div id="progressFill" class="fill" style="width:0%"></div>
|
||
</div>
|
||
<div id="modalStep" class="modal-step">正在读取素材...</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<script>
|
||
// ==================== 状态管理 ====================
|
||
let currentView = 'home';
|
||
let isLoggedIn = false;
|
||
let currentStep = 1;
|
||
let currentPlayingVoice = null;
|
||
let playbackTimer = null;
|
||
|
||
// 模板剪辑计划数据
|
||
const templatePlans = {
|
||
'画中画混剪': [
|
||
{ scene: '主讲口播 · 开场钩子', time: '0-8s' },
|
||
{ scene: '产品特写 · B-roll', time: '8-20s' },
|
||
{ scene: '用户反馈 · 结尾', time: '20-30s' }
|
||
],
|
||
'一镜到底': [
|
||
{ scene: '场景建立 · 环境展示', time: '0-10s' },
|
||
{ scene: '核心讲解 · 过程演示', time: '10-30s' },
|
||
{ scene: '总结收尾 · 行动号召', time: '30-45s' }
|
||
],
|
||
'人物口播': [
|
||
{ scene: '人物出场 · 自我介绍', time: '0-10s' },
|
||
{ scene: '知识要点一', time: '10-25s' },
|
||
{ scene: '知识要点二', time: '25-40s' },
|
||
{ scene: '知识要点三', time: '40-55s' },
|
||
{ scene: '总结 · 引导关注', time: '55-60s' }
|
||
],
|
||
'种草推荐': [
|
||
{ scene: '痛点切入 · 引起共鸣', time: '0-5s' },
|
||
{ scene: '产品介绍 · 核心卖点', time: '5-20s' },
|
||
{ scene: '使用体验 · 效果展示', time: '20-35s' },
|
||
{ scene: '限时优惠 · 行动号召', time: '35-45s' }
|
||
],
|
||
'产品评测': [
|
||
{ scene: '开箱亮相 · 第一印象', time: '0-8s' },
|
||
{ scene: '外观设计 · 细节展示', time: '8-20s' },
|
||
{ scene: '功能测试 · 实际体验', time: '20-35s' },
|
||
{ scene: '优缺点总结 · 购买建议', time: '35-45s' }
|
||
],
|
||
'品牌宣传': [
|
||
{ scene: '品牌理念 · 价值观', time: '0-8s' },
|
||
{ scene: '产品特色 · 差异化', time: '8-25s' },
|
||
{ scene: '用户见证 · 社会认可', time: '25-38s' },
|
||
{ scene: '品牌号召 · 情感共鸣', time: '38-45s' }
|
||
]
|
||
};
|
||
|
||
// 更新预览区
|
||
function updatePreview() {
|
||
// 更新标题
|
||
const titleEl = document.querySelector('#step-3 select');
|
||
const title = titleEl ? titleEl.value : '3秒抓住注意力,30秒讲清卖点';
|
||
const captionEl = document.getElementById('preview-caption');
|
||
if (captionEl) captionEl.textContent = title;
|
||
|
||
// 更新剪辑计划时间线
|
||
const timelineEl = document.getElementById('preview-timeline');
|
||
if (!timelineEl) return;
|
||
|
||
// 获取当前选中的模板
|
||
const selectedTemplate = document.querySelector('#step-1 .choice-item.selected h4');
|
||
const templateName = selectedTemplate ? selectedTemplate.textContent : '画中画混剪';
|
||
|
||
// 获取对应的剪辑计划
|
||
const plan = templatePlans[templateName] || templatePlans['画中画混剪'];
|
||
|
||
// 更新时间线HTML
|
||
let timelineHTML = '';
|
||
plan.forEach((item, idx) => {
|
||
timelineHTML += `
|
||
<div class="timeline-item">
|
||
<div class="num">${idx + 1}</div>
|
||
<span>${item.scene}</span>
|
||
<span>${item.time}</span>
|
||
</div>
|
||
`;
|
||
});
|
||
timelineEl.innerHTML = timelineHTML;
|
||
}
|
||
|
||
// ==================== 模态框通用函数 ====================
|
||
function openModal(modalId) {
|
||
document.getElementById(modalId).classList.add('show');
|
||
}
|
||
function closeModal(modalId) {
|
||
document.getElementById(modalId).classList.remove('show');
|
||
}
|
||
function closeAllModals() {
|
||
document.querySelectorAll('.modal-overlay.show').forEach(m => m.classList.remove('show'));
|
||
}
|
||
|
||
// ESC关闭和点击遮罩关闭
|
||
document.addEventListener('keydown', (e) => {
|
||
if (e.key === 'Escape') closeAllModals();
|
||
});
|
||
document.addEventListener('click', (e) => {
|
||
if (e.target.classList.contains('modal-overlay')) {
|
||
e.target.classList.remove('show');
|
||
}
|
||
});
|
||
|
||
// ==================== 显示视图 ====================
|
||
function showView(viewId) {
|
||
document.querySelectorAll('.view').forEach(v => v.classList.remove('active'));
|
||
const targetView = document.getElementById('view-' + viewId);
|
||
if (targetView) {
|
||
targetView.classList.add('active');
|
||
currentView = viewId;
|
||
}
|
||
|
||
// 更新导航高亮
|
||
document.querySelectorAll('.nav-links span, .sidebar-item').forEach(item => {
|
||
item.classList.remove('active');
|
||
});
|
||
|
||
// Handle subscription-logged highlighting for subscription
|
||
const viewForHighlight = viewId === 'subscription-logged' ? 'subscription' : viewId;
|
||
document.querySelectorAll('.nav-links span[data-view="' + viewId + '"], .sidebar-item[data-view="' + viewId + '"], .sidebar-item[data-view="' + viewForHighlight + '"]').forEach(item => {
|
||
item.classList.add('active');
|
||
});
|
||
|
||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||
}
|
||
|
||
// ==================== 登录登出 ====================
|
||
function login() { showView('login'); }
|
||
function doLogin() {
|
||
isLoggedIn = true;
|
||
document.getElementById('authButtons').style.display = 'none';
|
||
document.getElementById('userMenu').style.display = 'flex';
|
||
showView('dashboard');
|
||
}
|
||
function logout() {
|
||
isLoggedIn = false;
|
||
document.getElementById('authButtons').style.display = 'flex';
|
||
document.getElementById('userMenu').style.display = 'none';
|
||
showView('home');
|
||
}
|
||
|
||
// ==================== 标题库交互 ====================
|
||
// 新建标题
|
||
function openNewTitleModal() { openModal('modal-new-title'); }
|
||
function saveNewTitle() {
|
||
const content = document.getElementById('new-title-content').value;
|
||
const category = document.getElementById('new-title-category').value;
|
||
if (content.trim()) {
|
||
alert('标题创建成功!');
|
||
closeModal('modal-new-title');
|
||
document.getElementById('new-title-content').value = '';
|
||
}
|
||
}
|
||
// 批量导入
|
||
function openBatchImportModal() { openModal('modal-batch-import'); }
|
||
function startBatchImport() {
|
||
alert('批量导入已开始,请等待处理完成...');
|
||
closeModal('modal-batch-import');
|
||
}
|
||
// 编辑标题
|
||
function openEditTitleModal(card) {
|
||
const titleContent = card.querySelector('.content').textContent;
|
||
document.getElementById('edit-title-content').value = titleContent;
|
||
openModal('modal-edit-title');
|
||
window.currentEditingTitle = card;
|
||
}
|
||
function saveEditTitle() {
|
||
const newContent = document.getElementById('edit-title-content').value;
|
||
if (newContent.trim() && window.currentEditingTitle) {
|
||
window.currentEditingTitle.querySelector('.content').textContent = newContent;
|
||
closeModal('modal-edit-title');
|
||
alert('标题已更新!');
|
||
}
|
||
}
|
||
// 删除标题
|
||
function openDeleteTitleModal(card) {
|
||
window.currentDeletingTitle = card;
|
||
openModal('modal-delete-title');
|
||
}
|
||
function confirmDeleteTitle() {
|
||
if (window.currentDeletingTitle) {
|
||
window.currentDeletingTitle.style.transform = 'scale(0)';
|
||
window.currentDeletingTitle.style.opacity = '0';
|
||
setTimeout(() => {
|
||
window.currentDeletingTitle.remove();
|
||
closeModal('modal-delete-title');
|
||
}, 300);
|
||
}
|
||
}
|
||
// 收藏切换
|
||
function toggleFavorite(btn) {
|
||
btn.classList.toggle('favorited');
|
||
if (btn.classList.contains('favorited')) {
|
||
btn.textContent = '★';
|
||
} else {
|
||
btn.textContent = '☆';
|
||
}
|
||
}
|
||
|
||
// ==================== 素材库交互 ====================
|
||
// 新建素材库
|
||
function openNewAssetLibModal() { openModal('modal-new-assetlib'); }
|
||
function saveNewAssetLib() {
|
||
const name = document.getElementById('new-assetlib-name').value;
|
||
if (name.trim()) {
|
||
alert('素材库创建成功!');
|
||
closeModal('modal-new-assetlib');
|
||
document.getElementById('new-assetlib-name').value = '';
|
||
document.getElementById('new-assetlib-desc').value = '';
|
||
}
|
||
}
|
||
// 上传素材
|
||
function openUploadModal() { openModal('modal-upload'); }
|
||
// 诊断
|
||
function openDiagnoseModal(card) {
|
||
openModal('modal-diagnose');
|
||
const title = card.querySelector('h4').textContent;
|
||
document.getElementById('diagnose-score').textContent = '0%';
|
||
document.getElementById('diagnose-result').style.display = 'none';
|
||
// 模拟诊断过程
|
||
let progress = 0;
|
||
const interval = setInterval(() => {
|
||
progress += 20;
|
||
document.getElementById('diagnose-score').textContent = progress + '%';
|
||
if (progress >= 100) {
|
||
clearInterval(interval);
|
||
document.getElementById('diagnose-score').textContent = '85%';
|
||
document.getElementById('diagnose-result').style.display = 'block';
|
||
}
|
||
}, 200);
|
||
}
|
||
|
||
// ==================== 配音库交互 ====================
|
||
// AI生成配音
|
||
function openAIGenerateModal() { openModal('modal-ai-generate'); }
|
||
function startAIGenerate() {
|
||
const text = document.getElementById('ai-voice-text').value;
|
||
if (!text.trim()) {
|
||
alert('请输入配音文本');
|
||
return;
|
||
}
|
||
let progress = 0;
|
||
document.getElementById('ai-generate-status').textContent = '生成中...';
|
||
const interval = setInterval(() => {
|
||
progress += 10;
|
||
document.getElementById('ai-generate-progress').style.width = progress + '%';
|
||
if (progress >= 100) {
|
||
clearInterval(interval);
|
||
document.getElementById('ai-generate-status').textContent = '生成完成';
|
||
alert('配音生成成功!');
|
||
closeModal('modal-ai-generate');
|
||
document.getElementById('ai-voice-text').value = '';
|
||
document.getElementById('ai-generate-progress').style.width = '0%';
|
||
}
|
||
}, 300);
|
||
}
|
||
// 新建配音
|
||
function openNewVoiceModal() { openModal('modal-new-voice'); }
|
||
function saveNewVoice() {
|
||
const name = document.getElementById('new-voice-name').value;
|
||
if (name.trim()) {
|
||
alert('配音创建成功!');
|
||
closeModal('modal-new-voice');
|
||
document.getElementById('new-voice-name').value = '';
|
||
}
|
||
}
|
||
// 手动创建配音
|
||
function openManualVoiceModal() { openModal('modal-manual-voice'); }
|
||
function saveManualVoice() {
|
||
const text = document.getElementById('manual-voice-text').value;
|
||
if (text.trim()) {
|
||
alert('配音已提交审核!');
|
||
closeModal('modal-manual-voice');
|
||
document.getElementById('manual-voice-text').value = '';
|
||
}
|
||
}
|
||
|
||
// ==================== 模板库交互 ====================
|
||
// 打开模板编辑器
|
||
function openTemplateEditor() { openModal('modal-template-editor'); }
|
||
function saveTemplate() {
|
||
const name = document.getElementById('template-name').value;
|
||
if (name.trim()) {
|
||
alert('模板保存成功!');
|
||
closeModal('modal-template-editor');
|
||
} else {
|
||
alert('请输入模板名称');
|
||
}
|
||
}
|
||
// 使用模板 - 跳转到剪辑计划编辑器并预选模板
|
||
function useTemplate(card) {
|
||
const title = card.querySelector('h4').textContent;
|
||
// 跳转到剪辑计划编辑器
|
||
showView('editing-planner');
|
||
// 尝试预选模板
|
||
setTimeout(() => {
|
||
const templateItems = document.querySelectorAll('#ep-templates .template-card');
|
||
templateItems.forEach(item => {
|
||
if (item.querySelector('h4')?.textContent === title) {
|
||
item.click();
|
||
}
|
||
});
|
||
}, 100);
|
||
}
|
||
// 选择模板
|
||
function selectTemplate(el) {
|
||
document.querySelectorAll('#modal-select-template .choice-item').forEach(item => item.classList.remove('selected'));
|
||
el.classList.add('selected');
|
||
}
|
||
// 选择素材
|
||
function selectMaterial(el) {
|
||
el.classList.toggle('selected');
|
||
}
|
||
// 确认选择素材
|
||
function confirmSelectMaterial() {
|
||
const selected = document.querySelectorAll('#modal-select-material .choice-item.selected').length;
|
||
if (selected > 0) {
|
||
alert('已选择 ' + selected + ' 个素材');
|
||
}
|
||
closeModal('modal-select-material');
|
||
}
|
||
// 选择标题
|
||
function selectTitle(el) {
|
||
document.querySelectorAll('#modal-select-title .choice-item').forEach(item => item.classList.remove('selected'));
|
||
el.classList.add('selected');
|
||
}
|
||
// 选择配音
|
||
function selectVoice(el) {
|
||
document.querySelectorAll('#modal-select-voice .choice-item').forEach(item => item.classList.remove('selected'));
|
||
el.classList.add('selected');
|
||
}
|
||
|
||
// ==================== 一键生成交互 ====================
|
||
function selectChoice(el) {
|
||
// 单选:先取消所有选中,再选中当前
|
||
el.parentElement.querySelectorAll('.choice-item').forEach(item => item.classList.remove('selected'));
|
||
el.classList.add('selected');
|
||
// 切换模板时更新预览
|
||
updatePreview();
|
||
}
|
||
function prevStep() {
|
||
if (currentStep > 1) {
|
||
currentStep--;
|
||
updateStepUI();
|
||
}
|
||
}
|
||
function nextStep() {
|
||
if (currentStep < 4) {
|
||
currentStep++;
|
||
updateStepUI();
|
||
} else if (currentStep === 4) {
|
||
// 第4步完成后弹出确认生成弹窗
|
||
openConfirmGenerateModal();
|
||
}
|
||
}
|
||
function updateStepUI() {
|
||
document.querySelectorAll('.step-item').forEach(item => {
|
||
const step = parseInt(item.dataset.step);
|
||
item.classList.remove('active', 'done');
|
||
if (step < currentStep) item.classList.add('done');
|
||
if (step === currentStep) item.classList.add('active');
|
||
});
|
||
// 只显示当前步骤的表单区域
|
||
document.querySelectorAll('.form-section').forEach((section, idx) => {
|
||
section.style.display = (idx + 1 === currentStep) ? 'block' : 'none';
|
||
});
|
||
// 更新按钮文字
|
||
const prevBtn = document.querySelector('.generate-form .btn.ghost');
|
||
const nextBtn = document.querySelector('.generate-form .btn.primary:not(.sm)');
|
||
if (prevBtn) prevBtn.style.display = currentStep > 1 ? 'inline-flex' : 'none';
|
||
if (nextBtn) nextBtn.textContent = currentStep === 4 ? '✨ 确认生成' : '下一步 →';
|
||
}
|
||
// 打开确认生成弹窗
|
||
function openConfirmGenerateModal() {
|
||
// 读取当前选择的值
|
||
const templateEl = document.querySelector('#step-1 .choice-item.selected h4');
|
||
const materialEl = document.querySelector('#step-2 select');
|
||
const titleEl = document.querySelector('#step-3 select');
|
||
const voiceEl = document.querySelector('#step-4 select:last-of-type') || document.querySelector('#step-4 select');
|
||
|
||
const templateName = templateEl ? templateEl.textContent : '未选择';
|
||
const materialName = materialEl ? materialEl.value : '未选择';
|
||
const titleName = titleEl ? titleEl.value : '未选择';
|
||
const voiceName = voiceEl ? voiceEl.value : '未选择';
|
||
|
||
// 更新弹窗内容
|
||
document.getElementById('confirm-template').textContent = templateName;
|
||
document.getElementById('confirm-material').textContent = materialName;
|
||
document.getElementById('confirm-title').textContent = titleName;
|
||
document.getElementById('confirm-voice').textContent = voiceName;
|
||
|
||
openModal('modal-confirm-generate');
|
||
}
|
||
// 确认生成
|
||
function confirmGenerate() {
|
||
closeModal('modal-confirm-generate');
|
||
startGeneration();
|
||
}
|
||
function openSelectVoice() { openModal('modal-select-voice'); }
|
||
function startGeneration() {
|
||
openModal('modalOverlay');
|
||
const modal = document.getElementById('generationModal');
|
||
modal.classList.remove('done');
|
||
let progress = 0;
|
||
const steps = ['正在读取素材...', '正在分析内容...', '正在生成剪辑计划...', '正在合成视频...', '即将完成...'];
|
||
const progressFill = document.getElementById('progressFill');
|
||
const modalStep = document.getElementById('modalStep');
|
||
|
||
const interval = setInterval(() => {
|
||
progress += 2;
|
||
progressFill.style.width = progress + '%';
|
||
modalStep.textContent = steps[Math.min(Math.floor(progress / 20), steps.length - 1)];
|
||
|
||
if (progress >= 100) {
|
||
clearInterval(interval);
|
||
modal.classList.add('done');
|
||
document.getElementById('modalTitle').textContent = '生成完成!';
|
||
document.getElementById('modalText').textContent = '视频已保存到成片库,可以开始下载或发布了。';
|
||
modalStep.textContent = '准备就绪';
|
||
setTimeout(() => {
|
||
closeModal('modalOverlay');
|
||
showView('products');
|
||
}, 1500);
|
||
}
|
||
}, 100);
|
||
}
|
||
|
||
// ==================== 成片库交互 ====================
|
||
function downloadProduct(card) {
|
||
const name = card.querySelector('h4').textContent;
|
||
openModal('modal-download');
|
||
document.getElementById('download-product-name').textContent = name + '.mp4';
|
||
let progress = 0;
|
||
const interval = setInterval(() => {
|
||
progress += 15;
|
||
document.getElementById('download-progress-bar').style.width = progress + '%';
|
||
if (progress >= 100) {
|
||
clearInterval(interval);
|
||
setTimeout(() => {
|
||
closeModal('modal-download');
|
||
alert('下载完成!');
|
||
}, 500);
|
||
}
|
||
}, 300);
|
||
}
|
||
// 平台对应的账号数据
|
||
const platformAccounts = {
|
||
douyin: ['小虾智剪-官方号', '小虾智剪-产品号', '小虾智剪-运营号'],
|
||
kuaishou: ['小虾智剪-官方号', '小虾智剪-带货号'],
|
||
xiaohongshu: ['小虾智剪-种草号', '小虾智剪-品牌号'],
|
||
wechat: ['小虾智剪-视频号']
|
||
};
|
||
const platformNames = { douyin:'抖音', kuaishou:'快手', xiaohongshu:'小红书', wechat:'微信视频号' };
|
||
let publishTags = ['产品推荐', '短视频'];
|
||
|
||
// 打开发布弹窗
|
||
function openPublishModal(card) {
|
||
// 保存当前发布的卡片引用
|
||
window.currentPublishCard = card;
|
||
// 重置表单
|
||
const title = card ? card.querySelector('h4')?.textContent || '' : '';
|
||
document.getElementById('publish-title').value = title;
|
||
document.getElementById('publish-desc').value = '';
|
||
document.getElementById('publish-tag-input').value = '';
|
||
publishTags = [];
|
||
renderPublishTags();
|
||
renderRecentTopics();
|
||
// 默认选中抖音,更新账号列表
|
||
updateAccountSelect('douyin');
|
||
openModal('modal-publish');
|
||
}
|
||
|
||
// 选择发布平台
|
||
function selectPublishPlatform(el) {
|
||
document.querySelectorAll('.publish-platform-item').forEach(item => {
|
||
item.style.border = '1px solid var(--line)';
|
||
item.style.background = '';
|
||
item.classList.remove('selected');
|
||
});
|
||
el.style.border = '2px solid var(--primary)';
|
||
el.style.background = 'var(--primary-soft)';
|
||
el.classList.add('selected');
|
||
el.querySelector('input[type="radio"]').checked = true;
|
||
const platform = el.dataset.platform;
|
||
updateAccountSelect(platform);
|
||
}
|
||
|
||
// 更新账号下拉
|
||
function updateAccountSelect(platform) {
|
||
const select = document.getElementById('publish-account');
|
||
const accounts = platformAccounts[platform] || [];
|
||
select.innerHTML = '<option value="">请选择账号</option>';
|
||
accounts.forEach(acc => {
|
||
const opt = document.createElement('option');
|
||
opt.value = acc;
|
||
opt.textContent = acc;
|
||
select.appendChild(opt);
|
||
});
|
||
if (accounts.length > 0) select.value = accounts[0];
|
||
}
|
||
|
||
// 渲染标签
|
||
function renderPublishTags() {
|
||
const container = document.getElementById('publish-tags-container');
|
||
container.innerHTML = publishTags.map(tag =>
|
||
'<span style="display:inline-flex;align-items:center;gap:4px;padding:4px 10px;background:var(--primary-soft);color:var(--primary);border-radius:999px;font-size:12px;font-weight:600">' +
|
||
'#' + tag + ' <span onclick="removePublishTag(\'' + tag + '\')" style="cursor:pointer;margin-left:2px;font-size:14px;color:#94a3b8">×</span></span>'
|
||
).join('');
|
||
}
|
||
|
||
// 添加标签
|
||
function addPublishTag() {
|
||
const input = document.getElementById('publish-tag-input');
|
||
const tag = input.value.trim();
|
||
if (tag && !publishTags.includes(tag)) {
|
||
publishTags.push(tag);
|
||
renderPublishTags();
|
||
renderRecentTopics();
|
||
input.value = '';
|
||
}
|
||
}
|
||
|
||
// 删除标签
|
||
function removePublishTag(tag) {
|
||
publishTags = publishTags.filter(t => t !== tag);
|
||
renderPublishTags();
|
||
renderRecentTopics();
|
||
}
|
||
|
||
// 常用话题(历史使用过的)
|
||
const recentTopics = ['产品推荐', '好物分享', '短视频', '直播切片', '开箱测评', '日常分享', '教程', '干货分享', '种草', '避坑指南', '数码', '科技'];
|
||
|
||
// 渲染常用话题列表
|
||
function renderRecentTopics() {
|
||
const container = document.getElementById('publish-recent-topics');
|
||
container.innerHTML = recentTopics.map(topic => {
|
||
const isSelected = publishTags.includes(topic);
|
||
if (isSelected) {
|
||
return '<span style="padding:4px 10px;background:#f1f5f9;color:#94a3b8;border-radius:999px;font-size:12px;cursor:default;text-decoration:line-through">#' + topic + '</span>';
|
||
}
|
||
return '<span onclick="toggleRecentTopic(\'' + topic + '\')" style="padding:4px 10px;background:#fff;border:1px dashed var(--line);color:var(--text);border-radius:999px;font-size:12px;cursor:pointer;transition:all .15s" onmouseover="this.style.borderColor=\'var(--primary)\';this.style.color=\'var(--primary)\'" onmouseout="this.style.borderColor=\'var(--line)\';this.style.color=\'var(--text)\'">+ #' + topic + '</span>';
|
||
}).join('');
|
||
}
|
||
|
||
// 点击常用话题直接添加
|
||
function toggleRecentTopic(topic) {
|
||
if (!publishTags.includes(topic)) {
|
||
publishTags.push(topic);
|
||
renderPublishTags();
|
||
renderRecentTopics();
|
||
}
|
||
}
|
||
|
||
// 确认发布
|
||
function confirmPublish() {
|
||
const platform = document.querySelector('input[name="platform"]:checked').value;
|
||
const platformName = platformNames[platform] || platform;
|
||
const account = document.getElementById('publish-account').value;
|
||
const title = document.getElementById('publish-title').value || '(使用默认标题)';
|
||
const tags = publishTags.length > 0 ? publishTags.map(t => '#' + t).join(' ') : '(无话题)';
|
||
|
||
if (!account) {
|
||
alert('请选择发布账号');
|
||
return;
|
||
}
|
||
|
||
closeModal('modal-publish');
|
||
|
||
// 显示"正在发布"弹窗
|
||
document.getElementById('publish-progress-text').textContent = '正在发布到' + platformName + '...';
|
||
document.getElementById('publish-progress-bar').style.width = '0%';
|
||
document.getElementById('publish-progress-icon').innerHTML = '<div class="spinner"></div>';
|
||
openModal('modal-publishProgress');
|
||
|
||
// 模拟发布进度
|
||
let progress = 0;
|
||
const progressInterval = setInterval(() => {
|
||
progress += Math.random() * 30 + 15;
|
||
if (progress >= 100) {
|
||
progress = 100;
|
||
clearInterval(progressInterval);
|
||
setTimeout(() => {
|
||
document.getElementById('publish-progress-icon').innerHTML = '<div class="success-icon">✓</div>';
|
||
document.getElementById('publish-progress-text').textContent = '发布成功!';
|
||
// 标记当前视频为已发布
|
||
if (window.currentPublishCard) {
|
||
markProductPublished(window.currentPublishCard.dataset.productId);
|
||
}
|
||
// 2秒后自动关闭
|
||
setTimeout(() => {
|
||
closeModal('modal-publishProgress');
|
||
}, 2000);
|
||
}, 500);
|
||
}
|
||
document.getElementById('publish-progress-bar').style.width = progress + '%';
|
||
}, 400);
|
||
}
|
||
|
||
// ==================== 账号管理 ====================
|
||
// 已绑定账号数据
|
||
const boundAccounts = {
|
||
douyin: ['小虾智剪-官方号', '小虾智剪-好物推荐'],
|
||
kuaishou: ['小虾智剪-快手'],
|
||
xiaohongshu: ['小虾智剪-种草号'],
|
||
wechat: []
|
||
};
|
||
|
||
// 当前解绑的账号信息
|
||
let currentUnbindInfo = { platform: '', account: '' };
|
||
|
||
// 打开绑定账号弹窗
|
||
function openBindAccountModal(platform) {
|
||
document.getElementById('bind-platform').value = platform || 'douyin';
|
||
openModal('modal-bindAccount');
|
||
}
|
||
|
||
// 确认绑定账号
|
||
function confirmBindAccount() {
|
||
const platform = document.getElementById('bind-platform').value;
|
||
const platformName = platformNames[platform] || platform;
|
||
closeModal('modal-bindAccount');
|
||
alert('✅ 授权成功!\n\n已成功绑定' + platformName + '账号。\n您现在可以通过小虾智剪发布视频到该平台。');
|
||
// 实际应用中这里应该刷新账号列表
|
||
}
|
||
|
||
// 打开解绑确认弹窗
|
||
function openUnbindModal(platform, account) {
|
||
currentUnbindInfo = { platform, account };
|
||
document.getElementById('unbind-account-name').textContent = account;
|
||
openModal('modal-unbindAccount');
|
||
}
|
||
|
||
// 确认解绑
|
||
function confirmUnbind() {
|
||
const { platform, account } = currentUnbindInfo;
|
||
const platformName = platformNames[platform] || platform;
|
||
|
||
// 从数据中移除
|
||
const idx = boundAccounts[platform].indexOf(account);
|
||
if (idx > -1) {
|
||
boundAccounts[platform].splice(idx, 1);
|
||
}
|
||
|
||
closeModal('modal-unbindAccount');
|
||
alert('✅ 解绑成功!\n\n已解除绑定:' + platformName + ' - ' + account);
|
||
|
||
// 刷新账号列表(简单模拟)
|
||
refreshAccountList(platform);
|
||
}
|
||
|
||
// 刷新账号列表(模拟)
|
||
function refreshAccountList(platform) {
|
||
const listId = 'accounts-' + platform + '-list';
|
||
const container = document.getElementById(listId);
|
||
if (!container) return;
|
||
|
||
const accounts = boundAccounts[platform] || [];
|
||
if (accounts.length === 0) {
|
||
container.innerHTML = '<div style="padding:20px;text-align:center;color:var(--muted);font-size:14px"><div style="font-size:32px;margin-bottom:8px">🔓</div><p style="margin:0">暂未绑定账号</p></div>';
|
||
} else {
|
||
const colors = {
|
||
douyin: 'linear-gradient(135deg,#fe2c55,#25f4ee)',
|
||
kuaishou: 'linear-gradient(135deg,#ff4906,#ffba00)',
|
||
xiaohongshu: 'linear-gradient(135deg,#ff2442,#ff6b6b)',
|
||
wechat: 'linear-gradient(135deg,#07c160,#4ade80)'
|
||
};
|
||
const icons = { douyin: '🎬', kuaishou: '快', xiaohongshu: '📕', wechat: '💬' };
|
||
|
||
container.innerHTML = accounts.map(acc => {
|
||
const icon = icons[platform] || '📱';
|
||
const color = colors[platform] || '#6366f1';
|
||
return '<div style="display:flex;align-items:center;gap:10px;padding:12px;background:#f8fafc;border-radius:12px">' +
|
||
'<div style="width:36px;height:36px;border-radius:50%;background:' + color + ';display:grid;place-items:center;color:#fff;font-weight:700;font-size:14px">' + icon + '</div>' +
|
||
'<div style="flex:1"><div style="font-weight:600;font-size:14px">' + acc + '</div><span class="pill ok" style="font-size:10px;padding:2px 6px">已连接</span></div>' +
|
||
'<button class="btn ghost sm" onclick="openUnbindModal(\'' + platform + '\', \'' + acc + '\')" style="padding:6px 10px;font-size:12px">解绑</button></div>';
|
||
}).join('');
|
||
}
|
||
|
||
// 更新底部统计
|
||
updateAccountsStats();
|
||
}
|
||
|
||
// 更新账号统计
|
||
function updateAccountsStats() {
|
||
let totalAccounts = 0;
|
||
Object.values(boundAccounts).forEach(accs => totalAccounts += accs.length);
|
||
// 找到统计元素并更新
|
||
const statsEl = document.querySelector('#view-accounts .section:last-child .page-head + .section span[style*="color:var(--primary)"]');
|
||
if (statsEl) {
|
||
statsEl.textContent = totalAccounts;
|
||
}
|
||
}
|
||
|
||
// ==================== 已发布视频管理 ====================
|
||
// 标记视频为已发布状态
|
||
function markProductPublished(productId) {
|
||
const card = document.querySelector('.product-card[data-product-id="' + productId + '"]');
|
||
if (!card) return;
|
||
|
||
card.dataset.published = 'true';
|
||
card.style.opacity = '0.65';
|
||
|
||
// 禁用checkbox
|
||
const cb = card.querySelector('input[type="checkbox"]');
|
||
if (cb) {
|
||
cb.checked = false;
|
||
cb.disabled = true;
|
||
cb.style.opacity = '0.4';
|
||
}
|
||
card.classList.remove('selected');
|
||
selectedProducts.delete(productId);
|
||
|
||
// 替换发布按钮为"已发布"标签
|
||
const publishBtn = card.querySelector('button[onclick*="openPublishModal"]');
|
||
if (publishBtn) {
|
||
const badge = document.createElement('span');
|
||
badge.className = 'pill ok';
|
||
badge.textContent = '✅ 已发布';
|
||
badge.style.cssText = 'flex:1;padding:6px 4px;font-size:12px;text-align:center;display:inline-block';
|
||
publishBtn.replaceWith(badge);
|
||
}
|
||
|
||
// 添加"已发布"角标
|
||
if (!card.querySelector('.published-badge')) {
|
||
const badge = document.createElement('div');
|
||
badge.className = 'published-badge';
|
||
badge.textContent = '已发布';
|
||
badge.style.cssText = 'position:absolute;top:12px;right:12px;background:var(--green);color:#fff;font-size:11px;font-weight:700;padding:3px 8px;border-radius:6px;z-index:10';
|
||
card.appendChild(badge);
|
||
}
|
||
|
||
// 把卡片移到最后(排序到最下面)
|
||
const parent = card.parentNode;
|
||
parent.appendChild(card);
|
||
|
||
updateBatchPublishUI();
|
||
}
|
||
|
||
// ==================== 批量发布 ====================
|
||
// 选中的视频
|
||
let selectedProducts = new Set();
|
||
// 批量发布的话题标签
|
||
let batchPublishTags = [];
|
||
|
||
// 切换视频选中状态
|
||
function toggleProductSelect(card) {
|
||
const productId = card.dataset.productId;
|
||
const checkbox = card.querySelector('input[type="checkbox"]');
|
||
|
||
if (checkbox.checked) {
|
||
selectedProducts.add(productId);
|
||
card.classList.add('selected');
|
||
} else {
|
||
selectedProducts.delete(productId);
|
||
card.classList.remove('selected');
|
||
}
|
||
|
||
updateBatchPublishUI();
|
||
}
|
||
|
||
// 全选/取消全选
|
||
function toggleSelectAllProducts() {
|
||
const selectAllCheckbox = document.getElementById('select-all-products');
|
||
const allCards = document.querySelectorAll('.product-card');
|
||
|
||
if (selectAllCheckbox.checked) {
|
||
allCards.forEach(card => {
|
||
// 跳过已发布的视频
|
||
if (card.dataset.published === 'true') return;
|
||
const cb = card.querySelector('input[type="checkbox"]');
|
||
if (cb && !cb.disabled) {
|
||
selectedProducts.add(card.dataset.productId);
|
||
card.classList.add('selected');
|
||
cb.checked = true;
|
||
}
|
||
});
|
||
} else {
|
||
selectedProducts.clear();
|
||
allCards.forEach(card => {
|
||
card.classList.remove('selected');
|
||
const cb = card.querySelector('input[type="checkbox"]');
|
||
if (cb && !cb.disabled) cb.checked = false;
|
||
});
|
||
}
|
||
|
||
updateBatchPublishUI();
|
||
}
|
||
|
||
// 更新批量发布UI状态
|
||
function updateBatchPublishUI() {
|
||
const count = selectedProducts.size;
|
||
const countEl = document.querySelector('#selected-count span');
|
||
const batchBtn = document.getElementById('batch-publish-btn');
|
||
const selectAll = document.getElementById('select-all-products');
|
||
|
||
if (countEl) countEl.textContent = count;
|
||
|
||
if (batchBtn) {
|
||
if (count > 0) {
|
||
batchBtn.disabled = false;
|
||
batchBtn.style.opacity = '1';
|
||
batchBtn.style.cursor = 'pointer';
|
||
} else {
|
||
batchBtn.disabled = true;
|
||
batchBtn.style.opacity = '0.5';
|
||
batchBtn.style.cursor = 'not-allowed';
|
||
}
|
||
}
|
||
|
||
// 更新全选框状态
|
||
const allCards = document.querySelectorAll('.product-card');
|
||
if (selectAll && allCards.length > 0) {
|
||
selectAll.checked = count === allCards.length;
|
||
selectAll.indeterminate = count > 0 && count < allCards.length;
|
||
}
|
||
}
|
||
|
||
// 打开批量发布弹窗
|
||
function openBatchPublishModal() {
|
||
if (selectedProducts.size === 0) {
|
||
alert('请先选择要发布的视频');
|
||
return;
|
||
}
|
||
|
||
// 获取选中的视频信息
|
||
const selectedCards = [];
|
||
selectedProducts.forEach(id => {
|
||
const card = document.querySelector('.product-card[data-product-id="' + id + '"]');
|
||
if (card) {
|
||
selectedCards.push({
|
||
id: id,
|
||
name: card.dataset.productName || card.querySelector('h4')?.textContent || '未命名视频'
|
||
});
|
||
}
|
||
});
|
||
|
||
// 渲染视频列表
|
||
const videoList = document.getElementById('batch-video-list');
|
||
videoList.innerHTML = selectedCards.map((video, idx) =>
|
||
'<div style="display:flex;align-items:center;gap:12px;padding:12px;background:#f8fafc;border-radius:12px">' +
|
||
'<div style="flex:1;min-width:0"><div style="font-weight:600;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">' + video.name + '</div></div>' +
|
||
'<select id="batch-platform-' + idx + '" onchange="updateBatchAccountSelect(' + idx + ', this.value)" style="height:36px;border:1px solid var(--line);border-radius:var(--radius-sm);padding:0 10px;font-size:13px;min-width:100px">' +
|
||
'<option value="">选择平台</option>' +
|
||
'<option value="douyin">📱 抖音</option>' +
|
||
'<option value="kuaishou">🎬 快手</option>' +
|
||
'<option value="xiaohongshu">📕 小红书</option>' +
|
||
'<option value="wechat">💬 视频号</option>' +
|
||
'</select>' +
|
||
'<select id="batch-account-' + idx + '" onchange="refreshAllBatchAccounts()" style="height:36px;border:1px solid var(--line);border-radius:var(--radius-sm);padding:0 10px;font-size:13px;min-width:120px">' +
|
||
'<option value="">先选平台</option>' +
|
||
'</select>' +
|
||
'</div>'
|
||
).join('');
|
||
|
||
// 重置批量标签
|
||
batchPublishTags = [];
|
||
renderBatchPublishTags();
|
||
renderBatchRecentTopics();
|
||
|
||
// 更新统计
|
||
updateBatchPublishStats();
|
||
|
||
openModal('modal-batchPublish');
|
||
}
|
||
|
||
// 批量发布中平台→账号联动
|
||
function getBatchSelectedAccounts() {
|
||
const selected = new Set();
|
||
document.querySelectorAll('[id^="batch-account-"]').forEach(sel => {
|
||
if (sel.value) selected.add(sel.value);
|
||
});
|
||
return selected;
|
||
}
|
||
|
||
function refreshAllBatchAccounts() {
|
||
document.querySelectorAll('[id^="batch-platform-"]').forEach((platformSel, idx) => {
|
||
if (platformSel.value) {
|
||
updateBatchAccountSelect(idx, platformSel.value);
|
||
}
|
||
});
|
||
}
|
||
|
||
function updateBatchAccountSelect(videoIndex, platform) {
|
||
const accountSelect = document.getElementById('batch-account-' + videoIndex);
|
||
if (!accountSelect) return;
|
||
|
||
if (!platform) {
|
||
accountSelect.innerHTML = '<option value="">先选平台</option>';
|
||
return;
|
||
}
|
||
|
||
const accounts = boundAccounts[platform] || [];
|
||
const alreadySelected = getBatchSelectedAccounts();
|
||
const currentAccount = accountSelect.value; // 保留当前选中
|
||
|
||
if (accounts.length === 0) {
|
||
accountSelect.innerHTML = '<option value="">暂无可用账号</option>';
|
||
} else {
|
||
const available = accounts.filter(acc => !alreadySelected.has(acc) || acc === currentAccount);
|
||
if (available.length === 0) {
|
||
accountSelect.innerHTML = '<option value="">所有账号已被分配</option>';
|
||
} else {
|
||
accountSelect.innerHTML = '<option value="">选择账号</option>' +
|
||
available.map(acc => '<option value="' + acc + '"' + (acc === currentAccount ? ' selected' : '') + '>' + acc + '</option>').join('');
|
||
}
|
||
}
|
||
|
||
// 刷新所有其他视频的账号下拉(因为当前选择变了)
|
||
document.querySelectorAll('[id^="batch-platform-"]').forEach((platformSel, idx) => {
|
||
if (idx !== videoIndex && platformSel.value) {
|
||
const otherAccountSel = document.getElementById('batch-account-' + idx);
|
||
if (otherAccountSel) {
|
||
const otherAccounts = boundAccounts[platformSel.value] || [];
|
||
const selected2 = getBatchSelectedAccounts();
|
||
const currentVal = otherAccountSel.value;
|
||
const avail = otherAccounts.filter(acc => !selected2.has(acc) || acc === currentVal);
|
||
otherAccountSel.innerHTML = '<option value="">选择账号</option>' +
|
||
avail.map(acc => '<option value="' + acc + '"' + (acc === currentVal ? ' selected' : '') + '>' + acc + '</option>').join('');
|
||
}
|
||
}
|
||
});
|
||
|
||
updateBatchPublishStats();
|
||
}
|
||
|
||
// 渲染批量发布标签
|
||
function renderBatchPublishTags() {
|
||
const container = document.getElementById('batch-tags-container');
|
||
container.innerHTML = batchPublishTags.map(tag =>
|
||
'<span style="display:inline-flex;align-items:center;gap:4px;padding:4px 10px;background:var(--primary-soft);color:var(--primary);border-radius:999px;font-size:12px;font-weight:600">' +
|
||
'#' + tag + ' <span onclick="removeBatchTag(\'' + tag + '\')" style="cursor:pointer;margin-left:2px;font-size:14px;color:#94a3b8">×</span></span>'
|
||
).join('');
|
||
}
|
||
|
||
// 添加批量发布标签
|
||
function addBatchTag() {
|
||
const input = document.getElementById('batch-tag-input');
|
||
const tag = input.value.trim();
|
||
if (tag && !batchPublishTags.includes(tag)) {
|
||
batchPublishTags.push(tag);
|
||
renderBatchPublishTags();
|
||
renderBatchRecentTopics();
|
||
input.value = '';
|
||
}
|
||
}
|
||
|
||
// 删除批量发布标签
|
||
function removeBatchTag(tag) {
|
||
batchPublishTags = batchPublishTags.filter(t => t !== tag);
|
||
renderBatchPublishTags();
|
||
renderBatchRecentTopics();
|
||
}
|
||
|
||
// 渲染批量发布常用话题
|
||
function renderBatchRecentTopics() {
|
||
const container = document.getElementById('batch-recent-topics');
|
||
container.innerHTML = recentTopics.map(topic => {
|
||
const isSelected = batchPublishTags.includes(topic);
|
||
if (isSelected) {
|
||
return '<span style="padding:4px 10px;background:#f1f5f9;color:#94a3b8;border-radius:999px;font-size:12px;cursor:default;text-decoration:line-through">#' + topic + '</span>';
|
||
}
|
||
return '<span onclick="addBatchTopic(\'' + topic + '\')" style="padding:4px 10px;background:#fff;border:1px dashed var(--line);color:var(--text);border-radius:999px;font-size:12px;cursor:pointer">+ #' + topic + '</span>';
|
||
}).join('');
|
||
}
|
||
|
||
// 添加批量话题
|
||
function addBatchTopic(topic) {
|
||
if (!batchPublishTags.includes(topic)) {
|
||
batchPublishTags.push(topic);
|
||
renderBatchPublishTags();
|
||
renderBatchRecentTopics();
|
||
}
|
||
}
|
||
|
||
// 更新批量发布统计
|
||
function updateBatchPublishStats() {
|
||
const videoCount = selectedProducts.size;
|
||
const platformSet = new Set();
|
||
|
||
// 统计已选平台数
|
||
document.querySelectorAll('[id^="batch-platform-"]').forEach(sel => {
|
||
if (sel.value) platformSet.add(sel.value);
|
||
});
|
||
|
||
document.getElementById('batch-video-count').textContent = videoCount;
|
||
document.getElementById('batch-platform-count').textContent = platformSet.size;
|
||
}
|
||
|
||
// 确认批量发布
|
||
function confirmBatchPublish() {
|
||
// 收集发布信息(保持原有逻辑)
|
||
const videoCount = selectedProducts.size;
|
||
const videos = [];
|
||
let validCount = 0;
|
||
|
||
document.querySelectorAll('[id^="batch-platform-"]').forEach((platformSel, idx) => {
|
||
const accountSel = document.getElementById('batch-account-' + idx);
|
||
const productId = Array.from(selectedProducts)[idx];
|
||
const card = document.querySelector('.product-card[data-product-id="' + productId + '"]');
|
||
const videoName = card ? (card.dataset.productName || card.querySelector('h4')?.textContent) : '视频' + (idx + 1);
|
||
|
||
videos.push({
|
||
productId: productId,
|
||
name: videoName,
|
||
platform: platformSel.value,
|
||
account: accountSel ? accountSel.value : ''
|
||
});
|
||
|
||
if (platformSel.value && accountSel && accountSel.value) {
|
||
validCount++;
|
||
}
|
||
});
|
||
|
||
if (validCount === 0) {
|
||
alert('请至少选择一个平台和账号');
|
||
return;
|
||
}
|
||
|
||
closeModal('modal-batchPublish');
|
||
|
||
// 显示"正在发布"弹窗
|
||
document.getElementById('publish-progress-text').textContent = '正在发布 ' + validCount + ' 个视频...';
|
||
document.getElementById('publish-progress-bar').style.width = '0%';
|
||
document.getElementById('publish-progress-icon').innerHTML = '<div class="spinner"></div>';
|
||
openModal('modal-publishProgress');
|
||
|
||
// 模拟发布进度
|
||
let progress = 0;
|
||
const progressInterval = setInterval(() => {
|
||
progress += Math.random() * 25 + 10;
|
||
if (progress >= 100) {
|
||
progress = 100;
|
||
clearInterval(progressInterval);
|
||
|
||
// 发布完成
|
||
setTimeout(() => {
|
||
document.getElementById('publish-progress-icon').innerHTML = '<div class="success-icon">✓</div>';
|
||
document.getElementById('publish-progress-text').textContent = '发布成功!';
|
||
|
||
// 标记已发布的视频
|
||
videos.forEach(v => {
|
||
if (v.platform && v.account) {
|
||
markProductPublished(v.productId);
|
||
}
|
||
});
|
||
|
||
// 2秒后自动关闭进度弹窗
|
||
setTimeout(() => {
|
||
closeModal('modal-publishProgress');
|
||
}, 2000);
|
||
}, 500);
|
||
}
|
||
document.getElementById('publish-progress-bar').style.width = progress + '%';
|
||
}, 400);
|
||
|
||
// 清除选中状态
|
||
selectedProducts.clear();
|
||
document.querySelectorAll('.product-card').forEach(card => {
|
||
card.classList.remove('selected');
|
||
const cb = card.querySelector('input[type="checkbox"]');
|
||
if (cb) cb.checked = false;
|
||
});
|
||
updateBatchPublishUI();
|
||
}
|
||
|
||
// ==================== 任务历史交互 ====================
|
||
function filterTasks(filter) {
|
||
document.querySelectorAll('.tab').forEach(tab => tab.classList.remove('active'));
|
||
event.target.classList.add('active');
|
||
}
|
||
|
||
// ==================== 查重检测交互 ====================
|
||
function simulateUpload() {
|
||
alert('模拟上传功能:请在真实环境中选择视频文件');
|
||
}
|
||
|
||
// ==================== 订阅管理交互 ====================
|
||
function openUpgradeModal(planName) {
|
||
document.getElementById('upgrade-plan-name').textContent = planName;
|
||
openModal('modal-upgrade');
|
||
}
|
||
function confirmUpgrade() {
|
||
alert('升级成功!');
|
||
closeModal('modal-upgrade');
|
||
}
|
||
function openDowngradeModal() { openModal('modal-downgrade'); }
|
||
function confirmDowngrade() {
|
||
alert('降级申请已提交,将在当前周期结束后生效');
|
||
closeModal('modal-downgrade');
|
||
}
|
||
function openRenewModal() { openModal('modal-renew'); }
|
||
function confirmRenew() {
|
||
alert('正在跳转到支付页面...');
|
||
closeModal('modal-renew');
|
||
}
|
||
|
||
// 侧边栏导航点击
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
document.querySelectorAll('.sidebar-item[data-view], .nav-links span[data-view]').forEach(item => {
|
||
item.addEventListener('click', function() {
|
||
const viewId = this.dataset.view;
|
||
if (viewId) showView(viewId);
|
||
});
|
||
});
|
||
|
||
// 一键生成步骤初始化 - 只显示第1步
|
||
updateStepUI();
|
||
|
||
// 初始化预览区
|
||
updatePreview();
|
||
});
|
||
</script>
|
||
|
||
<!-- ==================== 标题库模态框 ==================== -->
|
||
<!-- 新建标题模态框 -->
|
||
<div id="modal-new-title" class="modal-overlay">
|
||
<div class="modal" style="max-width:520px">
|
||
<h3 style="margin:0 0 20px;font-size:20px">📝 新建标题</h3>
|
||
<div class="form-field">
|
||
<label>标题内容</label>
|
||
<textarea id="new-title-content" style="width:100%;height:100px;border:1px solid var(--line);border-radius:var(--radius-sm);padding:12px;font-size:14px;resize:none" placeholder="输入标题内容..."></textarea>
|
||
</div>
|
||
<div class="form-field" style="margin-top:16px">
|
||
<label>选择分类</label>
|
||
<select id="new-title-category" style="width:100%;height:44px;border:1px solid var(--line);border-radius:var(--radius-sm);padding:0 14px;font-size:14px">
|
||
<option>口播开场</option>
|
||
<option>产品介绍</option>
|
||
<option>教程类</option>
|
||
<option>种草推荐</option>
|
||
<option>直播引流</option>
|
||
</select>
|
||
</div>
|
||
<div style="display:flex;gap:12px;margin-top:24px">
|
||
<button class="btn ghost" onclick="closeModal('modal-new-title')" style="flex:1">取消</button>
|
||
<button class="btn primary" onclick="saveNewTitle()" style="flex:1">保存</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 批量导入模态框 -->
|
||
<div id="modal-batch-import" class="modal-overlay">
|
||
<div class="modal" style="max-width:560px">
|
||
<h3 style="margin:0 0 20px;font-size:20px">📥 批量导入标题</h3>
|
||
<div style="border:2px dashed var(--line);border-radius:var(--radius-md);padding:40px;text-align:center;background:#f8fafc;cursor:pointer;margin-bottom:16px">
|
||
<div style="font-size:40px;margin-bottom:12px">📁</div>
|
||
<p style="margin:0;color:var(--muted)">拖拽文件到此处,或点击选择文件</p>
|
||
<p style="margin:8px 0 0;color:var(--muted);font-size:12px">支持格式:TXT、CSV、Excel</p>
|
||
</div>
|
||
<div style="background:#f8fafc;border-radius:var(--radius-sm);padding:14px;font-size:13px;color:var(--muted)">
|
||
<p style="margin:0 0 8px">📋 导入说明:</p>
|
||
<ul style="margin:0;padding-left:18px">
|
||
<li>每行一个标题</li>
|
||
<li>CSV/Excel首行需包含"标题"列</li>
|
||
<li>单次最多导入500条</li>
|
||
</ul>
|
||
</div>
|
||
<div style="display:flex;gap:12px;margin-top:24px">
|
||
<button class="btn ghost" onclick="closeModal('modal-batch-import')" style="flex:1">取消</button>
|
||
<button class="btn primary" onclick="startBatchImport()" style="flex:1">开始导入</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 编辑标题模态框 -->
|
||
<div id="modal-edit-title" class="modal-overlay">
|
||
<div class="modal" style="max-width:520px">
|
||
<h3 style="margin:0 0 20px;font-size:20px">✏️ 编辑标题</h3>
|
||
<div class="form-field">
|
||
<label>标题内容</label>
|
||
<textarea id="edit-title-content" style="width:100%;height:100px;border:1px solid var(--line);border-radius:var(--radius-sm);padding:12px;font-size:14px;resize:none"></textarea>
|
||
</div>
|
||
<div style="display:flex;gap:12px;margin-top:24px">
|
||
<button class="btn ghost" onclick="closeModal('modal-edit-title')" style="flex:1">取消</button>
|
||
<button class="btn primary" onclick="saveEditTitle()" style="flex:1">保存</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 删除确认模态框 -->
|
||
<div id="modal-delete-title" class="modal-overlay">
|
||
<div class="modal" style="max-width:400px;text-align:center">
|
||
<div style="width:60px;height:60px;border-radius:50%;background:#fee2e2;margin:0 auto 16px;display:grid;place-items:center;font-size:28px">⚠️</div>
|
||
<h3 style="margin:0 0 8px;font-size:18px">确认删除</h3>
|
||
<p style="margin:0;color:var(--muted)">确定要删除这个标题吗?此操作无法撤销。</p>
|
||
<div style="display:flex;gap:12px;margin-top:24px">
|
||
<button class="btn ghost" onclick="closeModal('modal-delete-title')" style="flex:1">取消</button>
|
||
<button class="btn" onclick="confirmDeleteTitle()" style="flex:1;background:#ef4444;color:#fff">删除</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ==================== 素材库模态框 ==================== -->
|
||
<!-- 新建素材库模态框 -->
|
||
<div id="modal-new-assetlib" class="modal-overlay">
|
||
<div class="modal" style="max-width:480px">
|
||
<h3 style="margin:0 0 20px;font-size:20px">📦 新建素材库</h3>
|
||
<div class="form-field">
|
||
<label>素材库名称</label>
|
||
<input id="new-assetlib-name" type="text" placeholder="输入素材库名称" style="width:100%;height:44px;border:1px solid var(--line);border-radius:var(--radius-sm);padding:0 14px;font-size:14px"/>
|
||
</div>
|
||
<div class="form-field" style="margin-top:16px">
|
||
<label>描述(可选)</label>
|
||
<textarea id="new-assetlib-desc" style="width:100%;height:80px;border:1px solid var(--line);border-radius:var(--radius-sm);padding:12px;font-size:14px;resize:none" placeholder="简短描述素材库用途..."></textarea>
|
||
</div>
|
||
<div style="display:flex;gap:12px;margin-top:24px">
|
||
<button class="btn ghost" onclick="closeModal('modal-new-assetlib')" style="flex:1">取消</button>
|
||
<button class="btn primary" onclick="saveNewAssetLib()" style="flex:1">创建</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 上传素材模态框 -->
|
||
<div id="modal-upload" class="modal-overlay">
|
||
<div class="modal" style="max-width:500px">
|
||
<h3 style="margin:0 0 20px;font-size:20px">📤 上传素材</h3>
|
||
<div style="border:2px dashed var(--line);border-radius:var(--radius-md);padding:40px;text-align:center;background:linear-gradient(180deg,#fff,#f8fafc);cursor:pointer;margin-bottom:16px">
|
||
<div style="font-size:48px;margin-bottom:12px">🖼️</div>
|
||
<p style="margin:0;font-weight:600">拖拽文件到此处上传</p>
|
||
<p style="margin:8px 0 0;color:var(--muted)">或点击选择文件</p>
|
||
<p style="margin:8px 0 0;color:var(--muted);font-size:12px">支持:MP4、MOV、AVI、MKV、图片、音频</p>
|
||
</div>
|
||
<div style="margin-bottom:12px">
|
||
<div style="display:flex;justify-content:space-between;font-size:13px;margin-bottom:6px">
|
||
<span>上传进度</span>
|
||
<span id="upload-status">准备上传...</span>
|
||
</div>
|
||
<div style="height:8px;background:#f1f5f9;border-radius:999px;overflow:hidden">
|
||
<div id="upload-progress" style="height:100%;background:linear-gradient(90deg,var(--primary),var(--primary-light));width:0%;transition:width .3s"></div>
|
||
</div>
|
||
</div>
|
||
<div style="display:flex;gap:12px">
|
||
<button class="btn ghost" onclick="closeModal('modal-upload')" style="flex:1">取消</button>
|
||
<button class="btn primary" style="flex:1">开始上传</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 素材详情模态框 -->
|
||
<div id="modal-asset-detail" class="modal-overlay">
|
||
<div class="modal" style="max-width:600px">
|
||
<h3 style="margin:0 0 16px;font-size:20px">📦 素材详情</h3>
|
||
<div style="display:grid;grid-template-columns:200px 1fr;gap:20px">
|
||
<div style="aspect-ratio:9/16;background:linear-gradient(135deg,#0ea5e9,#0284c7);border-radius:var(--radius-md);display:grid;place-items:center;color:#fff;font-size:40px">▶</div>
|
||
<div>
|
||
<h4 id="detail-asset-title" style="margin:0 0 12px;font-size:16px">主播口播开场.mp4</h4>
|
||
<div id="detail-asset-meta" style="font-size:13px;color:var(--muted)"></div>
|
||
<div style="margin-top:16px;padding:12px;background:#f8fafc;border-radius:var(--radius-sm)">
|
||
<div style="display:flex;justify-content:space-between;margin-bottom:8px">
|
||
<span style="color:var(--muted)">文件大小</span>
|
||
<span>12.5 MB</span>
|
||
</div>
|
||
<div style="display:flex;justify-content:space-between;margin-bottom:8px">
|
||
<span style="color:var(--muted)">分辨率</span>
|
||
<span>1920 × 1080</span>
|
||
</div>
|
||
<div style="display:flex;justify-content:space-between;margin-bottom:8px">
|
||
<span style="color:var(--muted)">时长</span>
|
||
<span>00:32</span>
|
||
</div>
|
||
<div style="display:flex;justify-content:space-between">
|
||
<span style="color:var(--muted)">AI分类</span>
|
||
<span>口播开场</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div style="display:flex;gap:12px;margin-top:24px">
|
||
<button class="btn ghost" onclick="closeModal('modal-asset-detail')" style="flex:1">关闭</button>
|
||
<button class="btn primary" onclick="closeModal('modal-asset-detail')" style="flex:1">下载素材</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 诊断结果模态框 -->
|
||
<div id="modal-diagnose" class="modal-overlay">
|
||
<div class="modal" style="max-width:500px">
|
||
<h3 style="margin:0 0 20px;font-size:20px">🔍 素材诊断</h3>
|
||
<div style="text-align:center;padding:20px 0">
|
||
<p style="margin:0 0 12px;color:var(--muted)">正在分析素材质量...</p>
|
||
<div style="font-size:48px;font-weight:800;color:var(--primary)" id="diagnose-score">0%</div>
|
||
</div>
|
||
<div id="diagnose-result" style="display:none;padding:20px;background:#f8fafc;border-radius:var(--radius-md)">
|
||
<h4 style="margin:0 0 12px;font-size:15px">诊断结果</h4>
|
||
<div style="display:flex;align-items:center;gap:12px;margin-bottom:12px">
|
||
<span style="width:36px;height:36px;border-radius:50%;background:#dcfce7;color:#166534;display:grid;place-items:center">✓</span>
|
||
<span>画质清晰度:良好</span>
|
||
</div>
|
||
<div style="display:flex;align-items:center;gap:12px;margin-bottom:12px">
|
||
<span style="width:36px;height:36px;border-radius:50%;background:#fef3c7;color:#92400e;display:grid;place-items:center">!</span>
|
||
<span>建议:适当裁剪边缘区域</span>
|
||
</div>
|
||
<div style="display:flex;align-items:center;gap:12px">
|
||
<span style="width:36px;height:36px;border-radius:50%;background:#dcfce7;color:#166534;display:grid;place-items:center">✓</span>
|
||
<span>音频质量:正常</span>
|
||
</div>
|
||
</div>
|
||
<div style="display:flex;gap:12px;margin-top:24px">
|
||
<button class="btn ghost" onclick="closeModal('modal-diagnose')" style="flex:1">关闭</button>
|
||
<button class="btn primary" onclick="closeModal('modal-diagnose')" style="flex:1">查看详情</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ==================== 配音库模态框 ==================== -->
|
||
<!-- AI生成配音模态框 -->
|
||
<div id="modal-ai-generate" class="modal-overlay">
|
||
<div class="modal" style="max-width:560px">
|
||
<h3 style="margin:0 0 20px;font-size:20px">🎙️ AI生成配音</h3>
|
||
<div class="form-field">
|
||
<label>配音文本</label>
|
||
<textarea id="ai-voice-text" style="width:100%;height:120px;border:1px solid var(--line);border-radius:var(--radius-sm);padding:12px;font-size:14px;resize:none" placeholder="输入需要转换的文本..."></textarea>
|
||
</div>
|
||
<div class="form-row" style="display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:16px">
|
||
<div class="form-field">
|
||
<label>选择音色</label>
|
||
<select id="ai-voice-select" style="width:100%;height:44px;border:1px solid var(--line);border-radius:var(--radius-sm);padding:0 14px;font-size:14px">
|
||
<option>温柔女声</option>
|
||
<option>专业男声</option>
|
||
<option>活力女声</option>
|
||
<option>磁性男声</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-field">
|
||
<label>语速调节</label>
|
||
<select style="width:100%;height:44px;border:1px solid var(--line);border-radius:var(--radius-sm);padding:0 14px;font-size:14px">
|
||
<option>0.75x(慢速)</option>
|
||
<option>1.0x(正常)</option>
|
||
<option>1.25x(快速)</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div style="margin-top:16px">
|
||
<div style="display:flex;justify-content:space-between;font-size:13px;margin-bottom:6px">
|
||
<span>生成进度</span>
|
||
<span id="ai-generate-status">准备就绪</span>
|
||
</div>
|
||
<div style="height:8px;background:#f1f5f9;border-radius:999px;overflow:hidden">
|
||
<div id="ai-generate-progress" style="height:100%;background:linear-gradient(90deg,var(--primary),var(--primary-light));width:0%;transition:width .3s"></div>
|
||
</div>
|
||
</div>
|
||
<div style="display:flex;gap:12px;margin-top:24px">
|
||
<button class="btn ghost" onclick="closeModal('modal-ai-generate')" style="flex:1">取消</button>
|
||
<button class="btn primary" onclick="startAIGenerate()" style="flex:1">开始生成</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 新建配音模态框 -->
|
||
<div id="modal-new-voice" class="modal-overlay">
|
||
<div class="modal" style="max-width:480px">
|
||
<h3 style="margin:0 0 20px;font-size:20px">🎵 新建配音</h3>
|
||
<div class="form-field">
|
||
<label>配音名称</label>
|
||
<input id="new-voice-name" type="text" placeholder="输入配音名称" style="width:100%;height:44px;border:1px solid var(--line);border-radius:var(--radius-sm);padding:0 14px;font-size:14px"/>
|
||
</div>
|
||
<div class="form-field" style="margin-top:16px">
|
||
<label>上传音频文件</label>
|
||
<div style="border:2px dashed var(--line);border-radius:var(--radius-sm);padding:30px;text-align:center;background:#f8fafc;cursor:pointer">
|
||
<p style="margin:0;color:var(--muted)">点击选择音频文件</p>
|
||
<p style="margin:8px 0 0;color:var(--muted);font-size:12px">支持:MP3、WAV、M4A</p>
|
||
</div>
|
||
</div>
|
||
<div style="display:flex;gap:12px;margin-top:24px">
|
||
<button class="btn ghost" onclick="closeModal('modal-new-voice')" style="flex:1">取消</button>
|
||
<button class="btn primary" onclick="saveNewVoice()" style="flex:1">创建</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 手动创建配音模态框 -->
|
||
<div id="modal-manual-voice" class="modal-overlay">
|
||
<div class="modal" style="max-width:560px">
|
||
<h3 style="margin:0 0 20px;font-size:20px">✍️ 手动创建配音</h3>
|
||
<div class="form-field">
|
||
<label>配音文本</label>
|
||
<textarea id="manual-voice-text" style="width:100%;height:150px;border:1px solid var(--line);border-radius:var(--radius-sm);padding:12px;font-size:14px;resize:none" placeholder="输入配音文本内容..."></textarea>
|
||
</div>
|
||
<div style="background:#f8fafc;border-radius:var(--radius-sm);padding:14px;margin-top:16px;font-size:13px;color:var(--muted)">
|
||
<p style="margin:0">💡 提示:手动创建的配音会进入审核队列,审核通过后即可使用。</p>
|
||
</div>
|
||
<div style="display:flex;gap:12px;margin-top:24px">
|
||
<button class="btn ghost" onclick="closeModal('modal-manual-voice')" style="flex:1">取消</button>
|
||
<button class="btn primary" onclick="saveManualVoice()" style="flex:1">提交审核</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 配音播放模态框 -->
|
||
<div id="modal-voice-play" class="modal-overlay">
|
||
<div class="modal" style="max-width:400px;text-align:center">
|
||
<h3 style="margin:0 0 20px;font-size:20px">🎧 正在播放</h3>
|
||
<p id="playing-voice-name" style="font-weight:600;margin:0 0 16px">温柔女声 - 轻松种草</p>
|
||
<div style="width:80px;height:80px;border-radius:50%;background:var(--primary-soft);margin:0 auto 20px;display:grid;place-items:center;font-size:36px;color:var(--primary)">🎙️</div>
|
||
<div style="margin-bottom:8px">
|
||
<span id="voice-play-time" style="font-size:14px;color:var(--muted)">00:00 / 00:28</span>
|
||
</div>
|
||
<div style="height:6px;background:#f1f5f9;border-radius:999px;overflow:hidden;margin-bottom:20px">
|
||
<div id="voice-play-progress" style="height:100%;background:var(--primary);width:0%;transition:width .5s"></div>
|
||
</div>
|
||
<button class="btn ghost" onclick="closeModal('modal-voice-play')" style="width:100%">关闭</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ==================== 模板库模态框 ==================== -->
|
||
<!-- 模板编辑器模态框 -->
|
||
<div id="modal-template-editor" class="modal-overlay" style="padding:40px">
|
||
<div class="modal" style="max-width:1000px;max-height:90vh;overflow-y:auto">
|
||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:20px">
|
||
<h3 style="margin:0;font-size:20px">🎨 模板编辑器</h3>
|
||
<button onclick="closeModal('modal-template-editor')" style="background:none;border:none;font-size:24px;cursor:pointer">×</button>
|
||
</div>
|
||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:24px">
|
||
<!-- 左侧:参数配置 -->
|
||
<div>
|
||
<div class="form-field">
|
||
<label>模板名称</label>
|
||
<input id="template-name" type="text" placeholder="输入模板名称" style="width:100%;height:44px;border:1px solid var(--line);border-radius:var(--radius-sm);padding:0 14px;font-size:14px"/>
|
||
</div>
|
||
<div class="form-field" style="margin-top:16px">
|
||
<label>剪辑模式</label>
|
||
<select style="width:100%;height:44px;border:1px solid var(--line);border-radius:var(--radius-sm);padding:0 14px;font-size:14px">
|
||
<option>一镜到底</option>
|
||
<option>画中画</option>
|
||
<option>口播</option>
|
||
<option>口播+画中画</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-field" style="margin-top:16px">
|
||
<label>片段数量</label>
|
||
<div style="display:flex;align-items:center;gap:12px">
|
||
<input type="range" min="1" max="10" value="3" style="flex:1"/>
|
||
<span style="font-weight:600;min-width:30px;text-align:center">3</span>
|
||
</div>
|
||
</div>
|
||
<div class="form-field" style="margin-top:16px">
|
||
<label>字幕样式</label>
|
||
<select style="width:100%;height:44px;border:1px solid var(--line);border-radius:var(--radius-sm);padding:0 14px;font-size:14px">
|
||
<option>底部居中白字</option>
|
||
<option>顶部居中白字</option>
|
||
<option>底部描边字</option>
|
||
<option>动感字幕</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-field" style="margin-top:16px">
|
||
<label>背景音乐</label>
|
||
<select style="width:100%;height:44px;border:1px solid var(--line);border-radius:var(--radius-sm);padding:0 14px;font-size:14px">
|
||
<option>不使用</option>
|
||
<option>轻快背景音乐</option>
|
||
<option>激情背景音乐</option>
|
||
<option>舒缓背景音乐</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<!-- 右侧:预览 -->
|
||
<div>
|
||
<div style="background:#1a1a2e;border-radius:var(--radius-md);padding:16px;text-align:center">
|
||
<p style="color:#fff;margin:0 0 12px;font-size:14px">模板预览</p>
|
||
<div style="aspect-ratio:9/16;max-height:300px;margin:0 auto;border-radius:var(--radius-sm);background:linear-gradient(180deg,#2d2d44,#1a1a2e);display:grid;place-items:center;color:#fff;font-size:48px">
|
||
🎬
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div style="display:flex;gap:12px;margin-top:24px">
|
||
<button class="btn ghost" onclick="closeModal('modal-template-editor')" style="flex:1">取消</button>
|
||
<button class="btn primary" onclick="saveTemplate()" style="flex:1">保存模板</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 模板详情模态框 -->
|
||
<div id="modal-template-detail" class="modal-overlay">
|
||
<div class="modal" style="max-width:600px">
|
||
<h3 style="margin:0 0 16px;font-size:20px">🎨 模板详情</h3>
|
||
<div style="aspect-ratio:16/9;background:linear-gradient(135deg,#fbbf24,#f59e0b);border-radius:var(--radius-md);display:grid;place-items:center;color:#fff;font-size:60px;margin-bottom:16px">PIP</div>
|
||
<h4 id="detail-template-title" style="margin:0 0 12px;font-size:16px">画中画混剪</h4>
|
||
<div id="detail-template-meta" style="font-size:13px;color:var(--muted);margin-bottom:16px"></div>
|
||
<div style="padding:16px;background:#f8fafc;border-radius:var(--radius-md)">
|
||
<h5 style="margin:0 0 12px;font-size:14px">参数配置</h5>
|
||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;font-size:13px">
|
||
<div><span style="color:var(--muted)">剪辑模式:</span>画中画</div>
|
||
<div><span style="color:var(--muted)">片段数量:</span>5个</div>
|
||
<div><span style="color:var(--muted)">字幕样式:</span>底部居中</div>
|
||
<div><span style="color:var(--muted)">背景音乐:</span>轻快BGM</div>
|
||
<div><span style="color:var(--muted)">使用次数:</span>56次</div>
|
||
<div><span style="color:var(--muted)">创建时间:</span>2024-01-15</div>
|
||
</div>
|
||
</div>
|
||
<div style="display:flex;gap:12px;margin-top:24px">
|
||
<button class="btn ghost" onclick="closeModal('modal-template-detail')" style="flex:1">关闭</button>
|
||
<button class="btn primary" onclick="closeModal('modal-template-detail');showView('generate')" style="flex:1">使用此模板</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ==================== 一键生成选择弹窗 ==================== -->
|
||
<!-- 选择模板弹窗 -->
|
||
<div id="modal-select-template" class="modal-overlay">
|
||
<div class="modal" style="max-width:700px">
|
||
<h3 style="margin:0 0 20px;font-size:20px">🎨 选择模板</h3>
|
||
<div class="choice-list" style="display:grid;grid-template-columns:repeat(3,1fr);gap:12px">
|
||
<div class="choice-item" onclick="selectTemplate(this)">
|
||
<div class="thumb" style="background:linear-gradient(135deg,#fbbf24,#f59e0b)">PIP</div>
|
||
<h4>画中画混剪</h4>
|
||
<p>产品展示</p>
|
||
<div class="check-icon">✓</div>
|
||
</div>
|
||
<div class="choice-item" onclick="selectTemplate(this)">
|
||
<div class="thumb" style="background:linear-gradient(135deg,#3b82f6,#1d4ed8)">ONE</div>
|
||
<h4>一镜到底</h4>
|
||
<p>口播</p>
|
||
<div class="check-icon">✓</div>
|
||
</div>
|
||
<div class="choice-item" onclick="selectTemplate(this)">
|
||
<div class="thumb" style="background:linear-gradient(135deg,#6366f1,#4f46e5)">PER</div>
|
||
<h4>人物口播</h4>
|
||
<p>口播</p>
|
||
<div class="check-icon">✓</div>
|
||
</div>
|
||
<div class="choice-item" onclick="selectTemplate(this)">
|
||
<div class="thumb" style="background:linear-gradient(135deg,#10b981,#059669)">SUP</div>
|
||
<h4>种草推荐</h4>
|
||
<p>种草</p>
|
||
<div class="check-icon">✓</div>
|
||
</div>
|
||
<div class="choice-item" onclick="selectTemplate(this)">
|
||
<div class="thumb" style="background:linear-gradient(135deg,#ec4899,#db2777)">REV</div>
|
||
<h4>产品评测</h4>
|
||
<p>产品</p>
|
||
<div class="check-icon">✓</div>
|
||
</div>
|
||
<div class="choice-item" onclick="selectTemplate(this)">
|
||
<div class="thumb" style="background:linear-gradient(135deg,#8b5cf6,#7c3aed)">BRD</div>
|
||
<h4>品牌宣传</h4>
|
||
<p>品牌</p>
|
||
<div class="check-icon">✓</div>
|
||
</div>
|
||
</div>
|
||
<div style="display:flex;gap:12px;margin-top:24px">
|
||
<button class="btn ghost" onclick="closeModal('modal-select-template')" style="flex:1">取消</button>
|
||
<button class="btn primary" onclick="closeModal('modal-select-template')" style="flex:1">确认选择</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 选择素材弹窗 -->
|
||
<div id="modal-select-material" class="modal-overlay">
|
||
<div class="modal" style="max-width:800px">
|
||
<h3 style="margin:0 0 20px;font-size:20px">📦 选择素材</h3>
|
||
<div class="asset-grid" style="display:grid;grid-template-columns:repeat(4,1fr);gap:12px">
|
||
<div class="choice-item" onclick="selectMaterial(this)">
|
||
<div class="thumb" style="height:60px;background:linear-gradient(135deg,#0ea5e9,#0284c7);border-radius:8px">▶</div>
|
||
<h4 style="font-size:12px;margin:8px 0 0">主播口播开场</h4>
|
||
<div class="check-icon">✓</div>
|
||
</div>
|
||
<div class="choice-item" onclick="selectMaterial(this)">
|
||
<div class="thumb" style="height:60px;background:linear-gradient(135deg,#f59e0b,#d97706);border-radius:8px">▶</div>
|
||
<h4 style="font-size:12px;margin:8px 0 0">产品特写镜头</h4>
|
||
<div class="check-icon">✓</div>
|
||
</div>
|
||
<div class="choice-item" onclick="selectMaterial(this)">
|
||
<div class="thumb" style="height:60px;background:linear-gradient(135deg,#10b981,#059669);border-radius:8px">▶</div>
|
||
<h4 style="font-size:12px;margin:8px 0 0">用户评价片段</h4>
|
||
<div class="check-icon">✓</div>
|
||
</div>
|
||
<div class="choice-item" onclick="selectMaterial(this)">
|
||
<div class="thumb" style="height:60px;background:linear-gradient(135deg,#6366f1,#4f46e5);border-radius:8px">▶</div>
|
||
<h4 style="font-size:12px;margin:8px 0 0">开箱展示</h4>
|
||
<div class="check-icon">✓</div>
|
||
</div>
|
||
<div class="choice-item" onclick="selectMaterial(this)">
|
||
<div class="thumb" style="height:60px;background:linear-gradient(135deg,#ec4899,#db2777);border-radius:8px">▶</div>
|
||
<h4 style="font-size:12px;margin:8px 0 0">使用场景演示</h4>
|
||
<div class="check-icon">✓</div>
|
||
</div>
|
||
<div class="choice-item" onclick="selectMaterial(this)">
|
||
<div class="thumb" style="height:60px;background:linear-gradient(135deg,#14b8a6,#0d9488);border-radius:8px">▶</div>
|
||
<h4 style="font-size:12px;margin:8px 0 0">直播高光时刻</h4>
|
||
<div class="check-icon">✓</div>
|
||
</div>
|
||
</div>
|
||
<div style="display:flex;gap:12px;margin-top:24px">
|
||
<button class="btn ghost" onclick="closeModal('modal-select-material')" style="flex:1">取消</button>
|
||
<button class="btn primary" onclick="confirmSelectMaterial()" style="flex:1">确认选择</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 选择标题弹窗 -->
|
||
<div id="modal-select-title" class="modal-overlay">
|
||
<div class="modal" style="max-width:600px">
|
||
<h3 style="margin:0 0 20px;font-size:20px">📝 选择标题</h3>
|
||
<div style="display:flex;flex-direction:column;gap:10px">
|
||
<div class="choice-item" onclick="selectTitle(this)" style="padding:14px">
|
||
<h4 style="margin:0;font-size:14px">3秒抓住注意力,30秒讲清卖点</h4>
|
||
<div class="check-icon">✓</div>
|
||
</div>
|
||
<div class="choice-item" onclick="selectTitle(this)" style="padding:14px">
|
||
<h4 style="margin:0;font-size:14px">新手也能看懂的自动剪辑教程</h4>
|
||
<div class="check-icon">✓</div>
|
||
</div>
|
||
<div class="choice-item" onclick="selectTitle(this)" style="padding:14px">
|
||
<h4 style="margin:0;font-size:14px">这款产品让效率提升10倍的秘密</h4>
|
||
<div class="check-icon">✓</div>
|
||
</div>
|
||
<div class="choice-item" onclick="selectTitle(this)" style="padding:14px">
|
||
<h4 style="margin:0;font-size:14px">产品功能详解,看这一期就够了</h4>
|
||
<div class="check-icon">✓</div>
|
||
</div>
|
||
<div class="choice-item" onclick="selectTitle(this)" style="padding:14px">
|
||
<h4 style="margin:0;font-size:14px">如何使用小虾智剪快速生成视频</h4>
|
||
<div class="check-icon">✓</div>
|
||
</div>
|
||
</div>
|
||
<div style="display:flex;gap:12px;margin-top:24px">
|
||
<button class="btn ghost" onclick="closeModal('modal-select-title')" style="flex:1">取消</button>
|
||
<button class="btn primary" onclick="closeModal('modal-select-title')" style="flex:1">确认选择</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 选择配音弹窗 -->
|
||
<div id="modal-select-voice" class="modal-overlay">
|
||
<div class="modal" style="max-width:600px">
|
||
<h3 style="margin:0 0 20px;font-size:20px">🎙️ 选择配音</h3>
|
||
<div style="display:flex;flex-direction:column;gap:10px">
|
||
<div class="choice-item" onclick="selectVoice(this)" style="padding:14px;display:flex;align-items:center;gap:12px">
|
||
<div style="width:40px;height:40px;border-radius:50%;background:linear-gradient(135deg,#ec4899,#db2777);display:grid;place-items:center;color:#fff;font-size:18px">🎙️</div>
|
||
<div>
|
||
<h4 style="margin:0;font-size:14px">温柔女声 - 轻松种草</h4>
|
||
<p style="margin:4px 0 0;font-size:12px;color:var(--muted)">短视频带货配音</p>
|
||
</div>
|
||
<div class="check-icon">✓</div>
|
||
</div>
|
||
<div class="choice-item" onclick="selectVoice(this)" style="padding:14px;display:flex;align-items:center;gap:12px">
|
||
<div style="width:40px;height:40px;border-radius:50%;background:linear-gradient(135deg,#6366f1,#4f46e5);display:grid;place-items:center;color:#fff;font-size:18px">🎙️</div>
|
||
<div>
|
||
<h4 style="margin:0;font-size:14px">专业男声 - 产品介绍</h4>
|
||
<p style="margin:4px 0 0;font-size:12px;color:var(--muted)">品牌宣传配音</p>
|
||
</div>
|
||
<div class="check-icon">✓</div>
|
||
</div>
|
||
<div class="choice-item" onclick="selectVoice(this)" style="padding:14px;display:flex;align-items:center;gap:12px">
|
||
<div style="width:40px;height:40px;border-radius:50%;background:linear-gradient(135deg,#0ea5e9,#0284c7);display:grid;place-items:center;color:#fff;font-size:18px">🎙️</div>
|
||
<div>
|
||
<h4 style="margin:0;font-size:14px">活力女声 - 直播预告</h4>
|
||
<p style="margin:4px 0 0;font-size:12px;color:var(--muted)">短视频带货配音</p>
|
||
</div>
|
||
<div class="check-icon">✓</div>
|
||
</div>
|
||
<div class="choice-item" onclick="selectVoice(this)" style="padding:14px;display:flex;align-items:center;gap:12px">
|
||
<div style="width:40px;height:40px;border-radius:50%;background:linear-gradient(135deg,#10b981,#059669);display:grid;place-items:center;color:#fff;font-size:18px">🎙️</div>
|
||
<div>
|
||
<h4 style="margin:0;font-size:14px">知性女声 - 知识讲解</h4>
|
||
<p style="margin:4px 0 0;font-size:12px;color:var(--muted)">知识分享配音</p>
|
||
</div>
|
||
<div class="check-icon">✓</div>
|
||
</div>
|
||
</div>
|
||
<div style="display:flex;gap:12px;margin-top:24px">
|
||
<button class="btn ghost" onclick="closeModal('modal-select-voice')" style="flex:1">取消</button>
|
||
<button class="btn primary" onclick="closeModal('modal-select-voice')" style="flex:1">确认选择</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 确认生成弹窗 -->
|
||
<div id="modal-confirm-generate" class="modal-overlay">
|
||
<div class="modal" style="max-width:480px">
|
||
<h3 style="margin:0 0 20px;font-size:20px;text-align:center">✨ 确认生成视频</h3>
|
||
<div style="background:#f8fafc;border-radius:16px;padding:20px;margin-bottom:20px">
|
||
<div style="display:flex;justify-content:space-between;align-items:center;padding:10px 0;border-bottom:1px solid #e2e8f0">
|
||
<span style="color:var(--muted);font-size:14px">模板</span>
|
||
<span id="confirm-template" style="font-weight:600;font-size:14px;color:var(--slate)">画中画混剪</span>
|
||
</div>
|
||
<div style="display:flex;justify-content:space-between;align-items:center;padding:10px 0;border-bottom:1px solid #e2e8f0">
|
||
<span style="color:var(--muted);font-size:14px">素材</span>
|
||
<span id="confirm-material" style="font-weight:600;font-size:14px;color:var(--slate)">直播切片素材库</span>
|
||
</div>
|
||
<div style="display:flex;justify-content:space-between;align-items:center;padding:10px 0;border-bottom:1px solid #e2e8f0">
|
||
<span style="color:var(--muted);font-size:14px">标题</span>
|
||
<span id="confirm-title" style="font-weight:600;font-size:14px;color:var(--slate);max-width:220px;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">3秒抓住注意力,30秒讲清卖点</span>
|
||
</div>
|
||
<div style="display:flex;justify-content:space-between;align-items:center;padding:10px 0">
|
||
<span style="color:var(--muted);font-size:14px">配音</span>
|
||
<span id="confirm-voice" style="font-weight:600;font-size:14px;color:var(--slate)">温柔女声 - 轻松种草</span>
|
||
</div>
|
||
</div>
|
||
<div style="display:flex;gap:12px">
|
||
<button class="btn ghost" onclick="closeModal('modal-confirm-generate')" style="flex:1">取消</button>
|
||
<button class="btn primary" onclick="confirmGenerate()" style="flex:1">确认生成</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ==================== 成片库模态框 ==================== -->
|
||
<!-- 成片预览模态框 -->
|
||
<div id="modal-product-preview" class="modal-overlay">
|
||
<div class="modal" style="max-width:700px">
|
||
<h3 style="margin:0 0 16px;font-size:20px">🎬 视频预览</h3>
|
||
<div style="aspect-ratio:9/16;max-height:400px;margin:0 auto;border-radius:var(--radius-md);background:linear-gradient(135deg,#0ea5e9,#0284c7);display:grid;place-items:center;color:#fff;font-size:80px;position:relative;overflow:hidden">
|
||
<div style="position:absolute;inset:0;background:radial-gradient(circle at 72% 28%,rgba(255,255,255,.2),transparent 40%)"></div>
|
||
<div style="position:relative;width:80px;height:80px;border-radius:50%;background:rgba(255,255,255,.2);display:grid;place-items:center;backdrop-filter:blur(8px)">▶</div>
|
||
</div>
|
||
<div style="margin-top:16px">
|
||
<h4 id="preview-product-title" style="margin:0 0 12px;font-size:16px">直播切片成片_v2</h4>
|
||
<div style="display:grid;grid-template-columns:repeat(3,1fr);gap:12px;font-size:13px">
|
||
<div><span style="color:var(--muted)">时长:</span>00:32</div>
|
||
<div><span style="color:var(--muted)">分辨率:</span>1080P</div>
|
||
<div><span style="color:var(--muted)">大小:</span>25.6 MB</div>
|
||
<div><span style="color:var(--muted)">生成时间:</span>今天 14:32</div>
|
||
<div><span style="color:var(--muted)">模板:</span>画中画混剪</div>
|
||
<div><span style="color:var(--muted)">状态:</span><span class="pill ok">可发布</span></div>
|
||
</div>
|
||
</div>
|
||
<div style="display:flex;gap:12px;margin-top:24px">
|
||
<button class="btn ghost" onclick="closeModal('modal-product-preview')" style="flex:1">关闭</button>
|
||
<button class="btn ghost" onclick="closeModal('modal-product-preview');downloadProduct()" style="flex:1">下载</button>
|
||
<button class="btn primary" onclick="closeModal('modal-product-preview');openPublishModal()" style="flex:1">发布</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 发布视频模态框 -->
|
||
<div id="modal-publish" class="modal-overlay">
|
||
<div class="modal" style="max-width:520px;max-height:90vh;overflow-y:auto;text-align:left">
|
||
<h3 style="margin:0 0 20px;font-size:20px">📢 发布视频</h3>
|
||
|
||
<!-- 第1步:选择平台 -->
|
||
<div id="publish-step-platform">
|
||
<p style="margin:0 0 12px;font-weight:600;font-size:14px">选择发布平台</p>
|
||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:20px">
|
||
<label class="publish-platform-item selected" onclick="selectPublishPlatform(this)" data-platform="douyin" style="display:flex;align-items:center;gap:10px;padding:14px;border:2px solid var(--primary);border-radius:var(--radius-sm);cursor:pointer;background:var(--primary-soft)">
|
||
<input type="radio" name="platform" value="douyin" checked style="width:16px;height:16px;accent-color:var(--primary)"/>
|
||
<span style="font-size:22px">📱</span>
|
||
<span style="font-weight:600">抖音</span>
|
||
</label>
|
||
<label class="publish-platform-item" onclick="selectPublishPlatform(this)" data-platform="kuaishou" style="display:flex;align-items:center;gap:10px;padding:14px;border:1px solid var(--line);border-radius:var(--radius-sm);cursor:pointer">
|
||
<input type="radio" name="platform" value="kuaishou" style="width:16px;height:16px"/>
|
||
<span style="font-size:22px">🎬</span>
|
||
<span style="font-weight:600">快手</span>
|
||
</label>
|
||
<label class="publish-platform-item" onclick="selectPublishPlatform(this)" data-platform="xiaohongshu" style="display:flex;align-items:center;gap:10px;padding:14px;border:1px solid var(--line);border-radius:var(--radius-sm);cursor:pointer">
|
||
<input type="radio" name="platform" value="xiaohongshu" style="width:16px;height:16px"/>
|
||
<span style="font-size:22px">📕</span>
|
||
<span style="font-weight:600">小红书</span>
|
||
</label>
|
||
<label class="publish-platform-item" onclick="selectPublishPlatform(this)" data-platform="wechat" style="display:flex;align-items:center;gap:10px;padding:14px;border:1px solid var(--line);border-radius:var(--radius-sm);cursor:pointer">
|
||
<input type="radio" name="platform" value="wechat" style="width:16px;height:16px"/>
|
||
<span style="font-size:22px">💬</span>
|
||
<span style="font-weight:600">微信视频号</span>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 第2步:选择账号 -->
|
||
<div id="publish-step-account" style="margin-bottom:16px">
|
||
<p style="margin:0 0 8px;font-weight:600;font-size:14px">选择发布账号</p>
|
||
<select id="publish-account" style="width:100%;height:44px;border:1px solid var(--line);border-radius:var(--radius-sm);padding:0 14px;font-size:14px;background:#fff">
|
||
<option value="">请选择账号</option>
|
||
</select>
|
||
</div>
|
||
|
||
<!-- 视频信息 -->
|
||
<div style="margin-bottom:16px">
|
||
<p style="margin:0 0 8px;font-weight:600;font-size:14px">视频标题 <span style="color:var(--muted);font-weight:400;font-size:12px">(可选,不填则使用默认标题)</span></p>
|
||
<input id="publish-title" type="text" placeholder="输入视频标题(选填)" style="width:100%;height:44px;border:1px solid var(--line);border-radius:var(--radius-sm);padding:0 14px;font-size:14px"/>
|
||
</div>
|
||
|
||
<div style="margin-bottom:16px">
|
||
<p style="margin:0 0 8px;font-weight:600;font-size:14px">话题标签 <span style="color:var(--muted);font-weight:400;font-size:12px">(发布时的话题 #)</span></p>
|
||
<div id="publish-tags-container" style="display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px"></div>
|
||
<div style="display:flex;gap:8px;margin-bottom:10px">
|
||
<input id="publish-tag-input" type="text" placeholder="输入话题后按回车添加" style="flex:1;height:36px;border:1px solid var(--line);border-radius:var(--radius-sm);padding:0 12px;font-size:13px" onkeydown="if(event.key==='Enter'){event.preventDefault();addPublishTag()}"/>
|
||
<button class="btn ghost sm" onclick="addPublishTag()">+ 添加</button>
|
||
</div>
|
||
<div>
|
||
<p style="margin:0 0 6px;font-size:12px;color:var(--muted)">💡 常用话题(点击直接添加)</p>
|
||
<div id="publish-recent-topics" style="display:flex;flex-wrap:wrap;gap:6px"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="margin-bottom:20px">
|
||
<p style="margin:0 0 8px;font-weight:600;font-size:14px">视频描述 <span style="color:var(--muted);font-weight:400;font-size:12px">(可选)</span></p>
|
||
<textarea id="publish-desc" style="width:100%;height:80px;border:1px solid var(--line);border-radius:var(--radius-sm);padding:12px;font-size:14px;resize:none" placeholder="添加视频描述..."></textarea>
|
||
</div>
|
||
|
||
<div style="display:flex;gap:12px">
|
||
<button class="btn ghost" onclick="closeModal('modal-publish')" style="flex:1">取消</button>
|
||
<button class="btn primary" onclick="confirmPublish()" style="flex:1">🚀 确认发布</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 下载进度模态框 -->
|
||
<div id="modal-download" class="modal-overlay">
|
||
<div class="modal" style="max-width:400px;text-align:center">
|
||
<h3 style="margin:0 0 16px;font-size:20px">📥 正在下载</h3>
|
||
<p id="download-product-name" style="font-weight:600;margin:0 0 16px">直播切片成片_v2.mp4</p>
|
||
<div style="height:8px;background:#f1f5f9;border-radius:999px;overflow:hidden;margin-bottom:12px">
|
||
<div id="download-progress-bar" style="height:100%;background:linear-gradient(90deg,var(--green),#34d399);width:0%;transition:width .3s"></div>
|
||
</div>
|
||
<p style="margin:0;font-size:14px;color:var(--muted)">请稍候...</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 绑定账号模态框 -->
|
||
<div id="modal-bindAccount" class="modal-overlay">
|
||
<div class="modal" style="max-width:440px;text-align:left">
|
||
<h3 style="margin:0 0 20px;font-size:20px">🔗 绑定新账号</h3>
|
||
<div style="margin-bottom:20px">
|
||
<label style="display:block;margin-bottom:8px;font-weight:600;font-size:14px">选择平台</label>
|
||
<select id="bind-platform" style="width:100%;height:44px;border:1px solid var(--line);border-radius:var(--radius-sm);padding:0 14px;font-size:14px;background:#fff">
|
||
<option value="douyin">📱 抖音</option>
|
||
<option value="kuaishou">🎬 快手</option>
|
||
<option value="xiaohongshu">📕 小红书</option>
|
||
<option value="wechat">💬 微信视频号</option>
|
||
</select>
|
||
</div>
|
||
<div style="background:#f8fafc;border-radius:var(--radius-md);padding:16px;margin-bottom:20px">
|
||
<div style="display:flex;align-items:center;gap:10px;margin-bottom:10px">
|
||
<span style="font-size:18px">💡</span>
|
||
<span style="font-weight:600;font-size:14px">授权说明</span>
|
||
</div>
|
||
<p style="margin:0;font-size:13px;color:var(--muted);line-height:1.6">点击"前往授权"后将跳转到平台授权页面,授权成功后即可通过小虾智剪发布视频到该平台。</p>
|
||
</div>
|
||
<div style="display:flex;gap:12px">
|
||
<button class="btn ghost" onclick="closeModal('modal-bindAccount')" style="flex:1">取消</button>
|
||
<button class="btn primary" onclick="confirmBindAccount()" style="flex:1">🚀 前往授权</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 解绑确认模态框 -->
|
||
<div id="modal-unbindAccount" class="modal-overlay">
|
||
<div class="modal" style="max-width:400px;text-align:center">
|
||
<h3 style="margin:0 0 16px;font-size:20px">⚠️ 确认解绑</h3>
|
||
<div style="background:#fef2f2;border-radius:16px;padding:20px;margin-bottom:20px">
|
||
<p style="margin:0;font-size:14px;color:#991b1b">确定要解除绑定以下账号吗?</p>
|
||
<p id="unbind-account-name" style="margin:12px 0 0;font-weight:700;font-size:16px;color:#991b1b">小虾智剪-官方号</p>
|
||
</div>
|
||
<p style="margin:0 0 20px;font-size:13px;color:var(--muted)">解绑后该账号将无法通过小虾智剪发布视频,但不会影响您在平台上的账号本身。</p>
|
||
<div style="display:flex;gap:12px">
|
||
<button class="btn ghost" onclick="closeModal('modal-unbindAccount')" style="flex:1">取消</button>
|
||
<button class="btn" onclick="confirmUnbind()" style="flex:1;background:#ef4444;color:#fff">确认解绑</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 批量发布模态框 -->
|
||
<div id="modal-batchPublish" class="modal-overlay">
|
||
<div class="modal" style="max-width:640px;max-height:90vh;overflow-y:auto;text-align:left">
|
||
<h3 style="margin:0 0 20px;font-size:20px">📢 批量发布</h3>
|
||
<div style="margin-bottom:20px">
|
||
<p style="margin:0 0 8px;font-weight:600;font-size:14px">选择发布的视频</p>
|
||
<div id="batch-video-list" style="display:flex;flex-direction:column;gap:10px;max-height:280px;overflow-y:auto">
|
||
<!-- 动态填充 -->
|
||
</div>
|
||
</div>
|
||
<div style="margin-bottom:16px">
|
||
<p style="margin:0 0 8px;font-weight:600;font-size:14px">统一话题标签 <span style="color:var(--muted);font-weight:400;font-size:12px">(所有视频统一使用)</span></p>
|
||
<div id="batch-tags-container" style="display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px"></div>
|
||
<div style="display:flex;gap:8px;margin-bottom:10px">
|
||
<input id="batch-tag-input" type="text" placeholder="输入话题后按回车添加" style="flex:1;height:36px;border:1px solid var(--line);border-radius:var(--radius-sm);padding:0 12px;font-size:13px" onkeydown="if(event.key==='Enter'){event.preventDefault();addBatchTag()}"/>
|
||
<button class="btn ghost sm" onclick="addBatchTag()">+ 添加</button>
|
||
</div>
|
||
<div>
|
||
<p style="margin:0 0 6px;font-size:12px;color:var(--muted)">💡 常用话题(点击直接添加)</p>
|
||
<div id="batch-recent-topics" style="display:flex;flex-wrap:wrap;gap:6px"></div>
|
||
</div>
|
||
</div>
|
||
<div style="padding:14px 16px;background:#f8fafc;border-radius:var(--radius-md);margin-bottom:20px;display:flex;align-items:center;justify-content:center;gap:8px">
|
||
<span style="font-size:14px">📊 共 <span id="batch-video-count" style="font-weight:700;color:var(--primary)">0</span> 个视频,将发布到 <span id="batch-platform-count" style="font-weight:700;color:var(--primary)">0</span> 个平台</span>
|
||
</div>
|
||
<div style="display:flex;gap:12px">
|
||
<button class="btn ghost" onclick="closeModal('modal-batchPublish')" style="flex:1">取消</button>
|
||
<button class="btn primary" onclick="confirmBatchPublish()" style="flex:1">🚀 确认批量发布</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 发布进度模态框 -->
|
||
<div id="modal-publishProgress" class="modal-overlay">
|
||
<div class="modal" style="max-width:400px;text-align:center">
|
||
<div id="publish-progress-icon" style="margin-bottom:8px"><div class="spinner"></div></div>
|
||
<h3 style="margin:0 0 8px;font-size:18px">正在发布</h3>
|
||
<p id="publish-progress-text" style="margin:0 0 16px;color:var(--muted);font-size:14px">正在发布视频...</p>
|
||
<div style="height:8px;background:#f1f5f9;border-radius:999px;overflow:hidden;margin-bottom:12px">
|
||
<div id="publish-progress-bar" style="height:100%;background:linear-gradient(90deg,var(--primary),#38bdf8);width:0%;transition:width .4s;border-radius:999px"></div>
|
||
</div>
|
||
<p style="margin:0;font-size:12px;color:var(--muted)">请勿关闭页面</p>
|
||
</div>
|
||
</div>
|
||
|
||
<style>
|
||
.success-icon {
|
||
width:56px;
|
||
height:56px;
|
||
border-radius:50%;
|
||
background:#dcfce7;
|
||
color:#10b981;
|
||
display:inline-flex;
|
||
align-items:center;
|
||
justify-content:center;
|
||
font-size:28px;
|
||
font-weight:700;
|
||
}
|
||
.spinner {
|
||
width:56px;
|
||
height:56px;
|
||
border:4px solid #e2e8f0;
|
||
border-top-color:var(--primary);
|
||
border-radius:50%;
|
||
animation:spin .8s linear infinite;
|
||
margin:0 auto;
|
||
}
|
||
@keyframes spin {
|
||
to{transform:rotate(360deg)}
|
||
}
|
||
</style>
|
||
|
||
<!-- ==================== 任务历史模态框 ==================== -->
|
||
<!-- 任务详情模态框 -->
|
||
<div id="modal-task-detail" class="modal-overlay">
|
||
<div class="modal" style="max-width:600px">
|
||
<h3 style="margin:0 0 20px;font-size:20px">📋 任务详情</h3>
|
||
<div style="background:#f8fafc;border-radius:var(--radius-md);padding:20px;margin-bottom:20px">
|
||
<h4 id="detail-task-title" style="margin:0 0 8px;font-size:16px">产品卖点混剪视频</h4>
|
||
<p id="detail-task-meta" style="margin:0;font-size:13px;color:var(--muted)">一键生成 · 模板:画中画混剪</p>
|
||
</div>
|
||
<div style="margin-bottom:20px">
|
||
<h5 style="margin:0 0 12px;font-size:14px;font-weight:600">执行步骤</h5>
|
||
<div style="display:flex;flex-direction:column;gap:8px">
|
||
<div style="display:flex;align-items:center;gap:10px;padding:10px;background:#dcfce7;border-radius:8px">
|
||
<span style="width:24px;height:24px;border-radius:50%;background:#10b981;color:#fff;display:grid;place-items:center;font-size:12px">✓</span>
|
||
<span>读取素材</span>
|
||
</div>
|
||
<div style="display:flex;align-items:center;gap:10px;padding:10px;background:#dcfce7;border-radius:8px">
|
||
<span style="width:24px;height:24px;border-radius:50%;background:#10b981;color:#fff;display:grid;place-items:center;font-size:12px">✓</span>
|
||
<span>AI内容分析</span>
|
||
</div>
|
||
<div style="display:flex;align-items:center;gap:10px;padding:10px;background:#dcfce7;border-radius:8px">
|
||
<span style="width:24px;height:24px;border-radius:50%;background:#10b981;color:#fff;display:grid;place-items:center;font-size:12px">✓</span>
|
||
<span>生成剪辑计划</span>
|
||
</div>
|
||
<div style="display:flex;align-items:center;gap:10px;padding:10px;background:#fef3c7;border-radius:8px">
|
||
<span style="width:24px;height:24px;border-radius:50%;background:#f59e0b;color:#fff;display:grid;place-items:center;font-size:12px">⟳</span>
|
||
<span>合成视频</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div style="padding:14px;background:#f8fafc;border-radius:var(--radius-sm);font-size:13px;color:var(--muted)">
|
||
<div style="display:flex;justify-content:space-between">
|
||
<span>开始时间</span>
|
||
<span>今天 14:32:15</span>
|
||
</div>
|
||
<div style="display:flex;justify-content:space-between;margin-top:8px">
|
||
<span>总耗时</span>
|
||
<span>28秒</span>
|
||
</div>
|
||
</div>
|
||
<div style="display:flex;gap:12px;margin-top:24px">
|
||
<button class="btn ghost" onclick="closeModal('modal-task-detail')" style="flex:1">关闭</button>
|
||
<button class="btn primary" onclick="closeModal('modal-task-detail');showView('products')" style="flex:1">查看成片</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ==================== 查重检测模态框 ==================== -->
|
||
<div id="dup-upload-progress" class="modal-overlay" style="display:none" style="display:none;pointer-events:none">
|
||
<div class="modal" style="max-width:400px;text-align:center;pointer-events:auto">
|
||
<h3 style="margin:0 0 16px;font-size:20px">📤 上传进度</h3>
|
||
<p id="dup-upload-status" style="margin:0 0 12px;color:var(--muted)">上传中... 0%</p>
|
||
<div style="height:8px;background:#f1f5f9;border-radius:999px;overflow:hidden">
|
||
<div style="height:100%;background:var(--primary);width:0%;transition:width .3s"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ==================== 订阅管理模态框 ==================== -->
|
||
<!-- 升级确认 -->
|
||
<div id="modal-upgrade" class="modal-overlay">
|
||
<div class="modal" style="max-width:420px;text-align:center">
|
||
<div style="width:60px;height:60px;border-radius:50%;background:var(--primary-soft);margin:0 auto 16px;display:grid;place-items:center;font-size:28px;color:var(--primary)">⬆️</div>
|
||
<h3 style="margin:0 0 8px;font-size:18px">确认升级套餐</h3>
|
||
<p style="margin:0 0 16px;color:var(--muted)">升级到 <strong id="upgrade-plan-name">旗舰版</strong>,立即解锁更多功能</p>
|
||
<div style="padding:14px;background:#f8fafc;border-radius:var(--radius-sm);margin-bottom:20px;text-align:left">
|
||
<p style="margin:0;font-size:13px">• 无限视频生成</p>
|
||
<p style="margin:8px 0 0;font-size:13px">• 优先处理队列</p>
|
||
<p style="margin:8px 0 0;font-size:13px">• 高级AI功能</p>
|
||
</div>
|
||
<div style="display:flex;gap:12px">
|
||
<button class="btn ghost" onclick="closeModal('modal-upgrade')" style="flex:1">取消</button>
|
||
<button class="btn primary" onclick="confirmUpgrade()" style="flex:1">立即升级</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 降级确认 -->
|
||
<div id="modal-downgrade" class="modal-overlay">
|
||
<div class="modal" style="max-width:420px;text-align:center">
|
||
<div style="width:60px;height:60px;border-radius:50%;background:#fef3c7;margin:0 auto 16px;display:grid;place-items:center;font-size:28px;color:#92400e">⬇️</div>
|
||
<h3 style="margin:0 0 8px;font-size:18px">确认降级套餐</h3>
|
||
<p style="margin:0 0 16px;color:var(--muted)">降级后,部分高级功能将无法使用。已生成的视频不受影响。</p>
|
||
<div style="padding:14px;background:#fef3c7;border-radius:var(--radius-sm);margin-bottom:20px;font-size:13px;color:#92400e">
|
||
<p style="margin:0">⚠️ 降级将在当前计费周期结束后生效</p>
|
||
</div>
|
||
<div style="display:flex;gap:12px">
|
||
<button class="btn ghost" onclick="closeModal('modal-downgrade')" style="flex:1">取消</button>
|
||
<button class="btn" onclick="confirmDowngrade()" style="flex:1;background:#f59e0b;color:#fff">确认降级</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 续费确认 -->
|
||
<div id="modal-renew" class="modal-overlay">
|
||
<div class="modal" style="max-width:420px;text-align:center">
|
||
<div style="width:60px;height:60px;border-radius:50%;background:#dcfce7;margin:0 auto 16px;display:grid;place-items:center;font-size:28px;color:#166534">💳</div>
|
||
<h3 style="margin:0 0 8px;font-size:18px">续费套餐</h3>
|
||
<p style="margin:0 0 16px;color:var(--muted)">您的专业版套餐将在 <strong>15天后</strong> 到期</p>
|
||
<div style="padding:14px;background:#f8fafc;border-radius:var(--radius-sm);margin-bottom:20px">
|
||
<div style="display:flex;justify-content:space-between;margin-bottom:8px">
|
||
<span>当前套餐</span>
|
||
<span>专业版</span>
|
||
</div>
|
||
<div style="display:flex;justify-content:space-between;margin-bottom:8px">
|
||
<span>续费时长</span>
|
||
<span>1年</span>
|
||
</div>
|
||
<div style="display:flex;justify-content:space-between;font-weight:700">
|
||
<span>应付金额</span>
|
||
<span style="color:var(--primary)">¥1,299</span>
|
||
</div>
|
||
</div>
|
||
<div style="display:flex;gap:12px">
|
||
<button class="btn ghost" onclick="closeModal('modal-renew')" style="flex:1">取消</button>
|
||
<button class="btn primary" onclick="confirmRenew()" style="flex:1">前往支付</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ==================== 剪辑计划编辑器视图 ==================== -->
|
||
<section id="view-editing-planner" class="view">
|
||
<div class="app-layout">
|
||
<aside class="sidebar">
|
||
<div class="sidebar-logo">
|
||
<div class="logo" style="width:34px;height:34px;font-size:18px">🦐</div>
|
||
<span>小虾智剪</span>
|
||
</div>
|
||
<nav class="sidebar-nav">
|
||
<div class="sidebar-item" data-view="dashboard">
|
||
<div class="icon">📊</div>
|
||
<span>控制台</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="titles">
|
||
<div class="icon">📝</div>
|
||
<span>标题库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="assets">
|
||
<div class="icon">📦</div>
|
||
<span>素材库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="voices">
|
||
<div class="icon">🎙️</div>
|
||
<span>配音库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="templates">
|
||
<div class="icon">🎨</div>
|
||
<span>模板库</span>
|
||
</div>
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-item active" data-view="editing-planner">
|
||
<div class="icon" style="background:var(--primary);color:#fff">✂️</div>
|
||
<span>剪辑计划</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="generate">
|
||
<div class="icon">✨</div>
|
||
<span>一键生成</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="products">
|
||
<div class="icon">🎬</div>
|
||
<span>成片库</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="history">
|
||
<div class="icon">📋</div>
|
||
<span>任务历史</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="duplication">
|
||
<div class="icon">🔍</div>
|
||
<span>查重检测</span>
|
||
</div>
|
||
<div class="sidebar-item" data-view="voiceClone">
|
||
<div class="icon">🎤</div>
|
||
<span>我的音色</span>
|
||
</div>
|
||
<div class="sidebar-divider"></div>
|
||
<div class="sidebar-item" data-view="subscription-logged">
|
||
<div class="icon">💎</div>
|
||
<span>订阅管理</span>
|
||
</div>
|
||
</nav>
|
||
<div class="sidebar-bottom">
|
||
<div class="sidebar-item" onclick="logout()">
|
||
<div class="icon">🚪</div>
|
||
<span>退出登录</span>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
|
||
<!-- 剪辑计划主内容 -->
|
||
<div class="main-content" style="display:flex;flex-direction:column;height:calc(100vh - 68px);overflow:hidden">
|
||
|
||
<!-- 顶部工具栏 -->
|
||
<div style="height:52px;background:#fff;border-bottom:1px solid var(--line);display:flex;align-items:center;justify-content:space-between;padding:0 20px;flex-shrink:0">
|
||
<div style="display:flex;align-items:center;gap:12px">
|
||
<span style="font-weight:700;color:var(--primary)">✂️ 剪辑计划编辑器</span>
|
||
<span style="color:var(--muted);font-size:13px" id="ep-plan-title">空白模板</span>
|
||
<span style="font-size:11px;color:var(--muted)" id="ep-editing-indicator"></span>
|
||
</div>
|
||
<div style="display:flex;align-items:center;gap:10px">
|
||
<button class="btn ghost sm" onclick="epSaveTemplate()">💾 <span id="ep-save-btn-text">保存模板</span></button>
|
||
<button class="btn primary sm" onclick="epGenerateVideo()">🎬 使用此模板生成</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 剪辑模式切换 -->
|
||
<div style="height:56px;background:#fff;border-bottom:1px solid var(--line);display:flex;align-items:center;justify-content:center;gap:12px;padding:0 20px;flex-shrink:0">
|
||
<span style="font-size:12px;color:var(--muted);margin-right:8px">剪辑模式:</span>
|
||
<div style="display:flex;gap:8px">
|
||
<button class="ep-mode-btn active" data-mode="pip" onclick="switchEpMode('pip')">
|
||
<div style="font-size:18px">🎭</div>
|
||
<div style="font-size:10px;color:#888">画中画</div>
|
||
</button>
|
||
<button class="ep-mode-btn" data-mode="voice_over" onclick="switchEpMode('voice_over')">
|
||
<div style="font-size:18px">🎙️</div>
|
||
<div style="font-size:10px;color:#888">人物口播</div>
|
||
</button>
|
||
<button class="ep-mode-btn" data-mode="one_take" onclick="switchEpMode('one_take')">
|
||
<div style="font-size:18px">🎬</div>
|
||
<div style="font-size:10px;color:#888">一镜到底</div>
|
||
</button>
|
||
<button class="ep-mode-btn" data-mode="voice_pip" onclick="switchEpMode('voice_pip')">
|
||
<div style="font-size:18px">🎭🎙️</div>
|
||
<div style="font-size:10px;color:#888">口播+画中画</div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 三栏主体布局 -->
|
||
<div style="flex:1;display:flex;min-height:0;overflow:hidden">
|
||
|
||
<!-- 左侧:模板面板 -->
|
||
<div style="width:240px;background:#fff;border-right:1px solid var(--line);display:flex;flex-direction:column;flex-shrink:0">
|
||
<div style="padding:12px 14px;border-bottom:1px solid var(--line);display:flex;align-items:center;justify-content:space-between">
|
||
<span style="font-size:12px;font-weight:600;color:var(--muted)">📋 已保存模板</span>
|
||
<button style="font-size:10px;color:#aaa;background:none;border:none;cursor:pointer" onclick="epToggleTemplateList()" id="ep-back-btn" hidden>← 返回列表</button>
|
||
</div>
|
||
|
||
<!-- 搜索栏 -->
|
||
<div style="padding:10px 12px;border-bottom:1px solid #f1f5f9;position:relative">
|
||
<span style="position:absolute;left:20px;top:50%;transform:translateY(-50%);font-size:10px;color:#94a3b8">🔍</span>
|
||
<input type="text" id="ep-template-search" placeholder="搜索模板..." oninput="epFilterTemplates()" style="width:100%;padding:6px 8px 6px 28px;background:#f8fafc;border:1px solid var(--line);border-radius:8px;font-size:12px;outline:none">
|
||
</div>
|
||
|
||
<!-- 分类筛选 -->
|
||
<div style="padding:8px 12px;border-bottom:1px solid #f1f5f9;display:flex;gap:6px;flex-wrap:wrap" id="ep-filter-chips">
|
||
<span class="ep-filter-chip active" data-filter="all" onclick="epSetFilter(this)">全部</span>
|
||
<span class="ep-filter-chip" data-filter="种草" onclick="epSetFilter(this)">种草</span>
|
||
<span class="ep-filter-chip" data-filter="知识" onclick="epSetFilter(this)">知识</span>
|
||
<span class="ep-filter-chip" data-filter="日常" onclick="epSetFilter(this)">日常</span>
|
||
<span class="ep-filter-chip" data-filter="推荐" onclick="epSetFilter(this)">推荐</span>
|
||
</div>
|
||
|
||
<!-- 模板卡片列表 -->
|
||
<div style="flex:1;overflow-y:auto;padding:10px" id="ep-template-cards">
|
||
<!-- 动态生成 -->
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 中间:预览+时间线 -->
|
||
<div style="flex:1;display:flex;flex-direction:column;min-width:0;background:#f8fafc">
|
||
|
||
<!-- 上部:视频预览+封面预览 -->
|
||
<div style="display:flex;align-items:flex-start;justify-content:center;gap:40px;padding:20px;background:#fff;border-bottom:1px solid var(--line);height:320px;flex-shrink:0">
|
||
|
||
<!-- 视频预览 -->
|
||
<div style="display:flex;flex-direction:column;align-items:center">
|
||
<div style="font-size:11px;color:#94a3b8;margin-bottom:8px">🎬 视频预览</div>
|
||
<div style="width:150px;height:267px;background:#1a1a2e;border-radius:16px;overflow:hidden;box-shadow:0 8px 40px rgba(0,0,0,0.3);border:1px solid #333;position:relative">
|
||
<div style="height:20px;background:#0a0a14;display:flex;align-items:center;justify-content:space-between;padding:0 8px;font-size:8px;color:#666">
|
||
<span>9:41</span>
|
||
<span>📶 🔋</span>
|
||
</div>
|
||
<div style="flex:1;display:flex;align-items:center;justify-content:center;flex-direction:column;background:linear-gradient(180deg,#2d2d44,#1a1a2e)" id="ep-preview-content">
|
||
<div style="font-size:48px;opacity:0.5">🎬</div>
|
||
<div style="font-size:9px;color:#666">视频预览区域</div>
|
||
<div style="font-size:9px;color:#555;margin-top:4px" id="ep-preview-mode-label">画中画模式</div>
|
||
</div>
|
||
<div style="position:absolute;bottom:8px;left:0;right:0;display:flex;align-items:center;justify-content:center">
|
||
<button onclick="epTogglePreview()" style="width:32px;height:32px;border-radius:50%;background:rgba(99,102,241,0.8);color:#fff;border:none;cursor:pointer;font-size:12px;display:grid;place-items:center">▶</button>
|
||
</div>
|
||
<div style="position:absolute;bottom:8px;right:8px;padding:2px 6px;background:rgba(0,0,0,0.5);border-radius:4px;font-size:8px;color:#fff" id="ep-preview-time">00:00/02:00</div>
|
||
</div>
|
||
<!-- 进度条 -->
|
||
<div style="display:flex;align-items:center;gap:8px;margin-top:8px;width:150px">
|
||
<span style="font-size:9px;color:#94a3b8" id="ep-current-time">00:00</span>
|
||
<div style="flex:1;height:4px;background:#e2e8f0;border-radius:2px;overflow:hidden">
|
||
<div style="height:100%;background:var(--primary);transition:width .3s" id="ep-progress-bar"></div>
|
||
</div>
|
||
<span style="font-size:9px;color:#94a3b8" id="ep-total-time">02:00</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 封面预览 -->
|
||
<div style="display:flex;flex-direction:column;align-items:center">
|
||
<div style="font-size:11px;color:#94a3b8;margin-bottom:8px">🖼️ 封面预览</div>
|
||
<div style="display:flex;align-items:flex-start;gap:12px">
|
||
<div style="width:150px;height:267px;background:linear-gradient(135deg,#2d1f6e,#6366f1,#a29bfe);border-radius:16px;overflow:hidden;box-shadow:0 8px 40px rgba(99,102,241,0.3);border:1px solid #333;position:relative" id="ep-cover-preview-box">
|
||
<div style="position:absolute;inset:0;display:flex;align-items:center;justify-content:center">
|
||
<div style="text-align:center">
|
||
<div style="font-size:36px;opacity:0.5">👤</div>
|
||
<div style="font-size:9px;color:rgba(255,255,255,0.6);padding:0 8px">封面预览区</div>
|
||
</div>
|
||
</div>
|
||
<div style="position:absolute;bottom:8px;left:8px;padding:2px 6px;background:rgba(0,0,0,0.6);border-radius:4px;font-size:8px;color:rgba(255,255,255,0.8)" id="ep-cover-source-tag">🤖 AI选帧</div>
|
||
</div>
|
||
<!-- 封面方案按钮 -->
|
||
<div style="display:flex;flex-direction:column;gap:8px" id="ep-cover-tags">
|
||
<span class="ep-cover-tag active" data-cover="ai" onclick="epSelectCoverScheme(this)">🤖 AI选帧</span>
|
||
<span class="ep-cover-tag" data-cover="manual" onclick="epSelectCoverScheme(this)">👆 手动选</span>
|
||
<span class="ep-cover-tag" data-cover="upload" onclick="epSelectCoverScheme(this)">📤 上传</span>
|
||
<span class="ep-cover-tag" data-cover="repick" onclick="epSelectCoverScheme(this)">🔄 AI重选</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 下部:时间线 -->
|
||
<div style="flex:1;border-top:1px solid var(--line);display:flex;flex-direction:column;background:#fff;min-height:0">
|
||
<div style="display:flex;align-items:center;justify-content:space-between;padding:10px 16px;border-bottom:1px solid #f1f5f9;flex-shrink:0">
|
||
<div style="display:flex;align-items:center;gap:10px">
|
||
<span style="font-size:12px;color:#64748b">🎬 时间线</span>
|
||
<span style="font-size:12px;color:#f59e0b;font-weight:600" id="ep-total-duration-badge">总时长: 0:00</span>
|
||
<span style="font-size:10px;color:#94a3b8;padding:2px 8px;border-radius:4px;background:#f1f5f9;display:none" id="ep-one-take-hint">🔒 一镜到底:固定1个片段</span>
|
||
</div>
|
||
<div style="display:flex;align-items:center;gap:6px">
|
||
<button onclick="epUndo()" style="width:28px;height:28px;border-radius:8px;background:#f8fafc;border:1px solid var(--line);color:#94a3b8;cursor:pointer;font-size:12px;display:grid;place-items:center">↩</button>
|
||
<button onclick="epRedo()" style="width:28px;height:28px;border-radius:8px;background:#f8fafc;border:1px solid var(--line);color:#94a3b8;cursor:pointer;font-size:12px;display:grid;place-items:center">↪</button>
|
||
</div>
|
||
</div>
|
||
<!-- 时间标尺 -->
|
||
<div style="height:24px;background:#f8fafc;border-bottom:1px solid #f1f5f9;position:relative;display:flex;align-items:flex-end;padding:0 16px;flex-shrink:0">
|
||
<span style="font-size:9px;color:#cbd5e1;position:absolute;bottom:4px;left:10%">0:00</span>
|
||
<span style="font-size:9px;color:#cbd5e1;position:absolute;bottom:4px;left:30%">0:30</span>
|
||
<span style="font-size:9px;color:#cbd5e1;position:absolute;bottom:4px;left:55%">1:00</span>
|
||
<span style="font-size:9px;color:#cbd5e1;position:absolute;bottom:4px;left:80%">1:30</span>
|
||
</div>
|
||
<!-- 片段轨道 -->
|
||
<div style="flex:1;display:flex;align-items:center;gap:12px;padding:12px 16px;overflow-x:auto" id="ep-timeline-track">
|
||
<!-- 动态生成 -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 右侧:属性面板 -->
|
||
<div style="width:280px;background:#fff;border-left:1px solid var(--line);display:flex;flex-direction:column;flex-shrink:0;overflow-y:auto">
|
||
<div style="flex:1">
|
||
<!-- 标题设置 -->
|
||
<div style="padding:14px;border-bottom:1px solid #f1f5f9">
|
||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:12px">
|
||
<span style="font-size:11px;font-weight:600;color:#64748b;text-transform:uppercase">📌 标题设置</span>
|
||
<div class="toggle" id="ep-title-ai-toggle" onclick="epToggleTitleAi()"></div>
|
||
</div>
|
||
<div style="display:flex;flex-direction:column;gap:10px">
|
||
<div id="ep-title-ai-hint" style="display:none">
|
||
<div style="background:#eef2ff;border:1px solid #c7d2fe;border-radius:8px;padding:8px;text-align:center;font-size:10px;color:#6366f1">🤖 系统将从标题库自动匹配</div>
|
||
</div>
|
||
<div id="ep-title-input-section">
|
||
<input type="text" id="ep-title-input" placeholder="输入视频标题..." style="width:100%;padding:8px 10px;background:#f8fafc;border:1px solid var(--line);border-radius:8px;font-size:12px;outline:none">
|
||
</div>
|
||
<div style="display:flex;align-items:center;gap:8px">
|
||
<label style="font-size:11px;color:#94a3b8;width:36px">位置</label>
|
||
<select id="ep-title-position" style="flex:1;padding:6px 8px;background:#f8fafc;border:1px solid var(--line);border-radius:8px;font-size:12px;outline:none">
|
||
<option value="top">顶部</option>
|
||
<option value="bottom" selected>底部</option>
|
||
</select>
|
||
</div>
|
||
<div style="display:flex;align-items:center;gap:8px">
|
||
<select id="ep-title-font" style="flex:1;padding:6px 8px;background:#f8fafc;border:1px solid var(--line);border-radius:8px;font-size:12px;outline:none">
|
||
<option>默认字体</option>
|
||
<option>思源黑体</option>
|
||
<option>阿里巴巴普惠体</option>
|
||
</select>
|
||
<input type="color" id="ep-title-color" value="#ffffff" style="width:32px;height:32px;border-radius:8px;cursor:pointer;border:1px solid var(--line)">
|
||
</div>
|
||
<div style="display:flex;align-items:center;gap:8px">
|
||
<label style="font-size:11px;color:#94a3b8;width:36px">大小</label>
|
||
<input type="range" id="ep-title-size-slider" min="12" max="32" value="18" style="flex:1;accent-color:var(--primary)">
|
||
<span id="ep-title-size-value" style="font-size:11px;color:var(--primary);width:32px;text-align:right">18px</span>
|
||
</div>
|
||
<div style="display:flex;align-items:center;gap:10px">
|
||
<label style="display:flex;align-items:center;gap:4px;font-size:11px;color:#64748b;cursor:pointer"><input type="checkbox" checked id="ep-title-bold" style="accent-color:var(--primary)">粗体</label>
|
||
<label style="display:flex;align-items:center;gap:4px;font-size:11px;color:#64748b;cursor:pointer"><input type="checkbox" id="ep-title-italic" style="accent-color:var(--primary)">斜体</label>
|
||
<label style="display:flex;align-items:center;gap:4px;font-size:11px;color:#64748b;cursor:pointer"><input type="checkbox" checked id="ep-title-stroke" style="accent-color:var(--primary)">描边</label>
|
||
<label style="display:flex;align-items:center;gap:4px;font-size:11px;color:#64748b;cursor:pointer"><input type="checkbox" id="ep-title-shadow" style="accent-color:var(--primary)">阴影</label>
|
||
</div>
|
||
<div style="font-size:10px;color:#94a3b8;font-style:italic">💡 标题将贯穿整个视频显示</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 字幕设置 -->
|
||
<div style="padding:14px;border-bottom:1px solid #f1f5f9">
|
||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:12px">
|
||
<span style="font-size:11px;font-weight:600;color:#64748b;text-transform:uppercase">💬 字幕设置</span>
|
||
<div class="toggle on" onclick="this.classList.toggle('on')"></div>
|
||
</div>
|
||
<div style="display:flex;flex-direction:column;gap:10px">
|
||
<div style="display:flex;align-items:center;gap:8px">
|
||
<label style="font-size:11px;color:#94a3b8;width:36px">位置</label>
|
||
<select style="flex:1;padding:6px 8px;background:#f8fafc;border:1px solid var(--line);border-radius:8px;font-size:12px;outline:none">
|
||
<option value="top">顶部</option>
|
||
<option value="center">中部</option>
|
||
<option value="bottom" selected>底部</option>
|
||
</select>
|
||
</div>
|
||
<div style="display:flex;align-items:center;gap:8px">
|
||
<select style="flex:1;padding:6px 8px;background:#f8fafc;border:1px solid var(--line);border-radius:8px;font-size:12px;outline:none">
|
||
<option>系统默认</option>
|
||
<option>思源黑体</option>
|
||
</select>
|
||
<input type="color" value="#ffff00" style="width:32px;height:32px;border-radius:8px;cursor:pointer;border:1px solid var(--line)">
|
||
</div>
|
||
<div style="display:flex;align-items:center;gap:8px">
|
||
<label style="font-size:11px;color:#94a3b8;width:36px">动画</label>
|
||
<select style="flex:1;padding:6px 8px;background:#f8fafc;border:1px solid var(--line);border-radius:8px;font-size:12px;outline:none">
|
||
<option value="none">无</option>
|
||
<option value="fade" selected>渐入渐出</option>
|
||
<option value="bounce">弹跳</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- BGM设置 -->
|
||
<div style="padding:14px;border-bottom:1px solid #f1f5f9">
|
||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:12px">
|
||
<span style="font-size:11px;font-weight:600;color:#64748b;text-transform:uppercase">🎵 BGM设置</span>
|
||
<div class="toggle on" onclick="this.classList.toggle('on')"></div>
|
||
</div>
|
||
<select style="width:100%;padding:8px 10px;background:#f8fafc;border:1px solid var(--line);border-radius:8px;font-size:12px;outline:none">
|
||
<option value="">请选择背景音乐</option>
|
||
<option value="1" selected>🎸 活力电子 - 节奏感强</option>
|
||
<option value="2">🎹 轻快流行 - 青春活力</option>
|
||
<option value="3">🎻 舒缓钢琴 - 安静放松</option>
|
||
<option value="4">🥁 励志摇滚 - 激情澎湃</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 片段详情区 -->
|
||
<div style="border-top:2px solid var(--line);padding:14px" id="ep-segment-detail" hidden>
|
||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:12px">
|
||
<span style="font-size:12px;font-weight:600" id="ep-segment-detail-title">片段 1</span>
|
||
<button onclick="epDeleteCurrentSegment()" style="background:none;border:none;color:#94a3b8;cursor:pointer;font-size:14px">🗑️</button>
|
||
</div>
|
||
<div id="ep-duration-section" style="margin-bottom:12px">
|
||
<label style="font-size:11px;color:#94a3b8;display:block;margin-bottom:6px">片段时长范围</label>
|
||
<div style="display:flex;align-items:center;gap:6px">
|
||
<input type="number" id="ep-duration-min" value="3" min="1" max="60" style="width:48px;padding:6px;text-align:center;background:#f8fafc;border:1px solid var(--line);border-radius:8px;font-size:12px;outline:none">
|
||
<span style="font-size:11px;color:#94a3b8">-</span>
|
||
<input type="number" id="ep-duration-max" value="8" min="1" max="60" style="width:48px;padding:6px;text-align:center;background:#f8fafc;border:1px solid var(--line);border-radius:8px;font-size:12px;outline:none">
|
||
<span style="font-size:11px;color:#94a3b8">秒</span>
|
||
</div>
|
||
<div style="font-size:10px;color:#94a3b8;margin-top:4px">AI根据素材内容自适应决定具体时长</div>
|
||
</div>
|
||
<div id="ep-duration-locked" style="margin-bottom:12px;display:none">
|
||
<label style="font-size:11px;color:#94a3b8;display:block;margin-bottom:6px">片段时长</label>
|
||
<div style="padding:8px 10px;background:#f8fafc;border:1px solid var(--line);border-radius:8px;font-size:11px;color:#94a3b8">
|
||
🔒 由配音决定
|
||
</div>
|
||
</div>
|
||
<div style="margin-bottom:12px">
|
||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:6px">
|
||
<span style="font-size:11px;color:#94a3b8">配音文案</span>
|
||
<div style="display:flex;align-items:center;gap:8px">
|
||
<span style="font-size:10px;color:#94a3b8" id="ep-script-hint">🔇 使用原声</span>
|
||
<div class="toggle" id="ep-script-toggle" onclick="epToggleScript()"></div>
|
||
</div>
|
||
</div>
|
||
<div id="ep-script-input" style="display:none">
|
||
<textarea id="ep-script-textarea" rows="2" placeholder="输入配音文案..." style="width:100%;padding:8px;background:#f8fafc;border:1px solid var(--line);border-radius:8px;font-size:12px;outline:none;resize:none"></textarea>
|
||
</div>
|
||
</div>
|
||
<div id="ep-material-type-section" style="display:none;margin-bottom:12px">
|
||
<label style="font-size:11px;color:#94a3b8;display:block;margin-bottom:6px">素材类型</label>
|
||
<div style="display:flex;gap:8px">
|
||
<button class="ep-material-type-btn active" data-type="person" onclick="epSelectMaterialType(this)" style="flex:1;padding:6px 8px;border:1px solid var(--line);border-radius:6px;font-size:10px;cursor:pointer;background:#f8fafc">👤 人物</button>
|
||
<button class="ep-material-type-btn" data-type="scene" onclick="epSelectMaterialType(this)" style="flex:1;padding:6px 8px;border:1px solid var(--line);border-radius:6px;font-size:10px;cursor:pointer;background:#f8fafc">🏞️ 场景</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Toast容器 -->
|
||
<div id="ep-toast-container" style="position:fixed;top:50px;right:12px;z-index:9999;display:flex;flex-direction:column;gap:4px"></div>
|
||
|
||
<!-- 保存模板弹窗 -->
|
||
<div id="ep-save-template-modal" class="modal-overlay">
|
||
<div class="modal" style="max-width:420px">
|
||
<h3 style="margin:0 0 16px;font-size:18px" id="ep-save-modal-title">保存为模板</h3>
|
||
<div style="text-align:left;margin-bottom:16px">
|
||
<label style="display:block;font-size:12px;font-weight:600;margin-bottom:6px">模板名称</label>
|
||
<input type="text" id="ep-template-name-input" placeholder="输入模板名称..." style="width:100%;padding:10px 12px;background:#f8fafc;border:1px solid var(--line);border-radius:10px;font-size:13px;outline:none">
|
||
</div>
|
||
<div style="text-align:left;margin-bottom:16px">
|
||
<label style="display:block;font-size:12px;font-weight:600;margin-bottom:8px">标签分类</label>
|
||
<div style="display:flex;flex-wrap:wrap;gap:8px">
|
||
<label style="display:flex;align-items:center;gap:4px;font-size:12px;cursor:pointer;color:#64748b"><input type="checkbox" value="种草" style="accent-color:var(--primary)">种草</label>
|
||
<label style="display:flex;align-items:center;gap:4px;font-size:12px;cursor:pointer;color:#64748b"><input type="checkbox" value="知识" style="accent-color:var(--primary)">知识</label>
|
||
<label style="display:flex;align-items:center;gap:4px;font-size:12px;cursor:pointer;color:#64748b"><input type="checkbox" value="日常" style="accent-color:var(--primary)">日常</label>
|
||
<label style="display:flex;align-items:center;gap:4px;font-size:12px;cursor:pointer;color:#64748b"><input type="checkbox" value="推荐" style="accent-color:var(--primary)">推荐</label>
|
||
</div>
|
||
</div>
|
||
<div style="padding:12px;background:#f8fafc;border-radius:10px;font-size:12px;color:#64748b;text-align:left;margin-bottom:16px">
|
||
<div>📱 <b>视频格式</b>:竖屏 9:16(1080×1920)</div>
|
||
<div>🎭 <b>剪辑模式</b>:<span id="ep-template-mode-display">画中画</span></div>
|
||
<div>🎬 <b>片段数量</b>:<span id="ep-template-segment-count">0</span> 个</div>
|
||
</div>
|
||
<div style="display:flex;gap:10px">
|
||
<button class="btn ghost" onclick="closeModal('ep-save-template-modal')" style="flex:1">取消</button>
|
||
<button class="btn primary" onclick="epConfirmSaveTemplate()" style="flex:1">保存</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 生成视频弹窗 -->
|
||
<div id="ep-generate-modal" class="modal-overlay">
|
||
<div class="modal" style="max-width:420px">
|
||
<h3 style="margin:0 0 16px;font-size:18px">🎬 确认生成视频</h3>
|
||
<div id="ep-generate-summary" style="text-align:left;padding:14px;background:#f8fafc;border-radius:10px;font-size:13px;line-height:2;margin-bottom:16px"></div>
|
||
<div style="display:flex;gap:10px">
|
||
<button class="btn ghost" onclick="closeModal('ep-generate-modal')" style="flex:1">取消</button>
|
||
<button class="btn primary" onclick="epStartGenerate()" style="flex:1">开始生成</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<style>
|
||
/* 剪辑计划编辑器样式 */
|
||
.ep-mode-btn{padding:8px 14px;border-radius:10px;border:1px solid var(--line);cursor:pointer;transition:all .2s;background:#fff;display:flex;flex-direction:column;align-items:center;gap:2px;min-width:64px}
|
||
.ep-mode-btn:hover{border-color:var(--primary-light);background:#f8faff}
|
||
.ep-mode-btn.active{border-color:var(--primary);background:var(--primary-soft)}
|
||
.ep-mode-btn.active div:last-child{color:var(--primary)}
|
||
.ep-filter-chip{padding:4px 10px;border-radius:20px;font-size:10px;cursor:pointer;border:1px solid var(--line);color:#94a3b8;background:#f8fafc;transition:all .2s}
|
||
.ep-filter-chip:hover{border-color:var(--primary-light);color:#64748b}
|
||
.ep-filter-chip.active{border-color:var(--primary);color:var(--primary);background:var(--primary-soft)}
|
||
.ep-cover-tag{display:inline-flex;align-items:center;gap:4px;padding:6px 10px;border-radius:20px;font-size:10px;cursor:pointer;transition:all .2s;border:1px solid var(--line);color:#94a3b8;background:#f8fafc}
|
||
.ep-cover-tag:hover{border-color:var(--primary);color:var(--primary)}
|
||
.ep-cover-tag.active{border-color:var(--primary);color:var(--primary);background:var(--primary-soft)}
|
||
.ep-material-type-btn.active{border-color:var(--primary);background:var(--primary-soft);color:var(--primary)}
|
||
.ep-template-card{background:#fff;border:1px solid var(--line);border-radius:12px;padding:12px;cursor:pointer;transition:all .2s}
|
||
.ep-template-card:hover{border-color:var(--primary-light);box-shadow:0 4px 12px rgba(0,0,0,0.08)}
|
||
.ep-timeline-card{min-width:100px;height:100px;border-radius:12px;padding:10px;cursor:grab;position:relative;flex-shrink:0;display:flex;flex-direction:column;transition:all .15s;border:2px solid transparent}
|
||
.ep-timeline-card:hover{transform:translateY(-2px);box-shadow:0 4px 16px rgba(0,0,0,0.1)}
|
||
.ep-timeline-card.selected{border-color:var(--primary);box-shadow:0 0 12px rgba(99,102,241,0.4)}
|
||
.ep-toast{padding:10px 16px;border-radius:8px;font-size:12px;color:#fff;animation:epSlideIn .3s ease}
|
||
.ep-toast.hide{animation:epFadeOut .3s ease forwards}
|
||
.ep-toast-success{background:#10b981}
|
||
.ep-toast-info{background:var(--primary)}
|
||
.ep-toast-warning{background:#f59e0b;color:#fff}
|
||
@keyframes epSlideIn{from{opacity:0;transform:translateX(20px)}to{opacity:1;transform:translateX(0)}}
|
||
@keyframes epFadeOut{from{opacity:1}to{opacity:0}}
|
||
</style>
|
||
|
||
<script>
|
||
// ==================== 剪辑计划编辑器 JavaScript ====================
|
||
var epCurrentMode = 'pip';
|
||
var epSegments = [];
|
||
var epSelectedSegmentId = null;
|
||
var epCurrentTemplateId = null;
|
||
var epTemplates = [
|
||
{id:1,name:'产品卖点介绍',mode:'pip',tags:['种草','推荐'],segments:5,duration:'约2分钟'},
|
||
{id:2,name:'知识分享口播',mode:'voice_over',tags:['知识'],segments:3,duration:'约1分钟'},
|
||
{id:3,name:'一镜到底种草',mode:'one_take',tags:['种草','推荐'],segments:1,duration:'约30秒'},
|
||
];
|
||
var epCurrentFilter = 'all';
|
||
var epSearchQuery = '';
|
||
var epCurrentCoverScheme = 'ai';
|
||
var epIsPlaying = false;
|
||
var epPlayTimer = null;
|
||
var epPlayProgress = 0;
|
||
|
||
var EP_MODE_CONFIG = {
|
||
pip:{label:'画中画',icon:'🎭',color:'#6366f1'},
|
||
voice_over:{label:'人物口播',icon:'🎙️',color:'#10b981'},
|
||
one_take:{label:'一镜到底',icon:'🎬',color:'#f59e0b'},
|
||
voice_pip:{label:'口播+画中画',icon:'🎭🎙️',color:'#ec4899'}
|
||
};
|
||
var EP_COVER_SCHEME_LABELS = {
|
||
ai:'🤖 AI选帧',manual:'👆 手动选',upload:'📤 上传',repick:'🔄 AI重选'
|
||
};
|
||
|
||
function epInit(){
|
||
epRenderTemplateCards();
|
||
epRenderTimeline();
|
||
epUpdatePreview();
|
||
document.getElementById('ep-title-size-slider').addEventListener('input',function(){
|
||
document.getElementById('ep-title-size-value').textContent = this.value + 'px';
|
||
});
|
||
document.getElementById('ep-duration-min').addEventListener('change',epUpdateSegmentDuration);
|
||
document.getElementById('ep-duration-max').addEventListener('change',epUpdateSegmentDuration);
|
||
}
|
||
|
||
function epRenderTemplateCards(){
|
||
var container = document.getElementById('ep-template-cards');
|
||
if(epTemplates.length === 0){
|
||
container.innerHTML = '<div style="text-align:center;padding:20px;font-size:12px;color:#94a3b8">暂无已保存的模板</div>';
|
||
return;
|
||
}
|
||
var filtered = epTemplates;
|
||
if(epCurrentFilter !== 'all') filtered = filtered.filter(function(t){return t.tags.indexOf(epCurrentFilter) !== -1});
|
||
if(epSearchQuery){
|
||
var q = epSearchQuery.toLowerCase();
|
||
filtered = filtered.filter(function(t){return t.name.toLowerCase().indexOf(q) !== -1});
|
||
}
|
||
if(filtered.length === 0){
|
||
container.innerHTML = '<div style="text-align:center;padding:20px;font-size:12px;color:#94a3b8">未找到匹配的模板</div>';
|
||
return;
|
||
}
|
||
var html = '';
|
||
for(var i=0;i<filtered.length;i++){
|
||
var t = filtered[i];
|
||
html += '<div class="ep-template-card" onclick="epLoadTemplate(' + t.id + ')" style="margin-bottom:8px">';
|
||
html += '<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:6px">';
|
||
html += '<div style="font-size:12px;font-weight:600;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">' + t.name + '</div>';
|
||
html += '</div>';
|
||
html += '<div style="display:flex;align-items:center;gap:4px;margin-bottom:4px">';
|
||
html += '<span style="padding:2px 6px;background:var(--primary-soft);color:var(--primary);border-radius:4px;font-size:9px">' + (t.mode === 'pip' ? '🎭' : t.mode === 'voice_over' ? '🎙️' : '🎬') + '</span>';
|
||
html += '<span style="font-size:10px;color:#94a3b8">' + EP_MODE_CONFIG[t.mode].label + '</span>';
|
||
html += '</div>';
|
||
html += '<div style="font-size:10px;color:#94a3b8">' + t.segments + '个片段 · ' + t.duration + '</div>';
|
||
html += '</div>';
|
||
}
|
||
container.innerHTML = html;
|
||
}
|
||
|
||
function epLoadTemplate(id){
|
||
var t = null;
|
||
for(var i=0;i<epTemplates.length;i++){if(epTemplates[i].id === id){t = epTemplates[i];break;}}
|
||
if(!t) return;
|
||
epCurrentTemplateId = id;
|
||
switchEpMode(t.mode);
|
||
document.getElementById('ep-plan-title').textContent = t.name;
|
||
document.getElementById('ep-editing-indicator').textContent = '(编辑中)';
|
||
document.getElementById('ep-save-btn-text').textContent = '更新模板';
|
||
epShowToast('📋 已加载模板「' + t.name + '」','success');
|
||
}
|
||
|
||
function epFilterTemplates(){
|
||
epSearchQuery = document.getElementById('ep-template-search').value.trim();
|
||
epRenderTemplateCards();
|
||
}
|
||
|
||
function epSetFilter(el){
|
||
epCurrentFilter = el.dataset.filter;
|
||
var chips = document.querySelectorAll('#ep-filter-chips .ep-filter-chip');
|
||
for(var i=0;i<chips.length;i++) chips[i].classList.remove('active');
|
||
el.classList.add('active');
|
||
epRenderTemplateCards();
|
||
}
|
||
|
||
function epToggleTemplateList(){
|
||
document.getElementById('ep-back-btn').hidden = !document.getElementById('ep-back-btn').hidden;
|
||
}
|
||
|
||
function switchEpMode(mode){
|
||
epCurrentMode = mode;
|
||
var btns = document.querySelectorAll('.ep-mode-btn');
|
||
for(var i=0;i<btns.length;i++){
|
||
btns[i].classList.toggle('active', btns[i].dataset.mode === mode);
|
||
}
|
||
document.getElementById('ep-preview-mode-label').textContent = EP_MODE_CONFIG[mode].icon + ' ' + EP_MODE_CONFIG[mode].label;
|
||
document.getElementById('ep-template-mode-display').textContent = EP_MODE_CONFIG[mode].label;
|
||
document.getElementById('ep-one-take-hint').style.display = (mode === 'one_take') ? 'inline-block' : 'none';
|
||
if(mode === 'one_take' && epSegments.length > 1){
|
||
epSegments = [epSegments[0]];
|
||
epSelectedSegmentId = null;
|
||
document.getElementById('ep-segment-detail').hidden = true;
|
||
epShowToast('🔒 一镜到底模式已锁定为1个片段','warning');
|
||
}
|
||
epUpdateSegmentDetailPanel();
|
||
epRenderTimeline();
|
||
epUpdatePreview();
|
||
}
|
||
|
||
function epUpdateSegmentDetailPanel(){
|
||
var durSec = document.getElementById('ep-duration-section');
|
||
var durLock = document.getElementById('ep-duration-locked');
|
||
var matType = document.getElementById('ep-material-type-section');
|
||
if(epCurrentMode === 'one_take' || epCurrentMode === 'voice_over'){
|
||
durSec.style.display = 'none';
|
||
durLock.style.display = 'block';
|
||
}else{
|
||
durSec.style.display = 'block';
|
||
durLock.style.display = 'none';
|
||
}
|
||
if(epCurrentMode === 'voice_pip') matType.style.display = 'block';
|
||
else matType.style.display = 'none';
|
||
}
|
||
|
||
function epRenderTimeline(){
|
||
var track = document.getElementById('ep-timeline-track');
|
||
var html = '';
|
||
var cfg = EP_MODE_CONFIG[epCurrentMode];
|
||
for(var i=0;i<epSegments.length;i++){
|
||
var seg = epSegments[i];
|
||
var isSelected = (seg.id === epSelectedSegmentId);
|
||
var typeTag = '';
|
||
if(epCurrentMode === 'voice_pip'){
|
||
typeTag = '<span style="font-size:9px;padding:2px 6px;border-radius:4px;background:' + (seg.materialType === 'person' ? 'rgba(99,102,241,0.2)' : 'rgba(16,185,129,0.2)') + ';color:' + (seg.materialType === 'person' ? '#6366f1' : '#10b981') + '">' + (seg.materialType === 'person' ? '👤' : '🏞️') + '</span>';
|
||
}
|
||
var scriptIcon = seg.hasScript ? '🎤' : '🔇';
|
||
var durText = (epCurrentMode === 'one_take' || epCurrentMode === 'voice_over') ? '🔒 由配音决定' : seg.durationMin + '-' + seg.durationMax + 's';
|
||
html += '<div class="ep-timeline-card ' + (isSelected ? 'selected' : '') + '" style="background:' + cfg.color + '22;border-color:' + (isSelected ? '#fff' : cfg.color + '44') + '" draggable="true" data-id="' + seg.id + '" onclick="epSelectSegment(' + seg.id + ')" ondragstart="epDragStart(event,' + seg.id + ')" ondragover="epDragOver(event)" ondrop="epDrop(event,' + seg.id + ')">';
|
||
html += '<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:6px">';
|
||
html += '<span style="font-size:11px;font-weight:500">片段' + (i + 1) + '</span>';
|
||
html += '<div style="display:flex;align-items:center;gap:4px">' + typeTag + '<span style="font-size:9px">' + scriptIcon + '</span></div>';
|
||
html += '</div>';
|
||
html += '<div style="font-size:10px;color:rgba(255,255,255,0.7);background:rgba(0,0,0,0.3);padding:4px 8px;border-radius:4px;margin-bottom:auto">' + durText + '</div>';
|
||
html += '<div style="display:flex;align-items:center;justify-content:space-between;margin-top:auto;padding-top:6px">';
|
||
html += '<span style="font-size:9px;color:rgba(255,255,255,0.5)">👆 拖拽排序</span>';
|
||
html += '<button onclick="event.stopPropagation();epDeleteSegment(' + seg.id + ')" style="background:none;border:none;color:rgba(255,255,255,0.5);cursor:pointer;font-size:12px">×</button>';
|
||
html += '</div></div>';
|
||
}
|
||
var isOneTake = (epCurrentMode === 'one_take');
|
||
if(!isOneTake){
|
||
html += '<div onclick="epAddSegment()" style="min-width:60px;height:100px;border:2px dashed var(--line);border-radius:12px;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:24px;color:#94a3b8;transition:all .2s" onmouseover="this.style.borderColor=\'var(--primary)\';this.style.color=\'var(--primary)\'" onmouseout="this.style.borderColor=\'var(--line)\';this.style.color=\'#94a3b8\'">+</div>';
|
||
}else{
|
||
html += '<div style="min-width:60px;height:100px;border:2px dashed #e2e8f0;border-radius:12px;display:flex;align-items:center;justify-content:center;font-size:20px;color:#cbd5e1">🔒</div>';
|
||
}
|
||
track.innerHTML = html;
|
||
epUpdateDurationBadge();
|
||
}
|
||
|
||
function epUpdateDurationBadge(){
|
||
if(epCurrentMode === 'one_take' || epCurrentMode === 'voice_over'){
|
||
document.getElementById('ep-total-duration-badge').textContent = '总时长: 由配音决定';
|
||
document.getElementById('ep-total-time').textContent = '00:00 / 配音时长';
|
||
}else{
|
||
var totalMin = 0,totalMax = 0;
|
||
for(var i=0;i<epSegments.length;i++){totalMin += epSegments[i].durationMin;totalMax += epSegments[i].durationMax;}
|
||
document.getElementById('ep-total-duration-badge').textContent = '总时长: ' + totalMin + '-' + totalMax + 's';
|
||
var mm = String(Math.floor(totalMax / 60)).padStart(2,'0');
|
||
var ss = String(totalMax % 60).padStart(2,'0');
|
||
document.getElementById('ep-total-time').textContent = '00:00 / ' + mm + ':' + ss;
|
||
}
|
||
}
|
||
|
||
function epSelectSegment(id){
|
||
epSelectedSegmentId = id;
|
||
var seg = null;
|
||
for(var i=0;i<epSegments.length;i++){if(epSegments[i].id === id){seg = epSegments[i];break;}}
|
||
if(!seg) return;
|
||
document.getElementById('ep-segment-detail').hidden = false;
|
||
var idx = 0;
|
||
for(var i=0;i<epSegments.length;i++){if(epSegments[i].id === id){idx = i;break;}}
|
||
document.getElementById('ep-segment-detail-title').textContent = '片段 ' + (idx + 1);
|
||
document.getElementById('ep-duration-min').value = seg.durationMin;
|
||
document.getElementById('ep-duration-max').value = seg.durationMax;
|
||
var scriptToggle = document.getElementById('ep-script-toggle');
|
||
var scriptHint = document.getElementById('ep-script-hint');
|
||
var scriptInput = document.getElementById('ep-script-input');
|
||
if(seg.hasScript){
|
||
scriptToggle.classList.add('on');
|
||
scriptHint.textContent = '🎤 有配音文案';
|
||
scriptInput.style.display = 'block';
|
||
document.getElementById('ep-script-textarea').value = seg.script || '';
|
||
}else{
|
||
scriptToggle.classList.remove('on');
|
||
scriptHint.textContent = '🔇 使用原声';
|
||
scriptInput.style.display = 'none';
|
||
}
|
||
var btns = document.querySelectorAll('.ep-material-type-btn');
|
||
for(var i=0;i<btns.length;i++){
|
||
var isActive = (btns[i].dataset.type === seg.materialType);
|
||
btns[i].classList.toggle('active',isActive);
|
||
btns[i].style.borderColor = isActive ? 'var(--primary)' : 'var(--line)';
|
||
}
|
||
epRenderTimeline();
|
||
}
|
||
|
||
function epDeleteSegment(id){
|
||
if(epCurrentMode === 'one_take') return;
|
||
epSegments = epSegments.filter(function(s){return s.id !== id});
|
||
if(epSelectedSegmentId === id){epSelectedSegmentId = null;document.getElementById('ep-segment-detail').hidden = true;}
|
||
epRenderTimeline();
|
||
epShowToast('片段已删除','info');
|
||
}
|
||
|
||
function epDeleteCurrentSegment(){
|
||
if(epSelectedSegmentId) epDeleteSegment(epSelectedSegmentId);
|
||
}
|
||
|
||
function epAddSegment(){
|
||
if(epCurrentMode === 'one_take') return;
|
||
var newId = 1;
|
||
for(var i=0;i<epSegments.length;i++) if(epSegments[i].id >= newId) newId = epSegments[i].id + 1;
|
||
epSegments.push({id:newId,durationMin:3,durationMax:8,script:'',hasScript:false,materialType:'person'});
|
||
epSelectSegment(newId);
|
||
epRenderTimeline();
|
||
epShowToast('新片段已添加','success');
|
||
}
|
||
|
||
function epUpdateSegmentDuration(){
|
||
if(!epSelectedSegmentId) return;
|
||
for(var i=0;i<epSegments.length;i++){
|
||
if(epSegments[i].id === epSelectedSegmentId){
|
||
epSegments[i].durationMin = parseInt(document.getElementById('ep-duration-min').value) || 3;
|
||
epSegments[i].durationMax = parseInt(document.getElementById('ep-duration-max').value) || 8;
|
||
break;
|
||
}
|
||
}
|
||
epRenderTimeline();
|
||
}
|
||
|
||
function epToggleScript(){
|
||
var toggle = document.getElementById('ep-script-toggle');
|
||
var hint = document.getElementById('ep-script-hint');
|
||
var input = document.getElementById('ep-script-input');
|
||
toggle.classList.toggle('on');
|
||
var isOn = toggle.classList.contains('on');
|
||
if(isOn){
|
||
hint.textContent = '🎤 有配音文案';
|
||
input.style.display = 'block';
|
||
if(epSelectedSegmentId){
|
||
for(var i=0;i<epSegments.length;i++){
|
||
if(epSegments[i].id === epSelectedSegmentId){epSegments[i].hasScript = true;break;}
|
||
}
|
||
}
|
||
}else{
|
||
hint.textContent = '🔇 使用原声';
|
||
input.style.display = 'none';
|
||
if(epSelectedSegmentId){
|
||
for(var i=0;i<epSegments.length;i++){
|
||
if(epSegments[i].id === epSelectedSegmentId){epSegments[i].hasScript = false;epSegments[i].script = '';break;}
|
||
}
|
||
}
|
||
}
|
||
epRenderTimeline();
|
||
}
|
||
|
||
function epSelectMaterialType(btn){
|
||
var type = btn.dataset.type;
|
||
var btns = document.querySelectorAll('.ep-material-type-btn');
|
||
for(var i=0;i<btns.length;i++){btns[i].classList.remove('active');btns[i].style.borderColor = 'var(--line)';}
|
||
btn.classList.add('active');
|
||
btn.style.borderColor = 'var(--primary)';
|
||
if(epSelectedSegmentId){
|
||
for(var i=0;i<epSegments.length;i++){
|
||
if(epSegments[i].id === epSelectedSegmentId){epSegments[i].materialType = type;break;}
|
||
}
|
||
}
|
||
epRenderTimeline();
|
||
}
|
||
|
||
function epToggleTitleAi(){
|
||
var toggle = document.getElementById('ep-title-ai-toggle');
|
||
var hint = document.getElementById('ep-title-ai-hint');
|
||
var inputSection = document.getElementById('ep-title-input-section');
|
||
toggle.classList.toggle('on');
|
||
var isOn = toggle.classList.contains('on');
|
||
hint.style.display = isOn ? 'block' : 'none';
|
||
inputSection.style.display = isOn ? 'none' : 'block';
|
||
}
|
||
|
||
function epSelectCoverScheme(btn){
|
||
var tags = document.querySelectorAll('.ep-cover-tag');
|
||
for(var i=0;i<tags.length;i++) tags[i].classList.remove('active');
|
||
btn.classList.add('active');
|
||
epCurrentCoverScheme = btn.dataset.cover;
|
||
document.getElementById('ep-cover-source-tag').textContent = EP_COVER_SCHEME_LABELS[epCurrentCoverScheme];
|
||
var box = document.getElementById('ep-cover-preview-box');
|
||
if(epCurrentCoverScheme === 'upload'){
|
||
box.style.background = 'linear-gradient(135deg,#1a4a2e,#2d7a4e)';
|
||
}else if(epCurrentCoverScheme === 'manual'){
|
||
box.style.background = 'linear-gradient(135deg,#2a1f6e,#6366f1)';
|
||
}else if(epCurrentCoverScheme === 'repick'){
|
||
box.style.background = 'linear-gradient(135deg,#6e2d5c,#a29bfe)';
|
||
}else{
|
||
box.style.background = 'linear-gradient(135deg,#2d1f6e,#6366f1,#a29bfe)';
|
||
}
|
||
}
|
||
|
||
function epTogglePreview(){
|
||
if(epIsPlaying){epStopPreview();}else{epStartPreview();}
|
||
}
|
||
|
||
function epStartPreview(){
|
||
epIsPlaying = true;
|
||
var totalDur = 120;
|
||
if(epCurrentMode !== 'one_take' && epCurrentMode !== 'voice_over'){
|
||
totalDur = 0;
|
||
for(var i=0;i<epSegments.length;i++) totalDur += epSegments[i].durationMax;
|
||
if(totalDur === 0) totalDur = 120;
|
||
}
|
||
epPlayProgress = 0;
|
||
epPlayTimer = setInterval(function(){
|
||
epPlayProgress++;
|
||
if(epPlayProgress >= totalDur){epPlayProgress = 0;epStopPreview();return;}
|
||
var pct = (epPlayProgress / totalDur) * 100;
|
||
document.getElementById('ep-progress-bar').style.width = pct + '%';
|
||
document.getElementById('ep-current-time').textContent = epFormatTime(epPlayProgress);
|
||
if(epCurrentMode === 'one_take'){
|
||
document.getElementById('ep-preview-mode-label').textContent = '🎬 片段1';
|
||
}else{
|
||
var elapsed = 0;
|
||
for(var i=0;i<epSegments.length;i++){
|
||
if(epPlayProgress < elapsed + epSegments[i].durationMax){
|
||
document.getElementById('ep-preview-mode-label').textContent = '片段' + (i + 1);
|
||
break;
|
||
}
|
||
elapsed += epSegments[i].durationMax;
|
||
}
|
||
}
|
||
},1000);
|
||
}
|
||
|
||
function epStopPreview(){
|
||
epIsPlaying = false;
|
||
clearInterval(epPlayTimer);
|
||
}
|
||
|
||
function epUpdatePreview(){
|
||
var cfg = EP_MODE_CONFIG[epCurrentMode];
|
||
document.getElementById('ep-preview-mode-label').textContent = cfg.icon + ' ' + cfg.label;
|
||
}
|
||
|
||
function epUndo(){epShowToast('↩ 撤销','info');}
|
||
function epRedo(){epShowToast('↪ 重做','info');}
|
||
|
||
var epDragSegmentId = null;
|
||
function epDragStart(e,id){epDragSegmentId = id;e.target.style.opacity = '0.5';}
|
||
function epDragOver(e){e.preventDefault();}
|
||
function epDrop(e,targetId){
|
||
e.preventDefault();
|
||
if(epDragSegmentId === null || epDragSegmentId === targetId) return;
|
||
if(epCurrentMode === 'one_take') return;
|
||
var fromIdx = -1,toIdx = -1;
|
||
for(var i=0;i<epSegments.length;i++){
|
||
if(epSegments[i].id === epDragSegmentId) fromIdx = i;
|
||
if(epSegments[i].id === targetId) toIdx = i;
|
||
}
|
||
if(fromIdx !== -1 && toIdx !== -1){
|
||
var item = epSegments.splice(fromIdx,1)[0];
|
||
epSegments.splice(toIdx,0,item);
|
||
epRenderTimeline();
|
||
epShowToast('片段顺序已调整','info');
|
||
}
|
||
epDragSegmentId = null;
|
||
}
|
||
|
||
function epSaveTemplate(){
|
||
document.getElementById('ep-template-segment-count').textContent = epSegments.length;
|
||
document.getElementById('ep-template-mode-display').textContent = EP_MODE_CONFIG[epCurrentMode].label;
|
||
if(epCurrentTemplateId){
|
||
for(var i=0;i<epTemplates.length;i++){
|
||
if(epTemplates[i].id === epCurrentTemplateId){
|
||
document.getElementById('ep-template-name-input').value = epTemplates[i].name;
|
||
var cbs = document.querySelectorAll('#ep-save-template-modal input[type="checkbox"]');
|
||
for(var j=0;j<cbs.length;j++) cbs[j].checked = (epTemplates[i].tags.indexOf(cbs[j].value) !== -1);
|
||
break;
|
||
}
|
||
}
|
||
document.getElementById('ep-save-modal-title').textContent = '更新模板';
|
||
}else{
|
||
document.getElementById('ep-template-name-input').value = '';
|
||
var cbs = document.querySelectorAll('#ep-save-template-modal input[type="checkbox"]');
|
||
for(var j=0;j<cbs.length;j++) cbs[j].checked = false;
|
||
document.getElementById('ep-save-modal-title').textContent = '保存为模板';
|
||
}
|
||
openModal('ep-save-template-modal');
|
||
}
|
||
|
||
function epConfirmSaveTemplate(){
|
||
var name = document.getElementById('ep-template-name-input').value.trim();
|
||
if(!name){epShowToast('请输入模板名称','warning');return;}
|
||
var checkedTags = [];
|
||
var cbs = document.querySelectorAll('#ep-save-template-modal input[type="checkbox"]:checked');
|
||
for(var i=0;i<cbs.length;i++) checkedTags.push(cbs[i].value);
|
||
var totalMax = 0;
|
||
for(var i=0;i<epSegments.length;i++) totalMax += epSegments[i].durationMax;
|
||
var dur = '约' + Math.ceil(totalMax / 60) + '分钟';
|
||
if(epCurrentTemplateId){
|
||
for(var i=0;i<epTemplates.length;i++){
|
||
if(epTemplates[i].id === epCurrentTemplateId){
|
||
epTemplates[i].name = name;
|
||
epTemplates[i].mode = epCurrentMode;
|
||
epTemplates[i].tags = checkedTags.length ? checkedTags : ['未分类'];
|
||
epTemplates[i].segments = epSegments.length;
|
||
epTemplates[i].duration = dur;
|
||
break;
|
||
}
|
||
}
|
||
closeModal('ep-save-template-modal');
|
||
document.getElementById('ep-plan-title').textContent = name;
|
||
epShowToast('✅ 模板「' + name + '」已更新','success');
|
||
}else{
|
||
var newId = 1;
|
||
for(var i=0;i<epTemplates.length;i++) if(epTemplates[i].id >= newId) newId = epTemplates[i].id + 1;
|
||
epTemplates.push({id:newId,name:name,mode:epCurrentMode,tags:checkedTags.length ? checkedTags : ['未分类'],segments:epSegments.length,duration:dur});
|
||
epCurrentTemplateId = newId;
|
||
closeModal('ep-save-template-modal');
|
||
epShowToast('✅ 模板「' + name + '」已保存','success');
|
||
}
|
||
epRenderTemplateCards();
|
||
}
|
||
|
||
function epGenerateVideo(){
|
||
var segsWithScript = 0;
|
||
for(var i=0;i<epSegments.length;i++) if(epSegments[i].hasScript) segsWithScript++;
|
||
var durationText = '由配音决定';
|
||
if(epCurrentMode !== 'one_take' && epCurrentMode !== 'voice_over'){
|
||
var totalMin = 0,totalMax = 0;
|
||
for(var i=0;i<epSegments.length;i++){totalMin += epSegments[i].durationMin;totalMax += epSegments[i].durationMax;}
|
||
durationText = totalMin + '-' + totalMax + '秒';
|
||
}
|
||
document.getElementById('ep-generate-summary').innerHTML = '<div>📱 <b>视频格式</b>:竖屏 9:16(1080×1920)</div><div>🎭 <b>剪辑模式</b>:' + EP_MODE_CONFIG[epCurrentMode].icon + ' ' + EP_MODE_CONFIG[epCurrentMode].label + '</div><div>🎬 <b>片段数量</b>:' + epSegments.length + ' 个</div><div>⏱️ <b>预计总时长</b>:' + durationText + '</div><div>📝 <b>配音文案</b>:' + segsWithScript + ' 段有台词</div>';
|
||
openModal('ep-generate-modal');
|
||
}
|
||
|
||
function epStartGenerate(){
|
||
closeModal('ep-generate-modal');
|
||
epShowToast('🎬 视频生成任务已提交,预计需要3-5分钟...','success');
|
||
setTimeout(function(){epShowToast('🔍 正在进行查重检测...','info');},3000);
|
||
setTimeout(function(){epShowToast('✅ 查重通过,视频已就绪!','success');},6000);
|
||
}
|
||
|
||
function epFormatTime(seconds){
|
||
seconds = Math.max(0,Math.floor(seconds));
|
||
var m = Math.floor(seconds / 60);
|
||
var s = seconds % 60;
|
||
return String(m).padStart(2,'0') + ':' + String(s).padStart(2,'0');
|
||
}
|
||
|
||
function epShowToast(msg,type){
|
||
type = type || 'info';
|
||
var container = document.getElementById('ep-toast-container');
|
||
var toast = document.createElement('div');
|
||
toast.className = 'ep-toast ep-toast-' + type;
|
||
toast.textContent = msg;
|
||
container.appendChild(toast);
|
||
setTimeout(function(){
|
||
toast.classList.add('hide');
|
||
setTimeout(function(){toast.remove();},300);
|
||
},2500);
|
||
}
|
||
|
||
document.addEventListener('DOMContentLoaded',epInit);
|
||
</script>
|
||
|
||
<!-- ==================== 音色克隆功能 JavaScript ==================== -->
|
||
<script>
|
||
// 已克隆音色数据
|
||
var clonedVoices = [
|
||
{id: 1, name: '我的默认音色', duration: '15秒', createdAt: '2024年6月15日', status: 'ready'}
|
||
];
|
||
var selectedCloneVoiceId = null;
|
||
var currentCloneAudio = null;
|
||
var cloneRecordTimer = null;
|
||
var cloneRecordSeconds = 0;
|
||
var cloneAudioPlayTimer = null;
|
||
|
||
// 打开克隆音色弹窗
|
||
function openCloneVoiceModal() {
|
||
// 重置表单状态
|
||
document.getElementById('clone-voice-name').value = '我的声音 ' + (clonedVoices.length + 1);
|
||
document.getElementById('clone-upload-input').value = '';
|
||
document.getElementById('clone-audio-preview-modal').style.display = 'none';
|
||
document.getElementById('clone-modal-progress').style.display = 'none';
|
||
document.getElementById('clone-modal-success').style.display = 'none';
|
||
document.getElementById('clone-modal-buttons').style.display = 'flex';
|
||
document.getElementById('clone-modal-done').style.display = 'none';
|
||
document.getElementById('clone-start-btn').disabled = true;
|
||
document.getElementById('clone-record-idle').style.display = 'block';
|
||
document.getElementById('clone-record-recording').style.display = 'none';
|
||
document.getElementById('clone-record-preview').style.display = 'none';
|
||
currentCloneAudio = null;
|
||
openModal('modal-cloneVoice');
|
||
}
|
||
|
||
// 处理文件上传
|
||
function handleCloneFileUpload(input) {
|
||
if (input.files && input.files[0]) {
|
||
var file = input.files[0];
|
||
if (!file.name.match(/\.(mp3|wav)$/i)) {
|
||
alert('请上传 MP3 或 WAV 格式的音频文件');
|
||
return;
|
||
}
|
||
currentCloneAudio = {
|
||
name: file.name,
|
||
type: 'upload',
|
||
duration: Math.floor(Math.random() * 60) + 10 + '秒'
|
||
};
|
||
document.getElementById('clone-audio-preview-modal').style.display = 'block';
|
||
document.getElementById('clone-preview-name').textContent = file.name;
|
||
document.getElementById('clone-preview-duration').textContent = '00:00 / ' + currentCloneAudio.duration;
|
||
document.getElementById('clone-start-btn').disabled = false;
|
||
}
|
||
}
|
||
|
||
// 处理拖拽上传
|
||
function handleCloneDrop(e) {
|
||
e.preventDefault();
|
||
e.target.style.borderColor = 'var(--line)';
|
||
var files = e.dataTransfer.files;
|
||
if (files.length > 0) {
|
||
var input = document.getElementById('clone-upload-input');
|
||
var dt = new DataTransfer();
|
||
dt.items.add(files[0]);
|
||
input.files = dt.files;
|
||
handleCloneFileUpload(input);
|
||
}
|
||
}
|
||
|
||
// 移除音频
|
||
function removeCloneAudio() {
|
||
currentCloneAudio = null;
|
||
document.getElementById('clone-upload-input').value = '';
|
||
document.getElementById('clone-audio-preview-modal').style.display = 'none';
|
||
document.getElementById('clone-start-btn').disabled = true;
|
||
document.getElementById('clone-record-idle').style.display = 'block';
|
||
document.getElementById('clone-record-recording').style.display = 'none';
|
||
document.getElementById('clone-record-preview').style.display = 'none';
|
||
}
|
||
|
||
// 播放音频预览
|
||
function playClonePreview() {
|
||
// 模拟播放进度
|
||
var progress = 0;
|
||
var interval = setInterval(function() {
|
||
progress += 5;
|
||
if (progress >= 100) {
|
||
progress = 0;
|
||
clearInterval(interval);
|
||
}
|
||
document.getElementById('clone-preview-progress').style.width = progress + '%';
|
||
}, 200);
|
||
}
|
||
|
||
// 开始录音
|
||
function startCloneRecording() {
|
||
document.getElementById('clone-record-idle').style.display = 'none';
|
||
document.getElementById('clone-record-recording').style.display = 'block';
|
||
document.getElementById('clone-record-preview').style.display = 'none';
|
||
cloneRecordSeconds = 0;
|
||
updateCloneRecordTimer();
|
||
cloneRecordTimer = setInterval(function() {
|
||
cloneRecordSeconds++;
|
||
updateCloneRecordTimer();
|
||
if (cloneRecordSeconds >= 120) { // 最多2分钟
|
||
stopCloneRecording();
|
||
}
|
||
}, 1000);
|
||
}
|
||
|
||
function updateCloneRecordTimer() {
|
||
var m = Math.floor(cloneRecordSeconds / 60);
|
||
var s = cloneRecordSeconds % 60;
|
||
document.getElementById('clone-record-timer').textContent = String(m).padStart(2, '0') + ':' + String(s).padStart(2, '0');
|
||
}
|
||
|
||
// 停止录音
|
||
function stopCloneRecording() {
|
||
clearInterval(cloneRecordTimer);
|
||
document.getElementById('clone-record-idle').style.display = 'none';
|
||
document.getElementById('clone-record-recording').style.display = 'none';
|
||
document.getElementById('clone-record-preview').style.display = 'block';
|
||
currentCloneAudio = {
|
||
name: '录音_' + new Date().toLocaleTimeString() + '.wav',
|
||
type: 'record',
|
||
duration: Math.floor(cloneRecordSeconds) + '秒'
|
||
};
|
||
}
|
||
|
||
// 重新录制
|
||
function reRecordClone() {
|
||
document.getElementById('clone-record-idle').style.display = 'block';
|
||
document.getElementById('clone-record-recording').style.display = 'none';
|
||
document.getElementById('clone-record-preview').style.display = 'none';
|
||
currentCloneAudio = null;
|
||
document.getElementById('clone-start-btn').disabled = true;
|
||
}
|
||
|
||
// 使用录音
|
||
function useCloneRecording() {
|
||
document.getElementById('clone-audio-preview-modal').style.display = 'block';
|
||
document.getElementById('clone-preview-name').textContent = currentCloneAudio.name;
|
||
document.getElementById('clone-preview-duration').textContent = '00:00 / ' + currentCloneAudio.duration;
|
||
document.getElementById('clone-record-idle').style.display = 'none';
|
||
document.getElementById('clone-record-recording').style.display = 'none';
|
||
document.getElementById('clone-record-preview').style.display = 'none';
|
||
document.getElementById('clone-start-btn').disabled = false;
|
||
}
|
||
|
||
// 开始克隆流程
|
||
function startCloneVoiceProcess() {
|
||
if (!currentCloneAudio) {
|
||
alert('请先上传或录制音频');
|
||
return;
|
||
}
|
||
|
||
var voiceName = document.getElementById('clone-voice-name').value || '我的声音';
|
||
document.getElementById('clone-modal-buttons').style.display = 'none';
|
||
document.getElementById('clone-modal-progress').style.display = 'block';
|
||
document.getElementById('clone-modal-progress-text').textContent = '正在处理音频...';
|
||
|
||
var progress = 0;
|
||
var progressBar = document.getElementById('clone-modal-progress-bar');
|
||
var progressText = document.getElementById('clone-modal-progress-text');
|
||
var steps = ['正在处理音频...', '正在提取音色特征...', '正在训练AI模型...', '正在保存音色...', '即将完成...'];
|
||
|
||
var interval = setInterval(function() {
|
||
progress += 2;
|
||
progressBar.style.width = progress + '%';
|
||
progressText.textContent = steps[Math.min(Math.floor(progress / 20), steps.length - 1)];
|
||
|
||
if (progress >= 100) {
|
||
clearInterval(interval);
|
||
// 克隆成功
|
||
document.getElementById('clone-modal-progress').style.display = 'none';
|
||
document.getElementById('clone-modal-success').style.display = 'block';
|
||
document.getElementById('clone-modal-done').style.display = 'flex';
|
||
|
||
// 添加到音色列表
|
||
var newVoice = {
|
||
id: Date.now(),
|
||
name: voiceName,
|
||
duration: currentCloneAudio.duration,
|
||
createdAt: new Date().toLocaleDateString(),
|
||
status: 'ready'
|
||
};
|
||
clonedVoices.push(newVoice);
|
||
renderClonedVoices();
|
||
}
|
||
}, 60);
|
||
}
|
||
|
||
// 渲染音色列表
|
||
function renderClonedVoices() {
|
||
var container = document.getElementById('voice-clone-list');
|
||
if (!container) return;
|
||
|
||
if (clonedVoices.length === 0) {
|
||
document.getElementById('voice-clone-empty').style.display = 'block';
|
||
container.innerHTML = '';
|
||
return;
|
||
}
|
||
|
||
document.getElementById('voice-clone-empty').style.display = 'none';
|
||
|
||
var html = '';
|
||
clonedVoices.forEach(function(voice) {
|
||
var statusClass = voice.status === 'ready' ? 'ok' : (voice.status === 'cloning' ? 'warn' : 'bad');
|
||
var statusText = voice.status === 'ready' ? '已就绪' : (voice.status === 'cloning' ? '克隆中' : '失败');
|
||
|
||
html += '<div class="voice-clone-card" data-voice-id="' + voice.id + '" style="background:#fff;border:1px solid var(--line);border-radius:var(--radius-lg);padding:20px;position:relative">';
|
||
html += '<div style="position:absolute;top:16px;right:16px">';
|
||
html += '<button class="btn ghost sm" onclick="deleteVoiceCloneItem(' + voice.id + ')" style="padding:4px 8px;font-size:11px">🗑️</button>';
|
||
html += '<button class="btn ghost sm" onclick="renameVoiceCloneItem(' + voice.id + ')" style="padding:4px 8px;font-size:11px">✏️</button>';
|
||
html += '</div>';
|
||
html += '<div style="display:flex;align-items:center;gap:14px;margin-bottom:14px">';
|
||
html += '<div style="width:56px;height:56px;border-radius:50%;background:linear-gradient(135deg,#f59e0b,#d97706);display:grid;place-items:center;color:#fff;font-size:24px">🎤</div>';
|
||
html += '<div>';
|
||
html += '<h4 style="margin:0 0 4px;font-size:15px;font-weight:600">' + voice.name + '</h4>';
|
||
html += '<span class="pill ' + statusClass + '">' + statusText + '</span>';
|
||
html += '</div></div>';
|
||
html += '<div style="font-size:13px;color:var(--muted);margin-bottom:12px">';
|
||
html += '<div style="margin-bottom:4px">🎵 时长:' + voice.duration + '</div>';
|
||
html += '<div>📅 创建于:' + voice.createdAt + '</div></div>';
|
||
html += '<div style="display:flex;align-items:center;gap:10px;padding:10px;background:#f8fafc;border-radius:10px">';
|
||
html += '<button class="btn ghost sm" onclick="playVoiceCloneItem(' + voice.id + ')" style="flex:1">▶ 试听</button>';
|
||
html += '<button class="btn primary sm" onclick="useVoiceCloneItem(' + voice.id + ')" style="flex:1">✨ 使用此音色</button>';
|
||
html += '</div></div>';
|
||
});
|
||
container.innerHTML = html;
|
||
}
|
||
|
||
// 在一键生成页面渲染已克隆音色列表
|
||
function renderClonedVoicesForStep4() {
|
||
var container = document.getElementById('cloned-voice-list-step4');
|
||
if (!container) return;
|
||
|
||
if (clonedVoices.length === 0) {
|
||
container.innerHTML = '<p style="font-size:12px;color:var(--muted);padding:8px 0">暂无已克隆音色,<a href="#" onclick="showView(\'voiceClone\');return false" style="color:var(--primary)">去克隆</a></p>';
|
||
return;
|
||
}
|
||
|
||
var html = '';
|
||
clonedVoices.forEach(function(voice) {
|
||
html += '<label style="display:flex;align-items:center;gap:10px;padding:10px;background:#f8fafc;border-radius:10px;cursor:pointer">';
|
||
html += '<input type="radio" name="cloned-voice-select" value="' + voice.id + '" onclick="selectClonedVoice(' + voice.id + ')" style="width:16px;height:16px;accent-color:var(--primary)"/>';
|
||
html += '<div style="flex:1">';
|
||
html += '<div style="font-weight:600;font-size:13px">' + voice.name + '</div>';
|
||
html += '<div style="font-size:11px;color:var(--muted)">' + voice.duration + '</div></div>';
|
||
html += '<span class="pill ok" style="font-size:10px">就绪</span></label>';
|
||
});
|
||
container.innerHTML = html;
|
||
}
|
||
|
||
// 选择已克隆音色
|
||
function selectClonedVoice(voiceId) {
|
||
selectedCloneVoiceId = voiceId;
|
||
document.getElementById('start-clone-btn').disabled = false;
|
||
}
|
||
|
||
// 在step-4中选择配音选项
|
||
function selectVoiceChoice(el, voiceType) {
|
||
document.querySelectorAll('#voice-choice-list .choice-item').forEach(function(item) {
|
||
item.classList.remove('selected');
|
||
});
|
||
el.classList.add('selected');
|
||
|
||
// 隐藏/显示克隆声音展开区域
|
||
var expandArea = document.getElementById('clone-voice-expand');
|
||
if (voiceType === 'clone') {
|
||
expandArea.style.display = 'block';
|
||
renderClonedVoicesForStep4();
|
||
} else {
|
||
expandArea.style.display = 'none';
|
||
}
|
||
}
|
||
|
||
// 处理克隆音频上传(step-4中)
|
||
function handleCloneAudioUpload(input) {
|
||
if (input.files && input.files[0]) {
|
||
var file = input.files[0];
|
||
document.getElementById('clone-audio-preview').style.display = 'block';
|
||
document.getElementById('clone-audio-name').textContent = file.name;
|
||
document.getElementById('clone-audio-duration').textContent = '00:00 / 00:' + (Math.floor(Math.random() * 30) + 10);
|
||
document.getElementById('start-clone-btn').disabled = false;
|
||
}
|
||
}
|
||
|
||
// 播放克隆音频(step-4中)
|
||
function playCloneAudio() {
|
||
var progress = 0;
|
||
var interval = setInterval(function() {
|
||
progress += 5;
|
||
if (progress >= 100) {
|
||
progress = 0;
|
||
clearInterval(interval);
|
||
}
|
||
document.getElementById('clone-audio-progress').style.width = progress + '%';
|
||
}, 200);
|
||
}
|
||
|
||
// 开始克隆(step-4中)
|
||
function startVoiceClone() {
|
||
var progressArea = document.getElementById('clone-progress-area');
|
||
var successArea = document.getElementById('clone-success-area');
|
||
var progressBar = document.getElementById('clone-progress-bar');
|
||
var progressText = document.getElementById('clone-progress-text');
|
||
|
||
progressArea.style.display = 'block';
|
||
successArea.style.display = 'none';
|
||
|
||
var progress = 0;
|
||
var steps = ['正在处理音频...', '正在提取音色...', '正在克隆...', '即将完成...'];
|
||
|
||
var interval = setInterval(function() {
|
||
progress += 3;
|
||
progressBar.style.width = progress + '%';
|
||
progressText.textContent = steps[Math.min(Math.floor(progress / 25), steps.length - 1)];
|
||
|
||
if (progress >= 100) {
|
||
clearInterval(interval);
|
||
progressArea.style.display = 'none';
|
||
successArea.style.display = 'block';
|
||
}
|
||
}, 80);
|
||
}
|
||
|
||
// 音色库页面操作
|
||
function deleteVoiceClone(btn) {
|
||
var card = btn.closest('.voice-clone-card');
|
||
if (card) {
|
||
var voiceId = card.dataset.voiceId;
|
||
if (confirm('确定要删除这个音色吗?')) {
|
||
clonedVoices = clonedVoices.filter(function(v) { return v.id != voiceId; });
|
||
renderClonedVoices();
|
||
}
|
||
}
|
||
}
|
||
|
||
function renameVoiceClone(btn) {
|
||
var card = btn.closest('.voice-clone-card');
|
||
if (card) {
|
||
var voiceId = parseInt(card.dataset.voiceId);
|
||
var voice = clonedVoices.find(function(v) { return v.id == voiceId; });
|
||
if (voice) {
|
||
var newName = prompt('请输入新的音色名称:', voice.name);
|
||
if (newName && newName.trim()) {
|
||
voice.name = newName.trim();
|
||
renderClonedVoices();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function playVoiceClone(btn) {
|
||
alert('播放音色预览(模拟)');
|
||
}
|
||
|
||
function useVoiceClone(btn) {
|
||
var card = btn.closest('.voice-clone-card');
|
||
if (card) {
|
||
selectedCloneVoiceId = parseInt(card.dataset.voiceId);
|
||
alert('已选择音色,正在跳转到一键生成页面...');
|
||
showView('generate');
|
||
// 自动切换到step-4
|
||
currentStep = 4;
|
||
updateStepUI();
|
||
}
|
||
}
|
||
|
||
// 音色库卡片操作
|
||
function deleteVoiceCloneItem(id) {
|
||
if (confirm('确定要删除这个音色吗?')) {
|
||
clonedVoices = clonedVoices.filter(function(v) { return v.id != id; });
|
||
renderClonedVoices();
|
||
}
|
||
}
|
||
|
||
function renameVoiceCloneItem(id) {
|
||
var voice = clonedVoices.find(function(v) { return v.id == id; });
|
||
if (voice) {
|
||
var newName = prompt('请输入新的音色名称:', voice.name);
|
||
if (newName && newName.trim()) {
|
||
voice.name = newName.trim();
|
||
renderClonedVoices();
|
||
}
|
||
}
|
||
}
|
||
|
||
function playVoiceCloneItem(id) {
|
||
alert('播放音色预览(模拟)');
|
||
}
|
||
|
||
function useVoiceCloneItem(id) {
|
||
selectedCloneVoiceId = id;
|
||
alert('已选择音色,正在跳转到一键生成页面...');
|
||
showView('generate');
|
||
currentStep = 4;
|
||
updateStepUI();
|
||
}
|
||
|
||
// 打开录制弹窗(从step-4中)
|
||
function openRecordModal() {
|
||
openCloneVoiceModal();
|
||
}
|
||
|
||
// 初始化音色列表
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
renderClonedVoices();
|
||
renderClonedVoicesForStep4();
|
||
});
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|