SpringBoot+MyBatis+Layui校医院门诊系统开发实战
简介:本系统基于SpringBoot、MyBatis与Layui构建,是一款面向校医院的门诊信息管理系统,旨在提升校园医疗服务的信息化水平。系统实现了门诊预约、就诊记录管理、药品库存管理、医生信息管理及用户权限控制等核心功能,采用模块化设计,具备良好的可维护性和扩展性。结合前后端技术优势,系统提供友好的用户界面和高效的数据处理能力,适用于医疗管理场景的数字化升级。 
1. SpringBoot框架搭建与配置
1.1 SpringBoot简介与核心功能
SpringBoot 是基于 Spring 框架的快速开发框架,旨在简化 Spring 应用的初始搭建和开发。它通过自动配置(Auto-Configuration)与起步依赖(Starter Dependencies)机制,大幅减少了传统 Spring 项目中繁杂的 XML 配置,提升了开发效率。
其核心功能包括:
- 内嵌 Tomcat、Jetty 等 Web 容器 ,无需部署 WAR 包即可运行 Web 应用。
- 自动配置机制 :根据类路径中的依赖自动配置 Bean,例如引入
spring-boot-starter-web会自动配置 MVC 环境。 - 健康检查与监控 :通过
spring-boot-starter-actuator提供系统健康、信息、指标等监控接口。 - 外部化配置 :支持
application.properties或application.yml文件进行配置管理,支持多环境配置(dev、test、prod)。
通过这些特性,SpringBoot 成为了构建微服务和企业级应用的首选框架。下一节将介绍如何搭建 SpringBoot 的开发环境并初始化项目。
2. MyBatis数据库持久化操作
MyBatis 是一个基于 Java 的持久层框架,以其灵活的 SQL 控制能力和简洁的配置方式,广泛应用于企业级开发中。本章将围绕 MyBatis 的核心原理、CRUD 操作实践以及数据库事务与性能优化三个方面,深入解析其在实际开发中的应用与调优策略。通过本章的学习,开发者将能够熟练掌握 MyBatis 的使用方式,并具备对数据库操作进行优化的能力。
2.1 MyBatis的基本原理与配置
MyBatis 通过将 SQL 语句与 Java 对象进行映射,实现对数据库的灵活操作。其核心机制包括:SQL 映射、结果集处理、动态 SQL 构建等。为了使 MyBatis 能够与数据库进行交互,必须进行相应的配置,包括数据源设置、连接池管理以及映射文件绑定等。
2.1.1 MyBatis框架的核心组成
MyBatis 框架由多个核心组件构成,主要包括以下几个部分:
| 组件名称 | 功能描述 |
|---|---|
SqlSessionFactory |
负责创建 SqlSession 实例,是 MyBatis 的核心工厂类 |
SqlSession |
提供数据库操作接口,如增删改查等 |
Mapper |
映射接口,用于绑定 SQL 语句与 Java 对象 |
Executor |
执行器,负责执行 SQL 语句并返回结果 |
TypeHandler |
类型处理器,用于 Java 类型与 JDBC 类型之间的转换 |
Cache |
缓存机制,提高数据库查询效率 |
这些组件构成了 MyBatis 的运行基础,其整体流程如下图所示:
graph TD
A[客户端调用Mapper接口] --> B(SqlSession调用Executor)
B --> C[Executor执行SQL]
C --> D[从数据库获取结果]
D --> E[TypeHandler转换数据类型]
E --> F[返回结果给客户端]
2.1.2 数据源配置与连接池管理
在 MyBatis 中,数据库连接的管理依赖于数据源配置和连接池技术。常见的连接池有 Druid、HikariCP、C3P0 等。以下是一个基于 HikariCP 的数据源配置示例:
<!-- mybatis-config.xml -->
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/hospital_db"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
</configuration>
代码逻辑分析:
<transactionManager>:配置事务管理器,此处使用 JDBC 事务。<dataSource>:配置数据源,type="POOLED"表示使用 MyBatis 内置的连接池。<property>:设置数据库驱动、URL、用户名和密码。<mappers>:指定映射文件的位置。
2.1.3 映射文件与接口绑定机制
MyBatis 通过 XML 映射文件或注解方式,将 SQL 语句与 Java 接口进行绑定。以下是基于 XML 的映射文件示例:
<!-- UserMapper.xml -->
<mapper namespace="com.example.mapper.UserMapper">
<select id="selectUserById" resultType="com.example.model.User">
SELECT * FROM users WHERE id = #{id}
</select>
</mapper>
对应的 Java 接口如下:
public interface UserMapper {
User selectUserById(int id);
}
逻辑说明:
namespace:指定接口的全限定类名,用于绑定接口与映射文件。id:方法名,与接口中的方法名保持一致。#{id}:表示方法参数,MyBatis 自动进行参数绑定。resultType:指定返回值类型,MyBatis 会自动将结果集映射为对应的 Java 对象。
2.2 数据库CRUD操作实践
CRUD(Create、Read、Update、Delete)是数据库操作中最基本的操作类型。MyBatis 提供了丰富的 SQL 构建方式,支持多种操作模式,包括 XML 配置、注解方式、动态 SQL 等。
2.2.1 增删改查操作的实现方式
以下是一个完整的 CRUD 示例:
<!-- UserMapper.xml -->
<mapper namespace="com.example.mapper.UserMapper">
<!-- 插入用户 -->
<insert id="insertUser">
INSERT INTO users (name, email, created_at)
VALUES (#{name}, #{email}, NOW())
</insert>
<!-- 查询用户 -->
<select id="selectUserById" resultType="com.example.model.User">
SELECT * FROM users WHERE id = #{id}
</select>
<!-- 更新用户 -->
<update id="updateUser">
UPDATE users
SET name = #{name}, email = #{email}
WHERE id = #{id}
</update>
<!-- 删除用户 -->
<delete id="deleteUserById">
DELETE FROM users WHERE id = #{id}
</delete>
</mapper>
逻辑分析:
<insert>:执行插入操作,#{}表示参数占位符。<select>:执行查询操作,resultType指定返回值类型。<update>:执行更新操作。<delete>:执行删除操作。
2.2.2 动态SQL语句构建技巧
MyBatis 支持动态 SQL,使得可以根据不同条件构建 SQL 语句。常用标签包括 <if> 、 <choose> 、 <when> 、 <set> 、 <foreach> 等。
以下是一个动态查询示例:
<select id="searchUsers" resultType="com.example.model.User">
SELECT * FROM users
<where>
<if test="name != null">
AND name LIKE CONCAT('%', #{name}, '%')
</if>
<if test="email != null">
AND email LIKE CONCAT('%', #{email}, '%')
</if>
</where>
</select>
参数说明:
<where>:自动处理AND或OR的前缀问题。<if>:根据条件判断是否拼接 SQL 子句。test:表达式用于判断是否执行该 SQL 片段。
2.2.3 多表关联查询与结果映射
在实际开发中,常常需要进行多表联合查询。MyBatis 提供了强大的结果映射能力,支持嵌套对象、集合等复杂数据结构。
以下是一个多表关联查询的示例:
<!-- UserMapper.xml -->
<resultMap id="userWithRoles" type="com.example.model.User">
<id property="id" column="id"/>
<result property="name" column="name"/>
<collection property="roles" ofType="com.example.model.Role">
<id property="roleId" column="role_id"/>
<result property="roleName" column="role_name"/>
</collection>
</resultMap>
<select id="getUserWithRoles" resultMap="userWithRoles">
SELECT u.id, u.name, r.id as role_id, r.name as role_name
FROM users u
LEFT JOIN user_roles ur ON u.id = ur.user_id
LEFT JOIN roles r ON ur.role_id = r.id
WHERE u.id = #{id}
</select>
逻辑分析:
<resultMap>:定义结果映射关系。<collection>:用于映射集合类型字段,如用户拥有的多个角色。<select>:执行多表联查,将结果自动映射到对象中。
2.3 数据库事务与性能优化
数据库事务的管理与性能优化是系统稳定性与高并发能力的关键。MyBatis 提供了完善的事务控制机制,并支持与 Spring 等框架集成,实现高级事务管理。
2.3.1 事务管理与回滚机制
MyBatis 通过 SqlSession 提供事务控制方法,包括 commit() 和 rollback() 。
以下是一个事务处理示例:
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper mapper = session.getMapper(UserMapper.class);
// 插入用户
mapper.insertUser(new User("张三", "zhangsan@example.com"));
// 更新用户
User user = mapper.selectUserById(1);
user.setEmail("newemail@example.com");
mapper.updateUser(user);
session.commit(); // 提交事务
} catch (Exception e) {
session.rollback(); // 回滚事务
e.printStackTrace();
} finally {
session.close();
}
逻辑说明:
openSession():开启一个新的会话。commit():提交事务,所有操作生效。rollback():回滚事务,所有操作撤销。- 适用于需要多个操作保持一致性的场景。
2.3.2 查询缓存机制与优化策略
MyBatis 提供了一级缓存和二级缓存两种机制,用于提高查询效率。
- 一级缓存 :默认开启,作用域为
SqlSession。 - 二级缓存 :作用域为
Mapper,需手动开启。
开启二级缓存的配置如下:
<!-- UserMapper.xml -->
<cache/>
同时,在 mybatis-config.xml 中开启全局缓存:
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
缓存生命周期:
- 一级缓存:每个
SqlSession独享。 - 二级缓存:跨
SqlSession共享,适用于读多写少的场景。
2.3.3 数据库连接池调优与监控
连接池的性能直接影响系统的并发能力。以 HikariCP 为例,常见的调优参数如下:
| 参数名 | 描述 | 建议值 |
|---|---|---|
maximumPoolSize |
最大连接数 | 根据数据库承受能力 |
minimumIdle |
最小空闲连接数 | 5-10 |
idleTimeout |
空闲连接超时时间 | 600000ms |
maxLifetime |
连接最大存活时间 | 1800000ms |
connectionTestQuery |
连接有效性检测 SQL 语句 | SELECT 1 |
监控建议:
- 使用 HikariCP 的
HikariPoolMXBean接口进行监控。 - 配合 Prometheus + Grafana 实现可视化监控。
- 日志记录连接池使用情况,定期分析瓶颈。
本章通过深入解析 MyBatis 的原理与配置方式、CRUD 操作实践以及事务与性能优化策略,为开发者构建了完整的数据库操作知识体系。下一章节将进入前端开发部分,围绕 Layui 框架展开讲解。
3. Layui前端UI界面开发
Layui 是一个经典的模块化前端 UI 框架,因其轻量、简洁、易用的特点,在前后端分离架构中被广泛应用于后台管理系统的前端界面开发。本章将深入探讨 Layui 框架在系统前端开发中的应用,涵盖页面结构设计、表单交互、数据绑定、分页组件使用以及用户体验优化等核心内容,旨在帮助开发者掌握使用 Layui 构建现代化 Web 界面的方法。
3.1 Layui框架概述与页面结构
3.1.1 Layui的特点与组件体系
Layui 采用模块化设计,支持按需加载,其组件体系丰富且风格统一,适用于快速构建企业级后台管理系统。其核心特点包括:
- 轻量级 :框架体积小,加载速度快;
- 响应式布局 :适配不同设备屏幕;
- 模块化设计 :每个功能组件可单独引入;
- 兼容性强 :兼容主流浏览器(包括 IE9+);
- 文档丰富 :提供详细的中文文档和示例。
Layui 常用模块包括:
| 模块名 | 功能描述 |
|---|---|
form |
表单组件与验证功能 |
table |
表格组件,支持分页与排序 |
layer |
弹窗组件,支持多种样式 |
laypage |
分页组件 |
upload |
文件上传组件 |
element |
基础元素与样式,如按钮、导航 |
3.1.2 页面布局与响应式设计
Layui 提供了灵活的布局系统,主要包括:
- 容器布局 :
layui-container用于创建居中容器; - 行与列布局 :使用
layui-row和layui-col-md*实现行列布局; - 响应式栅格系统 :通过
layui-col-xs*、layui-col-sm*、layui-col-md*、layui-col-lg*设置不同屏幕下的列宽。
以下是一个响应式布局的示例代码:
<div class="layui-container">
<div class="layui-row">
<div class="layui-col-md6 layui-col-xs12">
<div class="grid-content">左侧内容</div>
</div>
<div class="layui-col-md6 layui-col-xs12">
<div class="grid-content">右侧内容</div>
</div>
</div>
</div>
代码解析:
layui-container:定义一个居中容器,宽度自动适应;layui-row:表示一行;layui-col-md6:在中等屏幕上占6列(12列栅格系统);layui-col-xs12:在极小屏幕上占满整行。
响应式布局逻辑流程图:
graph TD
A[页面加载] --> B{屏幕宽度判断}
B -->|大于992px| C[使用md布局]
B -->|768px~992px| D[使用sm布局]
B -->|小于768px| E[使用xs布局]
3.2 表单组件与数据交互
3.2.1 表单元素的构建与校验
Layui 的 form 模块提供了丰富的表单控件和表单验证机制,支持常见的输入、选择、多选、开关等控件,并支持自定义校验规则。
示例代码:基本表单与校验
<form class="layui-form" action="">
<div class="layui-form-item">
<label class="layui-form-label">用户名</label>
<div class="layui-input-block">
<input type="text" name="username" required lay-verify="required" placeholder="请输入用户名" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">性别</label>
<div class="layui-input-block">
<input type="radio" name="sex" value="男" title="男">
<input type="radio" name="sex" value="女" title="女">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="formDemo">立即提交</button>
</div>
</div>
</form>
<script>
layui.use('form', function(){
var form = layui.form;
// 监听提交
form.on('submit(formDemo)', function(data){
console.log(data.field); // 获取表单字段
return false; // 阻止表单跳转
});
});
</script>
代码逻辑分析:
layui-form:表单容器类;lay-verify="required":设置字段为必填;form.on('submit'):监听表单提交事件,获取数据并处理;data.field:返回表单字段的键值对对象;return false:阻止表单默认提交行为,便于进行异步提交。
3.2.2 异步请求与数据绑定
结合 Layui 的 form 和 ajax ,可以实现表单的异步提交和动态数据绑定。
示例代码:异步提交表单
layui.use(['form', 'jquery'], function(){
var form = layui.form;
var $ = layui.jquery;
form.on('submit(formDemo)', function(data){
$.ajax({
url: '/api/submit',
type: 'POST',
data: data.field,
success: function(res) {
if (res.code === 0) {
layer.msg('提交成功');
} else {
layer.msg('提交失败');
}
}
});
return false;
});
});
参数说明:
url: 接口地址;type: 请求方式;data: 提交的数据;success: 成功回调函数;res.code: 假设接口返回的业务状态码,0 表示成功。
3.2.3 分页与表格组件应用
Layui 的 table 组件支持数据表格展示、分页、搜索、排序等功能,适用于数据管理类界面。
示例代码:基本表格与分页
<table id="demoTable" lay-filter="test"></table>
<script>
layui.use('table', function(){
var table = layui.table;
table.render({
elem: '#demoTable',
url: '/api/users',
page: true,
cols: [[
{field: 'id', title: 'ID'},
{field: 'username', title: '用户名'},
{field: 'sex', title: '性别'},
{field: 'age', title: '年龄'}
]]
});
});
</script>
代码解析:
elem: 表格容器;url: 数据接口地址;page: 是否启用分页;cols: 表头与字段映射;table.render: 初始化表格并绑定数据。
表格功能对比表:
| 功能 | 是否支持 | 说明 |
|---|---|---|
| 分页 | ✅ | 支持自定义分页大小 |
| 排序 | ✅ | 支持字段排序 |
| 筛选 | ✅ | 支持字段过滤 |
| 多选 | ✅ | 支持复选框 |
| 自定义模板 | ✅ | 支持字段自定义渲染 |
3.3 界面交互与用户体验优化
3.3.1 弹窗与提示信息的实现
Layui 的 layer 模块是其最强大的交互组件之一,支持多种弹窗类型,如提示框、确认框、加载框等。
示例代码:弹窗提示与确认
layui.use('layer', function(){
var layer = layui.layer;
layer.msg('这是一条提示信息');
layer.confirm('确定删除该记录?', {icon: 3, title: '提示'}, function(index){
// 执行删除操作
layer.close(index);
});
});
参数说明:
msg: 显示提示信息;confirm: 显示确认框;icon: 图标类型(3 表示问号图标);title: 弹窗标题;index: 当前弹窗索引,用于关闭。
3.3.2 文件上传与下载功能集成
Layui 提供了 upload 模块用于实现文件上传功能,支持单文件、多文件、拖拽上传等。
示例代码:文件上传功能
<button type="button" class="layui-btn" id="uploadBtn">上传文件</button>
<script>
layui.use('upload', function(){
var upload = layui.upload;
upload.render({
elem: '#uploadBtn',
url: '/api/upload',
done: function(res) {
console.log(res);
layer.msg('上传成功');
},
error: function() {
layer.msg('上传失败');
}
});
});
</script>
参数说明:
elem: 触发上传的元素;url: 上传接口地址;done: 上传成功回调;error: 上传失败回调。
3.3.3 主题定制与界面美化技巧
Layui 允许通过自定义 CSS 或使用其提供的主题工具进行界面风格定制。开发者可以通过修改变量、重写样式类、引入主题文件等方式实现个性化界面。
自定义 CSS 样式示例:
.layui-btn-primary {
background-color: #007BFF;
color: white;
}
美化建议:
- 统一颜色风格 :为按钮、表单、导航等组件设置统一色系;
- 图标字体替换 :使用 FontAwesome 等图标库替换默认图标;
- 响应式优化 :针对移动端优化布局与交互;
- 动画增强 :为弹窗、加载等交互添加过渡动画。
总结
Layui 作为一款轻量级、功能丰富的前端 UI 框架,其模块化设计和丰富的组件体系使其在企业级后台系统开发中表现出色。本章从页面布局、表单构建、数据交互、弹窗提示、文件上传到界面美化等多个维度,系统性地介绍了 Layui 的核心功能和使用技巧。通过掌握这些内容,开发者可以高效构建出结构清晰、交互流畅、体验良好的前端界面,为后续功能模块的实现打下坚实基础。
4. 门诊预约功能模块设计与实现
门诊预约系统是医院信息化管理中至关重要的一环,它不仅提升了患者的就医效率,也优化了医院的资源配置。本章将围绕门诊预约模块的业务逻辑分析、后端接口与数据库设计、前端页面实现与交互优化三个核心方面展开详细讲解,帮助读者构建一个完整、高效、可扩展的预约系统模块。
4.1 预约模块业务逻辑分析
门诊预约模块的核心在于合理安排患者的就诊时间与医生资源,避免冲突、提升用户体验。在开发之前,必须明确功能需求与用户流程,并建立有效的预约规则与冲突检测机制。
4.1.1 功能需求与用户流程梳理
门诊预约系统的主要功能包括:
- 用户注册与登录(非本章重点,但需考虑权限)
- 医生排班信息展示
- 指定日期与时间段的预约
- 预约记录查看与取消
- 预约状态反馈(如成功、失败、已取消)
用户流程图如下:
graph TD
A[用户登录] --> B[选择科室]
B --> C[选择医生]
C --> D[查看排班表]
D --> E[选择预约时间]
E --> F[提交预约请求]
F --> G{判断是否可预约}
G -->|是| H[生成预约记录]
G -->|否| I[提示预约失败]
H --> J[预约成功页面]
通过流程图可以清晰看出用户在使用预约系统时的关键操作路径。系统设计需围绕这一流程构建,确保用户体验流畅。
4.1.2 预约规则与冲突检测机制
预约规则包括:
- 时间限制 :每位患者每日最多可预约一次,预约时间需在医生排班范围内。
- 预约名额 :每个时间段有最大预约人数限制(如每30分钟最多5人)。
- 取消机制 :预约可取消,但需在预约时间前1小时。
冲突检测逻辑 :
- 时间冲突检测 :检查预约时间是否与已有预约冲突。
- 医生排班验证 :确认预约时间是否在医生排班时间范围内。
- 最大人数检测 :当前时间段是否已满员。
示例代码:预约冲突检测逻辑
public boolean checkAppointmentConflict(Integer doctorId, LocalDateTime appointmentTime) {
// 查询该医生在该时间段的预约记录
List<Appointment> existingAppointments = appointmentRepository
.findByDoctorIdAndAppointmentTime(doctorId, appointmentTime);
// 获取医生排班信息
Schedule schedule = scheduleRepository.findByDoctorIdAndDate(doctorId, appointmentTime.toLocalDate());
if (schedule == null) {
throw new RuntimeException("医生未排班");
}
// 检查是否超出最大预约人数
if (existingAppointments.size() >= schedule.getMaxAppointments()) {
return false;
}
return true;
}
代码逻辑分析:
- 第3行 :通过
appointmentRepository查询指定医生在指定时间的预约记录。 - 第6行 :获取医生的排班信息,判断是否排班。
- 第9-10行 :判断当前时间段的预约人数是否已满。
- 返回值 :若可预约返回
true,否则false。
该检测机制是预约系统中最核心的逻辑,必须在提交预约前调用,以确保系统稳定性与用户体验。
4.2 后端接口与数据库设计
门诊预约模块的后端设计主要包括接口规范的制定与数据模型的设计,这两者是实现功能的基础。
4.2.1 接口设计规范与RESTful风格
遵循 RESTful 设计原则,接口设计如下:
| 方法 | 接口路径 | 功能说明 |
|---|---|---|
| GET | /api/appointments |
获取所有预约记录 |
| GET | /api/appointments/{id} |
获取指定ID的预约记录 |
| POST | /api/appointments |
创建新的预约 |
| DELETE | /api/appointments/{id} |
删除指定ID的预约 |
| PUT | /api/appointments/{id} |
更新预约信息 |
示例接口定义:
@RestController
@RequestMapping("/api/appointments")
public class AppointmentController {
@Autowired
private AppointmentService appointmentService;
@GetMapping
public List<Appointment> getAllAppointments() {
return appointmentService.getAllAppointments();
}
@PostMapping
public ResponseEntity<Appointment> createAppointment(@RequestBody Appointment appointment) {
Appointment saved = appointmentService.saveAppointment(appointment);
return new ResponseEntity<>(saved, HttpStatus.CREATED);
}
@GetMapping("/{id}")
public ResponseEntity<Appointment> getAppointmentById(@PathVariable Long id) {
return appointmentService.getAppointmentById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
}
代码逻辑分析:
-
@RestController:表示该类处理 HTTP 请求并返回 JSON。 -
@RequestMapping:定义统一的接口路径前缀。 -
@GetMapping和@PostMapping:分别处理 GET 和 POST 请求。 -
@RequestBody:将请求体转换为 Java 对象。 -
@PathVariable:获取路径参数。
接口设计应保持简洁、统一、可扩展,方便前后端协作与后续维护。
4.2.2 预约数据模型与表结构定义
数据库表结构设计如下:
| 表名 | 字段 | 类型 | 说明 |
|---|---|---|---|
appointment |
id | BIGINT | 主键 |
| patient_id | BIGINT | 患者ID | |
| doctor_id | BIGINT | 医生ID | |
| appointment_time | DATETIME | 预约时间 | |
| status | VARCHAR(20) | 状态(预约中、已完成、已取消) | |
| created_at | DATETIME | 创建时间 |
MyBatis实体类定义:
public class Appointment {
private Long id;
private Long patientId;
private Long doctorId;
private LocalDateTime appointmentTime;
private String status;
private LocalDateTime createdAt;
// Getter and Setter
}
MyBatis映射文件示例:
<insert id="insertAppointment">
INSERT INTO appointment (patient_id, doctor_id, appointment_time, status, created_at)
VALUES (#{patientId}, #{doctorId}, #{appointmentTime}, #{status}, #{createdAt})
</insert>
<select id="selectByDoctorIdAndTime" resultType="Appointment">
SELECT * FROM appointment
WHERE doctor_id = #{doctorId}
AND appointment_time = #{appointmentTime}
</select>
参数说明:
#{patientId}:插入患者ID。#{doctorId}:插入医生ID。#{appointmentTime}:预约时间。#{status}:初始状态为“预约中”。#{createdAt}:记录创建时间。
该数据模型为门诊预约系统提供了结构化支持,便于后续的查询、统计和分析。
4.3 前端页面实现与交互优化
前端页面的设计不仅要美观,更要注重用户体验和交互逻辑。Layui 作为一款轻量级前端 UI 框架,在此模块中用于构建预约页面的核心交互组件。
4.3.1 预约页面的动态渲染
使用 Layui 构建预约页面,主要采用以下组件:
- layui.form :表单组件
- layui.table :表格组件
- layui.laydate :日期时间选择组件
HTML 结构示例:
<form class="layui-form" action="">
<div class="layui-form-item">
<label class="layui-form-label">选择医生</label>
<div class="layui-input-block">
<select name="doctor" lay-verify="required" id="doctorSelect">
<option value="">请选择医生</option>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">预约时间</label>
<div class="layui-input-block">
<input type="text" name="date" id="appointmentDate" class="layui-input" placeholder="请选择预约时间">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="submitAppointment">提交预约</button>
</div>
</div>
</form>
JavaScript 动态加载医生数据并初始化时间选择器:
layui.use(['form', 'laydate', 'jquery'], function() {
const form = layui.form;
const laydate = layui.laydate;
const $ = layui.jquery;
// 初始化时间选择器
laydate.render({
elem: '#appointmentDate',
type: 'datetime',
min: '2025-01-01 08:00:00',
max: '2025-12-31 18:00:00',
theme: '#393D49'
});
// 加载医生列表
$.get('/api/doctors', function(data) {
let options = '';
data.forEach(doctor => {
options += `<option value="${doctor.id}">${doctor.name}</option>`;
});
$('#doctorSelect').append(options);
form.render('select');
});
// 表单提交
form.on('submit(submitAppointment)', function(data) {
$.post('/api/appointments', data.field, function(res) {
layer.msg('预约成功');
});
return false;
});
});
代码逻辑说明:
- 第6-12行 :初始化日期选择器,设置最小最大时间范围。
- 第14-21行 :异步获取医生列表并填充到下拉框中。
- 第23-28行 :表单提交事件,将预约信息发送到后端。
该页面实现了医生选择、时间选择和预约提交的基本功能,具备良好的交互性。
4.3.2 时间选择与医生排班展示
在预约页面中,医生的排班信息需要与时间选择联动展示。例如,选择医生后,系统应动态加载其排班时间段,并在日历中高亮显示可预约时间。
实现思路:
- 用户选择医生后,发送请求获取该医生的排班信息。
- 根据排班信息,筛选出当前可预约的时间段。
- 在日历组件中高亮显示可预约时间。
Layui 日历组件集成示例:
laydate.render({
elem: '#appointmentDate',
type: 'datetime',
range: true,
theme: '#FF5722',
calendar: true,
mark: {
'2025-04-05': '休息',
'2025-04-10': '排班'
},
ready: function(date) {
// 获取医生排班数据
const doctorId = $('#doctorSelect').val();
$.get(`/api/schedules/${doctorId}`, function(schedules) {
// 根据排班数据设置可选时间
laydate.render({
elem: '#appointmentDate',
type: 'datetime',
min: schedules[0].startTime,
max: schedules[schedules.length - 1].endTime
});
});
}
});
参数说明:
mark:标记特殊日期,如休息日或排班日。ready:组件初始化后执行的回调函数,用于加载排班数据。
4.3.3 提交与状态反馈处理
预约提交后,系统需及时反馈预约状态,增强用户信任感。
Layui 层提示组件示例:
form.on('submit(submitAppointment)', function(data) {
$.ajax({
url: '/api/appointments',
method: 'POST',
data: JSON.stringify(data.field),
contentType: 'application/json',
success: function(res) {
layer.msg('预约成功', { icon: 1 });
},
error: function(xhr, status, error) {
layer.msg('预约失败,请重试', { icon: 2 });
}
});
return false;
});
参数说明:
success:预约成功时弹出提示框,显示成功图标。error:预约失败时提示错误信息,显示失败图标。
该反馈机制提升了用户的操作感知,增强了系统的可用性与友好性。
通过本章的详细讲解,我们完成了门诊预约功能模块的设计与实现,涵盖业务逻辑分析、后端接口与数据库设计、前端页面与交互优化等多个层面,构建了一个功能完整、逻辑清晰、交互友好的门诊预约系统模块。
5. 就诊记录管理模块设计与实现
就诊记录管理模块是医疗系统中不可或缺的重要功能模块,主要用于记录和管理患者的就诊历史信息,便于医生进行病史回溯、诊断分析以及后续治疗计划的制定。本章将围绕就诊记录模块的设计与实现展开深入探讨,内容涵盖功能需求分析、后端接口开发、数据模型定义、搜索筛选机制实现,以及前端页面的展示与交互优化。通过本章的学习,读者将掌握如何在SpringBoot与MyBatis框架下实现一个完整的就诊记录管理模块,并具备将其集成到实际医疗系统中的能力。
5.1 就诊记录模块功能分析
5.1.1 用户角色与权限划分
就诊记录模块涉及多个用户角色,主要包括医生、患者、管理员等。不同角色在系统中对就诊记录的访问和操作权限存在差异:
- 患者 :只能查看自己在该医院的就诊记录,不能修改或删除。
- 医生 :可以查看所负责患者的就诊记录,并进行记录的添加和更新操作。
- 管理员 :具备最高权限,可查看所有患者的就诊记录,进行数据维护和权限管理。
为实现权限控制,我们使用Spring Security进行角色认证与授权管理。例如,在接口层面通过 @PreAuthorize 注解限制访问权限:
@PreAuthorize("hasRole('DOCTOR') or hasRole('ADMIN')")
@GetMapping("/records/{patientId}")
public ResponseEntity<List<VisitRecord>> getVisitRecordsByPatientId(@PathVariable Long patientId) {
return ResponseEntity.ok(visitRecordService.findByPatientId(patientId));
}
代码逻辑分析 :
@PreAuthorize("hasRole('DOCTOR') or hasRole('ADMIN')"):表示只有角色为 DOCTOR 或 ADMIN 的用户才能访问该接口。@GetMapping("/records/{patientId}"):定义了一个GET请求的接口路径,用于根据患者ID获取就诊记录。ResponseEntity<List<VisitRecord>>:返回封装好的HTTP响应,包含就诊记录列表。
参数说明 :
@PathVariable Long patientId:从URL路径中提取patientId参数,用于查询指定患者的就诊记录。
5.1.2 记录内容与数据字段定义
就诊记录的核心数据字段包括以下内容:
| 字段名 | 类型 | 描述 |
|---|---|---|
| id | Long | 主键,唯一标识一条就诊记录 |
| patientId | Long | 关联患者ID |
| doctorId | Long | 接诊医生ID |
| visitDate | LocalDateTime | 就诊日期与时间 |
| chiefComplaint | String | 主诉 |
| diagnosis | String | 诊断结果 |
| treatmentPlan | String | 治疗方案 |
| remarks | String | 备注 |
| recordStatus | String | 记录状态(如“已保存”、“已归档”) |
在数据库中,我们使用MySQL进行数据存储,创建 visit_record 表如下:
CREATE TABLE visit_record (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
patient_id BIGINT NOT NULL,
doctor_id BIGINT NOT NULL,
visit_date DATETIME NOT NULL,
chief_complaint TEXT,
diagnosis TEXT,
treatment_plan TEXT,
remarks TEXT,
record_status VARCHAR(20) DEFAULT '已保存',
FOREIGN KEY (patient_id) REFERENCES patient(id),
FOREIGN KEY (doctor_id) REFERENCES doctor(id)
);
SQL逻辑分析 :
id:主键,自增字段,确保每条记录唯一。patient_id和doctor_id:分别关联患者和医生信息,外键约束确保数据完整性。visit_date:存储就诊时间,便于后续按时间排序与筛选。record_status:记录状态字段,支持数据归档和状态管理。
5.1.3 功能需求与用户流程梳理
就诊记录模块的主要功能需求如下:
- 记录创建 :医生在患者就诊后填写并保存记录。
- 记录查询 :支持按患者ID、医生ID、时间段等条件查询。
- 记录更新 :允许医生修改尚未归档的记录。
- 记录归档 :管理员可将记录标记为“已归档”,防止误修改。
- 权限控制 :确保不同角色只能访问其权限范围内的数据。
用户操作流程如下(使用Mermaid流程图展示):
graph TD
A[医生登录系统] --> B{权限验证}
B -- 通过 --> C[选择患者]
C --> D[填写就诊信息]
D --> E[提交保存记录]
E --> F{是否归档?}
F -- 是 --> G[记录状态更新为已归档]
F -- 否 --> H[等待后续修改]
A --> I[患者登录系统]
I --> J{权限验证}
J -- 通过 --> K[查看个人就诊记录]
流程图说明 :
- 图中展示了医生和患者两种角色在就诊记录模块中的主要操作流程。
- 医生在保存记录后,系统可判断是否需要归档;而患者只能查看自己的记录。
5.2 后端服务与接口开发
5.2.1 数据持久化与接口封装
我们使用MyBatis作为ORM框架,结合Spring Boot实现数据持久化操作。定义 VisitRecord 实体类如下:
@Entity
@Table(name = "visit_record")
public class VisitRecord {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long patientId;
private Long doctorId;
private LocalDateTime visitDate;
private String chiefComplaint;
private String diagnosis;
private String treatmentPlan;
private String remarks;
private String recordStatus;
// Getters and Setters
}
代码逻辑分析 :
@Entity:标识该类为JPA实体类,映射到数据库表。@Table(name = "visit_record"):指定实体类映射的数据库表名。@Id和@GeneratedValue:主键字段,使用自增策略。- 各字段对应数据库中的列,类型与长度需保持一致。
接下来,定义 VisitRecordRepository 接口:
public interface VisitRecordRepository extends JpaRepository<VisitRecord, Long> {
List<VisitRecord> findByPatientId(Long patientId);
List<VisitRecord> findByDoctorIdAndVisitDateBetween(Long doctorId, LocalDateTime start, LocalDateTime end);
}
接口说明 :
findByPatientId:根据患者ID查询就诊记录。findByDoctorIdAndVisitDateBetween:根据医生ID和时间段查询记录,用于统计和筛选。
5.2.2 搜索与筛选功能实现
为提升系统交互体验,我们实现了多条件搜索与筛选功能。后端接口如下:
@GetMapping("/search")
public ResponseEntity<List<VisitRecord>> searchVisitRecords(
@RequestParam(required = false) Long patientId,
@RequestParam(required = false) Long doctorId,
@RequestParam(required = false) LocalDateTime startDate,
@RequestParam(required = false) LocalDateTime endDate) {
List<VisitRecord> records = new ArrayList<>();
if (patientId != null) {
records = visitRecordRepository.findByPatientId(patientId);
} else if (doctorId != null && startDate != null && endDate != null) {
records = visitRecordRepository.findByDoctorIdAndVisitDateBetween(doctorId, startDate, endDate);
} else {
records = visitRecordRepository.findAll();
}
return ResponseEntity.ok(records);
}
代码逻辑分析 :
- 该接口支持按
patientId、doctorId+时间段等多种方式查询就诊记录。 - 若无参数,则返回所有记录。
- 使用
@RequestParam接收查询条件参数,灵活控制查询逻辑。
参数说明 :
patientId:可选参数,用于按患者ID过滤。doctorId、startDate、endDate:组合参数,用于按医生ID和时间段筛选记录。
5.3 前端页面与数据展示优化
5.3.1 表格数据展示与导出功能
前端使用Layui框架实现就诊记录的表格展示与导出功能。Layui表格组件支持分页、排序、导出等高级功能。HTML结构如下:
<table id="visitRecordTable" lay-filter="visitRecordTable"></table>
初始化表格脚本如下:
layui.use('table', function(){
var table = layui.table;
table.render({
elem: '#visitRecordTable',
url: '/api/visit/records',
page: true,
cols: [[
{field: 'id', title: '编号', width: 80},
{field: 'patientId', title: '患者ID', width: 100},
{field: 'doctorId', title: '医生ID', width: 100},
{field: 'visitDate', title: '就诊时间', width: 170},
{field: 'chiefComplaint', title: '主诉', width: 200},
{field: 'diagnosis', title: '诊断结果', width: 200},
{field: 'treatmentPlan', title: '治疗方案', width: 200},
{fixed: 'right', title: '操作', toolbar: '#tableBar'}
]]
});
});
代码逻辑分析 :
url: '/api/visit/records':设置表格数据源为后端接口。page: true:启用分页功能。cols:定义表格列字段及样式,支持固定列、宽度设置等。
导出功能实现如下:
$('#exportBtn').on('click', function() {
window.location.href = '/api/visit/export?token=' + layui.data('user').token;
});
逻辑说明 :
- 用户点击“导出”按钮后,跳转至导出接口,后端将数据以Excel格式返回。
5.3.2 条件过滤与分页交互优化
为了提升用户体验,我们实现了动态条件过滤与分页交互。前端通过表单提交条件,重新加载表格数据:
<form class="layui-form" id="searchForm">
<div class="layui-inline">
<label class="layui-form-label">患者ID</label>
<div class="layui-input-inline">
<input type="text" name="patientId" id="patientId" placeholder="请输入" class="layui-input">
</div>
</div>
<div class="layui-inline">
<button class="layui-btn" lay-submit lay-filter="formSearch">搜索</button>
</div>
</form>
JavaScript逻辑如下:
layui.use(['form', 'table'], function() {
var form = layui.form;
var table = layui.table;
form.on('submit(formSearch)', function(data) {
var field = data.field;
table.reload('visitRecordTable', {
where: field,
page: { curr: 1 }
});
return false;
});
});
逻辑说明 :
- 表单提交后,获取用户输入的过滤条件,调用
table.reload方法重新加载表格数据。 where: field:将表单数据作为查询条件传入后端接口。page: { curr: 1 }:重置分页为第一页,保证搜索结果从头开始。
通过以上章节的实现,我们构建了一个功能完善、交互友好的就诊记录管理模块。该模块不仅满足基本的业务需求,还通过权限控制、搜索筛选、导出等功能增强了系统的实用性与可扩展性,为后续医疗系统的整体开发奠定了坚实基础。
6. 药品库存管理系统开发
药品库存管理系统是医院信息系统(HIS)中不可或缺的重要模块,它直接关系到药品的流转效率、成本控制和患者用药安全。本章将围绕药品库存模块的业务流程展开分析,深入探讨药品数据模型的设计、库存变动接口的实现以及前端管理页面的构建。通过本章的学习,开发者将掌握药品库存系统的完整开发流程,并能够结合SpringBoot后端框架与Layui前端组件,实现一个具备药品信息管理、库存变动记录、库存预警和报表展示功能的完整系统。
6.1 药品库存模块业务分析
药品库存管理模块的核心在于实现药品信息的维护、库存的动态变化以及库存预警机制的建立。在医院环境中,药品的库存状态直接影响药品的供应能力,因此必须确保库存数据的准确性和实时性。
6.1.1 药品管理流程与库存变动规则
药品管理流程通常包括以下几个关键环节:
- 入库 :药品采购完成后,需要将药品信息录入系统,并增加库存数量。
- 出库 :药品用于患者治疗时,需从库存中扣除相应数量。
- 调拨 :不同科室或仓库之间的药品调拨操作。
- 报废 :过期或损坏药品的处理,需从库存中移除。
- 盘点 :定期进行库存盘点,确保账实一致。
库存变动的规则如下:
| 操作类型 | 库存变动方向 | 是否影响成本 | 是否记录日志 |
|---|---|---|---|
| 入库 | 增加 | 是 | 是 |
| 出库 | 减少 | 是 | 是 |
| 调拨 | 移动(一增一减) | 否 | 是 |
| 报废 | 减少 | 是 | 是 |
| 盘点 | 根据差异调整 | 是 | 是 |
⚠️ 注意:每种操作都应记录日志,以便于后续审计和追溯。
6.1.2 药品分类与库存预警机制
为了更好地管理药品,通常会对药品进行分类管理,如按用途分为“抗生素”、“解热镇痛药”、“心血管药”等类别。同时,系统应具备库存预警机制,当库存数量低于设定阈值时,系统自动发出预警提示。
库存预警机制的实现方式如下:
- 静态阈值预警 :为每类药品设置最低库存数量,当库存数量低于该值时触发预警。
- 动态阈值预警 :根据历史消耗量动态调整预警阈值,适用于需求波动较大的药品。
// 示例:库存预警判断逻辑
public boolean checkInventoryWarning(int currentStock, int minThreshold) {
return currentStock <= minThreshold;
}
代码逻辑分析:
currentStock表示当前库存数量。minThreshold表示最低库存阈值。- 如果当前库存小于等于阈值,返回
true,表示需要预警。
6.2 数据模型与接口实现
6.2.1 药品信息表结构设计
药品信息表是药品库存管理模块的核心数据结构,主要字段如下:
| 字段名 | 类型 | 描述 |
|---|---|---|
| id | BIGINT | 主键 |
| name | VARCHAR(100) | 药品名称 |
| category | VARCHAR(50) | 药品类别(如:抗生素) |
| unit | VARCHAR(20) | 单位(如:片、瓶) |
| stock | INT | 当前库存数量 |
| min_threshold | INT | 最低库存阈值 |
| price | DECIMAL | 单价 |
| created_at | DATETIME | 创建时间 |
| updated_at | DATETIME | 最后更新时间 |
CREATE TABLE drug_info (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
category VARCHAR(50),
unit VARCHAR(20),
stock INT DEFAULT 0,
min_threshold INT DEFAULT 10,
price DECIMAL(10,2),
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
SQL语句说明:
stock默认值为 0,表示初始无库存。min_threshold默认值为 10,当库存低于该值时触发预警。updated_at字段使用ON UPDATE CURRENT_TIMESTAMP自动更新时间。
6.2.2 库存变更接口与事务处理
库存变更操作涉及多个表的数据一致性问题,必须使用事务进行处理。例如,当药品出库时,需要同时更新药品库存表和出库记录表。
示例:药品出库接口实现(SpringBoot + MyBatis)
@Transactional
public boolean reduceStock(Long drugId, int quantity) {
// 1. 查询当前库存
DrugInfo drug = drugMapper.selectById(drugId);
if (drug == null || drug.getStock() < quantity) {
return false; // 库存不足或药品不存在
}
// 2. 更新库存
int newStock = drug.getStock() - quantity;
drugMapper.updateStock(drugId, newStock);
// 3. 记录出库日志
OutboundLog log = new OutboundLog();
log.setDrugId(drugId);
log.setQuantity(quantity);
log.setOperator("admin");
outboundLogMapper.insert(log);
return true;
}
代码逻辑分析:
- 使用
@Transactional注解确保事务一致性。 - 首先查询药品信息,判断库存是否足够。
- 然后更新库存数量。
- 最后记录出库日志,便于后续审计。
数据库事务处理流程图(Mermaid):
graph TD
A[开始事务] --> B[查询药品库存]
B --> C{库存是否足够?}
C -->|是| D[更新库存]
C -->|否| E[返回失败]
D --> F[插入出库日志]
F --> G[提交事务]
E --> H[回滚事务]
6.3 管理页面与功能集成
6.3.1 药品添加与编辑页面实现
药品信息的添加和编辑页面是药品管理模块的基础功能。使用Layui可以快速构建一个美观且功能齐全的页面。
示例:药品信息添加页面(Layui 表单)
<form class="layui-form" action="/drug/save" method="post">
<div class="layui-form-item">
<label class="layui-form-label">药品名称</label>
<div class="layui-input-block">
<input type="text" name="name" required lay-verify="required" placeholder="请输入药品名称" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">药品类别</label>
<div class="layui-input-block">
<input type="text" name="category" required lay-verify="required" placeholder="请输入药品类别" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">单位</label>
<div class="layui-input-block">
<input type="text" name="unit" required lay-verify="required" placeholder="请输入单位" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">库存数量</label>
<div class="layui-input-block">
<input type="number" name="stock" required lay-verify="required" placeholder="请输入库存数量" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">最低库存</label>
<div class="layui-input-block">
<input type="number" name="min_threshold" required lay-verify="required" placeholder="请输入最低库存" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">单价</label>
<div class="layui-input-block">
<input type="number" name="price" step="0.01" required lay-verify="required" placeholder="请输入单价" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="formDemo">提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
HTML代码说明:
- 使用了Layui的
layui-form类构建表单。 lay-verify="required"实现前端表单验证。- 提交按钮绑定
lay-submit触发提交逻辑。
页面效果(截图说明):
由于Markdown不支持图片插入,请在实际开发中将此页面嵌入至SpringBoot的Thymeleaf或Freemarker模板中,并通过浏览器访问测试。
6.3.2 库存报表与图表展示
库存报表功能可以帮助管理人员快速了解药品库存情况,Layui结合ECharts可以实现数据可视化。
示例:库存统计图表展示(ECharts + Layui)
<div id="main" style="width: 600px;height:400px;"></div>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.3.3/dist/echarts.min.js"></script>
<script>
var myChart = echarts.init(document.getElementById('main'));
$.get('/drug/report').done(function(data) {
myChart.setOption({
title: {
text: '药品库存统计'
},
tooltip: {},
xAxis: {
data: data.names
},
yAxis: {
type: 'value'
},
series: [{
name: '库存数量',
type: 'bar',
data: data.stocks
}]
});
});
</script>
代码逻辑分析:
- 使用
echarts.init初始化图表。 - 通过
$.get请求获取药品库存统计数据。 - 将药品名称作为X轴,库存数量作为Y轴绘制柱状图。
示例返回数据格式:
{
"names": ["阿莫西林", "头孢克肟", "布洛芬"],
"stocks": [120, 80, 150]
}
总结
第六章详细讲解了药品库存管理系统的设计与实现过程,包括业务流程分析、数据库结构设计、库存变动接口的事务处理以及前端管理页面的构建。通过SpringBoot与Layui的结合,开发者可以高效地完成一个功能完善、界面友好的药品库存管理系统。在后续章节中,我们将继续深入探讨其他核心模块的实现,帮助构建完整的医院信息系统。
7. 医生信息管理模块实现
医生信息管理是医院信息系统中的核心模块之一,负责医生的基础信息维护、排班安排以及门诊时间的管理。该模块不仅为预约系统提供基础数据支持,还为医院内部管理提供了结构化的医生资源信息。本章将从功能概述、数据模型与接口开发、前端页面实现三个方面,深入讲解医生信息管理模块的设计与实现。
7.1 医生信息管理功能概述
医生信息管理模块主要服务于医院管理人员,用于维护医生的基础资料、排班信息及门诊安排。该模块的稳定性和数据准确性直接影响到预约、挂号、就诊记录等多个业务流程。
7.1.1 医生角色与信息字段定义
医生信息主要包括以下几个维度:
| 字段名 | 数据类型 | 描述说明 |
|---|---|---|
| id | BIGINT | 主键,唯一标识医生 |
| name | VARCHAR(50) | 医生姓名 |
| gender | TINYINT | 性别(0-男,1-女) |
| department_id | BIGINT | 所属科室ID |
| title | VARCHAR(50) | 职称(如主治医师、副主任) |
| phone | VARCHAR(20) | 联系方式 |
| avatar | VARCHAR(255) | 头像URL |
| create_time | DATETIME | 创建时间 |
| update_time | DATETIME | 最后更新时间 |
此外,医生还可能涉及与科室、排班表、门诊时间等表的关联关系。
7.1.2 医生排班与门诊安排机制
医生排班信息通常包括:
- 排班日期(date)
- 上午/下午班(shift_type)
- 是否出诊(is_available)
- 门诊科室(clinic_department)
排班机制需要支持:
- 按周或按月批量设置排班
- 单日手动调整排班状态
- 排班与门诊预约系统联动,确保预约时排班信息实时有效
7.2 数据模型与接口开发
7.2.1 医生信息表结构与关联关系
医生信息管理模块涉及的主要数据表包括:
doctor_info:医生基本信息表doctor_schedule:医生排班表department:科室信息表
三者之间的关联关系如下(mermaid流程图):
erDiagram
doctor_info ||--o{ doctor_schedule : "1:N"
doctor_info ||--o{ department : "N:1"
doctor_info 表结构示例SQL如下:
CREATE TABLE `doctor_info` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
`gender` TINYINT NOT NULL DEFAULT '0',
`department_id` BIGINT NOT NULL,
`title` VARCHAR(50),
`phone` VARCHAR(20),
`avatar` VARCHAR(255),
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
7.2.2 接口设计与数据操作实现
采用RESTful风格设计接口,示例如下:
| 接口路径 | 请求方法 | 功能说明 |
|---|---|---|
| /api/doctor/list | GET | 获取医生列表 |
| /api/doctor/{id} | GET | 获取医生详情 |
| /api/doctor/create | POST | 新增医生信息 |
| /api/doctor/update/{id} | PUT | 更新医生信息 |
| /api/doctor/delete/{id} | DELETE | 删除医生信息 |
| /api/doctor/schedule/{id} | GET | 获取某医生的排班信息 |
后端采用SpringBoot + MyBatis实现医生信息查询接口示例:
@RestController
@RequestMapping("/api/doctor")
public class DoctorController {
@Autowired
private DoctorService doctorService;
@GetMapping("/{id}")
public ResponseEntity<DoctorVO> getDoctorById(@PathVariable Long id) {
DoctorVO doctor = doctorService.getDoctorById(id);
return ResponseEntity.ok(doctor);
}
@PostMapping("/create")
public ResponseEntity<String> createDoctor(@RequestBody DoctorDTO dto) {
doctorService.createDoctor(dto);
return ResponseEntity.status(HttpStatus.CREATED).body("医生创建成功");
}
}
其中, DoctorService 调用MyBatis Mapper执行数据库操作:
@Mapper
public interface DoctorMapper {
@Insert("INSERT INTO doctor_info(name, gender, department_id, title, phone, avatar) " +
"VALUES(#{name}, #{gender}, #{departmentId}, #{title}, #{phone}, #{avatar})")
@Options(useGeneratedKeys = true, keyProperty = "id")
void insert(DoctorDTO dto);
}
7.3 前端页面与信息维护功能
7.3.1 医生信息展示与编辑页面
在Layui框架中,使用 layui.table 组件展示医生信息列表,支持分页、搜索、字段排序等功能。
<table id="doctorTable" lay-filter="doctorTable"></table>
<script>
layui.use('table', function(){
var table = layui.table;
table.render({
elem: '#doctorTable',
url:'/api/doctor/list', // 数据接口
page: true, // 开启分页
cols: [[
{field:'id', title:'ID', sort: true},
{field:'name', title:'姓名'},
{field:'gender', title:'性别', templet: '#genderTpl'},
{field:'title', title:'职称'},
{field:'phone', title:'联系方式'},
{fixed: 'right', title:'操作', toolbar: '#barDemo'}
]]
});
});
</script>
<!-- 性别字段模板 -->
<script type="text/html" id="genderTpl">
{{# if(d.gender == 0){ }}
男
{{# } else { }}
女
{{# } }}
</script>
<!-- 操作栏模板 -->
<script type="text/html" id="barDemo">
<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
</script>
编辑页面使用Layui的 form 组件,结合 layer 弹窗实现:
layui.use(['layer', 'form'], function(){
var layer = layui.layer;
var form = layui.form;
// 编辑事件
table.on('tool(doctorTable)', function(obj){
var data = obj.data;
if(obj.event === 'edit'){
layer.open({
type: 2,
title: '编辑医生信息',
content: '/doctor/edit/' + data.id,
area: ['600px', '400px']
});
}
});
});
7.3.2 排班信息维护与时间管理
排班信息通常以日历形式展示,用户可通过点击日期设置医生是否出诊。使用Layui的 laydate 组件实现排班日期选择功能:
<input type="text" id="scheduleDate" placeholder="选择日期">
<script>
layui.use('laydate', function(){
var laydate = layui.laydate;
laydate.render({
elem: '#scheduleDate',
range: false,
theme: '#393D49',
format: 'yyyy-MM-dd',
calendar: true
});
});
</script>
排班信息保存接口示例:
function saveSchedule() {
let formData = {
doctorId: $('#doctorId').val(),
scheduleDate: $('#scheduleDate').val(),
shiftType: $('#shiftType').val(),
isAvailable: $('#isAvailable').is(':checked') ? 1 : 0
};
$.ajax({
url: '/api/doctor/schedule',
method: 'POST',
data: JSON.stringify(formData),
contentType: 'application/json',
success: function(res) {
alert('排班保存成功');
}
});
}
通过上述方式,医生信息管理模块实现了完整的数据展示、编辑、排班设置等功能,为后续的预约与门诊业务提供了坚实的数据支撑。
简介:本系统基于SpringBoot、MyBatis与Layui构建,是一款面向校医院的门诊信息管理系统,旨在提升校园医疗服务的信息化水平。系统实现了门诊预约、就诊记录管理、药品库存管理、医生信息管理及用户权限控制等核心功能,采用模块化设计,具备良好的可维护性和扩展性。结合前后端技术优势,系统提供友好的用户界面和高效的数据处理能力,适用于医疗管理场景的数字化升级。
更多推荐


所有评论(0)