1. 项目背景与核心需求
儿童疫苗接种是每个家庭都必须面对的重要事项。传统的线下预约方式存在诸多痛点:家长需要专门请假带孩子去医院排队,接种点人流量难以均衡分配,接种记录查询不便,错过接种时间的情况时有发生。这些问题在二三线城市和乡镇地区尤为突出。
我们开发的这套系统正是为了解决这些实际问题:
- 家长可以随时随地通过微信小程序查看接种计划
- 在线选择合适的时间段预约,避免长时间排队
- 系统自动提醒接种时间,防止遗忘
- 电子化接种记录,方便随时查阅
- 接种点可以合理分配资源,减少人员聚集
提示:系统设计时要特别注意儿童接种的特殊性,比如不同年龄段有不同的疫苗组合,接种间隔有严格要求,这些都是业务逻辑中的核心难点。
2. 技术架构设计
2.1 整体架构
系统采用前后端分离的架构模式:
code复制微信小程序(前端) → 云服务器(后端) → 数据库
前端使用Uni-app框架开发,一次编写可发布到多个平台(微信小程序、H5、App等)。后端采用Python+Django REST framework构建API服务,数据库使用MySQL存储业务数据。
2.2 技术选型考量
选择Uni-app的主要原因:
- 跨平台特性显著降低开发成本
- 基于Vue.js的语法,学习曲线平缓
- 丰富的插件市场可以快速实现常见功能
- 良好的社区支持和文档资源
选择Python+Django的原因:
- Django的ORM大大简化数据库操作
- Django Admin可以快速搭建管理后台
- Python丰富的科学计算库便于处理接种时间计算等复杂逻辑
- REST framework提供完善的API开发支持
3. 核心功能实现
3.1 用户认证与权限管理
微信小程序使用微信官方登录API获取用户openid作为唯一标识。系统设计了三种角色:
- 家长用户:可以管理孩子信息、预约接种
- 接种点工作人员:可以管理接种点信息、处理预约
- 系统管理员:拥有最高权限
权限控制采用Django的权限系统,结合自定义的权限装饰器实现接口级别的访问控制。
python复制# 示例:权限装饰器
def vaccinator_required(view_func):
@wraps(view_func)
def _wrapped_view(request, *args, **kwargs):
if not request.user.is_authenticated:
return JsonResponse({'code': 401, 'msg': '请先登录'})
if not request.user.role == 'vaccinator':
return JsonResponse({'code': 403, 'msg': '无操作权限'})
return view_func(request, *args, **kwargs)
return _wrapped_view
3.2 接种计划计算引擎
这是系统的核心算法模块,根据儿童的出生日期、已接种记录,自动计算未来需要接种的疫苗及时间窗口。
实现要点:
- 建立疫苗知识库,包含每种疫苗的适用年龄、接种剂次、间隔要求等
- 设计递归算法处理多疫苗组合情况
- 考虑特殊情况的处理(如补种、延迟接种等)
python复制def calculate_schedule(birth_date, vaccination_records):
schedule = []
# 获取所有适龄疫苗
eligible_vaccines = get_eligible_vaccines(birth_date)
for vaccine in eligible_vaccines:
# 检查是否已接种
received_doses = [r for r in vaccination_records if r.vaccine_id == vaccine.id]
# 计算还需要接种的剂次
remaining_doses = vaccine.total_doses - len(received_doses)
if remaining_doses > 0:
# 计算下一剂的最佳接种时间
if received_doses:
last_dose_date = max([r.date for r in received_doses])
next_dose_date = last_dose_date + timedelta(days=vaccine.interval_days)
else:
next_dose_date = birth_date + timedelta(days=vaccine.first_dose_age_days)
schedule.append({
'vaccine': vaccine.name,
'dose_number': len(received_doses) + 1,
'recommended_date': next_dose_date,
'time_window': (next_dose_date - timedelta(days=7), next_dose_date + timedelta(days=14))
})
return schedule
3.3 预约排队算法
为避免某个时间段预约人数过多,系统实现了智能分配算法:
- 实时监控各接种点的预约量
- 根据历史数据预测各时段的人流量
- 对新预约请求进行动态调整,推荐最优时间段
- 支持预约改签和取消
4. 微信小程序前端实现
4.1 Uni-app开发要点
Uni-app开发微信小程序需要注意:
- 使用微信小程序原生组件时要注意平台差异
- 合理使用条件编译处理平台特有逻辑
- 注意小程序包大小限制,优化资源文件
- 处理好登录态维护和token刷新机制
4.2 主要页面实现
- 首页:显示近期需要接种的疫苗提醒
- 接种计划:展示完整的接种时间表
- 预约页面:选择接种点和时间段
- 接种记录:查看历史接种信息
- 个人中心:管理家庭成员信息
关键代码示例(Vue组件):
html复制<template>
<view class="container">
<uni-calendar
:selected="selectedDates"
@monthChange="handleMonthChange"
@dateClick="handleDateClick"
/>
<view class="time-slots">
<view
v-for="slot in availableSlots"
:key="slot.id"
class="slot"
:class="{ 'selected': slot.id === selectedSlot }"
@click="selectSlot(slot.id)"
>
{{ slot.time }} (剩余{{ slot.quota }}个名额)
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
selectedDates: [],
availableSlots: [],
selectedSlot: null
}
},
methods: {
async loadAvailableSlots(date) {
const res = await this.$http.get('/api/appointments/slots', {
params: { date, clinic_id: this.clinicId }
})
this.availableSlots = res.data
},
selectSlot(slotId) {
this.selectedSlot = slotId
}
}
}
</script>
5. 后端API设计与实现
5.1 RESTful API设计
系统主要API端点:
/api/auth/- 认证相关/api/children/- 儿童信息管理/api/vaccines/- 疫苗信息查询/api/schedule/- 接种计划/api/appointments/- 预约管理/api/clinics/- 接种点信息
5.2 关键API实现示例
预约创建API:
python复制class AppointmentViewSet(viewsets.ModelViewSet):
queryset = Appointment.objects.all()
serializer_class = AppointmentSerializer
permission_classes = [IsAuthenticated]
def create(self, request):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
# 检查时间是否可用
slot = serializer.validated_data['time_slot']
if not slot.is_available:
return Response({'detail': '该时间段已约满'}, status=400)
# 检查儿童年龄是否符合疫苗要求
child = serializer.validated_data['child']
vaccine = serializer.validated_data['vaccine']
if not vaccine.is_age_appropriate(child.age):
return Response({'detail': '该儿童不符合接种年龄要求'}, status=400)
# 创建预约
appointment = serializer.save(user=request.user)
# 发送微信通知
send_wechat_notification(
request.user.openid,
title='预约成功',
content=f'您已成功预约{vaccine.name}接种'
)
return Response(serializer.data, status=201)
5.3 性能优化措施
- 使用Django的
select_related和prefetch_related优化数据库查询 - 对接种计划计算等耗时操作添加缓存
- 使用Celery异步处理通知发送等非即时任务
- 数据库读写分离,查询使用从库
6. 部署与运维
6.1 服务器环境配置
推荐使用Nginx + Gunicorn部署Django应用:
bash复制# 安装依赖
pip install gunicorn
# 启动Gunicorn
gunicorn --workers 4 --bind unix:/tmp/gunicorn.sock project.wsgi:application
# Nginx配置示例
location / {
proxy_pass http://unix:/tmp/gunicorn.sock;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
6.2 微信小程序发布流程
- 开发环境使用测试AppID
- 配置合法域名(API服务器地址)
- 上传代码到微信开发者平台
- 提交审核
- 审核通过后发布
6.3 监控与日志
- 使用Sentry捕获异常
- 日志记录所有关键操作
- 监控API响应时间和错误率
- 定期备份数据库
7. 实际开发中的经验教训
-
微信登录会话管理:微信的session_key有时会失效,需要设计完善的token刷新机制。我们最终实现了双token方案(access_token + refresh_token)。
-
接种时间计算:初期没有考虑闰年和各月份天数差异,导致某些情况下的计算错误。修正后使用了Python的dateutil库处理日期计算。
-
高并发预约:在推广期间出现了短时间内大量用户预约的情况,导致系统响应变慢。通过引入Redis队列和限流机制解决了这个问题。
-
小程序性能:初期页面加载较慢,通过以下优化显著提升:
- 图片懒加载
- 接口数据分页
- 减少不必要的setData调用
- 使用小程序分包加载
-
数据一致性:预约和取消操作需要保证数据一致性,我们使用了数据库事务和乐观锁来处理并发修改。
这套系统上线后,接种点的排队时间平均减少了60%,家长满意度显著提升。通过技术手段解决社会痛点问题,是开发者最有成就感的时刻。
