基于Spring Boot与Vue.js的住院病历档案管理系统开发实战
一、系统架构设计
本系统采用前后端分离架构,后端基于Spring Boot 2.7.15,前端基于Vue.js 3.3.4,数据库使用MySQL 8.0。系统需实现病历档案的数字化管理、权限控制、数据加密存储与检索功能。
1.1 技术栈选型
- 后端框架:Spring Boot 2.7.15
- 安全框架:Spring Security + JWT
- 数据库:MySQL 8.0
- ORM框架:MyBatis Plus 3.5.3.1
- 前端框架:Vue.js 3.3.4 + Element Plus 2.3.8
- 构建工具:Maven 3.8.6 + Node.js 18.17.0
二、开发环境搭建
2.1 后端环境配置
创建Spring Boot项目,pom.xml核心依赖配置如下:
```application.yml数据库配置:
``` spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/medical_record?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: your_password jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl ```2.2 前端环境配置
创建Vue项目并安装依赖:
``` npm create vue@latest medical-record-frontend cd medical-record-frontend npm install element-plus@2.3.8 npm install axios@1.5.0 npm install vue-router@4.2.4 npm install pinia@2.1.6 ```main.js全局配置:
``` import { createApp } from 'vue' import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' import App from './App.vue' import router from './router' import { createPinia } from 'pinia' const app = createApp(App) app.use(ElementPlus) app.use(router) app.use(createPinia()) app.mount('app') ```三、数据库设计
3.1 核心表结构
创建病历主表:
``` CREATE TABLE medical_record ( id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID', record_no VARCHAR(50) NOT NULL UNIQUE COMMENT '病历编号', patient_id BIGINT NOT NULL COMMENT '患者ID', patient_name VARCHAR(50) NOT NULL COMMENT '患者姓名', id_card VARCHAR(18) COMMENT '身份证号', admission_time DATETIME NOT NULL COMMENT '入院时间', discharge_time DATETIME COMMENT '出院时间', department VARCHAR(50) COMMENT '科室', attending_doctor VARCHAR(50) COMMENT '主治医生', diagnosis TEXT COMMENT '诊断结果', treatment TEXT COMMENT '治疗方案', record_status TINYINT DEFAULT 1 COMMENT '病历状态:1-在院,2-已出院,3-归档', created_by VARCHAR(50) COMMENT '创建人', created_time DATETIME DEFAULT CURRENT_TIMESTAMP, updated_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_patient_id (patient_id), INDEX idx_record_no (record_no), INDEX idx_admission_time (admission_time) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='病历主表'; ```
创建病历附件表:
``` CREATE TABLE record_attachment ( id BIGINT PRIMARY KEY AUTO_INCREMENT, record_id BIGINT NOT NULL COMMENT '病历ID', file_name VARCHAR(255) NOT NULL COMMENT '文件名', file_path VARCHAR(500) NOT NULL COMMENT '文件存储路径', file_type VARCHAR(50) COMMENT '文件类型', file_size BIGINT COMMENT '文件大小(字节)', upload_time DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (record_id) REFERENCES medical_record(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='病历附件表'; ```四、后端核心功能实现
4.1 实体类定义
MedicalRecord实体类:
``` @Data @TableName("medical_record") public class MedicalRecord { @TableId(type = IdType.AUTO) private Long id; private String recordNo; private Long patientId; private String patientName; private String idCard; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date admissionTime; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date dischargeTime; private String department; private String attendingDoctor; private String diagnosis; private String treatment; private Integer recordStatus; @TableField(fill = FieldFill.INSERT) private String createdBy; @TableField(fill = FieldFill.INSERT) private Date createdTime; @TableField(fill = FieldFill.INSERT_UPDATE) private Date updatedTime; } ```4.2 数据访问层
创建Mapper接口:
``` @Mapper public interface MedicalRecordMapper extends BaseMapper4.3 服务层实现
病历服务实现类:
``` @Service public class MedicalRecordServiceImpl extends ServiceImpl4.4 文件上传接口
文件上传控制器:
``` @RestController @RequestMapping("/api/attachment") public class AttachmentController { @Value("${file.upload.path}") private String uploadPath; @PostMapping("/upload") public Result uploadFile(@RequestParam("file") MultipartFile file, @RequestParam Long recordId) throws IOException { if (file.isEmpty()) { return Result.error("文件不能为空"); } // 创建存储目录 File dir = new File(uploadPath); if (!dir.exists()) { dir.mkdirs(); } // 生成唯一文件名 String originalName = file.getOriginalFilename(); String fileExt = originalName.substring(originalName.lastIndexOf(".")); String fileName = UUID.randomUUID().toString() + fileExt; String filePath = uploadPath + File.separator + fileName; // 保存文件 file.transferTo(new File(filePath)); // 保存到数据库 RecordAttachment attachment = new RecordAttachment(); attachment.setRecordId(recordId); attachment.setFileName(originalName); attachment.setFilePath(filePath); attachment.setFileType(fileExt); attachment.setFileSize(file.getSize()); attachmentService.save(attachment); return Result.success("上传成功", attachment); } } ```五、前端核心功能实现
5.1 病历列表页面
MedicalRecordList.vue核心代码:
```
病历档案管理
新增病历
5.2 病历详情页面
MedicalRecordDetail.vue文件上传组件:
```
支持上传图片、PDF、Word文档,单个文件不超过10MB