[开源] 科室运营赛季积分管理系统:用足球联赛机制激活临床科主任的数据关注力
本项目是一个面向医院运营管理场景的轻量级 Web 应用系统将临床科室类比为足球俱乐部以「赛季」为时间单元、「积分榜」为核心界面、「保级线」为关键阈值构建出一套可感知、可对标、可行动的科室运营数据反馈闭环。系统覆盖积分计算、排名预警、趋势可视化、跨科室挑战赛与赛季终局预测五大主线能力交付形态为前后端分离的浏览器应用无需安装客户端支持本地快速启动与 SQLite 单文件部署。技术栈采用 Node.js TypeScript Express 构建后端服务React TypeScript ECharts 实现前端交互与图表渲染全部逻辑围绕医疗管理中真实存在的科室运营指标如床位使用率、次均费用、CMI 值、药占比等展开映射与建模不依赖外部数据库或云服务。定位与能力范围我们不做全院级 HRP 系统的替代品也不对接 HIS 或 EMR 的底层数据管道而是聚焦在「已有运营报表导出后」这一中间态当科室主任拿到 Excel 表格、BI 看板截图或手工汇总表时本系统提供一个即插即用的「再加工层」把静态数字变成动态积分把单点排名变成赛季轨迹把孤立指标变成可发起挑战的对战目标。它解决的是「数据看得见但不动手」「报表有但没人盯」「考核有但难传导」这三类典型管理断点。适用对象明确限定为医院运营管理部、质控科、信息科中负责科室绩效分析的人员以及有自主改进意愿的临床科主任本人。系统不采集患者个案数据不触碰诊疗行为过程所有输入均为科室级聚合指标如月度出院人次、平均住院日、手术台次等符合常规管理数据安全边界。核心功能系统围绕「赛季」这一核心时间粒度组织全部能力每个赛季默认设为 12 周可配置每轮更新一次科室积分。所有功能模块均服务于一个目标让科主任打开页面的第一眼就能判断「我们队现在在第几名离降级还有几轮上一轮赢了谁下一轮能挑战谁」赛季积分引擎积分不是简单加总而是按预设权重对多个运营维度进行标准化加权合成。例如床位使用率贡献 30%、CMI 值贡献 25%、药占比反向扣分占 20%、三四级手术占比占 15%、门诊量增长率占 10%。各指标先经 Z-score 归一化消除量纲差异再按权重叠加最终生成当轮积分。该引擎完全封装在/src/engine/目录下类型定义清晰权重配置开放于config/score-rules.ts支持医院根据自身管理重点调整。保级警告机制系统自动识别连续两轮排名末位如共 20 个科室则持续第 19–20 名的科室在首页顶部横幅与科室详情页显眼位置触发黄色预警并推送简明提示「神经外科已连续两轮处于保级区第19名建议核查近两周药占比与手术结构」。该逻辑独立于积分计算由/src/services/ranking-service.ts中的checkRelegationRisk()方法驱动阈值与轮次数均可在配置中修改。多维趋势看板每个科室主页提供三条核心曲线本季累计积分走势、关键单项指标如平均住院日滚动均值、与上一赛季同期对比差值。ECharts 图表支持鼠标悬停查看具体周次数值点击图例可开关某项指标显示。所有趋势均以「周」为最小单位避免月度颗粒度过粗导致信号滞后。科室挑战赛科主任可在自己科室页点击「发起挑战」选择另一科室及指定指标如「比拼三四级手术占比」设定挑战周期26 周。系统自动生成挑战海报含双方科室名称、指标、起止时间、当前值支持导出 PNG 分享至院内工作群。挑战期间双方指标每日更新并实时比对结束时自动发布胜负结果与差距百分比。赛季终局预测基于当前积分、历史波动率与剩余轮次系统调用简易线性外推模型非黑箱 AI给出各科室「大概率排名区间」。例如显示「心血管内科85% 概率位列前 5极小概率跌出前 10」。预测结果不替代正式考核但为科主任预留改进窗口期若预测显示可能滑入保级区可提前启动内部复盘。功能模块输入依据输出形式可配置项积分计算各科室每周上传的 CSV 或粘贴表格含指标名与数值积分榜、科室详情页积分曲线权重分配、归一化方式、指标正负向保级警告连续排名数据 预设轮次数页面横幅、详情页警示条保级区定义倒数几名、连续轮次阈值挑战赛发起方选择的对手与指标挑战海报、实时比对面板、胜负报告挑战周期长度、允许挑战的指标白名单赛季预测当前积分、近 4 周标准差、剩余轮次排名概率区间提示如「70% 概率前 3」外推模型参数衰减系数、置信度阈值使用与配置系统设计为开箱即用无须服务器运维经验。所有配置集中于src/config/目录下的 TypeScript 文件修改后重启后端即可生效。首次运行只需三步# 安装依赖 npm install # 启动后端监听 http://localhost:3000 npm run dev # 启动前端监听 http://localhost:3001 cd frontend npm install npm run dev数据录入支持两种方式一是通过前端「数据导入」页粘贴 Excel 复制的纯文本制表符分隔系统自动识别表头并匹配字段二是将整理好的 CSV 文件拖入指定区域。字段名需与系统内置映射表一致如「出院人数」对应dischargeCount说明文档中列有完整字段对照表含中文别名与英文键名。科室信息名称、所属中心、负责人通过/src/data/initial-departments.ts初始化新增科室仅需在此文件追加一行对象无需改数据库 Schema。赛季起始时间、轮次总数、保级区定义等全局规则统一维护在src/config/season-config.ts所有参数均有注释说明其业务含义。工程结构代码组织严格遵循「能力域隔离」原则每个目录职责单一且命名直指用途/src/api/仅包含 Express 路由声明不写业务逻辑如router.get(/api/seasons/:id/rankings)/src/engine/积分计算核心含归一化算法、权重加载器、积分合成器所有函数纯函数式便于单元测试/src/storage/SQLite 封装层仅暴露saveWeeklyData()、getRankingsBySeason()等语义化方法屏蔽 SQL 细节/src/services/协调型服务如RankingService调用 engine 计算并调用 storage 存储再触发 warning 检查/frontend/src/components/组件按功能切分ScoreboardTable积分榜主表、TrendChart趋势图、ChallengeCard挑战卡片互不嵌套过深这种结构使二次开发成本可控若医院想接入 OA 系统自动推送预警只需扩写/src/services/notification-service.ts若需增加新指标如「微创手术占比」只需在 engine 中添加归一化函数并在 config 中加入权重配置前端组件自动识别新字段。数据与扩展系统默认使用 SQLite数据文件为单个db.sqlite存于项目根目录。这意味着无需安装数据库服务备份即复制该文件迁移只需拷贝整个项目文件夹多人协作时可将db.sqlite加入.gitignore由每位使用者本地初始化。所有数据表结构在/src/storage/schema.ts中明确定义含seasons、departments、weekly_data、challenges四张主表字段名均为业务可读如week_number、department_id、metric_value无缩写歧义。扩展新指标无需改动数据库 Schema系统采用宽表设计weekly_data表中metrics字段为 JSON 文本存储该周所有指标键值对。新增指标只需在前端录入界面添加输入框在 engine 中补充解析逻辑即可完成全流程支持。说明文档中详细列出当前支持的全部指标及其计算逻辑出处如「药占比 药品收入 / 医疗总收入 × 100%」方便医院核对口径一致性。限制与说明本系统定位为「管理意识唤醒工具」而非「考核决策唯一依据」。因此明确划出三条边界第一不替代院内正式考核流程所有积分与排名仅供内部参考第二不处理原始业务数据如 LIS、PACS 图像、病历文本仅消费已脱敏的科室级统计结果第三不提供 SSO 单点登录或 AD 域集成登录采用最简 JWT Token 方式管理员密码哈希后存于 SQLite适合小范围试点使用。常见问题已在说明文档中结构化归档例如「如何批量导入过去 8 周数据」→ 使用/src/data/batch-importer.ts脚本传入 CSV 文件路径与起始周数即可「能否导出 PDF 版积分榜」→ 前端页面支持浏览器原生「打印为 PDF」格式已适配 A4 纸张「预测不准怎么办」→ 说明文档指出该模型适用于趋势平稳科室对新成立或近期有重大政策调整的科室建议关闭预测模块专注人工研判。项目地址https://github.com/nexorin9/season-scoreboard