基于Spring Boot的疫苗预约系统毕设实战指南!从需求到测试全流程详解✨
谁懂啊!去年做疫苗预约系统毕设时,光预约审核和疫苗库存的关联就卡了3天——一开始没处理"预约时间段冲突"逻辑,同一时间段允许多个用户预约,导师演示时直接发现了这个重大漏洞😫 经过反复修改优化,终于总结出了这套疫苗预约系统毕设实战经验,今天就把全流程细节分享给大家!
一、需求分析:抓住疫苗预约核心流程
刚开始我想做一个"万能医疗系统",包含了病历管理、药品库存、医生排班等模块,结果导师说"重点不突出,核心预约流程不清晰"。后来明白,疫苗预约系统要围绕预约-审核-接种这个核心流程展开。
1. 核心用户角色与功能
系统主要面向三类用户,功能定位要精准:
-
管理员端(系统管理核心):
- 医院信息管理:维护接种点信息、地址、联系方式
- 疫苗信息管理:录入疫苗详情、设置库存、上传疫苗图片
- 医生信息管理:分配医生账号、设置医生权限
- 公告信息管理:发布接种通知、政策公告
- 数据统计:预约数据统计、接种情况分析
-
医生端(业务处理核心):
- 预约审核:审核用户提交的预约申请
- 接种确认:标记已接种用户、更新接种状态
- 信息查询:查看疫苗库存、医院信息
-
用户端(服务使用核心):
- 疫苗查询:查看可用疫苗、接种点信息
- 预约接种:选择疫苗、时间、接种点进行预约
- 论坛交流:在疫苗论坛发帖交流
- 个人中心:查看预约记录、接种历史
2. 需求分析实战技巧
- 实地调研很重要:我去社区医院观察了真实的疫苗接种流程,发现他们最需要"时间段分流"功能,于是重点设计了预约时间段管理
- 绘制业务流程图:用DrawIO画出"用户预约→医生审核→接种完成"的完整流程,答辩时清晰展示业务逻辑
- 明确业务规则:如"同一用户同种疫苗不能重复预约""预约后24小时内可取消"等约束条件
3. 可行性分析要点
- 技术可行性:Spring Boot+MySQL技术成熟,学习资料丰富
- 经济可行性:全部使用开源工具,零开发成本
- 操作可行性:界面设计参考主流预约平台,用户上手快
二、技术选型:稳定可靠的技术栈
曾经尝试用微服务架构,结果服务网关配置卡了2天,最终选择单体架构,开发效率大大提升!
1. 技术栈选择理由
| 技术组件 | 选择理由 | 避坑提醒 |
|---|---|---|
| Spring Boot 2.7 | 配置简单,快速开发 | 不要用3.x,兼容性问题多 |
| MySQL 8.0 | 数据关系明确,适合预约系统 | 记得配置时区 |
| JSP + Bootstrap | 开发速度快,前后端不分离 | Bootstrap用3.x版本 |
| Tomcat 9 | 稳定可靠 | 不要用Tomcat 10 |
2. 开发环境搭建
# 创建Spring Boot项目
使用Spring Initializr
选择Web、MySQL、MyBatis依赖
# 数据库配置
spring.datasource.url=jdbc:mysql://localhost:3306/vaccine_db?useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
三、数据库设计:预约业务数据建模
最初设计时把用户预约信息和疫苗库存放在同一张表,导致数据更新冲突。重新设计后按业务模块分表,系统稳定性大幅提升。
1. 核心数据表设计
预约接种表(yuyuejiezong)
CREATE TABLE `yuyuejiezong` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`yonghu_id` int(11) DEFAULT NULL COMMENT '用户ID',
`yimiao_id` int(11) DEFAULT NULL COMMENT '疫苗ID',
`yuyuejiezong_time` date DEFAULT NULL COMMENT '预约日期',
`yuyue_time_slot` varchar(50) DEFAULT NULL COMMENT '预约时间段',
`yuyuejiezong_text` text COMMENT '预约备注',
`yuyuejiezong_yesno_types` int(11) DEFAULT '0' COMMENT '预约审核:0待审核/1通过/2拒绝',
`yuyuejiezong_yesno_text` text COMMENT '审核原因',
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `fk_yonghu` (`yonghu_id`),
KEY `fk_yimiao` (`yimiao_id`),
UNIQUE KEY `uk_time_slot` (`yuyuejiezong_time`, `yuyue_time_slot`, `yimiao_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='预约接种表';
疫苗信息表(yimiao)
CREATE TABLE `yimiao` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`yimiao_name` varchar(200) DEFAULT NULL COMMENT '疫苗标题',
`yimiao_types` int(11) DEFAULT NULL COMMENT '疫苗类型',
`yimiao_photo` varchar(200) DEFAULT NULL COMMENT '疫苗图片',
`yiyuan_id` int(11) DEFAULT NULL COMMENT '医院信息',
`yimiao_kucun` int(11) DEFAULT '0' COMMENT '疫苗库存',
`yimiao_clicknum` int(11) DEFAULT '0' COMMENT '点击次数',
`insert_time` date DEFAULT NULL COMMENT '发布日期',
`yimiao_content` text COMMENT '疫苗详情',
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='疫苗信息表';
2. 表关系设计要点
- 状态字段设计:预约状态(待审核/通过/拒绝)、疫苗状态(可用/缺货)
- 唯一约束:同一时间段同一疫苗不能重复预约
- 库存管理:预约成功时扣减疫苗库存
四、核心功能实现与代码详解
1. 预约接种模块(用户端核心功能)
Service层实现:
@Service
public class YuyuejiezongServiceImpl implements YuyuejiezongService {
@Autowired
private YuyuejiezongMapper yuyuejiezongMapper;
@Autowired
private YimiaoMapper yimiaoMapper;
@Override
@Transactional
public void addYuyue(YuyuejiezongEntity yuyue) {
// 1. 检查疫苗库存
YimiaoEntity yimiao = yimiaoMapper.selectById(yuyue.getYimiaoId());
if (yimiao.getYimiaoKucun() <= 0) {
throw new RuntimeException("该疫苗库存不足,无法预约");
}
// 2. 检查时间段是否冲突
Integer count = yuyuejiezongMapper.selectCount(
new EntityWrapper<YuyuejiezongEntity>()
.eq("yuyuejiezong_time", yuyue.getYuyuejiezongTime())
.eq("yuyue_time_slot", yuyue.getYuyueTimeSlot())
.eq("yimiao_id", yuyue.getYimiaoId())
.in("yuyuejiezong_yesno_types", Arrays.asList(0, 1)) // 待审核和已通过的预约
);
if (count > 0) {
throw new RuntimeException("该时间段已被预约,请选择其他时间");
}
// 3. 检查用户是否重复预约同种疫苗
Integer userCount = yuyuejiezongMapper.selectCount(
new EntityWrapper<YuyuejiezongEntity>()
.eq("yonghu_id", yuyue.getYonghuId())
.eq("yimiao_id", yuyue.getYimiaoId())
.in("yuyuejiezong_yesno_types", Arrays.asList(0, 1))
);
if (userCount > 0) {
throw new RuntimeException("您已预约过该疫苗,请勿重复预约");
}
// 4. 保存预约信息
yuyue.setYuyuejiezongYesnoTypes(0); // 待审核状态
yuyuejiezongMapper.insert(yuyue);
// 5. 扣减疫苗库存
yimiao.setYimiaoKucun(yimiao.getYimiaoKucun() - 1);
yimiaoMapper.updateById(yimiao);
}
}
Controller层:
@Controller
@RequestMapping("/user/yuyue")
public class UserYuyueController {
@Autowired
private YuyuejiezongService yuyuejiezongService;
@PostMapping("/add")
public String addYuyue(YuyuejiezongEntity yuyue, HttpServletRequest request) {
try {
// 设置当前登录用户
YonghuEntity user = (YonghuEntity) request.getSession().getAttribute("user");
yuyue.setYonghuId(user.getId());
yuyuejiezongService.addYuyue(yuyue);
request.setAttribute("msg", "预约成功,等待审核");
} catch (Exception e) {
request.setAttribute("msg", "预约失败:" + e.getMessage());
}
return "redirect:/user/yuyue/list";
}
}
2. 预约审核模块(医生端核心功能)
Service层实现:
@Service
public class YuyueShenheServiceImpl implements YuyueShenheService {
@Autowired
private YuyuejiezongMapper yuyuejiezongMapper;
@Autowired
private YimiaoMapper yimiaoMapper;
@Override
@Transactional
public void shenheYuyue(Integer yuyueId, Integer shenheStatus, String shenheReason) {
YuyuejiezongEntity yuyue = yuyuejiezongMapper.selectById(yuyueId);
if (yuyue == null) {
throw new RuntimeException("预约记录不存在");
}
// 更新审核状态
yuyue.setYuyuejiezongYesnoTypes(shenheStatus);
yuyue.setYuyuejiezongYesnoText(shenheReason);
yuyuejiezongMapper.updateById(yuyue);
// 如果审核拒绝,恢复疫苗库存
if (shenheStatus == 2) {
YimiaoEntity yimiao = yimiaoMapper.selectById(yuyue.getYimiaoId());
yimiao.setYimiaoKucun(yimiao.getYimiaoKucun() + 1);
yimiaoMapper.updateById(yimiao);
}
}
}
3. 疫苗信息管理模块(管理员端)
VUE前端组件(如果使用前后端分离):
<template>
<div class="yimiao-management">
<el-card header="疫苗信息管理">
<el-table :data="yimiaoList" v-loading="loading">
<el-table-column prop="yimiaoName" label="疫苗名称"></el-table-column>
<el-table-column prop="yimiaoTypes" label="疫苗类型">
<template slot-scope="scope">
{{ getYimiaoType(scope.row.yimiaoTypes) }}
</template>
</el-table-column>
<el-table-column prop="yimiaoKucun" label="库存">
<template slot-scope="scope">
<el-tag :type="scope.row.yimiaoKucun > 10 ? 'success' : 'danger'">
{{ scope.row.yimiaoKucun }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button @click="editYimiao(scope.row)" size="mini">编辑</el-button>
<el-button @click="updateKucun(scope.row)" type="primary" size="mini">
更新库存
</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
</div>
</template>
五、系统测试:确保预约流程可靠
曾经以为功能实现就完成了,结果测试时发现同一用户能重复预约,紧急加了防重复预约逻辑。
1. 功能测试用例
预约流程测试:
| 测试场景 | 操作步骤 | 预期结果 |
|---|---|---|
| 疫苗库存为0 | 用户预约库存为0的疫苗 | 提示"库存不足" |
| 时间段冲突 | 用户预约已被占用的时间段 | 提示"时间段冲突" |
| 重复预约 | 用户预约已预约过的疫苗 | 提示"请勿重复预约" |
| 正常预约 | 用户填写完整预约信息 | 提示"预约成功,等待审核" |
审核流程测试:
| 测试场景 | 操作步骤 | 预期结果 |
|---|---|---|
| 审核通过 | 医生审核通过预约 | 预约状态变为"通过" |
| 审核拒绝 | 医生拒绝预约并填写原因 | 预约状态变为"拒绝",库存恢复 |
2. 压力测试要点
- 并发预约测试:模拟多个用户同时预约同一时间段
- 数据完整性测试:预约与疫苗库存的数据一致性
- 边界情况测试:库存为0、时间段已满等特殊情况
六、部署与演示准备
1. 数据库初始化脚本
-- 插入测试数据
INSERT INTO `yimiao` VALUES
(1, '新冠疫苗第一针', 1, '/images/yimiao1.jpg', 1, 100, 0, '2024-01-01', '新冠疫苗详细说明...', NOW()),
(2, 'HPV疫苗', 2, '/images/yimiao2.jpg', 1, 50, 0, '2024-01-01', 'HPV疫苗详细说明...', NOW());
INSERT INTO `yiyuan` VALUES
(1, '北京市第一社区医院', 1, '/images/yiyuan1.jpg', '北京市海淀区xx路xx号', '社区医院详细介绍...', NOW());
2. 演示流程设计
按照真实预约流程演示:
- 用户注册登录→查看疫苗信息→选择时间段预约
- 医生登录→审核预约申请→通过或拒绝
- 管理员登录→管理疫苗库存→查看统计报表
3. 答辩重点准备
- 业务逻辑亮点:时间段冲突检测、库存自动扣减
- 技术实现亮点:Spring事务管理、数据一致性保障
- 系统特色:论坛交流功能、多角色协同
结语
基于Spring Boot的疫苗预约系统毕设成功的关键在于:抓住预约业务核心,处理好并发冲突,保证数据一致性。这套系统虽然业务逻辑相对复杂,但一旦掌握,无论是完成度还是技术含量都能得到导师认可。
记住:预约冲突处理、库存管理、多角色权限是三大得分点!需要完整源码、数据库脚本、部署文档的同学可以在评论区留言。
点赞收藏这篇指南,你的疫苗预约系统毕设一定能顺利通过! 💉✨