1. 项目概述
这个基于ThinkPHP+Vue的学生在线投票系统是我去年为某高校学生会开发的一个实战项目。当时学生会需要一套能够支持多类型投票、实时统计结果的系统,同时要兼顾移动端和PC端的访问体验。经过技术选型对比,最终选择了ThinkPHP 6.0作为后端API服务,Vue 3作为前端框架的组合方案。
这套系统最核心的价值在于解决了传统纸质投票的三大痛点:一是统计效率低下,往往需要人工计票数小时;二是无法实现动态结果展示,参与者看不到实时投票进展;三是存在代投、重复投票等舞弊风险。我们的系统通过学号绑定、IP限制、验证码等多重验证机制,在提升投票效率的同时确保了公平性。
2. 技术架构设计
2.1 后端技术选型
选择ThinkPHP 6.0主要基于以下考量:
- 完善的ORM支持,能快速构建数据模型
- 内置的API开发模块简化了接口编写
- 中间件机制方便实现权限控制
- 社区活跃,遇到问题容易找到解决方案
数据库采用MySQL 8.0,主要表结构包括:
- 用户表(students):学号、姓名、院系等
- 投票表(votes):标题、描述、起止时间等
- 选项表(options):关联投票ID、选项内容等
- 记录表(records):关联用户和选项,记录投票时间
2.2 前端技术栈
Vue 3的组合式API让我们能够更灵活地组织代码。主要使用的技术包括:
- Vue Router管理前端路由
- Pinia作为状态管理工具
- Axios处理API请求
- ECharts实现数据可视化
- Vant UI提供移动端组件支持
特别值得一提的是使用了WebSocket实现实时投票数据推送。当有新的投票提交时,服务端会立即广播更新数据,所有在线用户都能看到实时变化的统计图表。
3. 核心功能实现
3.1 用户认证模块
采用JWT进行身份验证,关键实现步骤:
- 用户登录后生成包含学号的token
- 前端将token存储在localStorage
- 每次请求通过Authorization头传递
- 后端中间件校验token有效性
php复制// ThinkPHP中间件示例
public function handle($request, \Closure $next)
{
$token = $request->header('Authorization');
try {
$payload = Jwt::decode($token);
$request->studentId = $payload->student_id;
return $next($request);
} catch (\Exception $e) {
return json(['code' => 401, 'msg' => '无效token']);
}
}
3.2 投票业务流程
完整的投票流程包括:
- 管理员创建投票(设置标题、选项、时间等)
- 系统生成唯一投票链接
- 学生通过学号登录系统
- 选择选项提交投票
- 系统记录投票并更新统计
- 实时展示投票结果
为防止刷票,我们实现了以下限制:
- 每个学号只能投一次
- 同一IP每小时最多投5次
- 提交时需要验证码验证
- 投票时间外无法提交
3.3 实时数据展示
使用ECharts实现多种图表类型:
- 饼图显示各选项占比
- 柱状图对比不同选项得票
- 折线图展示投票趋势变化
WebSocket服务关键代码:
javascript复制// Vue组件中建立连接
const socket = new WebSocket('wss://yourdomain.com/vote-update');
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
this.chartOption.series[0].data = data;
this.chartInstance.setOption(this.chartOption);
};
4. 系统部署方案
4.1 服务器环境
- Nginx 1.18作为Web服务器
- PHP 8.0运行环境
- MySQL 8.0数据库
- Redis缓存投票计数
4.2 性能优化措施
- 使用Redis缓存热门投票数据
- 数据库查询添加适当索引
- 前端启用gzip压缩
- 静态资源使用CDN加速
- 开启OPcache提升PHP性能
5. 开发中的经验总结
5.1 踩过的坑
- Vue响应式数据更新不及时:使用nextTick确保DOM更新
- 高并发下的投票计数错误:采用Redis原子操作
- JWT令牌过期处理:实现自动刷新机制
- 移动端样式适配:使用vw/vh单位
5.2 值得推荐的实践
- 使用Swagger编写API文档
- 配置Git Hooks进行代码检查
- 采用Docker统一开发环境
- 实现自动化测试用例
- 使用Sentry监控系统错误
这个项目从技术选型到最终上线历时两个月,期间遇到了不少挑战,但也积累了很多全栈开发的经验。特别是WebSocket实时通信和防止刷票的多种机制,都是值得深入研究的课题。如果将来要扩展功能,我考虑加入投票评论、分享统计等功能模块。
