基于 Django 与 Vue 3 的智能实验室预约系统设计与实现
摘 要
随着高校实验室规模的不断扩大,传统的人工登记预约方式在时效性、透明度和资源利用率方面已难以满足实际需求。本文设计并实现了一套基于 B/S 架构的智能实验室预约系统,采用 Django + Django REST Framework 构建后端 API,Vue 3 + Element Plus 构建前端界面,MySQL 8.4(InnoDB)作为持久层,实现了学生在线预约、智能冲突检测、管理员审批、到场签到、占用热力图统计与站内通知的一体化管理。
系统在预约核心业务上给出了完整的工程化方案:以半开区间重叠模型判定时段冲突,在数据库事务内对实验室行加锁(select_for_update)串行化并发创建请求,从机制上杜绝了同一时段被重复预约的问题;预约单采用五状态机管理全生命周期;审批结果通过站内通知实时触达申请人。系统功能经 28 个接口级单元测试验证全部通过。
1 系统概述
1.1 课题背景
高校实验室是本科教学与科研活动的重要场所。在传统的管理模式下,实验室预约依赖人工登记或即时通讯工具报修式申请,存在以下问题:一是信息不透明,学生无法实时获知各实验室的空闲时段,经常出现"到楼才发现被占用"的情况;二是审批流程无序,申请与审批记录散落在聊天记录中,无法追溯;三是资源利用率失衡,热门时段扎堆、冷门时段空置,管理者缺乏量化的决策依据。
信息化预约系统将申请、审批、签到、统计全流程线上化,是解决上述问题的直接手段。
1.2 课题意义
本课题的意义体现在三个层面:
- 对学生:随时查看实验室列表与未来 7 天的占用热力图,错峰选择空闲时段,预约进度与审批结果实时可查;
- 对管理员:审批、实验室维护、数据统计集中在一个后台完成,审批结果一键通知申请人;
- 对毕业设计本身:预约冲突是典型的并发安全问题,本题覆盖了事务、行锁、区间重叠算法、状态机、JWT 认证等后端核心知识点,以及组件化、路由守卫、状态管理等前端工程实践,技术覆盖完整且难度适中。
1.3 主要内容
本文围绕系统的分析、设计与实现展开,共分六章:
- 第一章,绪论,介绍课题背景、意义与研究现状;
- 第二章,系统开发环境,介绍系统采用的关键技术;
- 第三章,需求分析,从可行性、功能需求、业务流程等方面分析系统;
- 第四章,系统概要设计,包括系统结构、功能结构与数据库设计;
- 第五章,系统详细设计与实现,按学生端与管理端分模块展示实现效果;
- 第六章,系统测试,给出测试环境、用例设计与测试结果分析。
1.4 研究现状
实验室、会议室、仪器等公共资源预约系统是管理信息系统的经典选题。现有开源方案多采用单体架构(如 JSP/PHP 全栈),功能集中在"增删改查 + 简单的时段查重",普遍缺少两个层面的设计:一是并发安全 ,高并发下"检测通过再写入"的两步操作存在竞态窗口,可能产生重复预约;二是数据驱动的引导,多数系统只记录预约结果,不向学生反馈"何时空闲"。本系统在这两点上做了针对性设计:以数据库行锁保证冲突检测与写入的原子性,以占用热力图引导学生错峰预约。
2 系统开发环境
2.1 总体技术栈
系统采用前后端分离架构:
| 层次 | 技术选型 | 说明 |
|---|---|---|
| 前端 | Vue 3 + Vite + Element Plus + Pinia + Vue Router + ECharts | 组件化 SPA,全部依赖 npm 本地打包,无 CDN 依赖 |
| 后端 | Django 6.1 + Django REST Framework + SimpleJWT | RESTful API,JWT 无状态认证 |
| 数据库 | MySQL 8.4(InnoDB,utf8mb4) | 事务与行锁支持完整,PyMySQL 驱动 |
| 联调 | Vite Dev Server 代理 /api → Django(8000) |
开发环境免跨域配置 |
2.2 Django REST Framework
Django 是 Python 生态主流的 Web 框架,其 ORM 层屏蔽了 SQL 细节,同时保留了对事务和锁的底层控制能力。Django REST Framework(DRF)在 Django 之上提供了序列化器(Serializer)、视图集(ViewSet)、权限类(Permission)三层抽象:序列化器负责模型实例与 JSON 的双向转换及入参校验;视图集将一组相关操作收敛为统一路由;权限类以声明式方式控制接口的访问级别。本系统所有接口均基于 DRF 构建。
2.3 Vue 3 与 Element Plus
Vue 3 的组合式 API(Composition API)配合 <script setup> 语法,使页面逻辑以函数为单位组织,比选项式 API 更适合中大型项目。Element Plus 提供表格、表单、标签页等成品组件,保证界面风格统一;ECharts 用于占用热力图渲染。前端状态管理采用 Pinia,仅登录态(token + 用户信息)进入全局 store,页面私有数据留在组件内,职责清晰。
2.4 JWT 认证机制
系统采用 SimpleJWT 实现基于 Token 的无状态认证:登录成功后服务端签发 access token(有效期 5 分钟)与 refresh token;前端将 token 存入 localStorage,axios 拦截器自动附加 Authorization: Bearer 头;后端权限类按"公开 → 登录可读 → 管理员可写 → 仅本人资源"四级控制访问。无状态认证使后端可以水平扩展,不依赖服务端会话存储。
2.5 MySQL 数据库
MySQL 的 InnoDB 存储引擎支持事务(ACID)与行级锁,这是本系统冲突检测正确性的基础。选择 utf8mb4 字符集以完整支持中文与表情符号。连接驱动使用纯 Python 实现的 PyMySQL,避免编译型 mysqlclient 在 Windows 环境下的安装成本。
3 需求分析
3.1 可行性分析
技术可行性:Django/DRF 与 Vue 3 均为成熟的主流框架,社区资料丰富;MySQL、JWT 技术栈稳定;开发机配置即可承载开发与演示运行。
经济可行性:系统全部基于开源软件构建,零授权成本;硬件仅需一台普通 PC 即可部署运行。
操作可行性:学生端操作路径为"登录 → 选实验室 → 选时段 → 填用途 → 提交",全程不超过五步;管理端为常规表格操作,无需培训即可上手。
3.2 功能需求
系统分学生端与管理端两个角色。
学生端功能:
- 注册(姓名 + 手机号,手机号即登录账号)、登录、忘记密码(凭手机号重置);
- 浏览实验室列表(名称、位置、容纳人数、设备、开放状态);
- 按日期与小时粒度选择时段提交预约申请;
- 查看我的预约列表,支持按状态筛选、取消预约(未过时)、到场签到;
- 查看未来 7/14 天各实验室 × 时段的占用热力图与错峰推荐;
- 接收审批结果站内通知。
管理端功能:
- 实验室信息管理(增删改查、维护/关闭状态切换);
- 预约审批(通过/驳回,驳回必填原因,驳回自动释放时段);
- 预约数据统计(总数、高峰/低谷时段、热力图);
- 仅限管理员访问,学生访问自动拦截。
3.3 业务流程
预约主流程为:学生提交预约 → 系统校验(时间合法性 + 冲突检测)→ 生成待审批单 → 管理员通过/驳回 → 申请人收到站内通知 → 已通过单在使用当日签到 → 时段结束后流转为已完成。任一环节取消或驳回均自动释放时段占用。
3.4 非功能需求
- 并发安全:同一实验室同一时段在任意并发压力下只允许一单成交;
- 数据隔离:学生只能读写本人预约单,越权访问返回 404(不暴露资源存在性);
- 性能:列表接口响应 < 300ms;热力图聚合在应用层完成,避免存储过程;
- 可维护:前后端分离、按业务域分模块(accounts / labs / bookings / notifications)。
4 系统概要设计
4.1 系统架构
系统采用典型的前后端分离三层架构:
浏览器(Vue 3 SPA)
│ HTTP / JSON,JWT 认证
▼
Django REST Framework(序列化 → 权限 → 视图 → ORM)
│ PyMySQL
▼
MySQL 8.4(InnoDB)
4.2 功能结构
系统功能结构如图 4-1 所示(学生端)与图 4-2 所示(管理端)。
图 4-1 学生端实验室列表界面

图 4-2 管理端实验室管理界面
4.3 数据库设计
系统核心业务表为四张:accounts_customuser(用户)、labs_lab(实验室)、bookings_booking(预约单)、notifications_notification(站内通知)。用户表扩展 Django 内置 AbstractUser,以 role 字段区分学生(0)与管理员(1),页面展示一律使用 real_name;预约单通过 user_id、lab_id 外键关联,并建立 lab_id + date + status 联合索引支撑冲突检测与热力图统计。预约单状态机为:待审批 0 → 已通过 1 / 已驳回 2;已通过可取消 → 已取消 3;时段结束自动流转 → 已完成 4。
详细的表结构、索引设计、冲突检测的半开区间模型与行锁机制,见 docs/数据库设计.md。
4.4 冲突检测设计(核心)
两区间 [s1,e1)、[s2,e2) 重叠的充要条件为 s1 < e2 AND e1 > s2。采用半开区间语义,使相邻时段(如 09:00-10:00 与 10:00-11:00)不冲突、可连约。为防止并发下"检测通过、写入时已被他人占用"的竞态,创建请求在事务内对实验室行加锁串行化:
python
with transaction.atomic():
lab = Lab.objects.select_for_update().get(pk=lab_id)
if Booking.objects.filter(lab=lab, date=date, status__in=(0, 1),
start_time__lt=end, end_time__gt=start).exists():
return 409 # 冲突,响应附带占用人与时段
第二个并发事务在锁释放后二次校验,必然读到第一个事务已提交的预约行,从而返回 409------行锁保证了"检测-写入"之间无插入窗口。
5 系统详细设计与实现
5.1 认证模块
系统登录页如图 5-1 所示。学生使用手机号 + 密码登录,管理员使用独立账号;登录成功后按角色跳转对应首页。注册仅需姓名、院系与手机号,系统自动生成内部账号,页面所有用户展示均使用姓名,接口不返回敏感字段。
图 5-1 系统登录界面
5.2 实验室浏览与预约模块(学生端)
学生登录后进入首页,可跳转实验室列表。实验室列表以卡片形式展示各实验室的位置、容纳人数与设备清单,并标注开放状态(图 5-2)。

图 5-2 实验室列表界面
点击"立即预约"进入时段选择页(图 5-3)。页面提供未来 7 天日期选择,开放 08:00-21:00 共 13 个小时粒度时段;已被占用或已过去的时段自动置灰,学生可多选连续空闲时段并填写用途提交。

图 5-3 预约时段选择界面
提交时服务端依次校验:日期范围(今天起 14 天内)、时段非过去、时长 ≥ 30 分钟、实验室开放状态、冲突检测。与已有"待审批/已通过"订单部分重叠时返回 409,前端弹出冲突详情面板。
5.3 我的预约与签到模块(学生端)
"我的预约"列表按状态分 tab 展示全部预约单(图 5-4),待审批与已通过且未过时的订单可取消;已通过订单在开始前 15 分钟至预约结束之间开放签到,防止代签与早签。

图 5-4 我的预约界面
5.4 占用热力图模块(双端共用)
热力图聚合未来 N 天各实验室 × 整点时段的占用率,以颜色深浅渲染矩阵(图 5-5),并给出高峰时段、低谷时段与空闲时段推荐,引导学生错峰预约;管理端复用同一组件进行全局观察。

图 5-5 学生端占用热力图界面
5.5 站内通知模块
审批通过或驳回时,系统自动向申请人写入站内通知(驳回含原因),学生端右上角铃铛显示未读角标,通知页支持单条已读与全部已读(图 5-6)。

图 5-6 站内通知界面
5.6 实验室管理模块(管理端)
管理员在后台维护实验室信息,包括名称、楼宇、房间号、容纳人数、设备清单与开放状态;维护中或关闭的实验室自动从学生端预约入口隐藏(图 5-7)。

图 5-7 实验室管理界面
5.7 预约审批模块(管理端)
审批列表按待审批/已通过/已驳回/全部分 tab 展示,每条申请含申请人(姓名)、实验室、日期时段与用途(图 5-8)。通过即时生效;驳回必填原因,驳回后时段自动释放并通知申请人。

图 5-8 预约审批界面
5.8 数据统计模块(管理端)
统计页提供活动预约总数、高峰时段、低谷时段、开放实验室数四个指标卡,以及占用热力图与错峰推荐(图 5-9),为实验室调度提供量化依据。

图 5-9 数据统计界面
6 系统测试
6.1 测试目的与方法
系统测试的目的是验证各功能模块的正确性、权限隔离的有效性与并发安全的可靠性。测试采用两种方法:
- 接口级单元测试 :使用 DRF 的 APITestCase 对后端 28 个场景做自动化断言,随
manage.py test一键执行; - 功能测试:按角色(学生/管理员)在浏览器中走查全部业务流程。
6.2 测试环境
| 项目 | 配置 |
|---|---|
| 操作系统 | Windows 11 |
| 后端 | Python 3.13 + Django 6.1 + DRF + PyMySQL |
| 数据库 | MySQL 8.4(InnoDB,utf8mb4) |
| 前端 | Node.js 22 + Vue 3 + Element Plus |
| 浏览器 | Chrome 最新版 |
6.3 核心测试用例
| 编号 | 测试场景 | 预期结果 | 实测 |
|---|---|---|---|
| T01 | 预约与已有单完全重叠 | 409 + 冲突详情 | 通过 |
| T02 | 预约跨边界部分重叠 | 409 | 通过 |
| T03 | 相邻时段预约(10:00 接 09:00-10:00) | 201 创建成功 | 通过 |
| T04 | 预约今天已过去的时段 | 400「该时段已过去」 | 通过 |
| T05 | 单次预约 20 分钟 | 400(不足 30 分钟) | 通过 |
| T06 | 预约维护中的实验室 | 400 | 通过 |
| T07 | 查看/取消他人预约单 | 404 | 通过 |
| T08 | 学生访问审批接口 | 403 | 通过 |
| T09 | 开始前 16 分钟签到 | 400(窗口未开) | 通过 |
| T10 | 开始前 14 分钟签到 | 200,记录签到时间 | 通过 |
| T11 | 重复签到 | 400 | 通过 |
| T12 | 审批驳回后同时段再约 | 201(时段已释放) | 通过 |
| T13 | 审批通过生成站内通知 | 通知落库、未读数 +1 | 通过 |
| T14 | 已过时段的已通过单查询 | 状态流转为「已完成」 | 通过 |
其中 T03 验证半开区间语义,T01/T02 验证重叠判定,T07/T08 验证权限隔离,T09-T11 验证签到窗口,T14 验证已完成状态的查询时流转。
6.4 并发安全验证
在 MySQL 8.4 下对冲突检测路径做并发验证:两个请求同时提交同一实验室相同时段的预约,行锁使二者串行执行,实测仅一单返回 201、另一单返回 409,无重复成交。这印证了 4.4 节的设计:应用层二次校验的正确性以数据库行锁为前提。
6.5 测试结果
后端 28 个接口级单元测试全部通过(manage.py test,测试库由框架自动创建与销毁);前端全部页面走查正常。系统满足设计目标。
结 论
本文完成了基于 Django + Vue 3 的智能实验室预约系统的全流程开发。系统在功能层面覆盖了"预约 → 审批 → 签到 → 统计 → 通知"完整业务闭环;在技术层面给出了两个超出常规 CRUD 选题的设计:一是以"半开区间模型 + 事务内行锁"解决预约冲突的并发安全问题,二是以"占用热力图 + 错峰推荐"将预约数据转化为对学生的引导信息。28 个单元测试与并发实测验证了设计的正确性。