基于 SpringBoot+JSP 的医疗预约与诊断系统设计与实现

发布于:2025-06-24 ⋅ 阅读:(17) ⋅ 点赞:(0)

摘要

本研究针对传统医疗预约与诊断流程中存在的效率低下、信息不透明、患者等待时间长等问题,设计并实现了一个基于 SpringBoot+JSP 的医疗预约与诊断系统。系统采用 B/S 架构,整合了用户管理、科室管理、医生排班、预约挂号、在线问诊、检查检验、诊断治疗等功能模块,实现了医疗服务的全流程数字化管理。系统前端使用 JSP+Bootstrap 构建界面,后端采用 SpringBoot 框架提供 RESTful API 服务,数据库使用 MySQL 存储业务数据。通过实际应用验证,系统具有良好的稳定性、可扩展性和用户体验,能够有效提高医院的管理效率和服务质量,改善患者的就医体验。

1. 引言

1.1 研究背景与意义

随着信息技术的快速发展和互联网的普及,数字化医疗已成为医疗行业发展的必然趋势。传统的医疗预约与诊断流程主要依赖人工操作,存在效率低下、信息不透明、患者等待时间长等问题,难以满足现代医疗服务的需求。

互联网医疗预约与诊断系统的出现,为解决上述问题提供了有效的途径。通过建立数字化医疗平台,患者可以在线预约挂号、查询医生信息、查看检查报告、进行在线问诊等,大大提高了就医效率,减少了等待时间。同时,医院也可以通过系统实现对医疗资源的合理配置和管理,提高医疗服务质量和管理水平。

本研究旨在设计并实现一个基于 SpringBoot+JSP 的医疗预约与诊断系统,通过整合医疗服务的各个环节,实现医疗预约与诊断的全流程数字化管理。系统将为患者提供便捷的就医服务渠道,为医院提供高效的管理工具,具有重要的现实意义。

1.2 国内外研究现状

国外在医疗信息化领域起步较早,已经形成了较为成熟的医疗信息系统和服务模式。例如,美国的 Epic、Cerner,欧洲的 iSoft 等公司开发的医疗信息系统,功能完善、操作简便,在国际市场上占据了较大份额。这些系统采用了先进的信息技术,如云计算、大数据分析、人工智能等,提高了医疗服务的效率和质量。

国内医疗信息化建设近年来也取得了显著进展。国家出台了一系列政策支持医疗信息化发展,推动了医院信息系统的普及和应用。国内一些软件企业开发了针对医院的管理系统,如东华软件、卫宁健康、万达信息等公司的产品,在国内市场上得到了广泛应用。

目前,国内外医疗预约与诊断系统仍存在一些问题,如系统功能不够完善、数据共享困难、用户体验不佳等。此外,随着移动互联网和智能终端的普及,用户对医疗服务的便捷性和个性化提出了更高的要求,需要进一步加强技术创新和服务创新。

1.3 研究内容与方法

本研究的主要内容包括:

  1. 系统需求分析:通过问卷调查、访谈等方式,了解患者、医生、医院管理人员的需求,明确系统的功能和性能要求。

  2. 系统设计:包括系统架构设计、数据库设计、功能模块设计等,确定系统的技术选型和实现方案。

  3. 系统实现:基于 SpringBoot+JSP 技术栈实现系统的各个功能模块,包括用户认证、科室管理、医生排班、预约挂号、在线问诊、检查检验、诊断治疗等。

  4. 系统测试:对系统进行功能测试、性能测试、安全测试等,确保系统的稳定性和可靠性。

  5. 系统部署与应用:将系统部署到生产环境中,进行实际应用验证,评估系统的使用效果和用户满意度。

本研究采用的研究方法包括:

  1. 文献研究法:查阅国内外相关文献,了解医疗预约与诊断系统的研究现状和发展趋势,为系统设计提供理论支持。

  2. 问卷调查法:通过问卷调查的方式,了解患者、医生、医院管理人员的需求和意见,为系统功能设计提供依据。

  3. 案例分析法:分析国内外知名医疗预约与诊断系统的成功案例,借鉴其设计思路和实现方法,为本系统的设计和实现提供参考。

  4. 实验研究法:通过实验对比不同的技术方案和算法,选择最优的方案和算法,提高系统的性能和用户体验。

2. 系统需求分析

2.1 功能需求

通过对患者、医生、医院管理人员的需求调研,确定系统的主要功能需求如下:

  1. 用户管理功能

    • 用户注册、登录、信息修改
    • 用户角色管理(管理员、医生、患者)
    • 用户权限控制
  2. 科室管理功能

    • 科室信息录入、修改、查询
    • 科室分类管理
    • 科室医生分配
  3. 医生管理功能

    • 医生信息录入、修改、查询
    • 医生排班管理
    • 医生出诊记录管理
    • 医生评价管理
  4. 预约挂号功能

    • 预约信息展示
    • 在线预约挂号
    • 预约查询与取消
    • 预约提醒
  5. 在线问诊功能

    • 图文问诊
    • 视频问诊
    • 问诊记录管理
  6. 检查检验功能

    • 检查检验项目管理
    • 检查检验申请
    • 检查检验结果查询
  7. 诊断治疗功能

    • 病历管理
    • 处方管理
    • 治疗方案制定
    • 医嘱管理
  8. 统计分析功能

    • 预约统计
    • 医生工作量统计
    • 收入统计
    • 患者满意度调查
2.2 非功能需求
  1. 性能需求

    • 系统响应时间应满足用户操作要求,一般查询操作响应时间不超过 3 秒,复杂操作响应时间不超过 10 秒
    • 系统应支持至少 500 个并发用户同时在线操作
    • 系统应能够处理大量数据,保证数据的完整性和一致性
  2. 安全性需求

    • 系统应保证用户数据的安全性和隐私性,严格遵守相关法律法规
    • 用户密码应进行加密存储,防止密码泄露
    • 系统应具备完善的访问控制机制,防止非法访问和操作
    • 系统应具备数据备份和恢复机制,防止数据丢失
  3. 可用性需求

    • 系统应具备良好的用户界面和操作体验,使用户能够轻松上手
    • 系统应提供完善的帮助文档和在线客服,解答用户疑问
    • 系统应具备高可用性,保证每天 24 小时不间断运行
  4. 可扩展性需求

    • 系统应具备良好的可扩展性,能够方便地添加新的功能模块
    • 系统应支持数据量和用户数的不断增长,能够通过集群化部署实现性能提升
  5. 兼容性需求

    • 系统应支持主流浏览器(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 数据库设计

根据系统需求,设计了以下主要数据表:

  1. 用户表 (User):存储系统用户的基本信息,包括用户 ID、用户名、密码、角色、姓名、性别、年龄、联系方式等。

  2. 科室表 (Department):存储医院科室信息,包括科室 ID、科室名称、科室描述、科室负责人等。

  3. 医生表 (Doctor):存储医生信息,包括医生 ID、用户 ID、科室 ID、职称、专长、简介等。

  4. 排班表 (Schedule):存储医生排班信息,包括排班 ID、医生 ID、日期、时间段、可预约数量等。

  5. 预约表 (Appointment):存储预约信息,包括预约 ID、患者 ID、医生 ID、排班 ID、预约时间、预约状态等。

  6. 病历表 (MedicalRecord):存储患者病历信息,包括病历 ID、患者 ID、医生 ID、就诊时间、主诉、现病史、体格检查、诊断结果、治疗方案等。

  7. 处方表 (Prescription):存储处方信息,包括处方 ID、病历 ID、药品 ID、药品名称、规格、用量、用法等。

  8. 检查检验表 (Examination):存储检查检验信息,包括检查 ID、病历 ID、检查项目、检查时间、检查结果等。

  9. 药品表 (Drug):存储药品信息,包括药品 ID、药品名称、规格、单位、价格、库存数量等。

  10. 公告表 (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 架构模式,将系统分为模型层、视图层和控制器层。以下是核心模块的实现细节:

  1. 用户认证与权限管理模块:基于 Spring Security 实现用户认证和权限控制,采用 JWT 实现无状态认证。

  2. 科室与医生管理模块:实现科室信息和医生信息的管理,支持医生排班和出诊记录的管理。

  3. 预约挂号模块:实现预约信息的展示、预约挂号、预约查询与取消等功能。

  4. 病历与诊疗管理模块:实现病历的创建、修改、查询等功能,支持处方开具、检查检验安排等诊疗流程。

  5. 药品管理模块:实现药品信息的管理、库存的查询和预警等功能。

  6. 系统设置模块:实现系统参数的设置、数据备份与恢复等功能。

以下是预约挂号模块的部分实现代码示例:

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 实现交互效果。以下是系统主要界面的设计与实现:

  1. 登录界面:提供用户登录功能,支持用户名 / 密码登录。

  2. 首页:展示系统概览信息,包括公告、预约提醒、医生排班等。

  3. 科室与医生列表界面:展示医院科室和医生信息,支持按科室筛选医生。

  4. 预约挂号界面:展示医生排班信息,支持选择日期和时间段进行预约挂号。

  5. 我的预约界面:展示用户的预约记录,支持查看详情和取消预约。

  6. 病历详情界面:展示病历详细信息,包括主诉、现病史、诊断结果、治疗方案等。

  7. 检查报告界面:展示检查检验结果,支持查看详细报告。

  8. 医生工作台界面:展示医生的待处理预约、已处理预约、病历管理等功能。

以下是预约挂号界面的部分实现代码示例:

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

七、其他案例: 

 

  

 


网站公告

今日签到

点亮在社区的每一天
去签到