吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1877|回复: 30
收起左侧

[Python 转载] 情人节浪漫相册

[复制链接]
phantomxjc 发表于 2026-2-12 17:30
情人节到了  利用AI配合写了一个记录恋爱的相册网站,送给对象做一个小惊喜:以下全文皆由AI生成

浪漫相册系统 - 完整功能介绍

一、核心系统架构

这是一个完整的Web应用程序,采用前后端分离架构:

前端技术栈

  • HTML5 + CSS3 + JavaScript
  • Bootstrap 5.3 响应式框架
  • Font Awesome 6.0 图标库
  • 自定义CSS动画和过渡效果
  • 粒子背景效果(particles.js)

后端技术栈

  • Python Flask Web框架
  • SQLite/MySQL数据库
  • 文件上传处理
  • RESTful API设计

二、主要功能模块

1. 主页展示模块

  • 浪漫的粒子背景动画
  • 相册卡片网格展示
  • 爱情故事展示区
  • 音乐播放器控制
  • 响应式布局设计

2. 相册管理模块

  • 创建/编辑/删除相册
  • 相册封面图片设置
  • 相册描述和元数据管理
  • 多种相册样式支持(标准、3D、杂志等)
  • 相册内照片缩略图预览

3. 照片管理模块

  • 批量照片上传(支持拖放)
  • 照片筛选和搜索
  • 大图查看和导航
  • 照片删除功能
  • 照片描述和元数据编辑

4. 音乐管理模块

  • 背景音乐上传
  • 音乐库管理
  • 音乐播放控制
  • 播放列表循环
  • 跨标签页音乐同步

5. 故事管理模块

  • 爱情故事创建/编辑
  • 故事富文本内容
  • 故事时间线展示
  • 故事分享功能

6. 轮播展示模块

  • 全屏照片轮播
  • 多种过渡效果
  • 自动播放控制
  • 键盘导航支持
  • 轮播设置自定义

7. 管理后台模块

  • 仪表盘统计数据
  • 相册管理界面
  • 照片批量操作
  • 音乐库管理
  • 故事内容管理
  • 轮播配置设置

三、特色功能

1. 用户体验优化

  • 双击相册全屏浏览
  • 图片自适应缩放
  • 控制按钮自动隐藏
  • 键盘快捷键支持
  • 触摸屏手势支持

2. 多媒体处理

  • 支持多种图片格式
  • 支持多种音频格式
  • 文件大小限制控制
  • 上传进度显示
  • 错误处理和重试

3. 响应式设计

  • 适配桌面端和移动端
  • 触摸友好的界面
  • 横竖屏自适应
  • 性能优化加载

4. 数据管理

  • 相册和照片分类
  • 音乐播放历史
  • 用户操作记录
  • 系统设置保存

四、技术特性

1. 前端特性

  • 模块化JavaScript代码
  • CSS变量主题系统
  • 动画和过渡效果
  • 本地存储使用
  • 异步数据加载

2. 后端特性

  • RESTful API设计
  • 文件上传处理
  • 数据库CRUD操作
  • 错误处理和日志
  • 配置管理

3. 安全特性

  • 文件类型验证
  • 文件大小限制
  • 路径安全处理
  • 输入验证过滤
  • 错误信息隐藏

五、使用场景

1. 个人用途

  • 情侣记录美好瞬间
  • 家庭照片整理
  • 旅行回忆收藏
  • 特殊事件纪念

2. 小型团队

  • 团队活动记录
  • 项目过程记录
  • 客户案例展示
  • 产品展示相册

3. 特殊场合

  • 婚礼相册制作
  • 生日纪念相册
  • 周年庆祝相册
  • 重要事件记录

六、扩展性

1. 功能扩展

  • 用户系统集成
  • 社交分享功能
  • 打印导出功能
  • 视频支持
  • 评论和点赞

2. 技术扩展

  • 云存储集成
  • CDN加速
  • 移动APP开发
  • 微信小程序
  • 第三方登录

3. 商业化扩展

  • 付费模板
  • 高级功能
  • 团队协作
  • API开放平台

关键代码:index.html:
[Asm] 纯文本查看 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>&#10084;&#65039; 我们的爱情故事相册 &#10084;&#10084;&#65039;</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Pacifico&family=Dancing+Script:wght@400;700&display=swap" rel="stylesheet">
    <style>
        :root {
            --primary-pink: #ff6b8b;
            --secondary-pink: #ffa5b5;
            --light-pink: #fff5f7;
            --gold: #ffd700;
            --purple: #9c88ff;
            --deep-pink: #ff1493;
            --rose-red: #e91e63;
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
            min-height: 100vh;
            font-family: 'Microsoft YaHei', sans-serif;
            overflow-x: hidden;
        }

        /* 粒子背景效果 */
        #particles-js {
            position: fixed;
            width: 100%;
            height: 100%;
            top: 0;
            left: 0;
            z-index: 0;
        }

        .main-container {
            position: relative;
            z-index: 1;
        }

        /* 浪漫标题样式 */
        .romantic-header {
            background: linear-gradient(45deg, var(--primary-pink), var(--purple), var(--deep-pink));
            -webkit-background-clip: text;
            background-clip: text;
            -webkit-text-fill-color: transparent;
            text-shadow: 0 4px 15px rgba(0,0,0,0.1);
            margin: 2rem 0;
            font-weight: 700;
        }

        .romantic-title {
            font-family: 'Pacifico', cursive;
            font-size: 3.5rem;
            margin-bottom: 0.5rem;
        }

        .romantic-subtitle {
            font-family: 'Dancing Script', cursive;
            font-size: 2rem;
            color: var(--primary-pink);
            margin-bottom: 2rem;
        }

        /* 音乐播放器 */
        .music-player {
            position: fixed;
            top: 20px;
            right: 20px;
            z-index: 1000;
            background: rgba(255, 255, 255, 0.95);
            backdrop-filter: blur(10px);
            border-radius: 25px;
            padding: 10px 15px;
            box-shadow: 0 5px 20px rgba(0,0,0,0.1);
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .music-player button {
            background: linear-gradient(45deg, var(--primary-pink), var(--purple));
            border: none;
            border-radius: 20px;
            padding: 8px 20px;
            color: white;
            font-weight: 600;
            transition: all 0.3s ease;
            box-shadow: 0 4px 15px rgba(255,107,139,0.4);
        }

        .music-player button:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 20px rgba(255,107,139,0.6);
        }

        /* 相册卡片样式 */
        .album-card {
            background: rgba(255, 255, 255, 0.95);
            backdrop-filter: blur(10px);
            border: none;
            border-radius: 20px;
            box-shadow: 0 15px 35px rgba(0,0,0,0.1);
            transition: all 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
            overflow: hidden;
            height: 100%;
            margin-bottom: 2rem;
        }

        .album-card:hover {
            transform: translateY(-15px) scale(1.02);
            box-shadow: 0 25px 50px rgba(0,0,0,0.2);
        }

        /* 3D样式相册 */
        .album-style-3d {
            transform-style: preserve-3d;
            perspective: 1000px;
        }

        .album-style-3d:hover {
            transform: rotateY(10deg) translateY(-10px);
        }

        /* 杂志样式相册 */
        .album-style-magazine {
            border-top: 5px solid var(--primary-pink);
            border-left: 3px solid var(--gold);
        }

        .album-style-magazine .album-header {
            background: linear-gradient(45deg, #667eea, #764ba2);
            color: white;
            padding: 15px;
        }

        /* 网格样式相册 */
        .album-style-grid {
            display: grid;
            grid-template-columns: repeat(2, 1fr);
            gap: 5px;
            padding: 10px;
        }

        .album-style-grid .album-thumbnail {
            border-radius: 8px;
            overflow: hidden;
        }

        /* 轮播样式相册 */
        .album-style-carousel {
            position: relative;
            overflow: hidden;
        }

        .album-style-carousel .album-images {
            display: flex;
            transition: transform 0.5s ease;
        }

        /* 瀑布流样式 */
        .album-style-masonry {
            columns: 2;
            column-gap: 10px;
        }

        .album-style-masonry .album-thumbnail {
            break-inside: avoid;
            margin-bottom: 10px;
        }

        /* 拍立得样式 */
        .album-style-polaroid {
            background: white;
            padding: 15px 15px 40px 15px;
            box-shadow: 0 5px 15px rgba(0,0,0,0.1);
        }

        .album-style-polaroid .album-cover {
            border: 1px solid #ddd;
            box-shadow: inset 0 0 10px rgba(0,0,0,0.1);
        }

        /* 相册封面 */
        .album-cover {
            position: relative;
            width: 100%;
            height: 200px;
            overflow: hidden;
            border-radius: 15px 15px 0 0;
        }

        .album-cover img {
            width: 100%;
            height: 100%;
            object-fit: cover;
            transition: transform 0.5s ease;
        }

        .album-card:hover .album-cover img {
            transform: scale(1.1);
        }

        /* 相册信息 */
        .album-info {
            padding: 20px;
        }

        .album-title {
            font-family: 'Dancing Script', cursive;
            font-size: 1.8rem;
            color: var(--deep-pink);
            margin-bottom: 10px;
            font-weight: 700;
        }

        .album-description {
            color: #666;
            font-size: 0.95rem;
            line-height: 1.6;
            margin-bottom: 15px;
        }

        .album-meta {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-top: 15px;
            padding-top: 15px;
            border-top: 1px solid #eee;
        }

        .album-date {
            color: #999;
            font-size: 0.85rem;
        }

        .album-photo-count {
            background: var(--light-pink);
            color: var(--primary-pink);
            padding: 4px 12px;
            border-radius: 20px;
            font-size: 0.85rem;
        }

        /* 双击提示样式 */
        .double-click-hint {
            margin-top: 10px;
            padding-top: 10px;
            border-top: 1px solid #eee;
            text-align: center;
            font-size: 0.8rem;
            color: #999;
        }

        /* 故事卡片 */
        .story-card {
            background: linear-gradient(135deg, #ffeef2, #ffffff);
            border: none;
            border-radius: 15px;
            padding: 25px;
            margin-bottom: 2rem;
            box-shadow: 0 5px 20px rgba(0,0,0,0.08);
            transition: all 0.3s ease;
            height: 100%;
        }

        .story-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 30px rgba(0,0,0,0.15);
        }

        .story-title {
            font-family: 'Dancing Script', cursive;
            font-size: 1.8rem;
            color: var(--primary-pink);
            margin-bottom: 15px;
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .story-content {
            color: #555;
            line-height: 1.8;
            font-size: 1.05rem;
        }

        .story-date {
            color: #999;
            font-size: 0.85rem;
            margin-top: 15px;
        }

        /* 操作按钮 */
        .action-buttons {
            margin-top: 3rem;
            text-align: center;
        }

        .romantic-btn {
            background: linear-gradient(45deg, var(--primary-pink), var(--purple));
            border: none;
            border-radius: 25px;
            padding: 12px 30px;
            color: white;
            font-weight: 600;
            transition: all 0.3s ease;
            box-shadow: 0 5px 20px rgba(255,107,139,0.4);
            margin: 0 10px 10px 10px;
        }

        .romantic-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 8px 25px rgba(255,107,139,0.6);
            color: white;
        }

        .romantic-btn-outline {
            background: transparent;
            border: 2px solid var(--primary-pink);
            color: var(--primary-pink);
        }

        .romantic-btn-outline:hover {
            background: linear-gradient(45deg, var(--primary-pink), var(--purple));
            color: white;
        }

        /* 标签样式 */
        .tag-cloud {
            display: flex;
            flex-wrap: wrap;
            gap: 10px;
            margin: 2rem 0;
            justify-content: center;
        }

        .romantic-tag {
            background: linear-gradient(45deg, var(--primary-pink), var(--purple));
            color: white;
            padding: 8px 20px;
            border-radius: 20px;
            font-size: 0.9rem;
            box-shadow: 0 3px 10px rgba(255,107,139,0.3);
            transition: all 0.3s ease;
        }

        .romantic-tag:hover {
            transform: translateY(-2px);
        }

        /* 动画效果 */
        @keyframes heartbeat {
            0%, 100% { transform: scale(1); }
            50% { transform: scale(1.1); }
        }

        @keyframes float {
            0%, 100% { transform: translateY(0); }
            50% { transform: translateY(-10px); }
        }

        .heart-animation {
            animation: heartbeat 1.5s ease-in-out infinite;
        }

        .float-animation {
            animation: float 3s ease-in-out infinite;
        }

        /* 全屏浏览样式 */
        .fullscreen-viewer {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.95);
            z-index: 9999;
            display: flex;
            flex-direction: column;
            animation: fadeIn 0.3s ease;
        }

        .fullscreen-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 20px;
            background: rgba(0, 0, 0, 0.7);
            color: white;
            z-index: 10;
        }

        .header-content {
            flex: 1;
        }

        .album-title-fullscreen {
            font-family: 'Dancing Script', cursive;
            font-size: 2.5rem;
            color: var(--primary-pink);
            margin-bottom: 5px;
        }

        .album-description-fullscreen {
            color: #ccc;
            margin-bottom: 10px;
        }

        .photo-counter {
            font-size: 1.1rem;
            color: var(--gold);
        }

        .btn-close-fullscreen {
            background: none;
            border: none;
            color: white;
            font-size: 1.5rem;
            cursor: pointer;
            padding: 10px;
            border-radius: 50%;
            transition: background 0.3s;
        }

        .btn-close-fullscreen:hover {
            background: rgba(255, 255, 255, 0.1);
        }

        .fullscreen-content {
            display: flex;
            align-items: center;
            justify-content: center;
            flex: 1;
            position: relative;
            padding: 20px;
        }

        .nav-btn {
            background: rgba(255, 255, 255, 0.2);
            border: none;
            color: white;
            width: 60px;
            height: 60px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 1.5rem;
            cursor: pointer;
            transition: all 0.3s;
            backdrop-filter: blur(10px);
            margin: 0 20px;
        }

        .nav-btn:hover {
            background: rgba(255, 107, 139, 0.8);
            transform: scale(1.1);
        }

        .photo-viewer {
            max-width: 80%;
            max-height: 80%;
            display: flex;
            flex-direction: column;
            align-items: center;
        }

        .photo-container {
            max-width: 100%;
            max-height: 70vh;
            display: flex;
            align-items: center;
            justify-content: center;
            margin-bottom: 20px;
        }

        .photo-container img {
            max-width: 100%;
            max-height: 100%;
            object-fit: contain;
            border-radius: 10px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
        }

        .photo-info {
            text-align: center;
            color: white;
            max-width: 600px;
        }

        .photo-info h4 {
            font-family: 'Dancing Script', cursive;
            font-size: 1.8rem;
            color: var(--primary-pink);
            margin-bottom: 10px;
        }

        .photo-info p {
            color: #ccc;
            font-size: 1rem;
        }

        .photo-thumbnails {
            display: flex;
            justify-content: center;
            padding: 20px;
            background: rgba(0, 0, 0, 0.7);
            overflow-x: auto;
            gap: 10px;
        }

        .thumbnail {
            width: 80px;
            height: 80px;
            border-radius: 5px;
            overflow: hidden;
            cursor: pointer;
            opacity: 0.6;
            transition: all 0.3s;
            border: 2px solid transparent;
        }

        .thumbnail:hover, .thumbnail.active {
            opacity: 1;
            transform: scale(1.1);
            border-color: var(--primary-pink);
        }

        .thumbnail img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }

        .fullscreen-controls {
            display: flex;
            justify-content: center;
            padding: 20px;
            background: rgba(0, 0, 0, 0.7);
            gap: 15px;
        }

        .control-btn {
            background: linear-gradient(45deg, var(--primary-pink), var(--purple));
            border: none;
            border-radius: 25px;
            padding: 10px 20px;
            color: white;
            cursor: pointer;
            transition: all 0.3s;
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .control-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 5px 15px rgba(255, 107, 139, 0.4);
        }

        /* 动画效果 */
        @keyframes fadeIn {
            from { opacity: 0; }
            to { opacity: 1; }
        }

        /* 响应式调整 */
        [url=home.php?mod=space&uid=945662]@media[/url] (max-width: 768px) {
            .romantic-title {
                font-size: 2.5rem;
            }

            .romantic-subtitle {
                font-size: 1.5rem;
            }

            .music-player {
                top: 10px;
                right: 10px;
                flex-direction: column;
                align-items: center;
            }

            .album-card {
                margin-bottom: 1.5rem;
            }

            .romantic-btn {
                display: block;
                width: 100%;
                margin: 10px 0;
            }

            /* 全屏浏览响应式 */
            .fullscreen-content {
                flex-direction: column;
                padding: 10px;
            }

            .nav-btn {
                width: 50px;
                height: 50px;
                margin: 10px 0;
            }

            .photo-viewer {
                max-width: 95%;
            }

            .album-title-fullscreen {
                font-size: 1.8rem;
            }

            .thumbnail {
                width: 60px;
                height: 60px;
            }

            .fullscreen-controls {
                flex-wrap: wrap;
            }

            .control-btn {
                padding: 8px 15px;
                font-size: 0.9rem;
            }
        }
    </style>
</head>
<body>
    <!-- 粒子背景 -->
    <div id="particles-js"></div>

    <!-- 音乐播放器 -->
    <div class="music-player" id="musicPlayer">
        <button onclick="toggleMusic()">
            <i class="fas fa-music"></i>
            <span id="musicText">播放</span>
        </button>
        <small id="musicTitle" class="text-muted"></small>
    </div>

    <div class="main-container">
        <div class="container py-5">
            <!-- 浪漫标题区 -->
            <div class="text-center mb-5">
                <h1 class="romantic-title romantic-header">
                    <i class="fas fa-heart heart-animation"></i>
                    我们的爱情故事
                    <i class="fas fa-heart heart-animation"></i>
                </h1>
                <h2 class="romantic-subtitle">记录每一个心动瞬间,珍藏每一份美好回忆</h2>

                <!-- 标签云 -->
                <div class="tag-cloud">
                    <span class="romantic-tag float-animation">相遇</span>
                    <span class="romantic-tag float-animation" style="animation-delay: 0.2s;">相爱</span>
                    <span class="romantic-tag float-animation" style="animation-delay: 0.4s;">相守</span>
                    <span class="romantic-tag float-animation" style="animation-delay: 0.6s;">永恒</span>
                    <span class="romantic-tag float-animation" style="animation-delay: 0.8s;">浪漫</span>
                    <span class="romantic-tag float-animation" style="animation-delay: 1s;">甜蜜</span>
                </div>
            </div>

            <!-- 相册展示区 -->
            <div class="row" id="albumsContainer">
                <!-- 相册将通过JavaScript动态加载 -->
                <div class="col-12 text-center py-5">
                    <div class="spinner-border text-primary" role="status">
                        <span class="visually-hidden">加载中...</span>
                    </div>
                    <p class="mt-3">正在加载相册...</p>
                </div>
            </div>

            <!-- 爱情故事区 -->
            <div class="row mt-5">
                <div class="col-12">
                    <h2 class="romantic-header text-center mb-4">
                        <i class="fas fa-book-heart me-2"></i>我们的爱情故事
                    </h2>

                    <div class="row" id="storiesContainer">
                        <!-- 故事将通过JavaScript动态加载 -->
                    </div>
                </div>
            </div>

            <!-- 轮播预览区 -->
            <div class="row mt-5">
                <div class="col-12">
                    <div class="slideshow-preview bg-white rounded-3 p-4 text-center">
                        <h3 class="romantic-header mb-3">浪漫轮播展示</h3>
                        <p class="text-muted mb-4">点击下方按钮,全屏欣赏我们的爱情故事</p>
                        <div class="slideshow-preview-images mb-4">
                            <div id="previewCarousel" class="carousel slide" data-bs-ride="carousel">
                                <div class="carousel-inner rounded-3">
                                    <!-- 轮播预览图片将通过JavaScript动态加载 -->
                                    <div class="carousel-item active">
                                        <div class="d-flex align-items-center justify-content-center bg-light rounded-3" style="height: 300px;">
                                            <i class="fas fa-heart fa-5x text-muted"></i>
                                        </div>
                                    </div>
                                </div>
                                <button class="carousel-control-prev" type="button" data-bs-target="#previewCarousel" data-bs-slide="prev">
                                    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
                                    <span class="visually-hidden">上一张</span>
                                </button>
                                <button class="carousel-control-next" type="button" data-bs-target="#previewCarousel" data-bs-slide="next">
                                    <span class="carousel-control-next-icon" aria-hidden="true"></span>
                                    <span class="visually-hidden">下一张</span>
                                </button>
                            </div>
                        </div>
                        <a href="/slideshow" class="btn romantic-btn btn-lg">
                            <i class="fas fa-play-circle me-2"></i>开始浪漫轮播
                        </a>
                    </div>
                </div>
            </div>

            <!-- 行动按钮区 -->
            <div class="text-center mt-5">
                <a href="/admin" class="btn romantic-btn me-3">
                    <i class="fas fa-cog me-2"></i>管理后台
                </a>
                <button class="btn romantic-btn-outline" onclick="randomizeAlbumStyles()">
                    <i class="fas fa-random me-2"></i>随机样式
                </button>
            </div>
        </div>
    </div>

    <!-- 相册详情模态框 -->
    <div class="modal fade" id="albumModal" tabindex="-1">
        <div class="modal-dialog modal-lg">
            <div class="modal-content">
                <div class="modal-header" style="background: linear-gradient(45deg, var(--primary-pink), var(--purple)); color: white;">
                    <h5 class="modal-title" id="albumModalTitle">相册详情</h5>
                    <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
                </div>
                <div class="modal-body" id="albumModalBody">
                    <!-- 相册内容将通过JavaScript动态加载 -->
                </div>
            </div>
        </div>
    </div>

    <!-- 故事详情模态框 -->
    <div class="modal fade" id="storyModal" tabindex="-1">
        <div class="modal-dialog modal-lg">
            <div class="modal-content">
                <div class="modal-header" style="background: linear-gradient(45deg, var(--primary-pink), var(--purple)); color: white;">
                    <h5 class="modal-title" id="storyModalTitle">爱情故事</h5>
                    <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
                </div>
                <div class="modal-body" id="storyModalContent">
                    <!-- 故事内容将通过JavaScript动态加载 -->
                </div>
            </div>
        </div>
    </div>

    <!-- 大图查看模态框 -->
    <div class="modal fade" id="imageModal" tabindex="-1">
        <div class="modal-dialog modal-xl">
            <div class="modal-content">
                <div class="modal-body text-center p-0">

                </div>
            </div>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
    <script src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js"></script>
    <script>
        // 全局变量
        let currentAudio = null;
        let albums = [];
        let stories = [];
        let albumStyles = [
            'standard', '3d', 'magazine', 'grid', 'carousel', 'masonry',
            'polaroid', 'filmstrip', 'collage', 'timeline', 'gallery',
            'slideshow', 'stack', 'flipbook', 'panorama', 'vintage',
            'modern', 'minimal', 'elegant'
        ];

        // 全屏浏览相关变量
        let currentAlbum = null;
        let currentPhotoIndex = 0;
        let autoPlayInterval = null;
        let clickTimer = null; // 用于处理单击/双击冲突

        // 页面加载完成后初始化
        document.addEventListener('DOMContentLoaded', function() {
            initParticles();
            loadAlbums();
            loadStories();
            loadMusic();
        });

        // 初始化粒子背景
        function initParticles() {
            if (typeof particlesJS !== 'undefined') {
                particlesJS('particles-js', {
                    particles: {
                        number: { value: 80, density: { enable: true, value_area: 800 } },
                        color: { value: ["#ff6b8b", "#9c88ff", "#ffd700", "#e91e63"] },
                        shape: { type: ["circle", "heart"] },
                        opacity: { value: 0.5, random: true },
                        size: { value: 3, random: true },
                        line_linked: {
                            enable: true,
                            distance: 150,
                            color: "#ff6b8b",
                            opacity: 0.2,
                            width: 1
                        },
                        move: {
                            enable: true,
                            speed: 2,
                            direction: "none",
                            random: true,
                            out_mode: "out"
                        }
                    }
                });
            }
        }

        // 加载相册数据
        async function loadAlbums() {
            try {
                const response = await fetch('/api/albums');
                if (!response.ok) throw new Error('加载相册失败');

                albums = await response.json();
                renderAlbums();
            } catch (error) {
                console.error('加载相册失败:', error);
                showError('相册加载失败,请稍后重试');
            }
        }

        // 渲染相册
        function renderAlbums() {
            const container = document.getElementById('albumsContainer');

            if (!albums || albums.length === 0) {
                container.innerHTML = `
                    <div class="col-12 text-center py-5">
                        <div class="album-card p-5">
                            <i class="fas fa-images fa-4x text-muted mb-3"></i>
                            <h3>还没有相册哦</h3>
                            <p class="text-muted">快去创建你的第一个相册吧!</p>
                            <a href="/admin" class="btn romantic-btn">创建相册</a>
                        </div>
                    </div>
                `;
                return;
            }

            let html = '';

            albums.forEach((album, index) => {
                // 随机选择一个样式
                const style = getRandomAlbumStyle(index);
                const photoCount = album.photos ? album.photos.length : 0;
                let coverImage = '';
                if (album.photos && album.photos.length > 0) {
                    const firstPhoto = album.photos[0];
                    coverImage = `/static/uploads/images/${firstPhoto.filename}`;  // 修改点1:修复照片路径
                } else {
                    coverImage = 'https://via.placeholder.com/400x300/ff6b8b/ffffff?text=暂无照片';
                }

                // 修改点2:添加单击和双击事件处理
                html += `
                    <div class="col-md-4 mb-4">
                        <div class="album-card album-style-${style}"
                             onclick="handleAlbumClick(${album.id})"
                             ondblclick="handleAlbumDoubleClick(${album.id})"
                             title="单击查看详情,双击全屏浏览">
                            <div class="album-cover">
                                <img src="${coverImage}" alt="${album.title}">
                            </div>
                            <div class="album-info">
                                <h3 class="album-title">${album.title}</h3>
                                <p class="album-description">${album.description || '记录我们的美好回忆'}</p>
                                <div class="album-meta">
                                    <span class="album-date">
                                        <i class="far fa-calendar me-1"></i>
                                        ${formatDate(album.create_time)}
                                    </span>
                                    <span class="album-photo-count">
                                        <i class="fas fa-image me-1"></i>
                                        ${photoCount} 张照片
                                    </span>
                                </div>
                                <!-- 添加双击提示 -->
                                <div class="double-click-hint">
                                    <small class="text-muted">
                                        <i class="fas fa-expand-alt me-1"></i>双击全屏浏览
                                    </small>
                                </div>
                            </div>
                        </div>
                    </div>
                `;
            });

            container.innerHTML = html;
        }

        // 修改点3:处理单击事件(延迟执行,避免与双击冲突)
        function handleAlbumClick(albumId) {
            // 清除之前的定时器
            clearTimeout(clickTimer);

            // 设置新的定时器,延迟执行单击操作
            clickTimer = setTimeout(() => {
                viewAlbumDetail(albumId);
            }, 300); // 300毫秒延迟,确保双击不会触发单击
        }

        // 修改点4:处理双击事件
        function handleAlbumDoubleClick(albumId) {
            // 清除单击事件的定时器
            clearTimeout(clickTimer);

            // 直接执行双击操作
            viewAlbumPhotosFullscreen(albumId);
            const container = document.getElementById('fullscreenAlbumViewer');

            if (!document.fullscreenElement) {
                container.requestFullscreen().catch(err => {
                    console.error('全屏请求失败:', err);
                });
            } else {
                document.exitFullscreen();
            }

        }

        // 获取随机相册样式
        function getRandomAlbumStyle(seed) {
            return albumStyles[seed % albumStyles.length];
        }

        // 随机化所有样式
        function randomizeAlbumStyles() {
            renderAlbums();
            showToast('样式已随机更新!');
        }

        // 查看相册详情
        async function viewAlbumDetail(albumId) {
            try {
                const album = albums.find(a => a.id === albumId);
                if (!album) {
                    showToast('相册不存在');
                    return;
                }

                document.getElementById('albumModalTitle').textContent = album.title;

                let photosHtml = '';
                if (album.photos && album.photos.length > 0) {
                    photosHtml = '<div class="row g-3">';
                    album.photos.forEach(photo => {
                        photosHtml += `
                            <div class="col-md-4 col-6">
                                <div class="photo-item" onclick="viewFullImage('${photo.filename}')">
                                    <img src="/static/uploads/images/${photo.filename}" alt="${photo.description || '照片'}" class="img-fluid rounded-3">
                                </div>
                            </div>
                        `;
                    });
                    photosHtml += '</div>';
                } else {
                    photosHtml = `
                        <div class="text-center py-5">
                            <i class="fas fa-images fa-4x text-muted mb-3"></i>
                            <h5>这个相册还没有照片</h5>
                            <p class="text-muted">快去上传照片吧!</p>
                        </div>
                    `;
                }

                document.getElementById('albumModalBody').innerHTML = `
                    <div class="mb-4">
                        <h6>相册描述:</h6>
                        <p class="lead">${album.description || '暂无描述'}</p>
                    </div>
                    <div>
                        <h6>照片 (${album.photos ? album.photos.length : 0}张):</h6>
                        ${photosHtml}
                    </div>
                `;

                new bootstrap.Modal(document.getElementById('albumModal')).show();

            } catch (error) {
                console.error('加载相册详情失败:', error);
                showToast('加载相册详情失败: ' + error.message);
            }
        }

        // 修改点5:添加全屏浏览相册照片功能
        function viewAlbumPhotosFullscreen(albumId) {
            const album = albums.find(a => a.id === albumId);
            if (!album || !album.photos || album.photos.length === 0) {
                showToast('这个相册还没有照片');
                return;
            }

            // 创建全屏浏览容器
            createFullscreenViewer(album);
        }

        // 修改点6:创建全屏浏览界面
        function createFullscreenViewer(album) {
            // 创建全屏容器
            const fullscreenContainer = document.createElement('div');
            fullscreenContainer.id = 'fullscreenAlbumViewer';
            fullscreenContainer.className = 'fullscreen-viewer';
            fullscreenContainer.innerHTML = `
                <div class="fullscreen-header">
                    <div class="header-content">
                        <h2 class="album-title-fullscreen">${album.title}</h2>
                        <p class="album-description-fullscreen">${album.description || ''}</p>
                        <div class="photo-counter">
                            <span id="currentPhotoIndex">1</span> / <span>${album.photos.length}</span>
                        </div>
                    </div>
                    <button class="btn-close-fullscreen" onclick="closeFullscreenViewer()">
                        <i class="fas fa-times"></i>
                    </button>
                </div>

                <div class="fullscreen-content">
                    <button class="nav-btn nav-prev" onclick="navigatePhoto(-1)">
                        <i class="fas fa-chevron-left"></i>
                    </button>

                    <div class="photo-viewer">
                        <div class="photo-container">
                            <img id="fullscreenPhoto" src="" alt="" onerror="this.onerror=null; this.src='https://via.placeholder.com/800x600/ff6b8b/ffffff?text=图片加载失败';">
                        </div>
                        <div class="photo-info">
                            <h4 id="photoTitle"></h4>
                            <p id="photoDescription"></p>
                        </div>
                    </div>

                    <button class="nav-btn nav-next" onclick="navigatePhoto(1)">
                        <i class="fas fa-chevron-right"></i>
                    </button>
                </div>

                <div class="photo-thumbnails">
                    ${album.photos.map((photo, index) => `
                        <div class="thumbnail ${index === 0 ? 'active' : ''}"
                             onclick="showPhoto(${index})">
                            <img src="/static/uploads/images/${photo.filename}" alt="${photo.description || '缩略图'}">
                        </div>
                    `).join('')}
                </div>

                <div class="fullscreen-controls">
                    <button class="control-btn" onclick="toggleAutoPlay()" id="autoPlayBtn">
                        <i class="fas fa-play"></i> 自动播放
                    </button>
                    <button class="control-btn" onclick="downloadCurrentPhoto()">
                        <i class="fas fa-download"></i> 下载
                    </button>
                    <button class="control-btn" onclick="toggleFullscreen()">
                        <i class="fas fa-expand"></i> 全屏
                    </button>
                </div>
            `;

            document.body.appendChild(fullscreenContainer);

            // 显示第一张照片
            currentAlbum = album;
            currentPhotoIndex = 0;
            showPhoto(0);

            // 添加键盘事件监听
            document.addEventListener('keydown', handleFullscreenKeydown);

            // 阻止背景滚动
            document.body.style.overflow = 'hidden';
        }

        // 修改点7:显示指定索引的照片
        function showPhoto(index) {
            if (!currentAlbum || !currentAlbum.photos) return;

            // 确保索引在有效范围内
            if (index < 0) index = currentAlbum.photos.length - 1;
            if (index >= currentAlbum.photos.length) index = 0;

            currentPhotoIndex = index;
            const photo = currentAlbum.photos[index];

            // 更新照片显示
            const photoImg = document.getElementById('fullscreenPhoto');
            const photoTitle = document.getElementById('photoTitle');
            const photoDescription = document.getElementById('photoDescription');
            const currentIndex = document.getElementById('currentPhotoIndex');

            if (photoImg) {
                photoImg.src = `/static/uploads/images/${photo.filename}`;  // 修改点8:修复照片路径
                photoImg.alt = photo.description || '美好的回忆';
            }
            if (photoTitle) {
                photoTitle.textContent = photo.description || '美好的回忆';
            }
            if (photoDescription) {
                photoDescription.textContent = `拍摄时间: ${formatDate(photo.upload_time)}`;
            }
            if (currentIndex) {
                currentIndex.textContent = index + 1;
            }

            // 更新缩略图激活状态
            document.querySelectorAll('.thumbnail').forEach((thumb, i) => {
                thumb.classList.toggle('active', i === index);
            });
        }

        // 修改点9:导航照片
        function navigatePhoto(direction) {
            showPhoto(currentPhotoIndex + direction);
        }

        // 修改点10:关闭全屏浏览
        function closeFullscreenViewer() {
            const viewer = document.getElementById('fullscreenAlbumViewer');
            if (viewer) {
                viewer.remove();
            }

            // 移除键盘事件监听
            document.removeEventListener('keydown', handleFullscreenKeydown);

            // 恢复背景滚动
            document.body.style.overflow = '';

            // 停止自动播放
            if (autoPlayInterval) {
                clearInterval(autoPlayInterval);
                autoPlayInterval = null;
            }
        }

        // 修改点11:键盘导航
        function handleFullscreenKeydown(e) {
            switch(e.key) {
                case 'ArrowLeft':
                case 'a':
                case 'A':
                    e.preventDefault();
                    navigatePhoto(-1);
                    break;
                case 'ArrowRight':
                case 'd':
                case 'D':
                    e.preventDefault();
                    navigatePhoto(1);
                    break;
                case 'Escape':
                    e.preventDefault();
                    closeFullscreenViewer();
                    break;
                case ' ':
                    e.preventDefault();
                    toggleAutoPlay();
                    break;
            }
        }

        // 修改点12:自动播放功能
        function toggleAutoPlay() {
            const btn = document.getElementById('autoPlayBtn');

            if (autoPlayInterval) {
                clearInterval(autoPlayInterval);
                autoPlayInterval = null;
                btn.innerHTML = '<i class="fas fa-play"></i> 自动播放';
            } else {
                autoPlayInterval = setInterval(() => {
                    navigatePhoto(1);
                }, 3000); // 3秒自动切换
                btn.innerHTML = '<i class="fas fa-pause"></i> 停止播放';
            }
        }

        // 修改点13:下载当前照片
        function downloadCurrentPhoto() {
            if (!currentAlbum || !currentAlbum.photos[currentPhotoIndex]) return;

            const photo = currentAlbum.photos[currentPhotoIndex];
            const link = document.createElement('a');
            link.href = `/static/uploads/images/${photo.filename}`;  // 修改点14:修复下载路径
            link.download = photo.filename;
            link.click();
        }

        // 修改点15:切换全屏模式
        function toggleFullscreen() {
            const container = document.getElementById('fullscreenAlbumViewer');

            if (!document.fullscreenElement) {
                container.requestFullscreen().catch(err => {
                    console.error('全屏请求失败:', err);
                });
            } else {
                document.exitFullscreen();
            }
        }

        // 修改点16:查看大图
        function viewFullImage(filename) {
            const modalImage = document.getElementById('modalImage');
            modalImage.src = `/static/uploads/images/${filename}`;  // 修改点17:修复大图查看路径
            new bootstrap.Modal(document.getElementById('imageModal')).show();
        }

        // 加载故事数据
        async function loadStories() {
            try {
                const response = await fetch('/api/stories');
                if (!response.ok) throw new Error('加载故事失败');

                stories = await response.json();
                renderStories();
            } catch (error) {
                console.error('加载故事失败:', error);
                document.getElementById('storiesContainer').innerHTML = `
                    <div class="col-12 text-center py-5">
                        <i class="fas fa-book-heart fa-4x text-muted mb-3"></i>
                        <h5>加载故事失败</h5>
                        <p class="text-muted">请检查网络连接或稍后重试</p>
                        <button class="btn romantic-btn mt-2" onclick="loadStories()">重试</button>
                    </div>
                `;
            }
        }

        // 渲染故事
        function renderStories() {
            const container = document.getElementById('storiesContainer');

            if (!stories || stories.length === 0) {
                container.innerHTML = `
                    <div class="col-12 text-center py-5">
                        <i class="fas fa-book-heart fa-4x text-muted mb-3"></i>
                        <h4>还没有爱情故事</h4>
                        <p class="text-muted">添加你们的第一篇故事,记录美好回忆</p>
                        <button class="btn romantic-btn" onclick="showCreateStoryModal()">
                            <i class="fas fa-plus me-2"></i>添加故事
                        </button>
                    </div>
                `;
                return;
            }

            let html = '';
            stories.forEach((story, index) => {
                const content = story.content.length > 150 ?
                    story.content.substring(0, 150) + '...' : story.content;

                html += `
                    <div class="col-md-6 mb-4">
                        <div class="story-card" onclick="viewStoryDetail(${index})">
                            <h3 class="story-title">
                                <i class="fas fa-star" style="color: var(--gold);"></i>
                                ${story.title}
                            </h3>
                            <p class="story-content">${content}</p>
                            <div class="story-date">
                                <i class="far fa-clock me-1"></i>
                                ${formatDate(story.create_time)}
                            </div>
                        </div>
                    </div>
                `;
            });

            container.innerHTML = html;
        }

        // 查看故事详情
        function viewStoryDetail(index) {
            const story = stories[index];
            if (!story) return;

            document.getElementById('storyModalTitle').textContent = story.title;
            document.getElementById('storyModalContent').innerHTML = `
                <div class="story-content" style="font-size: 1.1rem; line-height: 1.8;">
                    ${story.content.replace(/\n/g, '<br>')}
                </div>
                <div class="text-center mt-4">
                    <small class="text-muted">
                        <i class="far fa-clock me-1"></i>
                        ${formatDate(story.create_time)}
                    </small>
                </div>
            `;

            new bootstrap.Modal(document.getElementById('storyModal')).show();
        }

        // 显示创建故事模态框
        function showCreateStoryModal() {
            // 这里可以打开一个模态框来创建新故事
            // 由于我们没有实现后端,暂时使用简单提示
            alert('创建故事功能需要在管理后台中使用');
        }

        // 加载音乐
        async function loadMusic() {
            try {
                const response = await fetch('/api/music');
                const data = await response.json();
                setupMusicPlayer(data.currentMusic);
            } catch (error) {
                console.error('加载音乐失败:', error);
                // 设置默认音乐信息
                setupMusicPlayer({filename: '', title: '暂无音乐'});
            }
        }

        // 设置音乐播放器
        function setupMusicPlayer(music) {
            const title = document.getElementById('musicTitle');
            const text = document.getElementById('musicText');

            if (music && music.filename) {
                title.textContent = music.title || '背景音乐';
                text.textContent = '播放';

                // 创建音频元素
                currentAudio = new Audio(`/uploads/music/${music.filename}`);
                currentAudio.loop = true;
                currentAudio.volume = 0.3;

                // 尝试自动播放
                setTimeout(() => {
                    if (currentAudio) {
                        currentAudio.play().then(() => {
                            text.textContent = '暂停';
                        }).catch(() => {
                            // 自动播放被阻止
                        });
                    }
                }, 1000);
            } else {
                title.textContent = '暂无音乐';
                text.textContent = '播放';
            }
        }

        // 切换音乐播放状态
        function toggleMusic() {
            if (!currentAudio) {
                showToast('没有可播放的音乐');
                return;
            }

            const text = document.getElementById('musicText');
            if (currentAudio.paused) {
                currentAudio.play();
                text.textContent = '暂停';
            } else {
                currentAudio.pause();
                text.textContent = '播放';
            }
        }

        // 开始轮播
        function startSlideshow() {
            window.open('/slideshow', '_blank');
        }

        // 显示错误消息
        function showError(message) {
            const container = document.getElementById('albumsContainer');
            if (container) {
                container.innerHTML = `
                    <div class="col-12">
                        <div class="alert alert-danger" role="alert">
                            <i class="fas fa-exclamation-triangle me-2"></i>
                            ${message}
                            <button class="btn btn-sm btn-danger ms-2" onclick="loadAlbums()">重试</button>
                        </div>
                    </div>
                `;
            }
        }

        // 显示提示消息
        function showToast(message) {
            // 创建toast元素
            const toast = document.createElement('div');
            toast.className = 'position-fixed bottom-0 end-0 p-3';
            toast.style.zIndex = '1000';
            toast.innerHTML = `
                <div class="toast show" role="alert">
                    <div class="toast-header" style="background: linear-gradient(45deg, var(--primary-pink), var(--purple)); color: white;">
                        <strong class="me-auto">提示</strong>
                        <button type="button" class="btn-close btn-close-white" data-bs-dismiss="toast"></button>
                    </div>
                    <div class="toast-body">
                        ${message}
                    </div>
                </div>
            `;

            document.body.appendChild(toast);

            // 3秒后移除
            setTimeout(() => {
                toast.remove();
            }, 3000);
        }

        // 格式化日期
        function formatDate(dateString) {
            if (!dateString) return '未知日期';
            try {
                const date = new Date(dateString);
                return date.toLocaleDateString('zh-CN') + ' ' + date.toLocaleTimeString('zh-CN', {
                    hour: '2-digit',
                    minute: '2-digit'
                });
            } catch (error) {
                return dateString;
            }
        }

        // 模拟API数据(实际项目中应从后端API获取)
        function loadMockData() {
            // 模拟相册数据
            albums = [
                {
                    id: 1,
                    title: "旅行回忆",
                    description: "记录我们美好的旅行时光",
                    style: "standard",
                    create_time: "2026-01-15 10:30:00",
                    photos: [
                        { id: 1, filename: "travel1.jpg", description: "美丽的风景", upload_time: "2026-01-15 10:30:00" },
                        { id: 2, filename: "travel2.jpg", description: "我们的合影", upload_time: "2026-01-15 11:20:00" },
                        { id: 3, filename: "travel3.jpg", description: "美食探索", upload_time: "2026-01-15 12:15:00" }
                    ]
                },
                {
                    id: 2,
                    title: "家庭聚会",
                    description: "温馨的家庭聚会记录",
                    style: "magazine",
                    create_time: "2026-01-20 14:20:00",
                    photos: [
                        { id: 4, filename: "family1.jpg", description: "团圆时刻", upload_time: "2026-01-20 14:20:00" },
                        { id: 5, filename: "family2.jpg", description: "欢乐时光", upload_time: "2026-01-20 15:30:00" }
                    ]
                },
                {
                    id: 3,
                    title: "浪漫时刻",
                    description: "我们最珍贵的浪漫回忆",
                    style: "3d",
                    create_time: "2026-02-01 18:45:00",
                    photos: [
                        { id: 6, filename: "romantic1.jpg", description: "烛光晚餐", upload_time: "2026-02-01 18:45:00" },
                        { id: 7, filename: "romantic2.jpg", description: "海边漫步", upload_time: "2026-02-01 19:20:00" },
                        { id: 8, filename: "romantic3.jpg", description: "星空下的约定", upload_time: "2026-02-01 20:10:00" }
                    ]
                }
            ];

            // 模拟故事数据
            stories = [
                {
                    id: 1,
                    title: "我们的相遇",
                    content: "那是一个阳光明媚的下午,我们在咖啡馆偶然相遇。你的笑容如阳光般温暖,那一刻我就知道,你就是我一直在寻找的那个人。从那天起,我们的生活开始交织在一起,每一刻都充满了甜蜜和惊喜。",
                    create_time: "2026-01-10 09:15:00"
                },
                {
                    id: 2,
                    title: "第一次约会",
                    content: "还记得我们第一次约会去看电影,你紧张得一直搓手,我却觉得特别可爱。电影结束后,我们在江边散步,聊了很久很久... 那天晚上,我知道我已经深深地爱上了你。",
                    create_time: "2026-01-25 20:30:00"
                }
            ];

            // 渲染数据
            renderAlbums();
            renderStories();
        }

        // 如果API不可用,使用模拟数据
        setTimeout(() => {
            if (albums.length === 0) {
                loadMockData();
                showToast('使用示例数据演示,实际使用请连接后端API');
            }
        }, 2000);
    </script>
</body>
</html>
[mw_shl_code=asm,true]<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>浪漫相册轮播</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Pacifico&family=Dancing+Script:wght@400;700&display=swap" rel="stylesheet">
    <style>
        :root {
            --primary-pink: #ff6b8b;
            --secondary-pink: #ffa5b5;
            --light-pink: #fff5f7;
            --gold: #ffd700;
            --purple: #9c88ff;
            --deep-pink: #ff1493;
            --rose-red: #e91e63;
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Microsoft YaHei', sans-serif;
            background: #000;
            color: white;
            overflow: hidden;
            height: 100vh;
        }

        /* 全屏轮播容器 */
        .slideshow-container {
            position: relative;
            width: 100%;
            height: 100vh;
            overflow: hidden;
        }

        /* 控制面板 */
        .control-panel {
            position: fixed;
            top: 20px;
            right: 20px;
            z-index: 1000;
            background: rgba(0, 0, 0, 0.7);
            backdrop-filter: blur(10px);
            border-radius: 15px;
            padding: 15px;
            color: white;
            min-width: 200px;
            box-shadow: 0 5px 20px rgba(0,0,0,0.3);
        }

        .control-panel h4 {
            font-family: 'Pacifico', cursive;
            color: var(--primary-pink);
            margin-bottom: 15px;
            text-align: center;
        }

        .control-item {
            margin-bottom: 10px;
            display: flex;
            align-items: center;
            justify-content: space-between;
        }

        .control-label {
            font-size: 0.9rem;
        }

        .control-value {
            font-weight: bold;
            color: var(--gold);
        }

        .btn-control {
            background: linear-gradient(45deg, var(--primary-pink), var(--purple));
            border: none;
            border-radius: 20px;
            padding: 8px 15px;
            color: white;
            font-size: 0.9rem;
            transition: all 0.3s ease;
            width: 100%;
            margin-top: 10px;
        }

        .btn-control:hover {
            transform: translateY(-2px);
            box-shadow: 0 5px 15px rgba(255,107,139,0.6);
        }

        /* 音乐控制 */
        .music-control {
            position: fixed;
            top: 20px;
            left: 20px;
            z-index: 1000;
            background: rgba(0, 0, 0, 0.7);
            backdrop-filter: blur(10px);
            border-radius: 50%;
            width: 50px;
            height: 50px;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            box-shadow: 0 5px 15px rgba(0,0,0,0.3);
        }

        .music-control i {
            font-size: 1.5rem;
            color: var(--primary-pink);
        }

        /* 样式指示器 */
        .style-indicator {
            position: fixed;
            bottom: 20px;
            left: 50%;
            transform: translateX(-50%);
            z-index: 1000;
            background: rgba(0, 0, 0, 0.7);
            backdrop-filter: blur(10px);
            border-radius: 20px;
            padding: 10px 20px;
            color: white;
            text-align: center;
            min-width: 200px;
        }

        .style-name {
            font-family: 'Dancing Script', cursive;
            font-size: 1.5rem;
            color: var(--gold);
            margin-bottom: 5px;
        }

        .style-timer {
            font-size: 0.9rem;
            color: #ccc;
        }

        .progress-bar {
            height: 5px;
            background: rgba(255,255,255,0.2);
            border-radius: 5px;
            margin-top: 5px;
            overflow: hidden;
        }

        .progress {
            height: 100%;
            background: linear-gradient(90deg, var(--primary-pink), var(--purple));
            width: 0%;
            transition: width 1s linear;
        }

        /* 退出按钮 */
        .exit-btn {
            position: fixed;
            top: 20px;
            right: 20px;
            z-index: 1000;
            background: rgba(0, 0, 0, 0.7);
            backdrop-filter: blur(10px);
            border-radius: 50%;
            width: 50px;
            height: 50px;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            box-shadow: 0 5px 15px rgba(0,0,0,0.3);
            color: white;
            text-decoration: none;
        }

        .exit-btn:hover {
            background: rgba(255, 107, 139, 0.8);
            color: white;
        }

        /* 轮播样式 */

        /* 基础样式 */
        .slideshow-style {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            opacity: 0;
            transition: opacity 1.5s ease-in-out;
        }

        .slideshow-style.active {
            opacity: 1;
        }

        /* 1. 标准网格样式 */
        .style-grid {
            display: grid;
            grid-template-columns: repeat(4, 1fr);
            grid-template-rows: repeat(3, 1fr);
            gap: 10px;
            padding: 20px;
        }

        .style-grid .photo-item {
            border-radius: 10px;
            overflow: hidden;
            position: relative;
            box-shadow: 0 5px 15px rgba(0,0,0,0.3);
            transition: transform 0.5s ease;
        }

        .style-grid .photo-item:hover {
            transform: scale(1.05);
            z-index: 10;
        }

        .style-grid .photo-item img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }

        /* 2. 3D立方体样式 */
        .style-3d {
            perspective: 1000px;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .cube-container {
            width: 300px;
            height: 300px;
            position: relative;
            transform-style: preserve-3d;
            animation: rotateCube 20s infinite linear;
        }

        .cube-face {
            position: absolute;
            width: 300px;
            height: 300px;
            border: 2px solid rgba(255,255,255,0.1);
            border-radius: 10px;
            overflow: hidden;
            backface-visibility: hidden;
        }

        .cube-face img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }

        .cube-face.front { transform: translateZ(150px); }
        .cube-face.back { transform: rotateY(180deg) translateZ(150px); }
        .cube-face.right { transform: rotateY(90deg) translateZ(150px); }
        .cube-face.left { transform: rotateY(-90deg) translateZ(150px); }
        .cube-face.top { transform: rotateX(90deg) translateZ(150px); }
        .cube-face.bottom { transform: rotateX(-90deg) translateZ(150px); }

        @keyframes rotateCube {
            0% { transform: rotateY(0) rotateX(0); }
            100% { transform: rotateY(360deg) rotateX(360deg); }
        }

        /* 3. 杂志样式 */
        .style-magazine {
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 40px;
        }

        .magazine-spread {
            display: flex;
            width: 80%;
            height: 80%;
            background: white;
            border-radius: 10px;
            overflow: hidden;
            box-shadow: 0 10px 30px rgba(0,0,0,0.5);
        }

        .magazine-page {
            flex: 1;
            position: relative;
            overflow: hidden;
        }

        .magazine-page img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }

        .magazine-page::after {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: linear-gradient(45deg, rgba(255,107,139,0.1), rgba(156,136,255,0.1));
        }

        /* 4. 瀑布流样式 */
        .style-masonry {
            columns: 4;
            column-gap: 15px;
            padding: 20px;
        }

        .style-masonry .photo-item {
            break-inside: avoid;
            margin-bottom: 15px;
            border-radius: 10px;
            overflow: hidden;
            box-shadow: 0 5px 15px rgba(0,0,0,0.3);
        }

        .style-masonry .photo-item img {
            width: 100%;
            height: auto;
            display: block;
        }

        /* 5. 拍立得样式 */
        .style-polaroid {
            display: flex;
            flex-wrap: wrap;
            justify-content: center;
            align-items: center;
            padding: 40px;
            gap: 30px;
        }

        .polaroid-item {
            background: white;
            padding: 15px 15px 40px 15px;
            border-radius: 5px;
            box-shadow: 0 5px 15px rgba(0,0,0,0.3);
            transform: rotate(var(--rotation));
            transition: transform 0.5s ease;
        }

        .polaroid-item:hover {
            transform: rotate(0) scale(1.1);
            z-index: 10;
        }

        .polaroid-item img {
            width: 200px;
            height: 200px;
            object-fit: cover;
            display: block;
        }

        /* 6. 胶片样式 */
        .style-filmstrip {
            display: flex;
            height: 100%;
            align-items: center;
            overflow: hidden;
            position: relative;
        }

        .filmstrip {
            display: flex;
            animation: scrollFilm 30s linear infinite;
        }

        .film-frame {
            height: 80vh;
            width: auto;
            margin: 0 10px;
            border: 10px solid #000;
            border-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" fill="black"><rect width="100" height="100" fill="black"/></svg>') 10 round;
            box-shadow: 0 0 20px rgba(255,255,255,0.1);
        }

        .film-frame img {
            height: 100%;
            width: auto;
            object-fit: cover;
        }

        @keyframes scrollFilm {
            0% { transform: translateX(0); }
            100% { transform: translateX(calc(-100% + 100vw)); }
        }

        /* 7. 拼贴画样式 */
        .style-collage {
            display: grid;
            grid-template-columns: repeat(3, 1fr);
            grid-template-rows: repeat(3, 1fr);
            gap: 10px;
            padding: 20px;
            height: 100%;
        }

        .collage-item {
            border-radius: 10px;
            overflow: hidden;
            position: relative;
            box-shadow: 0 5px 15px rgba(0,0,0,0.3);
        }

        .collage-item:nth-child(1) { grid-column: 1 / 3; grid-row: 1 / 3; }
        .collage-item:nth-child(2) { grid-column: 3 / 4; grid-row: 1 / 2; }
        .collage-item:nth-child(3) { grid-column: 3 / 4; grid-row: 2 / 3; }
        .collage-item:nth-child(4) { grid-column: 1 / 2; grid-row: 3 / 4; }
        .collage-item:nth-child(5) { grid-column: 2 / 4; grid-row: 3 / 4; }

        .collage-item img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }

        /* 8. 时间线样式 */
        .style-timeline {
            display: flex;
            height: 100%;
            align-items: center;
            padding: 0 100px;
            position: relative;
        }

        .timeline {
            position: absolute;
            top: 50%;
            left: 0;
            right: 0;
            height: 3px;
            background: linear-gradient(90deg, var(--primary-pink), var(--purple));
        }

        .timeline-item {
            position: absolute;
            top: 50%;
            transform: translateY(-50%);
            width: 200px;
            text-align: center;
        }

        .timeline-item img {
            width: 150px;
            height: 150px;
            object-fit: cover;
            border-radius: 50%;
            border: 5px solid white;
            box-shadow: 0 5px 15px rgba(0,0,0,0.3);
            margin-bottom: 10px;
        }

        /* 9. 画廊样式 */
        .style-gallery {
            display: flex;
            align-items: center;
            justify-content: center;
            height: 100%;
        }

        .gallery-wall {
            display: grid;
            grid-template-columns: repeat(4, 1fr);
            grid-template-rows: repeat(3, 1fr);
            gap: 15px;
            width: 90%;
            height: 90%;
        }

        .gallery-item {
            border: 10px solid white;
            box-shadow: 0 10px 30px rgba(0,0,0,0.3);
            overflow: hidden;
            position: relative;
        }

        .gallery-item img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }

        /* 10. 翻转书样式 */
        .style-flipbook {
            display: flex;
            align-items: center;
            justify-content: center;
            height: 100%;
            perspective: 1000px;
        }

        .flipbook {
            width: 60%;
            height: 80%;
            position: relative;
            transform-style: preserve-3d;
        }

        .flip-page {
            position: absolute;
            width: 100%;
            height: 100%;
            background: white;
            border-radius: 5px;
            overflow: hidden;
            box-shadow: 0 10px 30px rgba(0,0,0,0.3);
            transform-origin: left center;
            transition: transform 1.5s ease-in-out;
        }

        .flip-page img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }

        /* 响应式调整 */
        @media (max-width: 768px) {
            .control-panel {
                top: 10px;
                right: 10px;
                padding: 10px;
                min-width: 150px;
            }

            .style-indicator {
                bottom: 10px;
                padding: 8px 15px;
                min-width: 150px;
            }

            .style-name {
                font-size: 1.2rem;
            }

            .music-control, .exit-btn {
                top: 10px;
                width: 40px;
                height: 40px;
            }

            .style-grid {
                grid-template-columns: repeat(2, 1fr);
                grid-template-rows: repeat(4, 1fr);
                gap: 5px;
                padding: 10px;
            }

            .style-masonry {
                columns: 2;
                column-gap: 10px;
                padding: 10px;
            }
        }
    </style>
</head>
<body>
    <!-- 退出按钮 -->
    <a href="/" class="exit-btn" title="返回首页">
        <i class="fas fa-home"></i>
    </a>

    <!-- 音乐控制 -->
    <div class="music-control" id="musicControl" onclick="toggleMusic()">
        <i class="fas fa-music"></i>
    </div>

    <!-- 控制面板 -->
    <div class="control-panel">
        <h4>浪漫轮播</h4>
        <div class="control-item">
            <span class="control-label">当前样式:</span>
            <span class="control-value" id="currentStyle">标准网格</span>
        </div>
        <div class="control-item">
            <span class="control-label">剩余时间:</span>
            <span class="control-value" id="timeRemaining">30秒</span>
        </div>
        <div class="control-item">
            <span class="control-label">照片数量:</span>
            <span class="control-value" id="photoCount">0张</span>
        </div>
        <button class="btn-control" onclick="togglePlayback()">
            <i class="fas fa-pause" id="playPauseIcon"></i> <span id="playPauseText">暂停</span>
        </button>
        <button class="btn-control" onclick="skipStyle()">
            <i class="fas fa-forward"></i> 跳过样式
        </button>
    </div>

    <!-- 样式指示器 -->
    <div class="style-indicator">
        <div class="style-name" id="styleName">标准网格</div>
        <div class="style-timer" id="styleTimer">00:30</div>
        <div class="progress-bar">
            <div class="progress" id="styleProgress"></div>
        </div>
    </div>

    <!-- 轮播容器 -->
    <div class="slideshow-container" id="slideshowContainer">
        <!-- 各种样式将通过JavaScript动态加载 -->
    </div>

    <!-- 音频元素 -->
    <audio id="backgroundMusic" loop>
        <source src="" type="audio/mp3">
    </audio>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
    <script>
        // 全局变量
        let currentStyleIndex = 0;
        let isPlaying = true;
        let styleTimer = null;
        let timeRemaining = 30; // 30秒
        let currentPhotos = [];
        let allPhotos = [];
        let backgroundMusic = null;
        let isMusicPlaying = false;

        // 可用的轮播样式
        const slideStyles = [
            { name: '标准网格', class: 'style-grid', description: '整齐的网格布局' },
            { name: '3D立方体', class: 'style-3d', description: '3D旋转立方体效果' },
            { name: '杂志风格', class: 'style-magazine', description: '杂志翻页效果' },
            { name: '瀑布流', class: 'style-masonry', description: '瀑布流布局' },
            { name: '拍立得', class: 'style-polaroid', description: '拍立得照片墙' },
            { name: '胶片风格', class: 'style-filmstrip', description: '电影胶片效果' },
            { name: '拼贴画', class: 'style-collage', description: '创意拼贴布局' },
            { name: '时间线', class: 'style-timeline', description: '时间线展示' },
            { name: '艺术画廊', class: 'style-gallery', description: '画廊展示效果' },
            { name: '翻转书', class: 'style-flipbook', description: '书本翻页效果' }
        ];

        // 页面加载完成后初始化
        document.addEventListener('DOMContentLoaded', function() {
            loadPhotos();
            loadMusic();
            startSlideshow();
        });

        // 加载照片数据
        async function loadPhotos() {
            try {
                // 模拟API调用,实际项目中替换为真实API
                const response = await fetch('/api/slideshow-photos');
                allPhotos = await response.json();

                // 如果没有照片,使用示例数据
                if (!allPhotos || allPhotos.length === 0) {
                    allPhotos = generateSamplePhotos(20);
                }

                document.getElementById('photoCount').textContent = allPhotos.length + '张';
                selectRandomPhotos();

            } catch (error) {
                console.error('加载照片失败:', error);
                // 使用示例数据
                allPhotos = generateSamplePhotos(20);
                document.getElementById('photoCount').textContent = allPhotos.length + '张';
                selectRandomPhotos();
            }
        }

        // 生成示例照片数据
        function generateSamplePhotos(count) {
            const samplePhotos = [];
            for (let i = 1; i <= count; i++) {
                samplePhotos.push({
                    id: i,
                    filename: `photo${i}.jpg`,
                    description: `示例照片 ${i}`,
                    album_title: '示例相册'
                });
            }
            return samplePhotos;
        }

        // 随机选择照片
        function selectRandomPhotos() {
            // 随机选择5-10张照片
            const count = Math.floor(Math.random() * 6) + 5;
            currentPhotos = [...allPhotos]
                .sort(() => 0.5 - Math.random())
                .slice(0, count);
        }

        // 加载音乐
        async function loadMusic() {
            try {
                const response = await fetch('/api/current-music');
                const music = await response.json();

                if (music && music.filename) {
                    backgroundMusic = document.getElementById('backgroundMusic');
                    backgroundMusic.src = `/uploads/music/${music.filename}`;
                    backgroundMusic.volume = 0.3;

                    // 尝试自动播放(需要用户交互)
                    setTimeout(() => {
                        backgroundMusic.play().then(() => {
                            isMusicPlaying = true;
                        }).catch(() => {
                            // 自动播放被阻止
                        });
                    }, 1000);
                }
            } catch (error) {
                console.error('加载音乐失败:', error);
            }
        }

        // 切换音乐播放状态
        function toggleMusic() {
            if (!backgroundMusic) return;

            if (isMusicPlaying) {
                backgroundMusic.pause();
                isMusicPlaying = false;
            } else {
                backgroundMusic.play();
                isMusicPlaying = true;
            }
        }

        // 开始轮播
        function startSlideshow() {
            applyRandomStyle();
            startStyleTimer();
        }

        // 应用随机样式
        function applyRandomStyle() {
            // 移除当前活动样式
            document.querySelectorAll('.slideshow-style').forEach(style => {
                style.classList.remove('active');
            });

            // 随机选择新样式(确保不与当前样式相同)
            let newIndex;
            do {
                newIndex = Math.floor(Math.random() * slideStyles.length);
            } while (newIndex === currentStyleIndex && slideStyles.length > 1);

            currentStyleIndex = newIndex;
            const style = slideStyles[currentStyleIndex];

            // 更新界面显示
            document.getElementById('currentStyle').textContent = style.name;
            document.getElementById('styleName').textContent = style.name;

            // 重新随机选择照片
            selectRandomPhotos();

            // 创建样式容器
            const container = document.getElementById('slideshowContainer');
            let styleHTML = '';

            // 根据样式生成对应的HTML结构
            switch(style.class) {
                case 'style-grid':
                    styleHTML = createGridStyle();
                    break;
                case 'style-3d':
                    styleHTML = create3DStyle();
                    break;
                case 'style-magazine':
                    styleHTML = createMagazineStyle();
                    break;
                case 'style-masonry':
                    styleHTML = createMasonryStyle();
                    break;
                case 'style-polaroid':
                    styleHTML = createPolaroidStyle();
                    break;
                case 'style-filmstrip':
                    styleHTML = createFilmstripStyle();
                    break;
                case 'style-collage':
                    styleHTML = createCollageStyle();
                    break;
                case 'style-timeline':
                    styleHTML = createTimelineStyle();
                    break;
                case 'style-gallery':
                    styleHTML = createGalleryStyle();
                    break;
                case 'style-flipbook':
                    styleHTML = createFlipbookStyle();
                    break;
                default:
                    styleHTML = createGridStyle();
            }

container.innerHTML = `
                <div class="slideshow-style ${style.class} active" id="currentStyle">
                    ${styleHTML}
                </div>
            `;

            // 重置计时器
            timeRemaining = 30;
            updateTimerDisplay();
        }

        // 创建网格样式HTML
        // 修复所有样式创建函数中的照片路径
        function createGridStyle() {
            let html = '';
            currentPhotos.forEach(photo => {
                html += `
                    <div class="photo-item">
                        <img src="/uploads/images/${photo.filename}" alt="${photo.title}">
                    </div>
                `;
            });
            return html;
        }

        // 添加错误处理函数
        function handleImageError(img, filename) {
            console.error('图片加载失败:', filename);
            img.src = 'https://via.placeholder.com/800x600?text=图片加载失败';
            img.alt = '图片加载失败';
        }

        // 创建3D样式HTML
        function create3DStyle() {
            let html = '<div class="cube-container">';
            const faces = ['front', 'back', 'right', 'left', 'top', 'bottom'];

            faces.forEach((face, index) => {
                const photo = currentPhotos[index % currentPhotos.length];
                html += `
                    <div class="cube-face ${face}">
                        <img src="/uploads/images/${photo.filename}" alt="${photo.title}">
                    </div>
                `;
            });

            html += '</div>';
            return html;
        }

        // 创建杂志样式HTML
        function createMagazineStyle() {
            let html = '<div class="magazine-spread">';

            // 创建杂志封面和内页
            const spreads = [
                { type: 'cover', photo: currentPhotos[0] },
                { type: 'spread', photos: [currentPhotos[1], currentPhotos[2]] },
                { type: 'spread', photos: [currentPhotos[3], currentPhotos[4]] },
                { type: 'back', photo: currentPhotos[5] }
            ];

            spreads.forEach((spread, index) => {
                if (spread.type === 'cover' && spread.photo) {
                    const photo = spread.photo;
                    html += `
                        <div class="magazine-cover" data-page="${index}">
                            <div class="cover-image">

                            </div>
                            <div class="cover-content">
                                <img src="/uploads/images/${photo.filename}" alt="${photo.title}">
                                <h2>${photo.album_title || '浪漫相册'}</h2>
                                <h1>${photo.description || '我们的爱情故事'}</h1>
                                <div class="cover-decoration">
                                    <i class="fas fa-heart"></i>
                                    <span>永恒的记忆</span>
                                    <i class="fas fa-heart"></i>
                                </div>
                            </div>
                        </div>
                    `;
                } else if (spread.type === 'spread' && spread.photos) {
                    html += `
                        <div class="magazine-spread-page" data-page="${index}">
                            <div class="spread-left">
                                ${spread.photos[0] ? `
                                    <div class="spread-photo">

                                        <div class="photo-caption">
                                            <img src="/uploads/images/${photo.filename}" alt="${photo.title}">
                                            <h3>${spread.photos[0].album_title || '回忆'}</h3>
                                            <p>${spread.photos[0].description || '珍贵的瞬间'}</p>
                                        </div>
                                    </div>
                                ` : '<div class="placeholder-text">更多美好回忆...</div>'}
                            </div>
                            <div class="spread-right">
                                ${spread.photos[1] ? `
                                    <div class="spread-photo">

                                        <div class="photo-caption">
                                            <img src="/uploads/images/${photo.filename}" alt="${photo.title}">
                                            <h3>${spread.photos[1].album_title || '时光'}</h3>
                                            <p>${spread.photos[1].description || '永恒的瞬间'}</p>
                                        </div>
                                    </div>
                                ` : '<div class="placeholder-text">期待更多故事...</div>'}
                            </div>
                        </div>
                    `;
                } else if (spread.type === 'back' && spread.photo) {
                    const photo = spread.photo;
                    html += `
                        <div class="magazine-back-cover" data-page="${index}">
                            <div class="back-content">
                                <div class="final-message">
                                    <i class="fas fa-heart fa-2x"></i>
                                    <h2>我们的故事还在继续...</h2>
                                    <p>每一张照片都是我们爱情的见证</p>
                                    <div class="signature">
                                        <span>永远爱你</span>
                                        <div class="heart-line"></div>
                                    </div>
                                </div>
                                <div class="back-photo">

                                </div>
                            </div>
                        </div>
                    `;
                }
            });

            html += '</div>';
            return html;
        }

        // 创建瀑布流样式HTML
        function createMasonryStyle() {
            let html = '';
            currentPhotos.forEach(photo => {
                // 随机高度,模拟瀑布流效果
                const heightClass = ['', 'tall', 'short'][Math.floor(Math.random() * 3)];

                html += `
                    <div class="photo-item ${heightClass}">
                        <img src="/uploads/images/${photo.filename}" alt="${photo.title}">
                    </div>
                `;
            });
            return html;
        }

        // 创建拍立得样式HTML
        function createPolaroidStyle() {
            let html = '';
            currentPhotos.forEach((photo, index) => {
                // 随机旋转角度
                const rotation = (Math.random() * 20) - 10; // -10到10度之间

                html += `
                    <div class="polaroid-item" style="--rotation: ${rotation}deg">
                        <img src="/uploads/images/${photo.filename}" alt="${photo.title}">
                    </div>
                `;
            });
            return html;
        }

        // 创建胶片样式HTML
        function createFilmstripStyle() {
            let html = '<div class="filmstrip">';

            // 创建足够多的胶片帧
            for (let i = 0; i < 10; i++) {
                const photo = currentPhotos[i % currentPhotos.length];
                html += `
                    <div class="film-frame">
                        <img src="/uploads/images/${photo.filename}" alt="${photo.title}">
                    </div>
                `;
            }

            html += '</div>';
            return html;
        }

        // 创建拼贴画样式HTML
        function createCollageStyle() {
            let html = '';

            // 创建5个拼贴项目
            for (let i = 0; i < 5; i++) {
                const photo = currentPhotos[i % currentPhotos.length];
                html += `
                    <div class="collage-item">
                        <img src="/uploads/images/${photo.filename}" alt="${photo.title}">
                    </div>
                `;
            }

            return html;
        }

        // 创建时间线样式HTML
        function createTimelineStyle() {
            let html = '<div class="timeline"></div>';

            // 在时间线上均匀分布照片
            currentPhotos.forEach((photo, index) => {
                const position = (index / (currentPhotos.length - 1)) * 80 + 10; // 10% 到 90%
                html += `
                    <div class="timeline-item" style="left: ${position}%">
                        <img src="/uploads/images/${photo.filename}" alt="${photo.title}">
                        <div>${photo.description || '美好回忆'}</div>
                    </div>
                `;
            });

            return html;
        }

        // 创建画廊样式HTML
        function createGalleryStyle() {
            let html = '<div class="gallery-wall">';

            // 创建12个画廊项目
            for (let i = 0; i < 12; i++) {
                const photo = currentPhotos[i % currentPhotos.length];
                html += `
                    <div class="gallery-item">
                        <img src="/uploads/images/${photo.filename}" alt="${photo.title}">
                    </div>
                `;
            }

            html += '</div>';
            return html;
        }

        function createFlipbookStyle() {
            let html = '<div class="flipbook">';

            // 创建3-5页翻转书,确保不超过照片数量
            const pageCount = Math.min(5, currentPhotos.length);

            for (let i = 0; i < pageCount; i++) {
                const photo = currentPhotos[i];
                if (!photo) continue;

                const delay = i * 0.8; // 每页延迟0.8秒,更自然的翻页效果
                const rotation = i * 10; // 每页稍微旋转,模拟真实书本

                html += `
                    <div class="flip-page" style="animation-delay: ${delay}s; transform: rotate(${rotation}deg);">
                        <div class="page-content">
                            <div class="page-image">

                            </div>
                            <div class="page-info">
                                <img src="/uploads/images/${photo.filename}" alt="${photo.title}">
                                <h4>${photo.album_title || '我们的回忆'}</h4>
                                <p>${photo.description || '美好的瞬间'}</p>
                                <small>第${i + 1}页</small>
                            </div>
                        </div>
                    </div>
                `;
            }

            html += '</div>';
            return html;
        }


        // 开始样式计时器
        function startStyleTimer() {
            if (styleTimer) {
                clearInterval(styleTimer);
            }

            timeRemaining = 30;
            updateTimerDisplay();

            styleTimer = setInterval(() => {
                if (isPlaying) {
                    timeRemaining--;
                    updateTimerDisplay();

                    if (timeRemaining <= 0) {
                        // 切换到下一个样式
                        applyRandomStyle();
                    }
                }
            }, 1000);
        }

        // 更新计时器显示
        function updateTimerDisplay() {
            document.getElementById('timeRemaining').textContent = timeRemaining + '秒';
            document.getElementById('styleTimer').textContent = formatTime(timeRemaining);

            // 更新进度条
            const progress = ((30 - timeRemaining) / 30) * 100;
            document.getElementById('styleProgress').style.width = progress + '%';
        }

        // 格式化时间显示
        function formatTime(seconds) {
            const mins = Math.floor(seconds / 60);
            const secs = seconds % 60;
            return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
        }

        // 切换播放状态
        function togglePlayback() {
            isPlaying = !isPlaying;

            const icon = document.getElementById('playPauseIcon');
            const text = document.getElementById('playPauseText');

            if (isPlaying) {
                icon.className = 'fas fa-pause';
                text.textContent = '暂停';
            } else {
                icon.className = 'fas fa-play';
                text.textContent = '播放';
            }

            // 控制背景音乐
            if (backgroundMusic) {
                if (isPlaying) {
                    backgroundMusic.play();
                } else {
                    backgroundMusic.pause();
                }
            }
        }

        // 跳过当前样式
        function skipStyle() {
            applyRandomStyle();
        }

        // 全屏显示
        function toggleFullscreen() {
            if (!document.fullscreenElement) {
                document.documentElement.requestFullscreen().catch(err => {
                    console.error('全屏请求失败:', err);
                });
            } else {
                if (document.exitFullscreen) {
                    document.exitFullscreen();
                }
            }
        }

        // 键盘快捷键支持
        document.addEventListener('keydown', function(e) {
            switch(e.key) {
                case ' ':
                    // 空格键切换播放状态
                    e.preventDefault();
                    togglePlayback();
                    break;
                case 'ArrowRight':
                    // 右箭头跳过当前样式
                    e.preventDefault();
                    skipStyle();
                    break;
                case 'f':
                case 'F':
                    // F键切换全屏
                    e.preventDefault();
                    toggleFullscreen();
                    break;
                case 'm':
                case 'M':
                    // M键切换音乐
                    e.preventDefault();
                    toggleMusic();
                    break;
                case 'Escape':
                    // ESC键退出全屏
                    if (document.fullscreenElement) {
                        document.exitFullscreen();
                    }
                    break;
            }
        });

        // 处理全屏变化
        document.addEventListener('fullscreenchange', function() {
            const isFullscreen = !!document.fullscreenElement;
            // 可以在这里添加全屏状态变化的处理逻辑
        });

        // 页面可见性变化处理(标签页切换时暂停)
        document.addEventListener('visibilitychange', function() {
            if (document.hidden) {
                // 页面隐藏时暂停
                if (isPlaying) {
                    togglePlayback();
                }
            }
        });

        // 页面加载完成后初始化
        window.addEventListener('load', function() {
            // 延迟加载,确保所有资源已加载
            setTimeout(() => {
                loadPhotos();
                loadMusic();
                startSlideshow();
            }, 500);
        });
    </script>
</body>
</html>

[/mw_shl_code]
示意图如下: image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

通过网盘分享的文件:love_story_app.zip
链接: https://pan.baidu.com/s/1XO48llnvojz52_7BhBaK8w?pwd=qa2z 提取码: qa2z 复制这段内容后打开百度网盘手机App,操作更方便哦

免费评分

参与人数 6吾爱币 +10 热心值 +6 收起 理由
丶贤之 + 1 + 1 我很赞同!
苏紫方璇 + 5 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
laozhang4201 + 1 + 1 热心回复!
CGR + 1 + 1 谢谢@Thanks!
realma2014 + 1 + 1 谢谢@Thanks!
ganbey + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

hurric 发表于 2026-2-12 20:45
UI挺好的,下来试试 ,感谢分享
qixia888 发表于 2026-2-12 20:50
Bison66680 发表于 2026-2-12 21:35
虽说是AI制作,也能体现贴主对一个项目工程超强的全局掌控,细致的流程把握!
cux666 发表于 2026-2-12 22:27
主打一个情调,浪漫的相册。
 楼主| phantomxjc 发表于 2026-2-12 22:49

咳咳  web项目  只能自己部署
mcse2006 发表于 2026-2-12 23:33
下来试试看效果,感谢
picoyiyi 发表于 2026-2-12 23:38
本地部署好,这样子相片就不会外流了。真正属于自己的
ma5635 发表于 2026-2-13 01:17
不错哦,学习了!~
fjjowhs 发表于 2026-2-13 05:58
这个可以有,辛苦了!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-4-29 09:59

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表