- 新增 HomePage.vue 主页组件 (玻璃态设计风格) - GlobalSidebar logo 改为可点击跳转主页 - 默认页面从 writer 改为 home - 新增玻璃态 CSS 变量支持 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
542 lines
13 KiB
Vue
542 lines
13 KiB
Vue
<template>
|
||
<div class="home-page">
|
||
<!-- Dynamic Background Decor -->
|
||
<div class="bg-decor">
|
||
<div class="blob blob-1"></div>
|
||
<div class="blob blob-2"></div>
|
||
<div class="blob blob-3"></div>
|
||
</div>
|
||
|
||
<!-- Hero Section -->
|
||
<header class="home-hero glass">
|
||
<div class="hero-content">
|
||
<div class="hero-icon-wrapper">
|
||
<div class="hero-icon-glow"></div>
|
||
<div class="hero-icon">
|
||
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||
<path d="M12 2L2 7L12 12L22 7L12 2Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||
<path d="M2 17L12 22L22 17" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||
<path d="M2 12L12 17L22 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
<h1 class="hero-title">AI 写作工坊</h1>
|
||
<p class="hero-subtitle">结构化内容生成平台</p>
|
||
<p class="hero-description">
|
||
通过智能范式系统,实现高质量、规范化的内容生成
|
||
</p>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- Stats Section -->
|
||
<section class="home-stats">
|
||
<div v-for="stat in statConfig" :key="stat.label" class="stat-card glass-card">
|
||
<div class="stat-icon" :style="{ color: stat.color }">
|
||
<IconLibrary :name="stat.icon" :size="24" />
|
||
</div>
|
||
<div class="stat-info">
|
||
<span class="stat-value text-glow" :style="{ '--glow-color': stat.color }">{{ stats[stat.key] }}</span>
|
||
<span class="stat-label">{{ stat.label }}</span>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Content Sections Grid -->
|
||
<div class="content-grid">
|
||
<!-- Quick Actions -->
|
||
<section class="home-section quick-actions-section">
|
||
<h2 class="section-title">
|
||
<IconLibrary name="sparkles" :size="18" />
|
||
<span>快速开始</span>
|
||
</h2>
|
||
<div class="action-list">
|
||
<button
|
||
v-for="action in quickActions"
|
||
:key="action.id"
|
||
@click="navigateTo(action.id)"
|
||
class="action-card glass-card"
|
||
>
|
||
<div class="action-icon-box" :style="{ background: action.gradient }">
|
||
<IconLibrary :name="action.icon" :size="24" />
|
||
</div>
|
||
<div class="action-content">
|
||
<h3 class="action-title">{{ action.title }}</h3>
|
||
<p class="action-desc">{{ action.description }}</p>
|
||
</div>
|
||
<div class="action-arrow-box">
|
||
<IconLibrary name="expand" :size="16" class="action-arrow" />
|
||
</div>
|
||
</button>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- All Features -->
|
||
<section class="home-section all-features-section">
|
||
<h2 class="section-title">
|
||
<IconLibrary name="list" :size="18" />
|
||
<span>全部功能</span>
|
||
</h2>
|
||
<div class="feature-grid">
|
||
<button
|
||
v-for="feature in features"
|
||
:key="feature.id"
|
||
@click="navigateTo(feature.id)"
|
||
class="feature-card glass-card"
|
||
>
|
||
<div class="feature-icon-wrapper">
|
||
<IconLibrary :name="feature.icon" :size="24" />
|
||
</div>
|
||
<span class="feature-name">{{ feature.name }}</span>
|
||
</button>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
|
||
<!-- Footer -->
|
||
<footer class="home-footer">
|
||
<div class="footer-divider"></div>
|
||
<p class="footer-text">Pro 版 · 基于 DeepSeek API · 极简高效</p>
|
||
</footer>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, onMounted } from 'vue'
|
||
import { useAppStore } from '../stores/app'
|
||
import { useDatabaseStore } from '../stores/database'
|
||
import { getParadigmList } from '../config/paradigms'
|
||
import IconLibrary from './icons/IconLibrary.vue'
|
||
|
||
const appStore = useAppStore()
|
||
const dbStore = useDatabaseStore()
|
||
|
||
// 统计数据
|
||
const stats = ref({
|
||
documents: 0,
|
||
materials: 0,
|
||
paradigms: 0
|
||
})
|
||
|
||
const statConfig = [
|
||
{ key: 'documents', label: '文稿', icon: 'folder', color: '#60a5fa' },
|
||
{ key: 'materials', label: '素材', icon: 'chart', color: '#34d399' },
|
||
{ key: 'paradigms', label: '范式', icon: 'analysis', color: '#c084fc' }
|
||
]
|
||
|
||
// 快速操作
|
||
const quickActions = [
|
||
{
|
||
id: 'writer',
|
||
title: 'AI 写作',
|
||
description: '智能生成高质量内容',
|
||
icon: 'edit',
|
||
gradient: 'linear-gradient(135deg, #3b82f6, #6366f1)'
|
||
},
|
||
{
|
||
id: 'rewrite',
|
||
title: '范式润色',
|
||
description: '按范式标准优化文章',
|
||
icon: 'sparkles',
|
||
gradient: 'linear-gradient(135deg, #f59e0b, #ef4444)'
|
||
},
|
||
{
|
||
id: 'analysis',
|
||
title: '范式库',
|
||
description: '管理和创建写作范式',
|
||
icon: 'analysis',
|
||
gradient: 'linear-gradient(135deg, #10b981, #06b6d4)'
|
||
}
|
||
]
|
||
|
||
// 全部功能
|
||
const features = [
|
||
{ id: 'writer', name: 'AI 写作', icon: 'edit' },
|
||
{ id: 'analysis', name: '范式库', icon: 'analysis' },
|
||
{ id: 'paradigmWriter', name: '范式写作', icon: 'article' },
|
||
{ id: 'documents', name: '文稿库', icon: 'folder' },
|
||
{ id: 'materials', name: '素材库', icon: 'chart' },
|
||
{ id: 'rewrite', name: '范式润色', icon: 'sparkles' },
|
||
{ id: 'compare', name: '对照检查', icon: 'compare' },
|
||
{ id: 'diffAnnotation', name: '差异标注', icon: 'chart' }
|
||
]
|
||
|
||
// 导航
|
||
const navigateTo = (page) => {
|
||
appStore.setCurrentPage(page)
|
||
}
|
||
|
||
// 加载统计数据
|
||
onMounted(() => {
|
||
// 获取范式数量
|
||
const defaultParadigms = getParadigmList()
|
||
const customParadigms = JSON.parse(localStorage.getItem('customParadigms') || '[]')
|
||
stats.value.paradigms = defaultParadigms.length + customParadigms.length
|
||
|
||
// 获取文稿和素材数量
|
||
stats.value.documents = dbStore.documents?.length || 0
|
||
stats.value.materials = dbStore.references?.length || 0
|
||
})
|
||
</script>
|
||
|
||
<style scoped>
|
||
.home-page {
|
||
flex: 1;
|
||
overflow-y: auto;
|
||
padding: var(--space-8);
|
||
background: var(--bg-primary);
|
||
position: relative;
|
||
z-index: 1;
|
||
}
|
||
|
||
/* Background Decor */
|
||
.bg-decor {
|
||
position: fixed;
|
||
inset: 0;
|
||
overflow: hidden;
|
||
z-index: -1;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.blob {
|
||
position: absolute;
|
||
width: 400px;
|
||
height: 400px;
|
||
background: radial-gradient(circle, rgba(96, 165, 250, 0.15) 0%, transparent 70%);
|
||
border-radius: 50%;
|
||
filter: blur(60px);
|
||
animation: float 20s infinite alternate cubic-bezier(0.45, 0, 0.55, 1);
|
||
}
|
||
|
||
.blob-1 { top: -100px; left: -100px; animation-delay: 0s; }
|
||
.blob-2 { bottom: -150px; right: -100px; background: radial-gradient(circle, rgba(192, 132, 252, 0.1) 0%, transparent 70%); animation-delay: -5s; }
|
||
.blob-3 { top: 20%; right: 10%; background: radial-gradient(circle, rgba(52, 211, 153, 0.08) 0%, transparent 70%); animation-delay: -10s; }
|
||
|
||
@keyframes float {
|
||
from { transform: translate(0, 0) scale(1); }
|
||
to { transform: translate(100px, 50px) scale(1.1); }
|
||
}
|
||
|
||
/* Glass Effect */
|
||
.glass {
|
||
background: var(--glass-bg);
|
||
backdrop-filter: blur(var(--glass-blur));
|
||
-webkit-backdrop-filter: blur(var(--glass-blur));
|
||
border: 1px solid var(--glass-border);
|
||
box-shadow: var(--shadow-xl);
|
||
}
|
||
|
||
.glass-card {
|
||
background: var(--glass-bg);
|
||
backdrop-filter: blur(var(--glass-blur));
|
||
-webkit-backdrop-filter: blur(var(--glass-blur));
|
||
border: 1px solid var(--glass-border);
|
||
transition: all var(--transition-normal);
|
||
}
|
||
|
||
.glass-card:hover {
|
||
background: var(--glass-bg-hover);
|
||
border-color: rgba(255, 255, 255, 0.2);
|
||
transform: translateY(-4px);
|
||
box-shadow: var(--shadow-xl), var(--shadow-glow);
|
||
}
|
||
|
||
/* Hero Section */
|
||
.home-hero {
|
||
text-align: center;
|
||
padding: var(--space-12) var(--space-6);
|
||
margin-bottom: var(--space-10);
|
||
border-radius: var(--radius-2xl);
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.home-hero::before {
|
||
content: '';
|
||
position: absolute;
|
||
inset: 0;
|
||
background: linear-gradient(135deg, rgba(96, 165, 250, 0.05) 0%, transparent 50%, rgba(192, 132, 252, 0.05) 100%);
|
||
}
|
||
|
||
.hero-content {
|
||
position: relative;
|
||
z-index: 2;
|
||
max-width: 600px;
|
||
margin: 0 auto;
|
||
}
|
||
|
||
.hero-icon-wrapper {
|
||
position: relative;
|
||
display: inline-flex;
|
||
margin-bottom: var(--space-6);
|
||
}
|
||
|
||
.hero-icon-glow {
|
||
position: absolute;
|
||
inset: -10px;
|
||
background: var(--accent-primary);
|
||
filter: blur(20px);
|
||
opacity: 0.3;
|
||
border-radius: var(--radius-xl);
|
||
}
|
||
|
||
.hero-icon {
|
||
position: relative;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 80px;
|
||
height: 80px;
|
||
background: linear-gradient(135deg, var(--accent-primary), #c084fc);
|
||
border-radius: var(--radius-xl);
|
||
color: white;
|
||
box-shadow: 0 10px 25px rgba(96, 165, 250, 0.4);
|
||
}
|
||
|
||
.hero-title {
|
||
font-size: var(--text-3xl);
|
||
font-weight: var(--font-bold);
|
||
color: var(--text-primary);
|
||
margin-bottom: var(--space-2);
|
||
letter-spacing: -0.02em;
|
||
}
|
||
|
||
.hero-subtitle {
|
||
font-size: var(--text-lg);
|
||
font-weight: var(--font-medium);
|
||
color: var(--accent-primary);
|
||
margin-bottom: var(--space-4);
|
||
background: linear-gradient(90deg, var(--accent-primary), #c084fc);
|
||
-webkit-background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
}
|
||
|
||
.hero-description {
|
||
font-size: var(--text-base);
|
||
color: var(--text-secondary);
|
||
line-height: 1.6;
|
||
}
|
||
|
||
/* Stats Section */
|
||
.home-stats {
|
||
display: grid;
|
||
grid-template-columns: repeat(3, 1fr);
|
||
gap: var(--space-6);
|
||
margin-bottom: var(--space-10);
|
||
}
|
||
|
||
.stat-card {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-4);
|
||
padding: var(--space-6);
|
||
border-radius: var(--radius-xl);
|
||
}
|
||
|
||
.stat-icon {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 52px;
|
||
height: 52px;
|
||
background: rgba(255, 255, 255, 0.05);
|
||
border-radius: var(--radius-lg);
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.stat-info {
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.stat-value {
|
||
font-size: var(--text-2xl);
|
||
font-weight: var(--font-bold);
|
||
color: var(--text-primary);
|
||
line-height: 1;
|
||
margin-bottom: var(--space-1);
|
||
}
|
||
|
||
.text-glow {
|
||
text-shadow: 0 0 10px var(--glow-color, rgba(96, 165, 250, 0.3));
|
||
}
|
||
|
||
.stat-label {
|
||
font-size: var(--text-xs);
|
||
color: var(--text-muted);
|
||
font-weight: var(--font-medium);
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.1em;
|
||
}
|
||
|
||
/* Content Grid */
|
||
.content-grid {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: var(--space-8);
|
||
}
|
||
|
||
.section-title {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-2);
|
||
font-size: var(--text-sm);
|
||
font-weight: var(--font-semibold);
|
||
color: var(--text-primary);
|
||
margin-bottom: var(--space-5);
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.05em;
|
||
opacity: 0.8;
|
||
}
|
||
|
||
/* Quick Actions */
|
||
.action-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-4);
|
||
}
|
||
|
||
.action-card {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-5);
|
||
padding: var(--space-5);
|
||
border-radius: var(--radius-xl);
|
||
cursor: pointer;
|
||
text-align: left;
|
||
width: 100%;
|
||
}
|
||
|
||
.action-icon-box {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 56px;
|
||
height: 56px;
|
||
border-radius: var(--radius-lg);
|
||
color: white;
|
||
flex-shrink: 0;
|
||
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
|
||
}
|
||
|
||
.action-content {
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
|
||
.action-title {
|
||
font-size: var(--text-base);
|
||
font-weight: var(--font-semibold);
|
||
color: var(--text-primary);
|
||
margin-bottom: var(--space-1);
|
||
}
|
||
|
||
.action-desc {
|
||
font-size: var(--text-sm);
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.action-arrow-box {
|
||
width: 32px;
|
||
height: 32px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
border-radius: var(--radius-full);
|
||
background: rgba(255, 255, 255, 0.05);
|
||
color: var(--text-muted);
|
||
transition: all var(--transition-fast);
|
||
}
|
||
|
||
.action-card:hover .action-arrow-box {
|
||
background: var(--accent-primary);
|
||
color: white;
|
||
transform: translateX(4px);
|
||
}
|
||
|
||
/* Feature Grid */
|
||
.feature-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
|
||
gap: var(--space-4);
|
||
}
|
||
|
||
.feature-card {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: var(--space-3);
|
||
padding: var(--space-6) var(--space-4);
|
||
border-radius: var(--radius-xl);
|
||
cursor: pointer;
|
||
}
|
||
|
||
.feature-icon-wrapper {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 48px;
|
||
height: 48px;
|
||
background: rgba(255, 255, 255, 0.05);
|
||
border-radius: var(--radius-lg);
|
||
color: var(--text-secondary);
|
||
transition: all var(--transition-normal);
|
||
}
|
||
|
||
.feature-card:hover .feature-icon-wrapper {
|
||
background: var(--accent-primary);
|
||
color: white;
|
||
transform: scale(1.1) rotate(5deg);
|
||
}
|
||
|
||
.feature-name {
|
||
font-size: var(--text-sm);
|
||
font-weight: var(--font-medium);
|
||
color: var(--text-secondary);
|
||
text-align: center;
|
||
}
|
||
|
||
.feature-card:hover .feature-name {
|
||
color: var(--text-primary);
|
||
}
|
||
|
||
/* Footer */
|
||
.home-footer {
|
||
margin-top: var(--space-12);
|
||
text-align: center;
|
||
}
|
||
|
||
.footer-divider {
|
||
height: 1px;
|
||
background: linear-gradient(90deg, transparent, var(--border-default), transparent);
|
||
margin-bottom: var(--space-6);
|
||
}
|
||
|
||
.footer-text {
|
||
font-size: var(--text-xs);
|
||
color: var(--text-muted);
|
||
letter-spacing: 0.02em;
|
||
}
|
||
|
||
/* Responsive */
|
||
@media (max-width: 1024px) {
|
||
.content-grid {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.home-stats {
|
||
grid-template-columns: 1fr;
|
||
gap: var(--space-4);
|
||
}
|
||
|
||
.hero-title {
|
||
font-size: var(--text-2xl);
|
||
}
|
||
|
||
.feature-grid {
|
||
grid-template-columns: repeat(2, 1fr);
|
||
}
|
||
}
|
||
</style>
|