1. 项目背景与核心需求
校园活动抽奖系统是学生组织、社团和学校管理部门经常需要的一个实用工具。传统的线下抽奖方式存在效率低、透明度不足、参与感弱等问题。基于微信小程序的解决方案能够完美解决这些痛点:
- 即时参与:学生通过微信扫码即可进入抽奖界面,无需下载额外APP
- 公平透明:抽奖算法和结果可实时展示,增强活动公信力
- 数据沉淀:所有参与记录和获奖情况自动留存,方便后续分析
- 成本低廉:相比定制开发APP,小程序方案开发维护成本更低
我去年为某高校迎新晚会开发的抽奖系统,上线当天就处理了超过2000次抽奖请求,峰值并发达到300+,验证了这种技术路线的可行性。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构设计
2.1 整体架构
系统采用前后端分离架构:
code复制微信小程序(前端)
↔ HTTPS →
Django REST Framework(后端API)
↔ ORM →
MySQL(数据存储)
2.2 技术选型考量
前端选择微信小程序的原因:
- 微信生态在校园渗透率接近100%
- 开发工具链成熟,文档丰富
- 无需考虑多端适配问题
- 发布审核流程比APP简单
后端选择Django的三大优势:
- ORM强大:简化数据库操作,快速实现CRUD
- Admin后台:内置管理界面,活动配置便捷
- 安全性高:自带CSRF防护、XSS防护等安全机制
提示:虽然Flask更轻量,但Django的全家桶特性更适合需要快速迭代的校园项目
3. 核心功能实现细节
3.1 抽奖算法实现
采用权重随机算法保证公平性:
python复制import random
def weighted_random_selection(participants):
total = sum(p['weight'] for p in participants)
rand = random.uniform(0, total)
upto = 0
for p in participants:
if upto + p['weight'] >= rand:
return p
upto += p['weight']
关键改进点:
- 增加去重机制,防止同一用户重复中奖
- 实现奖品池动态调整,确保奖品不会被超额抽取
- 添加黑名单功能,过滤不符合条件的用户
3.2 微信小程序端关键代码
用户授权登录:
javascript复制wx.login({
success: res => {
wx.request({
url: 'https://yourdomain.com/api/login',
data: { code: res.code },
success: loginRes => {
// 处理登录响应
}
})
}
})
抽奖按钮事件处理:
javascript复制handleLottery() {
if(this.data.hasParticipated) {
wx.showToast({ title: '已参与过抽奖' })
return
}
wx.request({
url: 'https://yourdomain.com/api/lottery',
method: 'POST',
data: { userId: this.data.userId },
success: res => {
// 处理抽奖结果
}
})
}
4. 数据库设计优化
4.1 核心表结构
活动表(activity):
sql复制CREATE TABLE `activity` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`start_time` datetime NOT NULL,
`end_time` datetime NOT NULL,
`status` tinyint(4) NOT NULL DEFAULT '0',
`rule_config` json DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
奖品表(prize):
sql复制CREATE TABLE `prize` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`activity_id` int(11) NOT NULL,
`name` varchar(50) NOT NULL,
`total` int(11) NOT NULL,
`remaining` int(11) NOT NULL,
`probability` decimal(5,4) NOT NULL,
PRIMARY KEY (`id`),
KEY `activity_id` (`activity_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
4.2 性能优化实践
- 读写分离:将抽奖记录写入单独的表,避免影响抽奖核心流程
- Redis缓存:热门活动的奖品信息缓存在Redis,减少数据库压力
- 索引优化:为常用查询字段添加复合索引,如
(activity_id, status)
5. 高并发处理方案
校园活动经常面临瞬时高并发的挑战,我们通过以下措施保证系统稳定:
5.1 限流策略
使用Django Ratelimit实现API限流:
python复制from django_ratelimit.decorators import ratelimit
@ratelimit(key='user', rate='5/s')
def lottery_api(request):
# 抽奖逻辑
5.2 异步任务处理
对于非核心流程采用Celery异步处理:
python复制@app.task
def send_win_notification(user_id, prize_id):
# 发送中奖通知
pass
# 视图函数中调用
send_win_notification.delay(user.id, prize.id)
5.3 数据库连接池
配置CONN_MAX_AGE避免频繁创建连接:
python复制DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'CONN_MAX_AGE': 60, # 1分钟连接池
# 其他配置...
}
}
6. 安全防护措施
6.1 防刷机制
- IP频率限制:同一IP每分钟最多5次请求
- 用户行为验证:关键操作需二次确认
- 签名验证:所有API请求必须携带有效签名
6.2 数据安全
- 敏感字段加密存储(如手机号)
- 日志脱敏处理
- 定期备份机制
7. 部署与监控
7.1 生产环境部署
推荐使用Docker Compose部署:
yaml复制version: '3'
services:
web:
build: .
command: gunicorn project.wsgi:application --bind 0.0.0.0:8000
ports:
- "8000:8000"
depends_on:
- redis
- db
redis:
image: redis:alpine
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: yourpassword
7.2 监控方案
- 日志收集:ELK栈集中管理日志
- 性能监控:Prometheus + Grafana监控系统指标
- 错误追踪:Sentry实时捕获异常
8. 项目扩展方向
基于现有系统可以进一步扩展:
- 数据分析看板:可视化抽奖参与情况
- 模板消息推送:活动提醒、中奖通知
- 多活动管理:支持同时进行多个抽奖活动
- 积分系统:参与活动获得积分,兑换奖品
我在实际部署中发现,加入实时弹幕功能能显著提升活动互动性。通过WebSocket实现获奖信息实时推送,现场气氛能提升30%以上。
