摘要
本研究针对传统医疗预约与诊断流程中存在的效率低下、信息不透明、患者等待时间长等问题,设计并实现了一个基于 SpringBoot+JSP 的医疗预约与诊断系统。系统采用 B/S 架构,整合了用户管理、科室管理、医生排班、预约挂号、在线问诊、检查检验、诊断治疗等功能模块,实现了医疗服务的全流程数字化管理。系统前端使用 JSP+Bootstrap 构建界面,后端采用 SpringBoot 框架提供 RESTful API 服务,数据库使用 MySQL 存储业务数据。通过实际应用验证,系统具有良好的稳定性、可扩展性和用户体验,能够有效提高医院的管理效率和服务质量,改善患者的就医体验。
1. 引言
1.1 研究背景与意义
随着信息技术的快速发展和互联网的普及,数字化医疗已成为医疗行业发展的必然趋势。传统的医疗预约与诊断流程主要依赖人工操作,存在效率低下、信息不透明、患者等待时间长等问题,难以满足现代医疗服务的需求。
互联网医疗预约与诊断系统的出现,为解决上述问题提供了有效的途径。通过建立数字化医疗平台,患者可以在线预约挂号、查询医生信息、查看检查报告、进行在线问诊等,大大提高了就医效率,减少了等待时间。同时,医院也可以通过系统实现对医疗资源的合理配置和管理,提高医疗服务质量和管理水平。
本研究旨在设计并实现一个基于 SpringBoot+JSP 的医疗预约与诊断系统,通过整合医疗服务的各个环节,实现医疗预约与诊断的全流程数字化管理。系统将为患者提供便捷的就医服务渠道,为医院提供高效的管理工具,具有重要的现实意义。
1.2 国内外研究现状
国外在医疗信息化领域起步较早,已经形成了较为成熟的医疗信息系统和服务模式。例如,美国的 Epic、Cerner,欧洲的 iSoft 等公司开发的医疗信息系统,功能完善、操作简便,在国际市场上占据了较大份额。这些系统采用了先进的信息技术,如云计算、大数据分析、人工智能等,提高了医疗服务的效率和质量。
国内医疗信息化建设近年来也取得了显著进展。国家出台了一系列政策支持医疗信息化发展,推动了医院信息系统的普及和应用。国内一些软件企业开发了针对医院的管理系统,如东华软件、卫宁健康、万达信息等公司的产品,在国内市场上得到了广泛应用。
目前,国内外医疗预约与诊断系统仍存在一些问题,如系统功能不够完善、数据共享困难、用户体验不佳等。此外,随着移动互联网和智能终端的普及,用户对医疗服务的便捷性和个性化提出了更高的要求,需要进一步加强技术创新和服务创新。
1.3 研究内容与方法
本研究的主要内容包括:
系统需求分析:通过问卷调查、访谈等方式,了解患者、医生、医院管理人员的需求,明确系统的功能和性能要求。
系统设计:包括系统架构设计、数据库设计、功能模块设计等,确定系统的技术选型和实现方案。
系统实现:基于 SpringBoot+JSP 技术栈实现系统的各个功能模块,包括用户认证、科室管理、医生排班、预约挂号、在线问诊、检查检验、诊断治疗等。
系统测试:对系统进行功能测试、性能测试、安全测试等,确保系统的稳定性和可靠性。
系统部署与应用:将系统部署到生产环境中,进行实际应用验证,评估系统的使用效果和用户满意度。
本研究采用的研究方法包括:
文献研究法:查阅国内外相关文献,了解医疗预约与诊断系统的研究现状和发展趋势,为系统设计提供理论支持。
问卷调查法:通过问卷调查的方式,了解患者、医生、医院管理人员的需求和意见,为系统功能设计提供依据。
案例分析法:分析国内外知名医疗预约与诊断系统的成功案例,借鉴其设计思路和实现方法,为本系统的设计和实现提供参考。
实验研究法:通过实验对比不同的技术方案和算法,选择最优的方案和算法,提高系统的性能和用户体验。
2. 系统需求分析
2.1 功能需求
通过对患者、医生、医院管理人员的需求调研,确定系统的主要功能需求如下:
用户管理功能
- 用户注册、登录、信息修改
- 用户角色管理(管理员、医生、患者)
- 用户权限控制
科室管理功能
- 科室信息录入、修改、查询
- 科室分类管理
- 科室医生分配
医生管理功能
- 医生信息录入、修改、查询
- 医生排班管理
- 医生出诊记录管理
- 医生评价管理
预约挂号功能
- 预约信息展示
- 在线预约挂号
- 预约查询与取消
- 预约提醒
在线问诊功能
- 图文问诊
- 视频问诊
- 问诊记录管理
检查检验功能
- 检查检验项目管理
- 检查检验申请
- 检查检验结果查询
诊断治疗功能
- 病历管理
- 处方管理
- 治疗方案制定
- 医嘱管理
统计分析功能
- 预约统计
- 医生工作量统计
- 收入统计
- 患者满意度调查
2.2 非功能需求
性能需求
- 系统响应时间应满足用户操作要求,一般查询操作响应时间不超过 3 秒,复杂操作响应时间不超过 10 秒
- 系统应支持至少 500 个并发用户同时在线操作
- 系统应能够处理大量数据,保证数据的完整性和一致性
安全性需求
- 系统应保证用户数据的安全性和隐私性,严格遵守相关法律法规
- 用户密码应进行加密存储,防止密码泄露
- 系统应具备完善的访问控制机制,防止非法访问和操作
- 系统应具备数据备份和恢复机制,防止数据丢失
可用性需求
- 系统应具备良好的用户界面和操作体验,使用户能够轻松上手
- 系统应提供完善的帮助文档和在线客服,解答用户疑问
- 系统应具备高可用性,保证每天 24 小时不间断运行
可扩展性需求
- 系统应具备良好的可扩展性,能够方便地添加新的功能模块
- 系统应支持数据量和用户数的不断增长,能够通过集群化部署实现性能提升
兼容性需求
- 系统应支持主流浏览器(Chrome、Firefox、Safari、Edge 等)
- 系统应支持多种操作系统(Windows、MacOS、Linux 等)
3. 系统总体设计
3.1 系统架构设计
本系统采用 B/S(浏览器 / 服务器)架构,将整个系统分为客户端、应用服务器和数据库服务器三个层次。系统的总体架构如图 1 所示。
图 1:系统总体架构图
客户端:负责与用户交互,接收用户请求并展示系统响应结果。客户端通过 Web 浏览器访问系统。
Web 服务器:负责处理 HTTP 请求,静态资源的存储和分发。本系统使用 Tomcat 作为 Web 服务器。
应用服务器:是系统的核心,负责处理业务逻辑和数据处理。应用服务器基于 SpringBoot 框架构建,采用 MVC 架构模式,分为 Controller 层、Service 层和 Repository 层。应用服务器还包括消息队列和缓存服务,用于处理异步任务和提高系统性能。
数据库服务器:负责存储系统的所有数据,包括用户信息、科室信息、医生信息、预约信息、病历信息等。本系统使用 MySQL 作为主要数据库,Redis 作为缓存数据库。
3.2 系统部署架构设计
系统部署架构采用分布式集群部署方式,以确保系统的高可用性和扩展性。系统部署架构如图 2 所示。
图 2:系统部署架构图
负载均衡器:采用 Nginx 或 HAProxy 实现,负责将用户请求分发到多个 Web 服务器,实现负载均衡和高可用性。
Nginx 服务器集群:部署多个 Nginx 服务器,处理 HTTP 请求和静态资源的分发。
应用服务器集群:部署多个 SpringBoot 应用服务器,处理业务逻辑和数据处理。应用服务器之间通过消息队列进行异步通信。
消息队列:采用 RabbitMQ 或 Kafka 实现,用于处理异步任务,如邮件发送、短信通知、报表生成等。
任务处理服务器集群:部署多个任务处理服务器,处理消息队列中的任务。
数据库集群:采用 MySQL 主从复制或集群技术,实现数据的高可用性和读写分离。
缓存集群:部署多个 Redis 服务器,实现数据缓存,提高系统性能。
监控系统:采用 Prometheus 和 Grafana 实现,对系统的各个组件进行实时监控和性能分析,确保系统的稳定运行。
3.3 系统用例图设计
系统用例图描述了系统与用户之间的交互关系,展示了系统的功能边界和用户角色。系统用例图如图 3 所示。
图 3:系统用例图
3.4 数据库设计
根据系统需求,设计了以下主要数据表:
用户表 (User):存储系统用户的基本信息,包括用户 ID、用户名、密码、角色、姓名、性别、年龄、联系方式等。
科室表 (Department):存储医院科室信息,包括科室 ID、科室名称、科室描述、科室负责人等。
医生表 (Doctor):存储医生信息,包括医生 ID、用户 ID、科室 ID、职称、专长、简介等。
排班表 (Schedule):存储医生排班信息,包括排班 ID、医生 ID、日期、时间段、可预约数量等。
预约表 (Appointment):存储预约信息,包括预约 ID、患者 ID、医生 ID、排班 ID、预约时间、预约状态等。
病历表 (MedicalRecord):存储患者病历信息,包括病历 ID、患者 ID、医生 ID、就诊时间、主诉、现病史、体格检查、诊断结果、治疗方案等。
处方表 (Prescription):存储处方信息,包括处方 ID、病历 ID、药品 ID、药品名称、规格、用量、用法等。
检查检验表 (Examination):存储检查检验信息,包括检查 ID、病历 ID、检查项目、检查时间、检查结果等。
药品表 (Drug):存储药品信息,包括药品 ID、药品名称、规格、单位、价格、库存数量等。
公告表 (Announcement):存储系统公告信息,包括公告 ID、标题、内容、发布时间等。
数据库表结构详细设计如下:
sql
-- 用户表
CREATE TABLE `user` (
`id` INT NOT NULL AUTO_INCREMENT COMMENT '用户ID',
`username` VARCHAR(50) NOT NULL COMMENT '用户名',
`password` VARCHAR(100) NOT NULL COMMENT '密码',
`role` TINYINT NOT NULL COMMENT '角色(1:管理员,2:医生,3:患者)',
`name` VARCHAR(50) DEFAULT NULL COMMENT '姓名',
`gender` TINYINT DEFAULT NULL COMMENT '性别(1:男,2:女)',
`age` INT DEFAULT NULL COMMENT '年龄',
`phone` VARCHAR(20) DEFAULT NULL COMMENT '电话',
`email` VARCHAR(50) DEFAULT NULL COMMENT '邮箱',
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '状态(0:禁用,1:启用)',
`create_time` DATETIME NOT NULL COMMENT '创建时间',
`update_time` DATETIME NOT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_username` (`username`),
UNIQUE KEY `idx_phone` (`phone`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
-- 科室表
CREATE TABLE `department` (
`id` INT NOT NULL AUTO_INCREMENT COMMENT '科室ID',
`name` VARCHAR(50) NOT NULL COMMENT '科室名称',
`description` VARCHAR(255) DEFAULT NULL COMMENT '科室描述',
`head_doctor_id` INT DEFAULT NULL COMMENT '科室负责人',
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '状态(0:禁用,1:启用)',
`create_time` DATETIME NOT NULL COMMENT '创建时间',
`update_time` DATETIME NOT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_name` (`name`),
FOREIGN KEY (`head_doctor_id`) REFERENCES `doctor` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='科室表';
-- 医生表
CREATE TABLE `doctor` (
`id` INT NOT NULL AUTO_INCREMENT COMMENT '医生ID',
`user_id` INT NOT NULL COMMENT '用户ID',
`department_id` INT NOT NULL COMMENT '科室ID',
`title` VARCHAR(50) DEFAULT NULL COMMENT '职称',
`specialty` VARCHAR(100) DEFAULT NULL COMMENT '专长',
`introduction` TEXT DEFAULT NULL COMMENT '医生简介',
`avatar` VARCHAR(255) DEFAULT NULL COMMENT '头像',
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '状态(0:禁用,1:启用)',
`create_time` DATETIME NOT NULL COMMENT '创建时间',
`update_time` DATETIME NOT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_user_id` (`user_id`),
FOREIGN KEY (`user_id`) REFERENCES `user` (`id`),
FOREIGN KEY (`department_id`) REFERENCES `department` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='医生表';
-- 排班表
CREATE TABLE `schedule` (
`id` INT NOT NULL AUTO_INCREMENT COMMENT '排班ID',
`doctor_id` INT NOT NULL COMMENT '医生ID',
`date` DATE NOT NULL COMMENT '日期',
`time_slot` TINYINT NOT NULL COMMENT '时间段(1:上午,2:下午,3:晚上)',
`available_slots` INT NOT NULL COMMENT '可预约数量',
`booked_slots` INT NOT NULL DEFAULT 0 COMMENT '已预约数量',
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '状态(0:取消,1:正常)',
`create_time` DATETIME NOT NULL COMMENT '创建时间',
`update_time` DATETIME NOT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_doctor_date_time` (`doctor_id`,`date`,`time_slot`),
FOREIGN KEY (`doctor_id`) REFERENCES `doctor` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='排班表';
-- 预约表
CREATE TABLE `appointment` (
`id` INT NOT NULL AUTO_INCREMENT COMMENT '预约ID',
`patient_id` INT NOT NULL COMMENT '患者ID',
`doctor_id` INT NOT NULL COMMENT '医生ID',
`schedule_id` INT NOT NULL COMMENT '排班ID',
`appointment_time` DATETIME NOT NULL COMMENT '预约时间',
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '状态(1:待确认,2:已确认,3:已完成,4:已取消)',
`symptoms` VARCHAR(255) DEFAULT NULL COMMENT '症状描述',
`create_time` DATETIME NOT NULL COMMENT '创建时间',
`update_time` DATETIME NOT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
FOREIGN KEY (`patient_id`) REFERENCES `user` (`id`),
FOREIGN KEY (`doctor_id`) REFERENCES `doctor` (`id`),
FOREIGN KEY (`schedule_id`) REFERENCES `schedule` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='预约表';
-- 病历表
CREATE TABLE `medical_record` (
`id` INT NOT NULL AUTO_INCREMENT COMMENT '病历ID',
`patient_id` INT NOT NULL COMMENT '患者ID',
`doctor_id` INT NOT NULL COMMENT '医生ID',
`appointment_id` INT DEFAULT NULL COMMENT '预约ID',
`visit_time` DATETIME NOT NULL COMMENT '就诊时间',
`chief_complaint` TEXT NOT NULL COMMENT '主诉',
`present_illness` TEXT DEFAULT NULL COMMENT '现病史',
`physical_examination` TEXT DEFAULT NULL COMMENT '体格检查',
`diagnosis` TEXT DEFAULT NULL COMMENT '诊断结果',
`treatment_plan` TEXT DEFAULT NULL COMMENT '治疗方案',
`follow_up` TEXT DEFAULT NULL COMMENT '随访建议',
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '状态(1:未完成,2:已完成)',
`create_time` DATETIME NOT NULL COMMENT '创建时间',
`update_time` DATETIME NOT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
FOREIGN KEY (`patient_id`) REFERENCES `user` (`id`),
FOREIGN KEY (`doctor_id`) REFERENCES `doctor` (`id`),
FOREIGN KEY (`appointment_id`) REFERENCES `appointment` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='病历表';
-- 处方表
CREATE TABLE `prescription` (
`id` INT NOT NULL AUTO_INCREMENT COMMENT '处方ID',
`medical_record_id` INT NOT NULL COMMENT '病历ID',
`drug_id` INT NOT NULL COMMENT '药品ID',
`drug_name` VARCHAR(100) NOT NULL COMMENT '药品名称',
`specification` VARCHAR(50) NOT NULL COMMENT '规格',
`dosage` VARCHAR(50) NOT NULL COMMENT '用量',
`usage` VARCHAR(50) NOT NULL COMMENT '用法',
`duration` INT NOT NULL COMMENT '天数',
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '状态(1:未取药,2:已取药)',
`create_time` DATETIME NOT NULL COMMENT '创建时间',
`update_time` DATETIME NOT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
FOREIGN KEY (`medical_record_id`) REFERENCES `medical_record` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='处方表';
-- 检查检验表
CREATE TABLE `examination` (
`id` INT NOT NULL AUTO_INCREMENT COMMENT '检查ID',
`medical_record_id` INT NOT NULL COMMENT '病历ID',
`examination_type` TINYINT NOT NULL COMMENT '检查类型(1:实验室检查,2:影像学检查,3:其他)',
`examination_item` VARCHAR(50) NOT NULL COMMENT '检查项目',
`examination_time` DATETIME NOT NULL COMMENT '检查时间',
`examination_result` TEXT DEFAULT NULL COMMENT '检查结果',
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '状态(1:未完成,2:已完成)',
`create_time` DATETIME NOT NULL COMMENT '创建时间',
`update_time` DATETIME NOT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
FOREIGN KEY (`medical_record_id`) REFERENCES `medical_record` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='检查检验表';
-- 药品表
CREATE TABLE `drug` (
`id` INT NOT NULL AUTO_INCREMENT COMMENT '药品ID',
`name` VARCHAR(100) NOT NULL COMMENT '药品名称',
`category` TINYINT NOT NULL COMMENT '药品分类(1:抗生素,2:抗病毒药,3:感冒药,4:消化系统药,5:心血管系统药,6:其他)',
`specification` VARCHAR(50) NOT NULL COMMENT '规格',
`unit` VARCHAR(10) NOT NULL COMMENT '单位',
`price` DECIMAL(10,2) NOT NULL COMMENT '价格',
`manufacturer` VARCHAR(100) DEFAULT NULL COMMENT '生产厂家',
`stock_quantity` INT NOT NULL DEFAULT 0 COMMENT '库存数量',
`min_stock` INT NOT NULL DEFAULT 0 COMMENT '最低库存',
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '状态(0:停用,1:启用)',
`create_time` DATETIME NOT NULL COMMENT '创建时间',
`update_time` DATETIME NOT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_name_spec` (`name`,`specification`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='药品表';
-- 公告表
CREATE TABLE `announcement` (
`id` INT NOT NULL AUTO_INCREMENT COMMENT '公告ID',
`title` VARCHAR(100) NOT NULL COMMENT '标题',
`content` TEXT NOT NULL COMMENT '内容',
`author_id` INT NOT NULL COMMENT '发布者ID',
`publish_time` DATETIME NOT NULL COMMENT '发布时间',
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '状态(0:已过期,1:有效)',
`create_time` DATETIME NOT NULL COMMENT '创建时间',
`update_time` DATETIME NOT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
FOREIGN KEY (`author_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='公告表';
4. 系统详细设计与实现
4.1 后端服务实现
后端服务基于 SpringBoot 框架实现,采用 MVC 架构模式,将系统分为模型层、视图层和控制器层。以下是核心模块的实现细节:
用户认证与权限管理模块:基于 Spring Security 实现用户认证和权限控制,采用 JWT 实现无状态认证。
科室与医生管理模块:实现科室信息和医生信息的管理,支持医生排班和出诊记录的管理。
预约挂号模块:实现预约信息的展示、预约挂号、预约查询与取消等功能。
病历与诊疗管理模块:实现病历的创建、修改、查询等功能,支持处方开具、检查检验安排等诊疗流程。
药品管理模块:实现药品信息的管理、库存的查询和预警等功能。
系统设置模块:实现系统参数的设置、数据备份与恢复等功能。
以下是预约挂号模块的部分实现代码示例:
java
// 预约挂号模块
package com.medical.appointment.controller;
import com.medical.appointment.common.Result;
import com.medical.appointment.entity.Appointment;
import com.medical.appointment.entity.Schedule;
import com.medical.appointment.service.AppointmentService;
import com.medical.appointment.service.ScheduleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.List;
@RestController
@RequestMapping("/api/appointment")
public class AppointmentController {
@Autowired
private AppointmentService appointmentService;
@Autowired
private ScheduleService scheduleService;
/**
* 获取医生排班列表
* @param doctorId 医生ID
* @param startDate 开始日期
* @param endDate 结束日期
* @return 排班列表
*/
@GetMapping("/schedules")
public Result<List<Schedule>> getSchedules(
@RequestParam Integer doctorId,
@RequestParam String startDate,
@RequestParam String endDate) {
List<Schedule> schedules = scheduleService.getSchedulesByDoctorAndDate(doctorId, startDate, endDate);
return Result.success(schedules);
}
/**
* 创建预约
* @param appointment 预约信息
* @return 预约结果
*/
@PostMapping("/create")
public Result<Appointment> createAppointment(@RequestBody Appointment appointment) {
// 检查排班是否存在且可预约
Schedule schedule = scheduleService.getScheduleById(appointment.getScheduleId());
if (schedule == null || schedule.getStatus() != 1 || schedule.getAvailableSlots() <= 0) {
return Result.error("该时段不可预约");
}
// 检查用户是否已有该时段的预约
boolean exists = appointmentService.checkUserAppointmentExists(
appointment.getPatientId(),
appointment.getScheduleId(),
appointment.getAppointmentTime());
if (exists) {
return Result.error("您已在该时段有预约");
}
// 创建预约
appointment.setStatus(1); // 待确认
appointment.setCreateTime(new Date());
appointment.setUpdateTime(new Date());
Appointment createdAppointment = appointmentService.createAppointment(appointment);
// 更新排班可用数量
schedule.setBookedSlots(schedule.getBookedSlots() + 1);
schedule.setUpdateTime(new Date());
scheduleService.updateSchedule(schedule);
return Result.success(createdAppointment);
}
/**
* 获取用户预约列表
* @param patientId 患者ID
* @param status 预约状态
* @return 预约列表
*/
@GetMapping("/list")
public Result<List<Appointment>> getAppointments(
@RequestParam Integer patientId,
@RequestParam(required = false) Integer status) {
List<Appointment> appointments = appointmentService.getAppointmentsByPatient(patientId, status);
return Result.success(appointments);
}
/**
* 获取预约详情
* @param id 预约ID
* @return 预约详情
*/
@GetMapping("/detail/{id}")
public Result<Appointment> getAppointmentDetail(@PathVariable Integer id) {
Appointment appointment = appointmentService.getAppointmentById(id);
return Result.success(appointment);
}
/**
* 取消预约
* @param id 预约ID
* @param patientId 患者ID
* @return 取消结果
*/
@PostMapping("/cancel/{id}")
public Result<?> cancelAppointment(@PathVariable Integer id, @RequestParam Integer patientId) {
Appointment appointment = appointmentService.getAppointmentById(id);
if (appointment == null) {
return Result.error("预约不存在");
}
if (!appointment.getPatientId().equals(patientId)) {
return Result.error("您无权取消该预约");
}
if (appointment.getStatus() != 1 && appointment.getStatus() != 2) {
return Result.error("该预约状态不可取消");
}
// 更新预约状态
appointment.setStatus(4); // 已取消
appointment.setUpdateTime(new Date());
appointmentService.updateAppointment(appointment);
// 更新排班可用数量
Schedule schedule = scheduleService.getScheduleById(appointment.getScheduleId());
if (schedule != null) {
schedule.setBookedSlots(schedule.getBookedSlots() - 1);
schedule.setUpdateTime(new Date());
scheduleService.updateSchedule(schedule);
}
return Result.success();
}
/**
* 医生确认预约
* @param id 预约ID
* @param doctorId 医生ID
* @return 确认结果
*/
@PostMapping("/confirm/{id}")
public Result<?> confirmAppointment(@PathVariable Integer id, @RequestParam Integer doctorId) {
Appointment appointment = appointmentService.getAppointmentById(id);
if (appointment == null) {
return Result.error("预约不存在");
}
if (!appointment.getDoctorId().equals(doctorId)) {
return Result.error("您无权确认该预约");
}
if (appointment.getStatus() != 1) {
return Result.error("该预约状态不可确认");
}
// 更新预约状态
appointment.setStatus(2); // 已确认
appointment.setUpdateTime(new Date());
appointmentService.updateAppointment(appointment);
return Result.success();
}
}
4.2 前端界面设计与实现
前端界面采用 JSP+Bootstrap 技术实现,结合 jQuery 实现交互效果。以下是系统主要界面的设计与实现:
登录界面:提供用户登录功能,支持用户名 / 密码登录。
首页:展示系统概览信息,包括公告、预约提醒、医生排班等。
科室与医生列表界面:展示医院科室和医生信息,支持按科室筛选医生。
预约挂号界面:展示医生排班信息,支持选择日期和时间段进行预约挂号。
我的预约界面:展示用户的预约记录,支持查看详情和取消预约。
病历详情界面:展示病历详细信息,包括主诉、现病史、诊断结果、治疗方案等。
检查报告界面:展示检查检验结果,支持查看详细报告。
医生工作台界面:展示医生的待处理预约、已处理预约、病历管理等功能。
以下是预约挂号界面的部分实现代码示例:
jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>预约挂号 - 医疗预约与诊断系统</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/static/css/bootstrap.min.css">
<link rel="stylesheet" href="${pageContext.request.contextPath}/static/css/font-awesome.min.css">
<style>
.container {
margin-top: 20px;
}
.schedule-table {
margin-top: 20px;
}
.schedule-day {
text-align: center;
padding: 10px;
border: 1px solid #ddd;
margin-bottom: 10px;
}
.schedule-time {
text-align: center;
padding: 10px;
border: 1px solid #ddd;
margin-bottom: 10px;
cursor: pointer;
}
.schedule-time-available {
background-color: #dff0d8;
}
.schedule-time-full {
background-color: #f2dede;
cursor: not-allowed;
}
.schedule-time-selected {
background-color: #d9edf7;
}
.appointment-form {
margin-top: 20px;
}
</style>
</head>
<body>
<!-- 导航栏 -->
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="${pageContext.request.contextPath}/">医疗预约与诊断系统</a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li><a href="${pageContext.request.contextPath}/">首页</a></li>
<li class="active"><a href="${pageContext.request.contextPath}/appointment">预约挂号</a></li>
<li><a href="${pageContext.request.contextPath}/medicalRecord">我的病历</a></li>
<li><a href="${pageContext.request.contextPath}/examination">检查报告</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-user"></i> ${sessionScope.user.name} <span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a href="${pageContext.request.contextPath}/user/profile">个人信息</a></li>
<li><a href="${pageContext.request.contextPath}/user/changePassword">修改密码</a></li>
<li role="separator" class="divider"></li>
<li><a href="${pageContext.request.contextPath}/logout">退出登录</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<div class="container">
<div class="row">
<div class="col-md-3">
<!-- 侧边栏 -->
<div class="panel panel-default">
<div class="panel-heading">科室导航</div>
<div class="panel-body">
<ul class="nav nav-pills nav-stacked">
<c:forEach items="${departments}" var="dept">
<li ${dept.id == departmentId ? 'class="active"' : ''}>
<a href="${pageContext.request.contextPath}/appointment?departmentId=${dept.id}">
${dept.name}
</a>
</li>
</c:forEach>
</ul>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">医生信息</div>
<div class="panel-body">
<div class="text-center">
<img src="${doctor.avatar ?: pageContext.request.contextPath}/static/images/default_avatar.jpg"
alt="医生头像" class="img-circle" width="100" height="100">
</div>
<h4 class="text-center">${doctor.name}</h4>
<p class="text-center text-muted">${doctor.title}</p>
<p class="text-center">${doctor.specialty}</p>
<p class="text-center">${doctor.introduction}</p>
</div>
</div>
</div>
<div class="col-md-9">
<!-- 主内容 -->
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">预约挂号</h3>
</div>
<div class="panel-body">
<div class="schedule-table">
<div class="row">
<c:forEach items="${schedules}" var="day" varStatus="status">
<div class="col-md-2">
<div class="schedule-day">
<div>${day.dateStr}</div>
<div class="text-muted">${day.weekStr}</div>
</div>
<c:forEach items="${day.schedules}" var="schedule">
<div class="schedule-time ${schedule.availableSlots > 0 ? 'schedule-time-available' : 'schedule-time-full'}"
data-schedule-id="${schedule.id}"
data-doctor-id="${schedule.doctorId}"
data-date="${day.dateStr}"
data-time="${schedule.timeSlotStr}"
onclick="selectTimeSlot(this, ${schedule.availableSlots > 0})">
${schedule.timeSlotStr}
<div class="text-muted">
${schedule.availableSlots}/${schedule.availableSlots + schedule.bookedSlots}
</div>
</div>
</c:forEach>
</div>
${status.index % 5 == 4 && !status.last ? '<div class="clearfix"></div><div class="col-md-12"><hr></div>' : ''}
</c:forEach>
</div>
</div>
<div class="appointment-form" id="appointmentForm" style="display: none;">
<form id="appointmentFormData" method="post" action="${pageContext.request.contextPath}/api/appointment/create">
<input type="hidden" name="patientId" value="${sessionScope.user.id}">
<input type="hidden" name="doctorId" id="doctorId">
<input type="hidden" name="scheduleId" id="scheduleId">
<input type="hidden" name="appointmentTime" id="appointmentTime">
<div class="form-group">
<label for="symptoms">症状描述</label>
<textarea class="form-control" id="symptoms" name="symptoms" rows="3" placeholder="请简要描述您的症状"></textarea>
</div>
<div class="form-group">
<label for="medicalHistory">既往病史</label>
<textarea class="form-control" id="medicalHistory" name="medicalHistory" rows="2" placeholder="请简要描述您的既往病史(可选)"></textarea>
</div>
<div class="form-group">
<label for="allergyHistory">过敏史</label>
<textarea class="form-control" id="allergyHistory" name="allergyHistory" rows="2" placeholder="请简要描述您的过敏史(可选)"></textarea>
</div>
<div class="form-group">
<button type="button" class="btn btn-default" onclick="cancelAppointment()">取消</button>
<button type="button" class="btn btn-primary" onclick="submitAppointment()">提交预约</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="${pageContext.request.context
博主介绍:硕士研究生,专注于信息化技术领域开发与管理,会使用java、标准c/c++等开发语言,以及毕业项目实战✌
从事基于java BS架构、CS架构、c/c++ 编程工作近16年,拥有近12年的管理工作经验,拥有较丰富的技术架构思想、较扎实的技术功底和资深的项目管理经验。
先后担任过技术总监、部门经理、项目经理、开发组长、java高级工程师及c++工程师等职位,在工业互联网、国家标识解析体系、物联网、分布式集群架构、大数据通道处理、接口开发、远程教育、办公OA、财务软件(工资、记账、决策、分析、报表统计等方面)、企业内部管理软件(ERP、CRM等)、arggis地图等信息化建设领域有较丰富的实战工作经验;拥有BS分布式架构集群、数据库负载集群架构、大数据存储集群架构,以及高并发分布式集群架构的设计、开发和部署实战经验;拥有大并发访问、大数据存储、即时消息等瓶颈解决方案和实战经验。
拥有产品研发和发明专利申请相关工作经验,完成发明专利构思、设计、编写、申请等工作,并获得发明专利1枚。
-----------------------------------------------------------------------------------
大家在毕设选题、项目升级、论文写作,就业毕业等相关问题都可以给我留言咨询,非常乐意帮助更多的人或加w 908925859。
相关博客地址:
csdn专业技术博客:https://blog.csdn.net/mr_lili_1986?type=blog
Iteye博客: https://www.iteye.com/blog/user/mr-lili-1986-163-com
门户:http://www.petsqi.cn
七、其他案例: