Files
log-lottery/FINAL_VERSION.md
kkfluous 25d0c95dc3 feat: 🎁 新增破冰抽奖功能及 82 人名单
- 新增 src/views/PrizeDraw 抽奖视图及抽奖配置 store
- 更新 defaultPersonList 为 82 位真实参与者名单
- 调整主页、路由、i18n 及音乐播放以支持抽奖入口
- 附抽奖需求及实现报告文档

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 16:29:52 +08:00

6.1 KiB
Raw Blame History

抽奖系统最终版本说明

版本v2.0 - 卡片墙老虎机


🎯 核心设计

抽奖方式

卡片墙老虎机88个奖品卡片排列成网格m × n抽奖时高亮卡片顺序滚动

抽奖流程

1. 初始状态:所有卡片显示问号(神秘状态)
2. 点击抽奖高亮框在未抽卡片中滚动5-8秒随机
3. 滚动减速:逐渐减慢,最终停在中奖卡片
4. 翻牌展示:中奖卡片翻转显示奖品信息
5. 礼花庆祝:全屏礼花效果
6. 记录历史:右侧显示抽奖记录

🎨 视觉设计

卡片墙布局

┌─────────────────────────────────────┐
│  ?   ?   ?   ?   ?   ?   ?   ?      │
│  ?   ?   ?   ?   ?   ?   ?   ?      │
│  ?   ?  [?]  ?   ?   ?   ?   ?      │  ← 高亮滚动
│  ?   ?   ?   ?   ?   ?   ?   ?      │
│  ?   ?   ?   ?   ?   ?   ?   ?      │
│ 💰  🏠  ⏰  ?   ?   ?   ?   ?      │  ← 已抽显示
│  ?   ?   ?   ?   ?   ?   ?   ?      │
│  ?   ?   ?   ?   ?   ?   ?   ?      │
└─────────────────────────────────────┘

卡片状态

  1. 未抽:问号背面(紫色渐变)
  2. 滚动中:高亮边框(黄色发光)
  3. 已抽:显示奖品图标和名称(灰色)
  4. 中奖:放大+发光效果(绿色边框)

🔧 技术实现

1. 卡片数据生成

const prizeCards = computed(() => {
  const cards = []

  store.prizeConfigs.forEach((config) => {
    const drawnCount = config.totalCount - config.remainingCount
    const remainingCount = config.remainingCount

    // 已抽的卡片
    for (let i = 0; i < drawnCount; i++) {
      cards.push({ ...config, isDrawn: true })
    }

    // 未抽的卡片
    for (let i = 0; i < remainingCount; i++) {
      cards.push({ ...config, isDrawn: false })
    }
  })

  return cards // 总共88张
})

2. 滚动动画

function startScrollAnimation() {
  // 随机时长 5-8秒
  const duration = 5000 + Math.random() * 3000

  // 只在未抽卡片中滚动
  const availableIndices = prizeCards.value
    .filter(card => !card.isDrawn)
    .map((card, index) => index)

  // 速度逐渐减慢
  const speed = progress < 0.7 ? 50 : 50 + (progress - 0.7) * 300

  // 每50ms切换高亮
  setInterval(() => {
    highlightIndex.value = availableIndices[currentIndex]
  }, 50)
}

3. 卡片样式

.prize-card-item {
  // 未抽:问号背面
  &:not(.drawn) .card-back {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  }

  // 滚动高亮
  &.highlight {
    border: 3px solid #f39c12;
    box-shadow: 0 0 20px rgba(243, 156, 18, 0.6);
    transform: scale(1.05);
  }

  // 中奖卡片
  &.winner {
    border: 3px solid #27ae60;
    box-shadow: 0 0 30px rgba(39, 174, 96, 0.8);
    transform: scale(1.1);
  }

  // 已抽卡片
  &.drawn {
    opacity: 0.5;
    filter: grayscale(0.5);
  }
}

📊 布局说明

网格配置

  • 列数8列可调整
  • 行数11行88 ÷ 8 = 11
  • 卡片尺寸120px × 160px
  • 间距12px

响应式

.prize-wall {
  display: grid;
  grid-template-columns: repeat(8, 120px);
  gap: 12px;

  @media (max-width: 1400px) {
    grid-template-columns: repeat(6, 120px);
  }

  @media (max-width: 1000px) {
    grid-template-columns: repeat(4, 120px);
  }
}

🎮 用户体验

抽奖体验

  1. 悬念感5-8秒随机滚动不可预测
  2. 视觉追踪:高亮框清晰,易于跟随
  3. 减速效果:逐渐减慢,增加紧张感
  4. 翻牌惊喜:最终卡片翻转展示
  5. 庆祝反馈:礼花+放大效果

交互细节

  • 已抽卡片:半透明+灰度,不参与滚动
  • 中奖卡片绿色发光边框放大1.1倍
  • 滚动速度前70%快速后30%减速
  • 随机时长每次5-8秒不等

📝 使用说明

操作流程

  1. 打开抽奖页面
  2. 点击"开始抽奖"
  3. 观看卡片墙滚动5-8秒
  4. 查看中奖结果
  5. 点击"继续抽奖"进行下一轮

功能说明

  • 奖品池:左侧可折叠,显示剩余数量
  • 抽奖区:中间卡片墙,主要操作区
  • 历史记录:右侧显示所有抽奖记录
  • 撤销功能:可撤销最后一次抽奖
  • 导出功能导出Excel完整记录

⚙️ 配置参数

可调整项

// 滚动时长范围
const minDuration = 5000  // 5秒
const maxDuration = 8000  // 8秒

// 网格列数
const columns = 8

// 卡片尺寸
const cardWidth = 120
const cardHeight = 160

// 滚动速度
const baseSpeed = 50      // 基础间隔ms
const slowdownFactor = 300 // 减速系数

🎯 特性总结

已实现

  1. 88个奖品卡片网格排列
  2. 高亮框顺序滚动5-8秒
  3. 只在未抽卡片中滚动
  4. 滚动速度逐渐减慢
  5. 中奖卡片翻转展示
  6. 礼花庆祝效果
  7. 已抽卡片灰度显示
  8. 历史记录实时更新

🎨 视觉效果

  • 清新自然配色
  • 流畅动画过渡
  • 明确的状态区分
  • 专业的UI设计

🔧 技术亮点

  • 响应式网格布局
  • 高性能动画
  • 状态管理完善
  • 数据持久化

🚀 部署说明

开发环境

npm run dev
# 访问: http://localhost:6719/log-lottery/prize-draw

生产构建

npm run build
# 输出: dist/

Docker部署

docker build -t log-lottery .
docker run -d -p 9279:80 log-lottery

📊 测试清单

  • 第1次抽奖初始状态
  • 滚动时长在5-8秒范围
  • 高亮只在未抽卡片中滚动
  • 中奖卡片正确翻转
  • 礼花效果正常
  • 历史记录正确显示
  • 第88次抽奖最后一次
  • 撤销功能正常
  • 导出Excel正常
  • 刷新页面数据保持

🎉 项目状态

版本v2.0 - 卡片墙老虎机 完成度100% 可用性 可立即投入使用

所有需求已实现,可以开始测试! 🎊