基于ASP.NET Core的医院不良事件管理系统的架构设计

基于ASP.NET Core的医院不良事件管理系统的架构设计

前言

医院不良事件管理是医疗质量安全管理的重要环节,一个优秀的不良事件管理系统需要覆盖事件上报、审核追踪、分析统计的完整闭环。本文将详细介绍如何基于ASP.NET Core构建一个完整的医院不良事件管理系统,涵盖26种不良事件类型、完善的权限体系、钉钉集成以及数据可视化统计。

一、系统整体架构

1.1 技术栈选型

csharp 复制代码
// 核心技术栈
- 框架: ASP.NET Core 3.1+
- 前端UI: Layui 2.9.7
- 数据库: MySQL (主数据库)
- 辅助数据库: Oracle (人事系统), SQL Server (HIS), PostgreSQL (LIS)
- ORM: Dapper (轻量级高性能)
- 图表: ECharts 5.x
- 即时通讯: 钉钉SDK
- PDF生成: QuestPDF, iText
- Excel操作: NPOI

1.2 项目结构

复制代码
QASystem/
├── Controllers/                 # 控制器层
│   ├── LoginController.cs      # 登录认证
│   ├── HarmfulEventController.cs    # 不良事件上报
│   ├── HarmfulEventManageController.cs  # 不良事件管理
│   └── HarmfulChartController.cs   # 图表统计
├── Models/                      # 数据模型
│   ├── Login/                   # 登录相关模型
│   ├── HarmfulEvent/           # 不良事件模型
│   ├── HarmfulEventManage/     # 管理模块模型
│   └── HarmfulChart/           # 图表模型
├── Views/                       # 视图层
│   ├── Login/                  # 登录视图
│   ├── HarmfulEvent/           # 26种事件表单视图
│   ├── HarmfulEventManage/     # 管理视图
│   └── HarmfulChart/           # 图表视图
├── Services/                    # 业务服务层
├── Unitity/                    # 工具类
└── Configuration/              # 配置文件

1.3 多数据库架构

系统需要对接多个业务系统,采用了多数据库连接架构:

csharp 复制代码
public class HarmfulEventController : CheckLoginController
{
    private readonly string _harmfulevent;   // 不良事件数据库
    private readonly string _qasystem;       // QA系统数据库
    private readonly string _his3;           // HIS3数据库
    private readonly string _sihis;          // SI医院信息系统
    private readonly string _lyradb;         // LIS数据库
    
    public HarmfulEventController(IConfiguration configuration)
    {
        _harmfulevent = configuration.GetConnectionString("harmfulevent");
        _qasystem = configuration.GetConnectionString("qasystem");
        _his3 = configuration.GetConnectionString("his3");
        _sihis = configuration.GetConnectionString("sihis");
        _lyradb = configuration.GetConnectionString("lyradb");
    }
}

这种设计使得系统能够:

  • 从HIS自动获取患者信息
  • 从人事系统获取员工数据
  • 从LIS获取检验数据
  • 统一管理不良事件数据

二、数据库设计

2.1 核心表结构

sql 复制代码
-- 不良事件主表
CREATE TABLE `medreportmt` (
  `id` INT PRIMARY KEY AUTO_INCREMENT,
  `repId` VARCHAR(50) NOT NULL,        -- 事件编号
  `repTypeId` INT NOT NULL,            -- 事件类型ID
  `repTypeId1` INT NOT NULL,           -- 事件类型ID(可修改)
  `status` TINYINT DEFAULT 0,          -- 状态:0暂存/1上报/2审核
  `empId` INT NOT NULL,                -- 上报人ID
  `empDeptId` INT NOT NULL,            -- 上报科室ID
  `createDate` DATETIME,               -- 创建时间
  `submitDate` DATETIME,              -- 提交时间
  `isTrack` TINYINT DEFAULT 0,         -- 追踪状态:0未/1可/2中/3已
  `isSend` TINYINT DEFAULT 0,          -- 是否转发
  `sac` INT DEFAULT 0,                  -- SAC分级
  UNIQUE KEY `repId` (`repId`)
);

-- 不良事件明细表
CREATE TABLE `medreportdt` (
  `id` INT PRIMARY KEY AUTO_INCREMENT,
  `repId` VARCHAR(50) NOT NULL,       -- 关联事件编号
  `repContent` JSON NOT NULL,         -- 事件详细内容(JSON)
  FOREIGN KEY (`repId`) REFERENCES `medreportmt`(`repId`)
);

-- 事件追踪表
CREATE TABLE `medreptrack` (
  `id` INT PRIMARY KEY AUTO_INCREMENT,
  `repId` VARCHAR(50) NOT NULL,       -- 关联事件编号
  `trackcontent` JSON NOT NULL,       -- 追踪内容
  `auditContent` JSON,                -- 审核内容
  FOREIGN KEY (`repId`) REFERENCES `medreportmt`(`repId`)
);

-- 事件转发表
CREATE TABLE `medreportsd` (
  `id` INT PRIMARY KEY AUTO_INCREMENT,
  `repId` VARCHAR(50) NOT NULL,
  `sendEmpId` INT NOT NULL,           -- 发送人
  `acceptEmpId` INT NOT NULL,         -- 接收人
  `sendDate` DATETIME
);

-- 附件表
CREATE TABLE `medreportfiles` (
  `id` INT PRIMARY KEY AUTO_INCREMENT,
  `repId` VARCHAR(50) NOT NULL,
  `fileName` VARCHAR(255),
  `fileExt` VARCHAR(20),
  `fileSize` VARCHAR(50),
  `filePath` VARCHAR(500),
  `uploader` INT,
  `uploadTime` DATETIME
);

2.2 事件内容JSON结构

不同类型的不良事件使用JSON存储灵活的事件内容:

csharp 复制代码
// 以药品不良反应为例 (HarmfulEvent06Model)
public class HarmfulEvent06Model
{
    public string deptid { get; set; }          // 发生科室
    public string occutime { get; set; }        // 发生时间
    public string occuaddr { get; set; }        // 发生地点
    public string pname { get; set; }            // 患者姓名
    public string psex { get; set; }           // 性别
    public string age { get; set; }             // 年龄
    public string diagnose { get; set; }        // 临床诊断
    public string mrn { get; set; }             // 病历号
    public string eventtype { get; set; }        // 事件类型
    public string effect { get; set; }           // 损害程度
    public string process { get; set; }          // 发生过程
    public string analysis { get; set; }         // 原因分析
    public string advise { get; set; }          // 建议
    // 药品相关字段
    public string impact { get; set; }          // 对原患疾病影响
    public string evaluation { get; set; }       // 关联性评价
    public string stopdrug { get; set; }        // 停药情况
    public string usedagain { get; set; }       // 再次使用
    public string eventresult { get; set; }     // 不良反应结果
}

三、控制器设计

3.1 控制器职责划分

复制代码
LoginController           - 认证授权、钉钉集成、SSO单点登录
    │
    ├─> HarmfulEventController      - 26种事件的上报、编辑、查看
    │       ├─ HarmfulEvent01Add/Edit/Show  (输血不良反应)
    │       ├─ HarmfulEvent02Add/Edit/Show  (输血相关事件)
    │       ├─ ...
    │       └─ HarmfulEvent26Add/Edit/Show  (非计划再次手术)
    │
    ├─> HarmfulEventManageController - 审核、追踪、转发、导出
    │       ├─ Index                      (管理首页)
    │       ├─ HarmfulEventManageAudit    (审核)
    │       ├─ HarmfulEventManageTrack    (追踪)
    │       ├─ HarmfulEventManageSend     (转发)
    │       └─ HarmfulEventManageExportExcel (导出)
    │
    └─> HarmfulChartController     - 7种统计图表
            ├─ echart01  (按科室统计趋势)
            ├─ echart02  (按伤害程度饼图)
            ├─ echart03  (按事件类型统计)
            ├─ echart04  (按人员类别饼图)
            ├─ echart05  (按月份季度统计)
            ├─ echart06  (按SAC分级饼图)
            └─ echart07  (按事件类型饼图)

3.2 统一响应模型

csharp 复制代码
// 统一的API响应格式
public class DataTableModel<T>
{
    public int code { get; set; }      // 0成功/1失败
    public int count { get; set; }     // 总记录数
    public string msg { get; set; }    // 消息
    public List<T> data { get; set; }  // 数据
}

public class MsgModel
{
    public int code { get; set; }
    public string msg { get; set; }
}

3.3 分页查询实现

csharp 复制代码
public IActionResult HarmfulEventManageList(HarmfulEventManageSearchModel model)
{
    int offset = (model.page - 1) * model.limit;
    int rows = model.limit;
    
    List<string> whereList = new List<string>();
    var countPm = new DynamicParameters();
    var pagePm = new DynamicParameters();
    
    // 动态构建查询条件
    if (model.repTypeId > 0)
    {
        whereList.Add("repTypeId1=?repTypeId1");
        countPm.Add("?repTypeId1", model.repTypeId);
        pagePm.Add("?repTypeId1", model.repTypeId);
    }
    
    if (!string.IsNullOrEmpty(model.submitDate))
    {
        string[] dates = model.submitDate.Split('~');
        whereList.Add("submitDate between ?startTime and ?endTime");
        countPm.Add("?startTime", dates[0].Trim() + " 00:00:00");
        countPm.Add("?endTime", dates[1].Trim() + " 23:59:59");
        pagePm.Add("?startTime", dates[0].Trim() + " 00:00:00");
        pagePm.Add("?endTime", dates[1].Trim() + " 23:59:59");
    }
    
    string wheresql = string.Join(" and ", whereList);
    string sqlPage = sql + " where " + wheresql + " ORDER BY submitDate DESC LIMIT ?pageoff,?limit";
    
    MedreportmtInfos = _mysqlService.DBQuery<MedreportmtModel>(_harmfulevent, sqlPage, pagePm);
    MedreportmtCount = _mysqlService.DBQuery<MedreportmtModel>(_harmfulevent, sqlCount, countPm);
    
    return Json(new DataTableModel<T> { 
        code = 0, 
        count = MedreportmtCount.Count, 
        data = MedreportmtInfos 
    });
}

四、会话与权限管理

4.1 Session存储用户信息

csharp 复制代码
// 登录时设置Session
private void SetEmployeeRoles(EmployeeModel LoginUser)
{
    HttpContext.Session.SetString("Employee", JsonConvert.SerializeObject(LoginUser));
    HttpContext.Session.SetString("EventTypes", JsonConvert.SerializeObject(
        DI.QueryMedreptypes(_mysqlService, _harmfulevent, LoginUser.roleId)));
    
    // 权限控制
    HttpContext.Session.SetString("CanTrack", 
        DI.isPermissions(_mysqlService, _qasystem, LoginUser.roleId, 47));  // 追踪权限
    HttpContext.Session.SetString("CanTrackAudit", 
        DI.isPermissions(_mysqlService, _qasystem, LoginUser.roleId, 50));  // 追踪审核权限
    HttpContext.Session.SetString("CanSend", 
        DI.isPermissions(_mysqlService, _qasystem, LoginUser.roleId, 51));  // 转发权限
    HttpContext.Session.SetString("DeptManager", 
        DI.isPermissions(_mysqlService, _qasystem, LoginUser.roleId, 42)); // 科室管理权限
}

4.2 权限验证基类

csharp 复制代码
public class CheckLoginController : Controller
{
    public new IActionResult View()
    {
        if (string.IsNullOrEmpty(HttpContext.Session.GetString("Employee")))
        {
            return Redirect("/Login/UserLogin");
        }
        return base.View();
    }
}

五、前端架构

5.1 Layui表格组件

html 复制代码
<table id="HarmfulEventsManageTable" lay-filter="HarmfulEventsManageTable"></table>

<script>
layui.use(['index', 'table'], function(){
    var table = layui.table;
    
    table.render({
        elem: '#HarmfulEventsManageTable'
        ,url: '/HarmfulEventManage/HarmfulEventManageList'
        ,cols: [[
            {type: 'checkbox', fixed: 'left'}
            ,{field: 'repId', width: 160, title: '文书ID'}
            ,{field: 'status', width: 70, title: '状态', templet: '#status'}
            ,{field: 'isTrack', width: 80, title: '追踪', templet: '#isTrack'}
            ,{field: 'repTypeName', width: 250, title: '事件类型'}
        ]]
        ,page: true
        ,limit: 20
        ,limits: [20, 100, 200, 300]
    });
});
</script>

5.2 事件类型模板

html 复制代码
<script type="text/html" id="status">
    {{# if(d.status == 0){  }}
    <button class="layui-btn layui-btn-warm layui-btn-xs">暂存</button>
    {{# }else if(d.status == 1){ }}
    <button class="layui-btn layui-btn-normal layui-btn-xs">上报</button>
    {{# }else if(d.status == 2){ }}
    <button class="layui-btn layui-btn-xs">审核</button>
    {{# } }}
</script>

六、26种不良事件类型

系统支持26种不良事件,涵盖了医院运营的各个关键环节:

编号 事件类型 特殊字段
01 输血不良反应 血型、配血结果
02 输血相关事件 血袋信息
03 手术并发症 手术信息、麻醉方式
04 术前术后诊断不符 诊断对比
05 其他手术相关事件 手术部位错误等
06 药品不良反应 用药信息、过敏史
07 用药差错事件 差错环节分类
08 职业暴露事件 暴露类型、病毒类型
09 医院感染相关 感染类型
10 麻醉镇静相关 麻醉方式
11 管路事件 管路类型、滑脱方式
12 公共意外事件 意外类型
13 跌倒坠床事件 跌倒评分、跌倒部位
14 治安事件 事件类型
15 其他不良事件 -
16 医疗设备器械 设备信息
17 其他医疗不良事件 -
18 护理给药错误 给药途径
19 其他护理不良事件 护理缺陷
20 压力性损伤 压疮分期
21 院感爆发 爆发类型
22 信息不良事件 网络安全
23 院内不预期心跳停止 心肺复苏
24 检查检验病理切片 标本信息
25 输液并发症 静脉炎分级
26 非计划再次手术 再手术原因

七、系统亮点

7.1 灵活的事件类型扩展

通过JSON存储事件内容,可以轻松添加新的事件类型而无需修改数据库结构。

7.2 多系统数据整合

通过统一的数据访问层,整合了HIS、LIS、人事系统等多个数据源。

7.3 完善的权限体系

基于角色的权限控制,细粒度的功能权限和数据权限管理。

7.4 实时的钉钉通知

关键操作自动推送钉钉消息,实现闭环管理。

总结

本文介绍了医院不良事件管理系统的整体架构设计,包括多数据库架构、26种事件类型设计、统一响应模型、Session权限管理等核心模块。下一篇文章将详细介绍权限认证与钉钉集成的具体实现。

相关推荐
小谢小哥2 小时前
53-熔断降级详解
java·后端·架构
满天星83035772 小时前
【Linux/多路复用】poll和epoll的使用
linux·服务器·c++·后端
覆东流2 小时前
第6天:python综合练习——制作简易计算器
开发语言·后端·python
CodeMartain2 小时前
shardingsphere-spring 实现数据分片(一)
java·后端·spring
Kiyra2 小时前
为什么远程调用别包进 Spring 事务里
java·后端·spring
武子康3 小时前
大数据-277 Spark MLib-梯度提升树(GBDT)算法原理与工程实现指南
大数据·后端·spark
Victor3563 小时前
MongoDB(101)如何处理MongoDB中的慢查询?
后端
Victor3563 小时前
MongoDB(102)如何处理MongoDB中的数据冲突?
后端
IT_陈寒3 小时前
SpringBoot自动配置的坑差点没把我埋了
前端·人工智能·后端