1. 项目概述:三端点名系统的全栈实现
这个项目源于高校教师的一个实际需求痛点:每次上课手动点名耗时费力,而现有教务系统又无法实现灵活的自定义统计。我决定用一套代码同时覆盖网页、小程序和APP三个终端,并通过爬虫技术自动同步教务数据,打造一个全自动化的智能点名系统。
选择uniapp作为核心框架,主要是看中其"一次开发,多端发布"的特性。配合Python爬虫从学校信息门户实时获取学生数据,整套系统从数据采集到终端展示形成了完整闭环。这种技术组合在考勤管理、活动签到等场景中具有很高的复用价值,特别适合需要跨平台部署的中小型应用。
2. 技术架构设计
2.1 跨端框架选型对比
在评估了Flutter、React Native和uniapp后,最终选择uniapp主要基于三点考量:
- 对微信小程序的原生支持更好(项目要求必须包含小程序端)
- Vue.js语法体系更符合团队现有技术栈
- 国内插件市场生态丰富(如uView UI组件库)
实际开发中,uniapp的跨端兼容性处理确实需要特别注意:
- 各平台CSS渲染差异(如flex布局在iOS下的表现)
- 原生API调用方式不同(如APP端的扫码功能)
- 页面生命周期管理的平台差异
2.2 数据流架构设计
系统采用分层架构设计:
code复制[信息门户爬虫] → [API服务器] ←→ [uniapp三端]
↳ [MySQL数据库]
爬虫模块使用Python的aiohttp实现异步采集,通过定时任务每天凌晨同步一次基础数据。考虑到学校服务器的压力,特别设置了:
- 请求间隔随机化(0.5-2秒)
- 工作时间段避开高峰(设定在凌晨1-3点执行)
- 遵守robots.txt协议(虽然学校没有设置)
重要提示:开发教育类爬虫务必注意流量控制,我曾在测试阶段因高频请求触发过学校防火墙,后来通过UserAgent轮换和代理IP池解决了这个问题。
3. 核心功能实现细节
3.1 uniapp多端适配方案
页面布局适配
使用uniapp的rpx单位配合flex布局,解决不同设备的显示适配问题。关键代码示例:
vue复制<template>
<view class="container">
<scroll-view :scroll-y="true" class="student-list">
<view v-for="(item,index) in studentData"
:key="index"
class="student-item">
<text>{{item.name}}</text>
<switch @change="handleCheckChange(index)"/>
</view>
</scroll-view>
</view>
</template>
<style>
.container {
display: flex;
flex-direction: column;
height: 100vh;
}
.student-list {
flex: 1;
}
.student-item {
display: flex;
justify-content: space-between;
padding: 20rpx 30rpx;
}
</style>
平台特性处理
通过条件编译处理多端差异:
javascript复制// #ifdef MP-WEIXIN
wx.requestSubscribeMessage() // 小程序订阅消息
// #endif
// #ifdef APP-PLUS
plus.runtime.getProperty() // APP版本检测
// #endif
3.2 爬虫模块关键技术
登录会话保持
学校信息门户采用JWT认证,爬虫需要模拟完整登录流程:
python复制async def login_portal(username, password):
async with aiohttp.ClientSession() as session:
# 获取登录页CSRF token
async with session.get(login_url) as resp:
text = await resp.text()
token = parse_csrf_token(text)
# 提交登录表单
form_data = {
'csrf_token': token,
'username': username,
'password': password
}
async with session.post(login_url, data=form_data) as resp:
if resp.status != 200:
raise Exception("Login failed")
# 保存cookies用于后续请求
cookies = session.cookie_jar.filter_cookies(login_url)
return cookies
数据解析优化
面对学校门户复杂的HTML结构,采用组合解析策略:
- 先用BeautifulSoup定位大致区域
- 对规整数据用正则提取
- 对嵌套结构用XPath精确定位
实测发现,这种组合方式比单一解析器效率提升40%以上。
4. 典型问题与解决方案
4.1 多端同步问题
初期遇到各终端状态不同步的情况,最终采用解决方案:
- 使用WebSocket保持实时连接
- 数据变更时通过uni.$emit全局事件通知
- 重要操作记录操作日志用于冲突检测
4.2 小程序审核问题
微信小程序审核时曾因"用户隐私政策"问题被拒,解决方法:
- 在manifest.json中补充隐私声明
- 首次启动时弹出授权弹窗
- 提供完整的隐私政策文档链接
4.3 性能优化实践
当班级人数超过100人时,列表渲染出现卡顿。通过以下优化显著提升性能:
- 虚拟列表技术(使用uni-list组件)
- 数据分页加载(上拉加载更多)
- 防抖处理搜索输入(300ms延迟)
5. 部署与运维方案
5.1 自动化构建流程
配置GitLab CI实现多端自动打包:
yaml复制stages:
- build
- deploy
build_app:
stage: build
script:
- npm install
- npm run build:app
- cd dist/build/app
- zip -r app.zip *
artifacts:
paths:
- dist/build/app/app.zip
build_mp:
stage: build
script:
- npm install
- npm run build:mp-weixin
artifacts:
paths:
- dist/build/mp-weixin
5.2 监控与告警
使用Prometheus+Grafana监控关键指标:
- 爬虫成功率(每天同步数据量)
- API响应时间(P99小于500ms)
- 并发用户数(高峰时段预警)
6. 扩展功能开发
6.1 智能识别增强
后期增加了以下创新功能:
- 蓝牙信标辅助定位(防代签)
- 人脸识别二次验证(可选功能)
- 异常签到行为分析(如频繁修改)
6.2 数据可视化
利用ECharts实现多维数据分析:
- 出勤率趋势图
- 缺勤原因词云
- 院系对比雷达图
这套系统经过一个学期的实际运行,平均节省教师点名时间85%,出勤数据准确率达到99.7%。最大的收获是:跨端开发一定要提前做好平台差异的测试方案,而爬虫开发必须把合规性和稳定性放在首位。
