吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4354|回复: 105
收起左侧

[其他原创] 智能抽奖系统(HTML5)

    [复制链接]
dongfang2025 发表于 2025-10-12 11:20
本帖最后由 dongfang2025 于 2025-10-12 11:22 编辑

1.png
2.png
3.png
4.png
5.png




[HTML] 纯文本查看 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>智能抽奖系统</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#4F46E5',
                        secondary: '#7C3AED',
                        accent: '#F59E0B',
                        dark: '#1E293B',
                        light: '#F1F5F9'
                    },
                    fontFamily: {
                        inter: ['Inter', 'system-ui', 'sans-serif'],
                    },
                }
            }
        }
    </script>
    <style type="text/tailwindcss">
        @layer utilities {
            .text-shadow {
                text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
            }
            .text-shadow-lg {
                text-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
            }
            .animation-delay-100 {
                animation-delay: 100ms;
            }
            .animation-delay-200 {
                animation-delay: 200ms;
            }
            .animation-delay-300 {
                animation-delay: 300ms;
            }
        }

        @keyframes lottery-animation {
            0% { opacity: 1; transform: scale(1); }
            50% { opacity: 0.8; transform: scale(0.95); }
            100% { opacity: 1; transform: scale(1); }
        }

        @keyframes falling {
            0% { transform: translateY(-20px) rotate(0deg); opacity: 1; }
            100% { transform: translateY(100vh) rotate(360deg); opacity: 0; }
        }

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

        .lottery-animation {
            animation: lottery-animation 0.2s infinite;
        }

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

        .confetti {
            position: fixed;
            pointer-events: none;
            z-index: 9999;
        }

        .firework {
            position: fixed;
            width: 10px;
            height: 10px;
            border-radius: 50%;
            z-index: 9999;
            pointer-events: none;
        }

        .firework-burst {
            position: fixed;
            width: 5px;
            height: 5px;
            border-radius: 50%;
            z-index: 9999;
            pointer-events: none;
        }
    </style>
</head>
<body class="font-inter bg-gradient-to-br from-primary/10 to-secondary/10 min-h-screen flex flex-col transition-all duration-500">
    <!-- 右键菜单 -->
    <div id="contextMenu" class="fixed hidden z-50 bg-white rounded-lg shadow-xl border border-gray-200 py-1 w-48">
        <div class="context-menu-item px-4 py-2 hover:bg-gray-100 cursor-pointer" data-action="startLottery">
            <i class="fa fa-play mr-2 text-primary"></i>开始抽奖
        </div>
        <div class="context-menu-item px-4 py-2 hover:bg-gray-100 cursor-pointer" data-action="stopLottery">
            <i class="fa fa-stop mr-2 text-red-500"></i>停止抽奖
        </div>
        <div class="border-t border-gray-200 my-1"></div>
        <div class="context-menu-item px-4 py-2 hover:bg-gray-100 cursor-pointer" data-action="viewWinners">
            <i class="fa fa-trophy mr-2 text-accent"></i>中奖名单
        </div>
        <div class="context-menu-item px-4 py-2 hover:bg-gray-100 cursor-pointer" data-action="clearWinners">
            <i class="fa fa-trash mr-2 text-gray-500"></i>清空中奖名单
        </div>
        <div class="border-t border-gray-200 my-1"></div>
        <div class="context-menu-item px-4 py-2 hover:bg-gray-100 cursor-pointer" data-action="manageNames">
            <i class="fa fa-users mr-2 text-secondary"></i>名单管理
        </div>
        <div class="context-menu-item px-4 py-2 hover:bg-gray-100 cursor-pointer" data-action="settings">
            <i class="fa fa-cog mr-2 text-gray-600"></i>系统设置
        </div>
    </div>

    <!-- 主抽奖界面 -->
    <div id="lotteryScreen" class="flex-1 flex flex-col">
        <!-- 标题区域 -->
        <header class="py-6 text-center">
            <h1 id="mainTitle" class="text-[clamp(2rem,5vw,3rem)] font-bold text-dark mb-2 text-shadow">智能抽奖系统</h1>
            <p id="subtitle" class="text-[clamp(1rem,2vw,1.25rem)] text-gray-600">点击开始按钮或按Enter键开始抽奖</p>
        </header>

        <!-- 抽奖区域 -->
        <main class="flex-1 flex items-center justify-center p-6">
            <div id="lotteryContainer" class="w-full max-w-4xl h-full flex items-center justify-center">
                <div id="lotteryName" class="text-[clamp(3rem,10vw,6rem)] font-bold text-dark text-center text-shadow-lg">准备开始</div>
            </div>
        </main>

        <!-- 控制区域 -->
        <footer class="py-8 px-6 text-center">
            <div class="flex justify-center gap-4 flex-wrap">
                <button id="startButton" class="px-8 py-4 bg-primary hover:bg-primary/90 text-white text-xl font-bold rounded-lg transition-colors shadow-lg hover:shadow-xl transform hover:scale-105">
                    <i class="fa fa-play mr-2"></i>开始抽奖
                </button>
                <button id="stopButton" class="hidden px-8 py-4 bg-red-500 hover:bg-red-600 text-white text-xl font-bold rounded-lg transition-colors shadow-lg hover:shadow-xl transform hover:scale-105">
                    <i class="fa fa-stop mr-2"></i>停止抽奖
                </button>
                <button id="viewWinnersButton" class="px-8 py-4 bg-accent hover:bg-accent/90 text-white text-xl font-bold rounded-lg transition-colors shadow-lg hover:shadow-xl transform hover:scale-105">
                    <i class="fa fa-trophy mr-2"></i>中奖名单
                </button>
                <button id="manageNamesButton" class="px-8 py-4 bg-secondary hover:bg-secondary/90 text-white text-xl font-bold rounded-lg transition-colors shadow-lg hover:shadow-xl transform hover:scale-105">
                    <i class="fa fa-users mr-2"></i>名单管理
                </button>
            </div>
        </footer>
    </div>

    <!-- 中奖名单界面 -->
    <div id="winnersScreen" class="fixed inset-0 bg-white z-40 hidden overflow-auto">
        <div class="p-6">
            <div class="flex justify-between items-center mb-8">
                <h2 class="text-[clamp(1.5rem,3vw,2.5rem)] font-bold text-dark">中奖名单</h2>
                <button id="backToMainButton" class="px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded-lg transition-colors">
                    <i class="fa fa-arrow-left mr-2"></i>返回
                </button>
            </div>
            <div id="winnersList" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
                <!-- 中奖名单将在这里动态生成 -->
            </div>
            <div class="flex justify-center gap-4 mt-8">
                <button id="clearWinnersButton" class="px-6 py-3 bg-red-500 hover:bg-red-600 text-white rounded-lg transition-colors">
                    <i class="fa fa-trash mr-2"></i>清空中奖名单
                </button>
                <button id="printWinnersButton" class="px-6 py-3 bg-gray-700 hover:bg-gray-800 text-white rounded-lg transition-colors">
                    <i class="fa fa-print mr-2"></i>打印名单
                </button>
            </div>
        </div>
    </div>

    <!-- 名单管理界面 -->
    <div id="namesManagementScreen" class="fixed inset-0 bg-white z-40 hidden overflow-auto">
        <div class="p-6">
            <div class="flex justify-between items-center mb-8">
                <h2 class="text-[clamp(1.5rem,3vw,2.5rem)] font-bold text-dark">名单管理</h2>
                <button id="backFromNamesButton" class="px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded-lg transition-colors">
                    <i class="fa fa-arrow-left mr-2"></i>返回
                </button>
            </div>
            
            <!-- 参与者名单管理 -->
            <div class="mb-8">
                <div class="flex justify-between items-center mb-4">
                    <h3 class="text-xl font-bold text-dark">参与者名单</h3>
                    <span id="participantsCount" class="text-sm bg-primary/10 text-primary px-3 py-1 rounded-full">0人</span>
                </div>
                <textarea id="participantsInput" class="w-full h-32 p-4 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary transition-all mb-4 resize-none" placeholder="请输入参与者名单,支持顿号分隔或每行一个格式"></textarea>
                <div class="flex flex-wrap gap-2">
                    <button id="addParticipantsButton" class="px-4 py-2 bg-primary hover:bg-primary/90 text-white rounded-lg transition-colors">
                        <i class="fa fa-plus mr-2"></i>添加名单
                    </button>
                    <button id="clearParticipantsButton" class="px-4 py-2 bg-gray-200 hover:bg-gray-300 text-gray-700 rounded-lg transition-colors">
                        <i class="fa fa-eraser mr-2"></i>清空输入
                    </button>
                    <button id="deleteAllParticipantsButton" class="px-4 py-2 bg-red-100 hover:bg-red-200 text-red-700 rounded-lg transition-colors">
                        <i class="fa fa-trash mr-2"></i>删除全部
                    </button>
                    <button id="loadExampleParticipantsButton" class="px-4 py-2 bg-secondary/10 hover:bg-secondary/20 text-secondary rounded-lg transition-colors">
                        <i class="fa fa-file-text-o mr-2"></i>加载示例
                    </button>
                </div>
                <div id="participantsList" class="mt-4">
                    <!-- 参与者列表将在这里动态生成 -->
                </div>
            </div>
            
            <!-- 领导名单管理 -->
            <div>
                <div class="flex justify-between items-center mb-4">
                    <h3 class="text-xl font-bold text-dark">领导名单</h3>
                    <span id="leadersCount" class="text-sm bg-secondary/10 text-secondary px-3 py-1 rounded-full">0人</span>
                </div>
                <textarea id="leadersInput" class="w-full h-24 p-4 border border-gray-300 rounded-lg focus:ring-2 focus:ring-secondary focus:border-secondary transition-all mb-4 resize-none" placeholder="请输入领导名单,支持顿号分隔或每行一个格式"></textarea>
                <div class="flex flex-wrap gap-2">
                    <button id="addLeadersButton" class="px-4 py-2 bg-secondary hover:bg-secondary/90 text-white rounded-lg transition-colors">
                        <i class="fa fa-plus mr-2"></i>添加领导
                    </button>
                    <button id="clearLeadersButton" class="px-4 py-2 bg-gray-200 hover:bg-gray-300 text-gray-700 rounded-lg transition-colors">
                        <i class="fa fa-eraser mr-2"></i>清空输入
                    </button>
                    <button id="deleteAllLeadersButton" class="px-4 py-2 bg-red-100 hover:bg-red-200 text-red-700 rounded-lg transition-colors">
                        <i class="fa fa-trash mr-2"></i>删除全部
                    </button>
                </div>
                <div id="leadersList" class="mt-4">
                    <!-- 领导列表将在这里动态生成 -->
                </div>
            </div>
        </div>
    </div>

    <!-- 设置界面 -->
    <div id="settingsScreen" class="fixed inset-0 bg-white z-40 hidden overflow-auto">
        <div class="p-6">
            <div class="flex justify-between items-center mb-8">
                <h2 class="text-[clamp(1.5rem,3vw,2.5rem)] font-bold text-dark">系统设置</h2>
                <button id="closeSettingsButton" class="px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded-lg transition-colors">
                    <i class="fa fa-times mr-2"></i>关闭
                </button>
            </div>
            
            <div class="max-w-3xl mx-auto space-y-8">
                <!-- 抽奖设置 -->
                <div class="bg-gray-50 p-6 rounded-xl">
                    <h3 class="text-xl font-bold text-dark mb-4">抽奖设置</h3>
                    
                    <!-- 中奖人数 -->
                    <div class="mb-6">
                        <label class="block text-gray-700 mb-2">中奖人数: <span id="winnersCountValue">3</span>人</label>
                        <input type="range" id="winnersCount" min="1" max="100" value="3" class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-primary">
                    </div>
                    
                    <!-- 抽奖速度 -->
                    <div class="mb-6">
                        <label class="block text-gray-700 mb-2">抽奖速度: <span id="lotterySpeedValue">5</span></label>
                        <input type="range" id="lotterySpeed" min="1" max="10" value="5" class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-primary">
                    </div>
                    
                    <!-- 字体大小 -->
                    <div class="mb-6">
                        <label class="block text-gray-700 mb-2">字体大小: <span id="fontSizeValue">10</span></label>
                        <input type="range" id="fontSize" min="1" max="20" value="10" class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-primary">
                    </div>
                    
                    <!-- 抽奖模式 -->
                    <div class="mb-6">
                        <label class="block text-gray-700 mb-2">抽奖模式</label>
                        <div class="flex space-x-4">
                            <label class="flex items-center">
                                <input type="radio" name="lotteryMode" value="random" checked class="w-4 h-4 text-primary focus:ring-primary">
                                <span class="ml-2 text-gray-700">单次循环抽奖</span>
                            </label>
                            <label class="flex items-center">
                                <input type="radio" name="lotteryMode" value="sequential" class="w-4 h-4 text-primary focus:ring-primary">
                                <span class="ml-2 text-gray-700">预设顺序抽奖</span>
                            </label>
                        </div>
                        <div class="mt-2 text-sm text-gray-500">
                            <p>单次循环抽奖:每次抽奖随机显示参与者名单,可重复抽取。</p>
                            <p>预设顺序抽奖:按名单顺序逐个显示参与者,避免重复抽取。</p>
                        </div>
                    </div>
                </div>
                
                <!-- 特效设置 -->
                <div class="bg-gray-50 p-6 rounded-xl">
                    <h3 class="text-xl font-bold text-dark mb-4">特效设置</h3>
                    
                    <!-- 音效开关 -->
                    <div class="flex items-center justify-between mb-4">
                        <label class="text-gray-700">抽奖音效</label>
                        <label class="relative inline-flex items-center cursor-pointer">
                            <input type="checkbox" id="enableDrawSound" checked class="sr-only peer">
                            <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-primary/50 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary"></div>
                        </label>
                    </div>
                    
                    <div class="flex items-center justify-between mb-4">
                        <label class="text-gray-700">中奖音效</label>
                        <label class="relative inline-flex items-center cursor-pointer">
                            <input type="checkbox" id="enableWinSound" checked class="sr-only peer">
                            <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-primary/50 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary"></div>
                        </label>
                    </div>
                    
                    <!-- 烟花特效 -->
                    <div class="flex items-center justify-between mb-4">
                        <label class="text-gray-700">烟花特效</label>
                        <label class="relative inline-flex items-center cursor-pointer">
                            <input type="checkbox" id="enableFireworks" checked class="sr-only peer">
                            <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-primary/50 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary"></div>
                        </label>
                    </div>
                </div>
                
                <!-- 显示设置 -->
                <div class="bg-gray-50 p-6 rounded-xl">
                    <h3 class="text-xl font-bold text-dark mb-4">显示设置</h3>
                    
                    <!-- 主标题 -->
                    <div class="mb-6">
                        <label class="block text-gray-700 mb-2">主标题</label>
                        <input type="text" id="titleInput" value="智能抽奖系统" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary transition-all">
                    </div>
                    
                    <!-- 副标题 -->
                    <div class="mb-6">
                        <label class="block text-gray-700 mb-2">副标题</label>
                        <input type="text" id="subtitleInput" value="点击开始按钮或按Enter键开始抽奖" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary transition-all">
                    </div>
                    
                    <!-- 背景模式 -->
                    <div class="mb-6">
                        <label class="block text-gray-700 mb-2">背景模式</label>
                        <div class="flex space-x-4">
                            <label class="flex items-center">
                                <input type="radio" name="backgroundMode" value="solid" checked class="w-4 h-4 text-primary focus:ring-primary">
                                <span class="ml-2 text-gray-700">纯色背景</span>
                            </label>
                            <label class="flex items-center">
                                <input type="radio" name="backgroundMode" value="image" class="w-4 h-4 text-primary focus:ring-primary">
                                <span class="ml-2 text-gray-700">壁纸背景</span>
                            </label>
                        </div>
                    </div>
                    
                    <!-- 背景颜色 -->
                    <div class="mb-6" id="backgroundColorContainer">
                        <label class="block text-gray-700 mb-2">背景颜色</label>
                        <div class="flex space-x-3">
                            <div class="w-full flex-1">
                                <input type="color" id="backgroundColor" value="#4F46E5" class="w-full h-10 border border-gray-300 rounded-lg cursor-pointer">
                            </div>
                            <div class="w-full flex-1">
                                <input type="color" id="backgroundGradient" value="#7C3AED" class="w-full h-10 border border-gray-300 rounded-lg cursor-pointer">
                            </div>
                        </div>
                        <p class="text-xs text-gray-500 mt-2">选择渐变背景的两种颜色</p>
                    </div>
                    
                    <!-- 背景图片URL -->
                    <div class="mb-6 hidden" id="backgroundImageContainer">
                        <label class="block text-gray-700 mb-2">背景图片URL</label>
                        <input type="text" id="backgroundImage" value="https://picsum.photos/id/1067/1920/1080" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary transition-all">
                    </div>
                </div>
            </div>
            
            <div class="flex justify-center gap-4 mt-8">
                <button id="resetSettingsButton" class="px-6 py-3 bg-gray-200 hover:bg-gray-300 text-gray-700 rounded-lg transition-colors">
                    <i class="fa fa-refresh mr-2"></i>重置设置
                </button>
                <button id="saveSettingsButton" class="px-6 py-3 bg-primary hover:bg-primary/90 text-white rounded-lg transition-colors">
                    <i class="fa fa-save mr-2"></i>保存设置
                </button>
            </div>
        </div>
    </div>

    <!-- 音效元素 -->
    <audio id="drawSound" preload="auto">
        <source src="https://assets.mixkit.co/sfx/preview/mixkit-winning-chimes-2015.mp3" type="audio/mpeg">
        <!-- 备用音频源 -->
        <source src="https://soundbible.com/grab.php?id=1747&type=mp3" type="audio/mpeg">
    </audio>
    <audio id="winSound" preload="auto">
        <source src="https://assets.mixkit.co/sfx/preview/mixkit-achievement-bell-600.mp3" type="audio/mpeg">
        <!-- 备用音频源 -->
        <source src="https://soundbible.com/grab.php?id=1759&type=mp3" type="audio/mpeg">
    </audio>

    <script>
        // 数据结构定义
        const data = {
            participants: [], // 参与者名单
            leaders: [], // 领导名单
            winners: [], // 中奖记录
            settings: {
                winnersCount: 3, // 中奖人数
                lotterySpeed: 5, // 抽奖速度(1-10,10最快)
                fontSize: 10, // 字体大小(1-20,10正常)
                lotteryMode: 'random', // 抽奖模式
                enableDrawSound: true, // 抽奖音效
                enableWinSound: true, // 中奖音效
                enableFireworks: true, // 烟花特效
                mainTitle: '智能抽奖系统', // 主标题
                subtitle: '点击开始按钮或按Enter键开始抽奖', // 副标题
                backgroundMode: 'solid', // 背景模式
                backgroundColor: '#4F46E5', // 背景颜色
                backgroundGradient: '#7C3AED', // 渐变背景颜色
                backgroundImage: 'https://picsum.photos/id/1067/1920/1080' // 背景图片URL
            }
        };

        // 应用状态
        const state = {
            isDrawing: false, // 是否正在抽奖
            drawInterval: null, // 抽奖定时器
            sequentialDrawIndex: 0, // 顺序抽奖的当前索引
            hasDrawnAll: false // 是否已经抽完所有参与者
        };

        // DOM元素引用
        const elements = {
            // 主界面元素
            lotteryScreen: document.getElementById('lotteryScreen'),
            mainTitle: document.getElementById('mainTitle'),
            subtitle: document.getElementById('subtitle'),
            lotteryContainer: document.getElementById('lotteryContainer'),
            lotteryName: document.getElementById('lotteryName'),
            startButton: document.getElementById('startButton'),
            stopButton: document.getElementById('stopButton'),
            viewWinnersButton: document.getElementById('viewWinnersButton'),
            manageNamesButton: document.getElementById('manageNamesButton'),
            
            // 中奖名单界面元素
            winnersScreen: document.getElementById('winnersScreen'),
            backToMainButton: document.getElementById('backToMainButton'),
            winnersList: document.getElementById('winnersList'),
            clearWinnersButton: document.getElementById('clearWinnersButton'),
            printWinnersButton: document.getElementById('printWinnersButton'),
            
            // 名单管理界面元素
            namesManagementScreen: document.getElementById('namesManagementScreen'),
            backFromNamesButton: document.getElementById('backFromNamesButton'),
            participantsInput: document.getElementById('participantsInput'),
            participantsList: document.getElementById('participantsList'),
            participantsCount: document.getElementById('participantsCount'),
            addParticipantsButton: document.getElementById('addParticipantsButton'),
            clearParticipantsButton: document.getElementById('clearParticipantsButton'),
            deleteAllParticipantsButton: document.getElementById('deleteAllParticipantsButton'),
            loadExampleParticipantsButton: document.getElementById('loadExampleParticipantsButton'),
            leadersInput: document.getElementById('leadersInput'),
            leadersList: document.getElementById('leadersList'),
            leadersCount: document.getElementById('leadersCount'),
            addLeadersButton: document.getElementById('addLeadersButton'),
            clearLeadersButton: document.getElementById('clearLeadersButton'),
            deleteAllLeadersButton: document.getElementById('deleteAllLeadersButton'),
            
            // 设置界面元素
            settingsScreen: document.getElementById('settingsScreen'),
            closeSettingsButton: document.getElementById('closeSettingsButton'),
            saveSettingsButton: document.getElementById('saveSettingsButton'),
            resetSettingsButton: document.getElementById('resetSettingsButton'),
            winnersCount: document.getElementById('winnersCount'),
            winnersCountValue: document.getElementById('winnersCountValue'),
            lotterySpeed: document.getElementById('lotterySpeed'),
            lotterySpeedValue: document.getElementById('lotterySpeedValue'),
            fontSize: document.getElementById('fontSize'),
            fontSizeValue: document.getElementById('fontSizeValue'),
            titleInput: document.getElementById('titleInput'),
            subtitleInput: document.getElementById('subtitleInput'),
            backgroundColor: document.getElementById('backgroundColor'),
            backgroundGradient: document.getElementById('backgroundGradient'),
            backgroundColorContainer: document.getElementById('backgroundColorContainer'),
            backgroundImage: document.getElementById('backgroundImage'),
            backgroundImageContainer: document.getElementById('backgroundImageContainer'),
            enableDrawSound: document.getElementById('enableDrawSound'),
            enableWinSound: document.getElementById('enableWinSound'),
            enableFireworks: document.getElementById('enableFireworks'),
            
            // 右键菜单
            contextMenu: document.getElementById('contextMenu'),
            
            // 音效元素
            drawSound: document.getElementById('drawSound'),
            winSound: document.getElementById('winSound')
        };

        // 更新设置显示
        function updateSettingsDisplay() {
            elements.winnersCount.value = data.settings.winnersCount;
            elements.winnersCountValue.textContent = data.settings.winnersCount;
            
            elements.lotterySpeed.value = data.settings.lotterySpeed;
            elements.lotterySpeedValue.textContent = data.settings.lotterySpeed;
            
            elements.fontSize.value = data.settings.fontSize;
            elements.fontSizeValue.textContent = data.settings.fontSize;
            
            elements.titleInput.value = data.settings.mainTitle;
            elements.subtitleInput.value = data.settings.subtitle;
            
            elements.backgroundColor.value = data.settings.backgroundColor;
            elements.backgroundGradient.value = data.settings.backgroundGradient;
            elements.backgroundImage.value = data.settings.backgroundImage;
            
            elements.enableDrawSound.checked = data.settings.enableDrawSound;
            elements.enableWinSound.checked = data.settings.enableWinSound;
            elements.enableFireworks.checked = data.settings.enableFireworks;
            
            // 设置抽奖模式
            document.querySelector(`input[name="lotteryMode"][value="${data.settings.lotteryMode}"]`).checked = true;
            
            // 设置背景模式
            document.querySelector(`input[name="backgroundMode"][value="${data.settings.backgroundMode}"]`).checked = true;
            
            // 更新背景模式相关UI
            if (data.settings.backgroundMode === 'solid') {
                elements.backgroundColorContainer.classList.remove('hidden');
                elements.backgroundImageContainer.classList.add('hidden');
            } else {
                elements.backgroundColorContainer.classList.add('hidden');
                elements.backgroundImageContainer.classList.remove('hidden');
            }
            
            // 应用背景
            updateBackground();
            
            // 应用标题
            elements.mainTitle.textContent = data.settings.mainTitle;
            elements.subtitle.textContent = data.settings.subtitle;
            
            // 应用字体大小
            const fontSizeMultiplier = 0.5 + (data.settings.fontSize * 0.05);
            elements.lotteryName.style.fontSize = `clamp(${2 * fontSizeMultiplier}rem, ${8 * fontSizeMultiplier}vw, ${5 * fontSizeMultiplier}rem)`;
        }

        // 保存设置
        function saveSettings() {
            data.settings.winnersCount = parseInt(elements.winnersCount.value);
            data.settings.lotterySpeed = parseInt(elements.lotterySpeed.value);
            data.settings.fontSize = parseInt(elements.fontSize.value);
            data.settings.lotteryMode = document.querySelector('input[name="lotteryMode"]:checked').value;
            data.settings.mainTitle = elements.titleInput.value;
            data.settings.subtitle = elements.subtitleInput.value;
            data.settings.backgroundMode = document.querySelector('input[name="backgroundMode"]:checked').value;
            data.settings.backgroundColor = elements.backgroundColor.value;
            data.settings.backgroundGradient = elements.backgroundGradient.value;
            data.settings.backgroundImage = elements.backgroundImage.value;
            data.settings.enableDrawSound = elements.enableDrawSound.checked;
            data.settings.enableWinSound = elements.enableWinSound.checked;
            data.settings.enableFireworks = elements.enableFireworks.checked;
            
            // 应用设置
            updateSettingsDisplay();
            
            // 保存到本地存储
            saveData();
            
            // 关闭设置界面
            elements.settingsScreen.classList.add('hidden');
        }

        // 重置设置
        function resetSettings() {
            if (confirm('确定要重置所有设置吗?')) {
                // 重置为默认设置
                data.settings = {
                    winnersCount: 3,
                    lotterySpeed: 5,
                    fontSize: 10,
                    lotteryMode: 'random',
                    enableDrawSound: true,
                    enableWinSound: true,
                    enableFireworks: true,
                    mainTitle: '智能抽奖系统',
                    subtitle: '点击开始按钮或按Enter键开始抽奖',
                    backgroundMode: 'solid',
                    backgroundColor: '#4F46E5',
                    backgroundGradient: '#7C3AED',
                    backgroundImage: 'https://picsum.photos/id/1067/1920/1080'
                };
                
                // 更新显示
                updateSettingsDisplay();
                
                // 保存到本地存储
                saveData();
            }
        }

        // 更新参与者名单显示
        function updateParticipantsList() {
            elements.participantsList.innerHTML = '';
            elements.participantsCount.textContent = `${data.participants.length}人`;
            
            if (data.participants.length === 0) {
                elements.participantsList.innerHTML = '<p class="text-gray-400 text-sm">暂无参与者</p>';
                return;
            }
            
            const list = document.createElement('div');
            list.className = 'flex flex-wrap gap-2';
            
            data.participants.forEach((name, index) => {
                const tag = document.createElement('div');
                tag.className = 'bg-primary/20 text-primary text-sm px-2 py-1 rounded-full flex items-center gap-1 border border-primary/30';
                tag.innerHTML = `
                  <span>${name}</span>
                  <button class="text-gray-400 hover:text-primary"><i class="fa fa-times"></i></button>
                `;
                list.appendChild(tag);
            });
            
            elements.participantsList.appendChild(list);
        }

        // 更新领导名单显示
        function updateLeadersList() {
            elements.leadersList.innerHTML = '';
            elements.leadersCount.textContent = `${data.leaders.length}人`;
            
            if (data.leaders.length === 0) {
                elements.leadersList.innerHTML = '<p class="text-gray-400 text-sm">暂无领导</p>';
                return;
            }
            
            const list = document.createElement('div');
            list.className = 'flex flex-wrap gap-2';
            
            data.leaders.forEach((name, index) => {
                const tag = document.createElement('div');
                tag.className = 'bg-secondary/20 text-secondary text-sm px-2 py-1 rounded-full flex items-center gap-1 border border-secondary/30';
                tag.innerHTML = `
                  <span><i class="fa fa-star mr-1"></i>${name}</span>
                  <button class="text-gray-400 hover:text-secondary"><i class="fa fa-times"></i></button>
                `;
                list.appendChild(tag);
            });
            
            elements.leadersList.appendChild(list);
        }

        // 更新中奖名单显示
        function updateWinnersList() {
            elements.winnersList.innerHTML = '';
            
            if (data.winners.length === 0) {
                elements.winnersList.innerHTML = `
                  <div class="col-span-full py-16 text-center text-gray-400">
                    <i class="fa fa-trophy text-5xl mb-6 block"></i>
                    <p class="text-xl">暂无中奖记录</p>
                  </div>
                `;
                return;
            }
            
            // 添加"恭喜"标题
            const congratulationTitle = document.createElement('div');
            congratulationTitle.className = 'col-span-full text-center mb-8';
            congratulationTitle.innerHTML = '<h3 class="text-3xl font-bold text-primary">恭喜中奖!</h3>';
            elements.winnersList.appendChild(congratulationTitle);
            
            // 横向排列中奖名单
            data.winners.forEach((winner, index) => {
                const isLeader = data.leaders.includes(winner.name);
                const card = document.createElement('div');
                card.className = `rounded-xl p-6 ${isLeader ? 'bg-secondary/20 border-2 border-secondary/50' : 'bg-white/90 border border-gray-200'} transform transition-all duration-300 hover:scale-105 hover:shadow-2xl`;
                card.innerHTML = `
                  <div class="flex flex-col items-center text-center">
                    <div class="w-16 h-16 rounded-full flex items-center justify-center mb-4 text-2xl font-bold ${isLeader ? 'bg-secondary text-white' : 'bg-primary text-white'} shadow-lg">
                      ${index + 1}
                    </div>
                    <h4 class="text-xl font-bold mb-2 ${isLeader ? 'text-secondary' : 'text-gray-800'}">${winner.name}</h4>
                    <p class="text-sm text-gray-500">${winner.time}</p>
                    ${isLeader ? '<div class="mt-3 inline-block bg-secondary text-white text-xs px-3 py-1 rounded-full"><i class="fa fa-trophy mr-1"></i>特别奖</div>' : ''}
                  </div>
                `;
                elements.winnersList.appendChild(card);
            });
        }

        // 开始抽奖
        function startLottery() {
            if (data.participants.length === 0) {
                alert('请先添加参与者名单!');
                return;
            }
            
            // 检查是否已经抽完所有参与者(仅适用于预设顺序抽奖)
            if (data.settings.lotteryMode === 'sequential' && state.hasDrawnAll) {
                if (confirm('所有参与者已经抽完,是否重新开始?')) {
                    state.sequentialDrawIndex = 0;
                    state.hasDrawnAll = false;
                } else {
                    return;
                }
            }
            
            // 重置抽奖显示,确保第二次点击抽奖时能直接回到滚动效果
            resetLotteryDisplay();
            
            state.isDrawing = true;
            elements.startButton.classList.add('hidden');
            elements.stopButton.classList.remove('hidden');
            elements.lotteryName.classList.add('lottery-animation');
            
            // 停止获奖音效并重置其状态
            if (elements.winSound) {
                elements.winSound.pause();
                elements.winSound.currentTime = 0;
            }
            
            // 播放抽奖音效
            if (data.settings.enableDrawSound && elements.drawSound) {
                elements.drawSound.currentTime = 0;
                elements.drawSound.play().catch(e => console.log('无法播放音效:', e));
            }
            
            // 计算抽奖间隔时间(速度越快,间隔越小)
            const intervalTime = 300 - (data.settings.lotterySpeed * 15);
            
            // 设置抽奖循环
            state.drawInterval = setInterval(() => {
                let randomIndex;
                
                if (data.settings.lotteryMode === 'sequential') {
                    // 预设顺序抽奖模式
                    randomIndex = state.sequentialDrawIndex % data.participants.length;
                    state.sequentialDrawIndex++;
                } else {
                    // 单次循环抽奖模式
                    randomIndex = Math.floor(Math.random() * data.participants.length);
                }
                
                elements.lotteryName.textContent = data.participants[randomIndex];
            }, intervalTime);
        }

        // 停止抽奖
        function stopLottery() {
            if (!state.isDrawing) return;
            
            state.isDrawing = false;
            clearInterval(state.drawInterval);
            elements.startButton.classList.remove('hidden');
            elements.stopButton.classList.add('hidden');
            elements.lotteryName.classList.remove('lottery-animation');
            
            // 停止抽奖音效
            if (elements.drawSound) {
                elements.drawSound.pause();
            }
            
            // 选择中奖者
            const winners = selectWinners();
            
            // 显示中奖者
            displayWinners(winners);
            
            // 播放中奖音效
            if (data.settings.enableWinSound && elements.winSound) {
                elements.winSound.currentTime = 0;
                elements.winSound.play().catch(e => console.log('无法播放音效:', e));
            }
            
            // 添加特效
            if (data.settings.enableFireworks) {
                createFireworks();
                createConfetti();
            }
            
            // 保存中奖记录
            saveWinners(winners);
        }

        // 选择中奖者
        function selectWinners() {
            const winners = [];
            let availableParticipants = [...data.participants];
            
            // 计算领导必中人数 (50%的概率让领导必中,随机选择1-3名领导)
            const shouldLeadersWin = Math.random() > 0.5 && data.leaders.length > 0;
            let leadersToWin = [];
            
            if (shouldLeadersWin) {
                const leadersCount = Math.min(Math.floor(Math.random() * 3) + 1, data.leaders.length);
                const shuffledLeaders = [...data.leaders].sort(() => Math.random() - 0.5);
                
                // 从打乱的领导名单中选择指定数量
                leadersToWin = shuffledLeaders.slice(0, leadersCount);
                
                // 将选中的领导从可用参与者中移除
                availableParticipants = availableParticipants.filter(participant => 
                    !leadersToWin.includes(participant)
                );
            }
            
            // 计算普通参与者中奖人数
            const normalWinnersCount = Math.max(0, data.settings.winnersCount - leadersToWin.length);
            const totalWinnersCount = Math.min(data.settings.winnersCount, leadersToWin.length + availableParticipants.length);
            
            // 添加领导中奖者
            leadersToWin.forEach(name => {
                winners.push({
                    name: name,
                    isLeader: true
                });
            });
            
            // 添加普通参与者中奖者
            for (let i = 0; i < normalWinnersCount && availableParticipants.length > 0; i++) {
                const randomIndex = Math.floor(Math.random() * availableParticipants.length);
                const isLeader = data.leaders.includes(availableParticipants[randomIndex]);
                
                winners.push({
                    name: availableParticipants[randomIndex],
                    isLeader: isLeader
                });
                
                availableParticipants.splice(randomIndex, 1);
            }
            
            // 打乱中奖顺序(避免领导总是排在前面)
            return winners.sort(() => Math.random() - 0.5);
        }

        // 显示中奖者
        function displayWinners(winners) {
            // 清空当前显示
            elements.lotteryContainer.innerHTML = '';
            
            // 创建中奖者显示容器
            const winnersContainer = document.createElement('div');
            winnersContainer.className = 'w-full h-full flex flex-col items-center justify-center p-6';
            
            // 中奖标题
            const title = document.createElement('h2');
            title.className = 'text-3xl font-bold text-primary mb-8';
            title.textContent = '恭喜中奖!';
            winnersContainer.appendChild(title);
            
            // 中奖者列表 - 横向排列
            const winnersList = document.createElement('div');
            winnersList.className = 'flex flex-wrap justify-center gap-6 w-full';
            
            winners.forEach((winner, index) => {
                const winnerCard = document.createElement('div');
                winnerCard.className = `p-6 rounded-xl text-center ${winner.isLeader ? 'bg-secondary/20 border-2 border-secondary animate-float' : 'bg-white/80 border border-gray-200'} transition-all duration-300 max-w-[200px]`;
                
                const name = document.createElement('div');
                name.className = `text-[clamp(1.5rem,5vw,2.5rem)] font-bold mb-3 ${winner.isLeader ? 'text-secondary' : 'text-gray-800'}`;
                name.textContent = winner.name;
                
                winnerCard.appendChild(name);
                
                // 如果是领导,添加特殊标识
                if (winner.isLeader) {
                    const badge = document.createElement('div');
                    badge.className = 'inline-block bg-secondary text-white text-xs px-3 py-1 rounded-full';
                    badge.innerHTML = '<i class="fa fa-trophy mr-1"></i>特别奖';
                    winnerCard.appendChild(badge);
                }
                
                winnersList.appendChild(winnerCard);
            });
            
            winnersContainer.appendChild(winnersList);
            
            // 返回按钮
            const backButton = document.createElement('button');
            backButton.className = 'mt-10 px-8 py-3 bg-gray-700 text-white rounded-lg hover:bg-gray-800 transition-colors text-lg';
            backButton.innerHTML = '<i class="fa fa-arrow-left mr-2"></i>返回';
            backButton.onclick = () => {
                resetLotteryDisplay();
            };
            
            winnersContainer.appendChild(backButton);
            
            // 添加到容器
            elements.lotteryContainer.appendChild(winnersContainer);
        }

        // 重置抽奖显示
        function resetLotteryDisplay() {
            elements.lotteryContainer.innerHTML = '';
            
            const nameElement = document.createElement('div');
            nameElement.id = 'lotteryName';
            nameElement.className = 'text-[clamp(3rem,10vw,6rem)] font-bold text-gray-800 text-center';
            nameElement.textContent = '准备开始';
            
            elements.lotteryContainer.appendChild(nameElement);
            
            // 重新获取DOM引用
            elements.lotteryName = document.getElementById('lotteryName');
        }

        // 保存中奖记录
        function saveWinners(winners) {
            const now = new Date();
            const formattedTime = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}`;
            
            winners.forEach(winner => {
                data.winners.unshift({
                    name: winner.name,
                    time: formattedTime
                });
            });
            
            saveData();
            updateWinnersList();
        }

        // 创建烟花效果
        function createFireworks() {
            const colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FECA57', '#DDA0DD', '#98D8C8'];
            
            for (let i = 0; i < 10; i++) {
                setTimeout(() => {
                    const firework = document.createElement('div');
                    firework.className = 'firework';
                    
                    // 随机位置
                    const x = Math.random() * window.innerWidth;
                    const y = Math.random() * window.innerHeight * 0.7;
                    
                    firework.style.left = `${x}px`;
                    firework.style.top = `${y}px`;
                    
                    // 随机颜色
                    const color = colors[Math.floor(Math.random() * colors.length)];
                    firework.style.backgroundColor = color;
                    
                    document.body.appendChild(firework);
                    
                    // 爆炸效果
                    setTimeout(() => {
                        createFireworkBurst(x, y, color);
                        document.body.removeChild(firework);
                    }, 500);
                }, i * 200);
            }
        }

        // 创建烟花爆炸效果
        function createFireworkBurst(x, y, color) {
            const particleCount = 30;
            
            for (let i = 0; i < particleCount; i++) {
                const particle = document.createElement('div');
                particle.className = 'firework-burst';
                
                // 设置位置
                particle.style.left = `${x}px`;
                particle.style.top = `${y}px`;
                particle.style.backgroundColor = color;
                
                // 计算随机方向和距离
                const angle = Math.random() * Math.PI * 2;
                const distance = Math.random() * 100 + 50;
                const endX = Math.cos(angle) * distance;
                const endY = Math.sin(angle) * distance;
                
                // 添加动画
                particle.style.transition = `transform ${Math.random() * 2 + 1}s ease-out, opacity 2s ease-out`;
                
                // 添加到DOM
                document.body.appendChild(particle);
                
                // 触发重排
                particle.offsetWidth;
                
                // 应用变换
                particle.style.transform = `translate(${endX}px, ${endY}px)`;
                particle.style.opacity = '0';
                
                // 移除粒子
                setTimeout(() => {
                    document.body.removeChild(particle);
                }, 2000);
            }
        }

        // 创建彩纸效果
        function createConfetti() {
            const colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FECA57', '#DDA0DD', '#98D8C8'];
            const confettiCount = 200;
            
            for (let i = 0; i < confettiCount; i++) {
                const confetti = document.createElement('div');
                confetti.className = 'confetti';
                
                // 随机位置
                const x = Math.random() * window.innerWidth;
                confetti.style.left = `${x}px`;
                confetti.style.top = `${-20}px`;
                
                // 随机颜色
                const color = colors[Math.floor(Math.random() * colors.length)];
                confetti.style.backgroundColor = color;
                
                // 随机大小
                const size = Math.random() * 10 + 5;
                confetti.style.width = `${size}px`;
                confetti.style.height = `${size}px`;
                
                // 随机动画持续时间
                const duration = Math.random() * 5 + 3;
                confetti.style.animation = `falling ${duration}s linear forwards`;
                
                // 随机旋转
                const rotation = Math.random() * 360;
                confetti.style.transform = `rotate(${rotation}deg)`;
                
                document.body.appendChild(confetti);
                
                // 移除彩纸
                setTimeout(() => {
                    document.body.removeChild(confetti);
                }, duration * 1000);
            }
        }

        // 中奖名单播放功能
        function playWinners() {
            if (data.winners.length === 0) {
                alert('暂无中奖记录!');
                return;
            }
            
            // 清空当前显示
            elements.lotteryContainer.innerHTML = '';
            
            // 创建播放容器
            const playContainer = document.createElement('div');
            playContainer.className = 'w-full h-full flex flex-col items-center justify-center p-6';
            
            // 标题
            const title = document.createElement('h2');
            title.className = 'text-3xl font-bold text-primary mb-8';
            title.textContent = '中奖名单回放';
            playContainer.appendChild(title);
            
            // 中奖者列表容器
            const winnersContainer = document.createElement('div');
            winnersContainer.className = 'flex flex-wrap justify-center gap-6 w-full';
            playContainer.appendChild(winnersContainer);
            
            // 返回按钮
            const backButton = document.createElement('button');
            backButton.className = 'mt-10 px-8 py-3 bg-gray-700 text-white rounded-lg hover:bg-gray-800 transition-colors text-lg';
            backButton.innerHTML = '<i class="fa fa-arrow-left mr-2"></i>返回';
            backButton.onclick = () => {
                resetLotteryDisplay();
            };
            playContainer.appendChild(backButton);
            
            // 添加到容器
            elements.lotteryContainer.appendChild(playContainer);
            
            // 逐个显示中奖者
            let currentIndex = 0;
            const showNextWinner = () => {
                if (currentIndex >= data.winners.length) return;
                
                const winner = data.winners[currentIndex];
                const isLeader = data.leaders.includes(winner.name);
                
                const winnerCard = document.createElement('div');
                winnerCard.className = `p-6 rounded-xl text-center ${isLeader ? 'bg-secondary/20 border-2 border-secondary animate-float' : 'bg-white/80 border border-gray-200'} transition-all duration-300 max-w-[200px] opacity-0`;
                
                const name = document.createElement('div');
                name.className = `text-[clamp(1.5rem,5vw,2.5rem)] font-bold mb-3 ${isLeader ? 'text-secondary' : 'text-gray-800'}`;
                name.textContent = winner.name;
                
                winnerCard.appendChild(name);
                
                // 时间
                const time = document.createElement('div');
                time.className = 'text-sm text-gray-500 mb-3';
                time.textContent = winner.time;
                winnerCard.appendChild(time);
                
                // 如果是领导,添加特殊标识
                if (isLeader) {
                    const badge = document.createElement('div');
                    badge.className = 'inline-block bg-secondary text-white text-xs px-3 py-1 rounded-full';
                    badge.innerHTML = '<i class="fa fa-trophy mr-1"></i>特别奖';
                    winnerCard.appendChild(badge);
                }
                
                winnersContainer.appendChild(winnerCard);
                
                // 淡入动画
                setTimeout(() => {
                    winnerCard.style.opacity = '1';
                    winnerCard.style.transition = 'opacity 0.5s';
                    
                    // 播放音效
                    if (data.settings.enableWinSound) {
                        elements.winSound.currentTime = 0;
                        elements.winSound.play().catch(e => console.log('无法播放音效:', e));
                    }
                    
                    currentIndex++;
                    setTimeout(showNextWinner, 1000);
                }, 100);
            };
            
            // 开始播放
            showNextWinner();
        }

        // 添加参与者
        function addParticipants() {
            const input = elements.participantsInput.value.trim();
            if (!input) return;
            
            // 支持顿号分隔或每行一个格式
            const names = input.split(/[、\n]+/).filter(name => name.trim());
            
            // 去重添加
            names.forEach(name => {
                if (!data.participants.includes(name.trim())) {
                    data.participants.push(name.trim());
                }
            });
            
            elements.participantsInput.value = '';
            updateParticipantsList();
            saveData();
        }

        // 添加领导
        function addLeaders() {
            const input = elements.leadersInput.value.trim();
            if (!input) return;
            
            // 支持顿号分隔或每行一个格式
            const names = input.split(/[、\n]+/).filter(name => name.trim());
            
            // 去重添加
            names.forEach(name => {
                if (!data.leaders.includes(name.trim())) {
                    data.leaders.push(name.trim());
                }
            });
            
            elements.leadersInput.value = '';
            updateLeadersList();
            saveData();
        }

        // 移除参与者
        function removeParticipant(index) {
            data.participants.splice(index, 1);
            updateParticipantsList();
            saveData();
        }

        // 移除领导
        function removeLeader(index) {
            data.leaders.splice(index, 1);
            updateLeadersList();
            saveData();
        }

        // 清空中奖名单
        function clearWinners() {
            if (confirm('确定要清空中奖名单吗?此操作不可恢复。')) {
                data.winners = [];
                updateWinnersList();
                saveData();
            }
        }

        // 打印中奖名单
        function printWinners() {
            if (data.winners.length === 0) {
                alert('暂无中奖记录!');
                return;
            }
            
            // 创建临时打印窗口
            const printWindow = window.open('', '_blank');
            printWindow.document.write(`
                <html>
                <head>
                    <title>中奖名单 - 智能抽奖系统</title>
                    <style>
                        body { font-family: Arial, sans-serif; margin: 20px; }
                        h1 { text-align: center; color: #4F46E5; font-size: 28px; margin-bottom: 30px; }
                        .congrats { text-align: center; color: #7C3AED; font-size: 22px; margin-bottom: 40px; font-weight: bold; }
                        .winners-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 20px; }
                        .winner-card { border: 1px solid #ddd; padding: 15px; border-radius: 8px; text-align: center; }
                        .winner-rank { background-color: #4F46E5; color: white; width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 10px; font-weight: bold; font-size: 18px; }
                        .winner-name { font-weight: bold; font-size: 18px; margin-bottom: 5px; }
                        .winner-time { color: #666; font-size: 14px; }
                        .leader-card { background-color: #f0e6ff; border-color: #7C3AED; }
                        .leader-rank { background-color: #7C3AED; }
                        .leader-badge { display: inline-block; background-color: #7C3AED; color: white; font-size: 12px; padding: 2px 8px; border-radius: 10px; margin-top: 8px; }
                    </style>
                </head>
                <body>
                    <h1>中奖名单</h1>
                    <div class="congrats">恭喜中奖!</div>
                    <div class="winners-grid">
                        ${data.winners.map((winner, index) => {
                            const isLeader = data.leaders.includes(winner.name);
                            return `
                                <div class="winner-card ${isLeader ? 'leader-card' : ''}">
                                    <div class="winner-rank ${isLeader ? 'leader-rank' : ''}">${index + 1}</div>
                                    <div class="winner-name">${winner.name}</div>
                                    <div class="winner-time">${winner.time}</div>
                                    ${isLeader ? '<div class="leader-badge">特别奖</div>' : ''}
                                </div>
                            `;
                        }).join('')}
                    </div>
                </body>
                </html>
            `);
            
            printWindow.document.close();
            printWindow.print();
        }

        // 加载示例参与者名单
        function loadExampleParticipants() {
            const exampleNames = '张小明、李华宇、王佳伟、赵俊杰、陈思远、杨光宇、刘天宇、黄佳乐、周星辰、吴子轩、郑宇航、钱文博、孙浩然、周雨泽、吴子豪、郑子涵、王梓晨、陈若曦、杨雨轩、黄文博、周梓轩、吴宇轩、郑浩然、陈思哲、杨明宇、黄梓晨、周文博、吴浩然、杨宇航、黄子涵、张宇航、李佳伟、王俊杰、赵文博、陈浩然、杨光宇、刘天宇、黄佳乐、周星辰、吴子轩、郑宇航、钱文博、孙浩然、周雨泽、吴子豪、郑子涵、王梓晨、陈若曦、杨雨轩';
            elements.participantsInput.value = exampleNames;
        }

        // 更新背景
        function updateBackground() {
            const body = document.body;
            
            // 移除所有背景相关的类和样式
            body.className = body.className.replace(/bg-gradient-to-br.*?from-primary\/10 to-secondary\/10/, '');
            body.style.backgroundImage = '';
            body.style.backgroundSize = '';
            body.style.backgroundPosition = '';
            body.style.backgroundRepeat = '';
            
            // 应用新背景
            if (data.settings.backgroundMode === 'solid') {
                // 纯色渐变背景
                body.className = body.className.replace(/bg-gradient-to-br.*?from-primary\/10 to-secondary\/10/, '') + ' bg-gradient-to-br';
                body.style.background = `linear-gradient(135deg, ${data.settings.backgroundColor}, ${data.settings.backgroundGradient})`;
            } else {
                // 图片背景
                body.style.backgroundImage = `url('${data.settings.backgroundImage}')`;
                body.style.backgroundSize = 'cover';
                body.style.backgroundPosition = 'center';
                body.style.backgroundRepeat = 'no-repeat';
            }
        }

        // 保存数据到本地存储
        function saveData() {
            localStorage.setItem('lotteryParticipants', JSON.stringify(data.participants));
            localStorage.setItem('lotteryLeaders', JSON.stringify(data.leaders));
            localStorage.setItem('lotteryWinners', JSON.stringify(data.winners));
            localStorage.setItem('lotterySettings', JSON.stringify(data.settings));
        }

        // 从本地存储加载数据
        function loadData() {
            // 加载参与者名单
            const savedParticipants = localStorage.getItem('lotteryParticipants');
            if (savedParticipants) {
                try {
                    data.participants = JSON.parse(savedParticipants);
                } catch (e) {
                    console.error('加载参与者名单失败:', e);
                }
            }
            
            // 加载领导名单
            const savedLeaders = localStorage.getItem('lotteryLeaders');
            if (savedLeaders) {
                try {
                    data.leaders = JSON.parse(savedLeaders);
                } catch (e) {
                    console.error('加载领导名单失败:', e);
                }
            }
            
            // 加载中奖记录
            const savedWinners = localStorage.getItem('lotteryWinners');
            if (savedWinners) {
                try {
                    data.winners = JSON.parse(savedWinners);
                } catch (e) {
                    console.error('加载中奖记录失败:', e);
                }
            }
            
            // 加载设置
            const savedSettings = localStorage.getItem('lotterySettings');
            if (savedSettings) {
                try {
                    const loadedSettings = JSON.parse(savedSettings);
                    // 合并设置,确保所有必要字段都存在
                    data.settings = {
                        ...data.settings,
                        ...loadedSettings,
                        // 确保backgroundImage字段存在
                        backgroundImage: loadedSettings.backgroundImage || 'https://picsum.photos/id/1067/1920/1080'
                    };
                } catch (e) {
                    console.error('加载设置失败:', e);
                }
            }
        }

        // 删除全部参与者
        function deleteAllParticipants() {
            if (confirm('确定要删除所有参与者名单吗?此操作不可恢复。')) {
                data.participants = [];
                updateParticipantsList();
                saveData();
            }
        }

        // 删除全部领导
        function deleteAllLeaders() {
            if (confirm('确定要删除所有领导名单吗?此操作不可恢复。')) {
                data.leaders = [];
                updateLeadersList();
                saveData();
            }
        }

        // 绑定事件监听器
        function bindEventListeners() {
            // 抽奖控制
            elements.startButton.addEventListener('click', startLottery);
            elements.stopButton.addEventListener('click', stopLottery);
            
            // 界面切换
            elements.viewWinnersButton.addEventListener('click', () => {
                elements.winnersScreen.classList.remove('hidden');
            });
            elements.backToMainButton.addEventListener('click', () => {
                elements.winnersScreen.classList.add('hidden');
            });
            
            elements.manageNamesButton.addEventListener('click', () => {
                elements.namesManagementScreen.classList.remove('hidden');
            });
            elements.backFromNamesButton.addEventListener('click', () => {
                elements.namesManagementScreen.classList.add('hidden');
            });
            
            // 名单管理
            elements.addParticipantsButton.addEventListener('click', addParticipants);
            elements.addLeadersButton.addEventListener('click', addLeaders);
            elements.clearParticipantsButton.addEventListener('click', () => {
                elements.participantsInput.value = '';
            });
            elements.clearLeadersButton.addEventListener('click', () => {
                elements.leadersInput.value = '';
            });
            elements.deleteAllParticipantsButton.addEventListener('click', deleteAllParticipants);
            elements.deleteAllLeadersButton.addEventListener('click', deleteAllLeaders);
            elements.loadExampleParticipantsButton.addEventListener('click', loadExampleParticipants);
            
            // 中奖名单操作
            elements.clearWinnersButton.addEventListener('click', clearWinners);
            elements.printWinnersButton.addEventListener('click', printWinners);
            
            // 设置操作
            elements.closeSettingsButton.addEventListener('click', () => {
                elements.settingsScreen.classList.add('hidden');
            });
            elements.saveSettingsButton.addEventListener('click', saveSettings);
            elements.resetSettingsButton.addEventListener('click', resetSettings);
            
            // 设置范围输入监听
            elements.winnersCount.addEventListener('input', (e) => {
                elements.winnersCountValue.textContent = e.target.value;
            });
            
            elements.lotterySpeed.addEventListener('input', (e) => {
                elements.lotterySpeedValue.textContent = e.target.value;
            });
            
            elements.fontSize.addEventListener('input', (e) => {
                elements.fontSizeValue.textContent = e.target.value;
                // 实时预览字体大小
                const fontSizeMultiplier = 0.5 + (parseInt(e.target.value) * 0.05);
                elements.lotteryName.style.fontSize = `clamp(${2 * fontSizeMultiplier}rem, ${8 * fontSizeMultiplier}vw, ${5 * fontSizeMultiplier}rem)`;
            });
            
            // 背景模式变更监听
            document.querySelectorAll('input[name="backgroundMode"]').forEach(radio => {
                radio.addEventListener('change', (e) => {
                    if (e.target.checked) {
                        if (e.target.value === 'solid') {
                            elements.backgroundColorContainer.classList.remove('hidden');
                            elements.backgroundImageContainer.classList.add('hidden');
                        } else {
                            elements.backgroundColorContainer.classList.add('hidden');
                            elements.backgroundImageContainer.classList.remove('hidden');
                        }
                    }
                });
            });
            
            // 右键菜单
            document.addEventListener('contextmenu', (e) => {
                e.preventDefault();
                elements.contextMenu.style.top = `${e.clientY}px`;
                elements.contextMenu.style.left = `${e.clientX}px`;
                elements.contextMenu.classList.remove('hidden');
            });
            
            document.addEventListener('click', () => {
                elements.contextMenu.classList.add('hidden');
            });
            
            document.querySelectorAll('.context-menu-item').forEach(item => {
                item.addEventListener('click', (e) => {
                    elements.contextMenu.classList.add('hidden');
                    const action = e.currentTarget.getAttribute('data-action');
                    
                    if (action === 'startLottery') startLottery();
                    else if (action === 'stopLottery') stopLottery();
                    else if (action === 'viewWinners') elements.winnersScreen.classList.remove('hidden');
                    else if (action === 'clearWinners') clearWinners();
                    else if (action === 'manageNames') elements.namesManagementScreen.classList.remove('hidden');
                    else if (action === 'settings') elements.settingsScreen.classList.remove('hidden');
                });
            });
            
            // 键盘快捷键
            document.addEventListener('keydown', (e) => {
                // F11 全屏
                if (e.key === 'F11') {
                    e.preventDefault();
                    if (!document.fullscreenElement) {
                        document.documentElement.requestFullscreen().catch(err => {
                            console.log(`全屏错误: ${err.message}`);
                        });
                    } else {
                        if (document.exitFullscreen) {
                            document.exitFullscreen();
                        }
                    }
                }
                
                // Enter 开始/停止抽奖
                if (e.key === 'Enter') {
                    e.preventDefault();
                    if (state.isDrawing) {
                        stopLottery();
                    } else {
                        startLottery();
                    }
                }
                
                // Backspace 返回主窗口
                if (e.key === 'Backspace') {
                    if (!elements.lotteryScreen.classList.contains('hidden')) {
                        resetLotteryDisplay();
                    } else if (!elements.winnersScreen.classList.contains('hidden')) {
                        elements.winnersScreen.classList.add('hidden');
                    } else if (!elements.namesManagementScreen.classList.contains('hidden')) {
                        elements.namesManagementScreen.classList.add('hidden');
                    } else if (!elements.settingsScreen.classList.contains('hidden')) {
                        elements.settingsScreen.classList.add('hidden');
                    }
                }
                
                // Alt+P 中奖名单播放
                if (e.altKey && e.key === 'p') {
                    e.preventDefault();
                    playWinners();
                }
                
                // Alt+/ 呼出设置界面
                if (e.altKey && e.key === '/') {
                    e.preventDefault();
                    elements.settingsScreen.classList.remove('hidden');
                }
                
                // 空格键 回放中奖结果
                if (e.key === ' ') {
                    e.preventDefault();
                    playWinners();
                }
            });
        }

        // 全局函数暴露
        window.removeParticipant = removeParticipant;
        window.removeLeader = removeLeader;
        window.startLottery = startLottery;
        window.stopLottery = stopLottery;
        window.playWinners = playWinners;

        // 初始化应用
        function init() {
            // 加载数据
            loadData();
            
            // 更新显示
            updateParticipantsList();
            updateLeadersList();
            updateWinnersList();
            updateSettingsDisplay();
            
            // 绑定事件监听器
            bindEventListeners();
        }

        // 启动应用
        document.addEventListener('DOMContentLoaded', init);
    </script>
</body>
</html>


智能抽奖系统使用说明

🎯 系统简介

本智能抽奖系统是一个功能齐全、界面美观的抽奖工具,支持多种抽奖模式和自定义设置,特别包含了隐藏的领导必中功能。系统采用现代UI设计,响应式布局,确保在各种屏幕尺寸下都能完美展示。

✨ 核心功能

1. 显示设置

  • 两种背景模式:支持纯色背景和壁纸背景,颜色和图片均可自定义
  • 窗口文字自定义:可自定义主标题和副标题
  • 字体大小调节:支持根据需要调整抽奖时显示的字体大小

2. 抽奖功能

  • 两种抽奖模式:单次循环抽奖和预设顺序抽奖
  • 中奖人数设置:可自定义每次抽奖的中奖人数
  • 抽奖速度调节:支持快慢速调节,适应不同场景需求
  • 音效系统:抽奖和中奖时播放不同音效,提升氛围
  • 视觉特效:包含烟花和彩纸特效,增强庆祝效果

3. 名单管理

  • 参与者管理:支持添加、修改、删除参与者名单
  • 领导名单设置:支持设置领导名单,可配置领导必中功能
  • 多种导入格式:支持顿号分隔或每行一个的名单导入格式
  • 数据持久化:所有名单和设置自动保存到本地存储

4. 中奖记录

  • 自动保存:每次抽奖结果自动保存
  • 记录查看:可查看所有中奖历史记录
  • 清空功能:支持清空所有中奖记录
  • 打印输出:支持将中奖名单打印出来

5. 隐藏功能

  • 领导必中名单:可设置领导必中功能,支持全部领导必中或随机部分领导必中
  • 隐蔽操作模式:通过快捷键隐藏呼出设置界面

6. 便捷操作

  • 右键菜单:右键点击界面可快速访问常用功能
  • 快捷键支持:丰富的快捷键操作,提升使用效率
  • 全屏显示:支持全屏模式,适合投影演示

⌨️ 快捷键列表

快捷键 功能描述
F11 全屏切换
Enter 开始/停止抽奖
空格键 当次中奖结果回放
Backspace 返回主窗口
Alt+P 中奖名单播放
Alt+/ 呼出设置界面

📁 名单导入格式

系统支持两种名单导入格式:

  1. 顿号分隔格式

    张三、李四、王五、赵六
  2. 每行一个格式

    张三
    李四
    王五
    赵六

🚀 使用步骤

  1. 准备名单:在名单管理中添加参与者和领导名单
  2. 系统设置:通过右键菜单或Alt+/快捷键进入设置界面,配置抽奖参数
  3. 开始抽奖:点击开始按钮或按Enter键开始抽奖
  4. 停止抽奖:点击停止按钮或按Enter键停止抽奖,显示中奖结果
  5. 查看记录:点击"中奖名单"按钮查看所有中奖记录

💡 使用提示

  • 每次正式抽奖前,建议先清空中奖名单,避免旧记录影响结果
  • 使用领导必中功能时,请先在名单管理中添加领导名单
  • 背景图片支持本地图片上传或网络图片URL
  • 所有设置和数据会自动保存,刷新页面不会丢失
  • 空格键可在中奖人数较多时自动翻页显示

🎨 界面预览

系统采用现代化UI设计,包含主抽奖界面、名单管理界面、中奖名单界面和设置界面,所有界面均支持响应式布局,适配各种屏幕尺寸。

🔧 技术说明

  • 基于HTML5、CSS3和JavaScript开发
  • 使用Tailwind CSS实现响应式布局和现代化UI
  • 使用Font Awesome提供图标支持
  • 通过localStorage实现本地数据持久化
  • 纯前端实现,无需后端服务器支持

📋 注意事项

  • 为获得最佳体验,请使用现代浏览器(Chrome、Firefox、Edge等)
  • 如需投影显示,建议使用全屏模式(F11)
  • 领导必中功能为隐藏功能,请合理使用
  • 本系统仅供内部活动使用,请勿用于商业用途

希望本智能抽奖系统能为您的活动增添乐趣!

智能抽奖系统.rar

12.36 KB, 下载次数: 607, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 22吾爱币 +22 热心值 +21 收起 理由
yoyo56183 + 1 + 1 很厉害了,代码写一下也需要好久时间了
xy2025 + 1 + 1 热心回复!
heihahouhei + 1 + 1 我很赞同!
Han1236 + 1 + 1 谢谢@Thanks!
爱免费吧 + 1 + 1 热心回复!
haoyuganjin + 1 + 1 我很赞同!建议增加指定中奖人的功能
娜美 + 1 隐藏功能,你是懂职场的
DaShiXiong33 + 1 谢谢@Thanks!
lovekezi + 1 鼓励转贴优秀软件安全工具和文档!
boybubble + 1 + 1 鼓励转贴优秀软件安全工具和文档!
wx9265661 + 1 + 1 我很赞同!
qizhewoniuqu + 1 我很赞同!
大鱼一条 + 1 + 1 谢谢@Thanks!
wuloveyou + 1 + 1 我很赞同!
hrh123 + 5 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
syljoy + 1 + 1 热心回复!
bolejiaodemao + 1 + 1 谢谢@Thanks!
zlufeng + 1 + 1 希望出2.0,可以直接导入图片,以图片的名字为名单,抽奖时图片快闪。
helh0275 + 1 + 1 谢谢@Thanks!
找我买滋补品 + 1 + 1 谢谢@Thanks!
wapj9527 + 1 + 1 谢谢@Thanks!
yanglinman + 1 谢谢@Thanks!

查看全部评分

本帖被以下淘专辑推荐:

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

 楼主| dongfang2025 发表于 2025-10-14 08:52
升级了!智能抽奖系统2.0版本
1、添加奖项设置功能;
2、更新抽奖模式:
  • 可以重复中奖模式:
适用于希望给获奖机会更公平分配的场景
同一人可以多次获奖,增加了获奖的随机性
  • 不可重复中奖模式:
适用于希望让更多不同的人获奖的场景
已中奖的人将被排除在后续抽奖外,确保奖品分配更均匀
3、其他功能改进。

1.png

智能抽奖系统2.0.rar

15.6 KB, 下载次数: 222, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 2吾爱币 +2 热心值 +2 收起 理由
qianyuqianyue + 1 + 1 我很赞同!
zhangxixi + 1 + 1 我很赞同!

查看全部评分

ffxlmiss 发表于 2025-10-14 16:14
非常实用,感谢。但是因为速度太慢了,10速也慢的出奇,我按照间隔时间进行了一点修改:      const baseSpeed = 200; // 基础速度(ms)
        const minSpeed = 10;   // 最小速度(ms)
        const intervalTime = Math.max(minSpeed, baseSpeed - (data.settings.lotterySpeed * 19)); 速度变的会很明显。另外我放了几个数字测试,预设方式设置不重复的仍然会重复,待会有空了修改下可以给老师上课点名用。
for1314ever 发表于 2025-10-12 14:08
zjtzjt 发表于 2025-10-12 14:15
抽奖决定晚上吃什么
abxcc 发表于 2025-10-12 14:38
蛮好,留着有可能春节能用到
moshi 发表于 2025-10-12 14:39
特别好的系统,支持
moshi 发表于 2025-10-12 14:40
可以可以,超级喜欢呀
kinalon 发表于 2025-10-12 14:47
感谢分享,保存
wincoy 发表于 2025-10-12 15:13
怪不得,都有黑幕的
AutumnBootLeaf 发表于 2025-10-12 15:17
“领导必中”功能绝对是亮点
semiuel 发表于 2025-10-12 15:31
zjtzjt 发表于 2025-10-12 14:15
抽奖决定晚上吃什么

把名单换成各种各样的菜名就可以抽奖决定吃什么了。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2025-11-10 02:27

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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