
本文参与 AtomGit 「0daymodel」首发模型体验活动聚焦 GLM-5 在前端开发中的实际赋能。相关链接GLM-5 在线体验项目源码AtomGit活动链接一、项目背景# 年会抽奖系统一个简单易用的年会抽奖网页应用支持1-10等奖的抽奖功能适合公司年会、团建活动等场景使用。## ✨ 功能特点- 支持1-10等奖共10个奖项等级- 真随机抽奖算法公平公正- 实时显示中奖名单和剩余人数- 支持导入自定义人员名单JSON格式- 支持导出抽奖结果- 精美的动画效果和渐变背景- 响应式设计支持各种屏幕尺寸- 单文件部署无需后端服务器## 奖项设置| 奖项 | 人数 ||------|------|| 一等奖 | 2人 || 二等奖 | 3人 || 三等奖 | 4人 || 四等奖 | 5人 || 五等奖 | 6人 || 六等奖 | 7人 || 七等奖 | 8人 || 八等奖 | 9人 || 九等奖 | 10人 || 十等奖 | 20人 |**总计74人**## 快速开始### 方法一直接使用1. 下载 lottery.html 文件2. 双击打开文件即可在浏览器中使用3. 系统默认包含100人的示例名单员工001-员工100### 方法二自定义人员名单1. 准备人员名单JSON文件参考下方格式2. 打开 lottery.html3. 点击导入人员名单按钮选择你的JSON文件4. 开始抽奖### 人员名单格式创建一个 participants.json 文件格式如下json[张三,李四,王五,赵六,...]**注意** 必须是JSON数组格式每个元素是一个字符串人员姓名。## 使用说明### 1. 选择奖项点击对应的奖项按钮如一等奖 (2人)按钮会高亮显示。### 2. 开始抽奖点击开始抽奖按钮屏幕上会快速滚动显示随机名字。### 3. 停止抽奖再次点击停止按钮系统会随机选出获奖者并显示在屏幕上。### 4. 查看结果所有中奖名单会实时显示在页面下方的中奖名单区域。### 5. 导出结果抽奖完成后点击导出结果按钮可以下载包含所有中奖信息的JSON文件。### 6. 重置抽奖如需重新开始点击重置抽奖按钮所有数据将被清空。## 操作流程导入人员名单可选↓选择奖项如一等奖↓点击开始抽奖↓点击停止确定获奖者↓继续抽取其他奖项↓导出结果可选## 使用技巧1. **建议抽奖顺序**从一等奖开始抽逐级往下营造悬念感2. **大屏幕展示**使用投影仪或大屏幕展示效果更佳3. **全屏模式**按 F11 进入全屏模式获得更好的视觉效果4. **音效配合**可以配合背景音乐使用增强现场气氛5. **备份结果**抽奖完成后及时导出结果避免误操作丢失数据## 技术栈- 纯HTML5 CSS3 JavaScript- 无任何第三方依赖- 无需Node.js或其他运行环境- 无需后端服务器## 文件说明.├── lottery.html # 抽奖系统主文件包含所有代码├── README.md # 说明文档└── participants.json # 人员名单示例可选二、AI 赋能向 GLM-5 提出需求我在AtomGit AI 平台向最新发布的GLM-5 模型提出具体开发需求帮我生成一个在年会上使用的抽奖页面包含完整代码分别抽取1-10等奖1等奖2人2等奖3人3等奖4人4等奖5人5等奖6人6等奖7人7等奖8人8等奖9人9等奖10人10等奖20人随机导入100人并包含几等奖提示以及中奖的人数同时生成对应的README让我可以直接发布github图GLM-5 在 AtomGit AI 平台给出的初始实现建议三、代码内容!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title年会抽奖系统/title style * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: Microsoft YaHei, Arial, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; display: flex; flex-direction: column; align-items: center; padding: 20px; color: #fff; } .container { max-width: 1200px; width: 100%; } h1 { text-align: center; font-size: 3em; margin: 30px 0; text-shadow: 2px 2px 4px rgba(0,0,0,0.3); animation: glow 2s ease-in-out infinite alternate; } keyframes glow { from { text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #e60073; } to { text-shadow: 0 0 20px #fff, 0 0 30px #ff4da6, 0 0 40px #ff4da6; } } .control-panel { background: rgba(255, 255, 255, 0.1); backdrop-filter: blur(10px); border-radius: 15px; padding: 30px; margin-bottom: 30px; box-shadow: 0 8px 32px rgba(0,0,0,0.1); } .prize-selector { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 20px; justify-content: center; } .prize-btn { padding: 12px 24px; font-size: 16px; border: none; border-radius: 8px; cursor: pointer; background: rgba(255, 255, 255, 0.2); color: #fff; transition: all 0.3s; font-weight: bold; } .prize-btn:hover { background: rgba(255, 255, 255, 0.3); transform: translateY(-2px); } .prize-btn.active { background: #ff4757; box-shadow: 0 4px 15px rgba(255, 71, 87, 0.4); } .prize-btn.completed { background: #2ed573; cursor: not-allowed; } .action-buttons { display: flex; gap: 15px; justify-content: center; margin-top: 20px; } .btn { padding: 15px 40px; font-size: 18px; border: none; border-radius: 10px; cursor: pointer; font-weight: bold; transition: all 0.3s; box-shadow: 0 4px 15px rgba(0,0,0,0.2); } .btn-start { background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); color: #fff; } .btn-start:hover { transform: scale(1.05); } .btn-start:disabled { background: #ccc; cursor: not-allowed; transform: none; } .btn-reset { background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); color: #fff; } .btn-export { background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%); color: #fff; } .display-area { background: rgba(255, 255, 255, 0.95); border-radius: 15px; padding: 40px; margin-bottom: 30px; min-height: 300px; display: flex; flex-direction: column; align-items: center; justify-content: center; box-shadow: 0 8px 32px rgba(0,0,0,0.1); } .current-prize { font-size: 2.5em; color: #ff4757; margin-bottom: 20px; font-weight: bold; } .rolling-names { font-size: 3em; color: #2f3542; font-weight: bold; min-height: 100px; display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 20px; } .winner-name { animation: bounce 0.5s; padding: 10px 20px; background: linear-gradient(135deg, #ffd89b 0%, #19547b 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } keyframes bounce { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-20px); } } .results-panel { background: rgba(255, 255, 255, 0.1); backdrop-filter: blur(10px); border-radius: 15px; padding: 30px; box-shadow: 0 8px 32px rgba(0,0,0,0.1); } .results-title { font-size: 2em; margin-bottom: 20px; text-align: center; } .prize-result { background: rgba(255, 255, 255, 0.1); border-radius: 10px; padding: 15px; margin-bottom: 15px; } .prize-result h3 { color: #ffd700; margin-bottom: 10px; font-size: 1.3em; } .prize-result .winners { display: flex; flex-wrap: wrap; gap: 10px; } .winner-tag { background: rgba(255, 255, 255, 0.2); padding: 8px 15px; border-radius: 20px; font-size: 0.9em; } .stats { text-align: center; margin-top: 20px; font-size: 1.1em; opacity: 0.9; } .file-upload { margin-bottom: 20px; text-align: center; } .file-upload input { display: none; } .file-upload label { padding: 10px 20px; background: rgba(255, 255, 255, 0.2); border-radius: 8px; cursor: pointer; display: inline-block; transition: all 0.3s; } .file-upload label:hover { background: rgba(255, 255, 255, 0.3); } /style /head body div classcontainer h1 年会抽奖系统 /h1 div classcontrol-panel div classfile-upload label forfileInput 导入人员名单JSON格式/label input typefile idfileInput accept.json span idfileStatus stylemargin-left: 15px;/span /div div classprize-selector idprizeSelector/div div classaction-buttons button classbtn btn-start idstartBtn onclickstartLottery()开始抽奖/button button classbtn btn-reset onclickresetLottery()重置抽奖/button button classbtn btn-export onclickexportResults()导出结果/button /div /div div classdisplay-area div classcurrent-prize idcurrentPrize请选择奖项/div div classrolling-names idrollingNames/div /div div classresults-panel h2 classresults-title 中奖名单 /h2 div idresultsContainer/div div classstats idstats/div /div /div script // 奖项配置 const prizeConfig [ { level: 1, name: 一等奖, count: 2, color: #ff4757 }, { level: 2, name: 二等奖, count: 3, color: #ff6348 }, { level: 3, name: 三等奖, count: 4, color: #ff7f50 }, { level: 4, name: 四等奖, count: 5, color: #ffa502 }, { level: 5, name: 五等奖, count: 6, color: #ffb142 }, { level: 6, name: 六等奖, count: 7, color: #ffd93d }, { level: 7, name: 七等奖, count: 8, color: #6bcf7f }, { level: 8, name: 八等奖, count: 9, color: #4bcffa }, { level: 9, name: 九等奖, count: 10, color: #5f27cd }, { level: 10, name: 十等奖, count: 20, color: #c44569 } ]; // 默认人员名单100人 let allParticipants []; for (let i 1; i 100; i) { allParticipants.push(员工${i.toString().padStart(3, 0)}); } let availableParticipants [...allParticipants]; let currentPrizeIndex null; let isRolling false; let rollingInterval null; let results {}; // 初始化 function init() { renderPrizeButtons(); updateResults(); updateStats(); } // 渲染奖项按钮 function renderPrizeButtons() { const container document.getElementById(prizeSelector); container.innerHTML ; prizeConfig.forEach((prize, index) { const btn document.createElement(button); btn.className prize-btn; btn.textContent ${prize.name} (${prize.count}人); btn.onclick () selectPrize(index); if (results[prize.level] results[prize.level].length prize.count) { btn.classList.add(completed); btn.disabled true; } container.appendChild(btn); }); } // 选择奖项 function selectPrize(index) { if (isRolling) return; currentPrizeIndex index; const prize prizeConfig[index]; // 更新按钮状态 document.querySelectorAll(.prize-btn).forEach((btn, i) { btn.classList.toggle(active, i index); }); document.getElementById(currentPrize).textContent ${prize.name} - 抽取 ${prize.count} 人; document.getElementById(rollingNames).textContent ; document.getElementById(startBtn).disabled false; } // 开始抽奖 function startLottery() { if (currentPrizeIndex null) { alert(请先选择奖项); return; } if (isRolling) { stopLottery(); return; } const prize prizeConfig[currentPrizeIndex]; if (availableParticipants.length prize.count) { alert(剩余人数不足); return; } isRolling true; document.getElementById(startBtn).textContent 停止; // 滚动显示随机名字 rollingInterval setInterval(() { const randomNames []; for (let i 0; i prize.count; i) { const randomIndex Math.floor(Math.random() * availableParticipants.length); randomNames.push(availableParticipants[randomIndex]); } document.getElementById(rollingNames).innerHTML randomNames.map(name span classwinner-name${name}/span).join(); }, 100); } // 停止抽奖 function stopLottery() { if (!isRolling) return; clearInterval(rollingInterval); isRolling false; document.getElementById(startBtn).textContent 开始抽奖; const prize prizeConfig[currentPrizeIndex]; const winners []; // 随机抽取获奖者 for (let i 0; i prize.count; i) { const randomIndex Math.floor(Math.random() * availableParticipants.length); winners.push(availableParticipants[randomIndex]); availableParticipants.splice(randomIndex, 1); } // 保存结果 results[prize.level] winners; // 显示获奖者 document.getElementById(rollingNames).innerHTML winners.map(name span classwinner-name${name}/span).join(); // 更新界面 renderPrizeButtons(); updateResults(); updateStats(); // 重置选择 setTimeout(() { currentPrizeIndex null; document.querySelectorAll(.prize-btn).forEach(btn { btn.classList.remove(active); }); document.getElementById(currentPrize).textContent 请选择下一个奖项; document.getElementById(startBtn).disabled true; }, 3000); } // 更新结果显示 function updateResults() { const container document.getElementById(resultsContainer); container.innerHTML ; prizeConfig.forEach(prize { if (results[prize.level] results[prize.level].length 0) { const div document.createElement(div); div.className prize-result; div.innerHTML h3${prize.name} (${results[prize.level].length}/${prize.count}人)/h3 div classwinners ${results[prize.level].map(name span classwinner-tag${name}/span ).join()} /div ; container.appendChild(div); } }); } // 更新统计信息 function updateStats() { const totalWinners Object.values(results).reduce((sum, arr) sum arr.length, 0); const totalPrizes prizeConfig.reduce((sum, prize) sum prize.count, 0); document.getElementById(stats).textContent 已抽取: ${totalWinners}/${totalPrizes} 人 | 剩余: ${availableParticipants.length} 人; } // 重置抽奖 function resetLottery() { if (!confirm(确定要重置所有抽奖结果吗)) return; availableParticipants [...allParticipants]; results {}; currentPrizeIndex null; isRolling false; if (rollingInterval) { clearInterval(rollingInterval); } document.getElementById(currentPrize).textContent 请选择奖项; document.getElementById(rollingNames).textContent ; document.getElementById(startBtn).textContent 开始抽奖; document.getElementById(startBtn).disabled true; renderPrizeButtons(); updateResults(); updateStats(); } // 导出结果 function exportResults() { const exportData { timestamp: new Date().toLocaleString(zh-CN), totalParticipants: allParticipants.length, results: {} }; prizeConfig.forEach(prize { if (results[prize.level]) { exportData.results[prize.name] results[prize.level]; } }); const dataStr JSON.stringify(exportData, null, 2); const blob new Blob([dataStr], { type: application/json }); const url URL.createObjectURL(blob); const a document.createElement(a); a.href url; a.download 抽奖结果_${new Date().getTime()}.json; a.click(); URL.revokeObjectURL(url); } // 文件上传 document.getElementById(fileInput).addEventListener(change, function(e) { const file e.target.files[0]; if (!file) return; const reader new FileReader(); reader.onload function(event) { try { const data JSON.parse(event.target.result); if (Array.isArray(data) data.length 0) { allParticipants data; availableParticipants [...allParticipants]; results {}; updateStats(); document.getElementById(fileStatus).textContent ✅ 已导入 ${allParticipants.length} 人; document.getElementById(fileStatus).style.color #2ed573; } else { throw new Error(格式错误); } } catch (error) { alert(文件格式错误请上传正确的JSON数组格式。); document.getElementById(fileStatus).textContent ❌ 导入失败; document.getElementById(fileStatus).style.color #ff4757; } }; reader.readAsText(file); }); // 页面加载时初始化 init(); /script /body /html四、项目开源源码地址https://atomgit.com/2302_77582029/test技术栈HTML5 CSS3 原生JavaScript (ES6)适用场景年会公司抽奖使用参与说明本文为 AtomGit「0daymodel」GLM-5 首发体验活动投稿。⭐ 如果这个项目对你有帮助欢迎给个Star 祝你的年会圆满成功