Files
hospital_performance/backend/app/scripts/init_templates.py
2026-02-28 15:06:52 +08:00

276 lines
24 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
初始化指标模板数据
根据考核指标模板文档初始化模板和指标数据
"""
import asyncio
import json
import sys
import io
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker
from sqlalchemy import select
# 设置标准输出编码
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
from app.core.config import settings
from app.models.models import (
Indicator, IndicatorTemplate, TemplateIndicator,
IndicatorType, BSCDimension, TemplateType
)
# 指标数据 - 基于文档中的模板
INDICATORS_DATA = [
# 财务管理维度
{"code": "FIN001", "name": "业务收支结余率", "indicator_type": IndicatorType.COST, "bs_dimension": BSCDimension.FINANCIAL, "weight": 1.0, "max_score": 100, "target_value": None, "target_unit": "%", "calculation_method": "(收入-支出)/收入×100%", "assessment_method": "区间法达标满分每低1%扣2分", "data_source": "财务科"},
{"code": "FIN002", "name": "百元医疗收入卫生材料消耗", "indicator_type": IndicatorType.COST, "bs_dimension": BSCDimension.FINANCIAL, "weight": 1.0, "max_score": 100, "target_value": 20, "target_unit": "", "calculation_method": "卫生材料消耗/医疗收入×100", "assessment_method": "目标参照法(≤目标值满分,超扣分)", "data_source": "物资科"},
{"code": "FIN003", "name": "可控成本占比", "indicator_type": IndicatorType.COST, "bs_dimension": BSCDimension.FINANCIAL, "weight": 1.0, "max_score": 100, "target_value": 30, "target_unit": "%", "calculation_method": "可控成本/总成本×100%", "assessment_method": "区间法", "data_source": "财务科"},
{"code": "FIN004", "name": "百元固定资产收入", "indicator_type": IndicatorType.EFFICIENCY, "bs_dimension": BSCDimension.FINANCIAL, "weight": 1.0, "max_score": 100, "target_value": 150, "target_unit": "", "calculation_method": "业务收入/固定资产原值×100", "assessment_method": "比较法(与去年同期/标杆比)", "data_source": "财务科、设备科"},
# 顾客服务维度
{"code": "CUS001", "name": "住院患者满意度得分", "indicator_type": IndicatorType.SERVICE, "bs_dimension": BSCDimension.CUSTOMER, "weight": 1.0, "max_score": 100, "target_value": 90, "target_unit": "", "calculation_method": "满意度调查问卷统计", "assessment_method": "区间法90-100满分每低1分扣2分", "data_source": "满意度调查"},
{"code": "CUS002", "name": "门诊患者满意度得分", "indicator_type": IndicatorType.SERVICE, "bs_dimension": BSCDimension.CUSTOMER, "weight": 1.0, "max_score": 100, "target_value": 85, "target_unit": "", "calculation_method": "满意度调查问卷统计", "assessment_method": "区间法", "data_source": "满意度调查"},
{"code": "CUS003", "name": "预约就诊率", "indicator_type": IndicatorType.SERVICE, "bs_dimension": BSCDimension.CUSTOMER, "weight": 1.0, "max_score": 100, "target_value": 60, "target_unit": "%", "calculation_method": "预约挂号人次/总挂号人次×100%", "assessment_method": "目标参照法", "data_source": "HIS系统"},
{"code": "CUS004", "name": "有效投诉次数", "indicator_type": IndicatorType.SERVICE, "bs_dimension": BSCDimension.CUSTOMER, "weight": 1.0, "max_score": 100, "target_value": 0, "target_unit": "", "calculation_method": "有效投诉统计", "assessment_method": "扣分法每发生1次扣5分", "data_source": "投诉办、党办"},
# 内部流程维度
{"code": "IPR001", "name": "出院患者平均住院日", "indicator_type": IndicatorType.EFFICIENCY, "bs_dimension": BSCDimension.INTERNAL_PROCESS, "weight": 1.0, "max_score": 100, "target_value": 9, "target_unit": "", "calculation_method": "出院患者占用总床日数/出院人次", "assessment_method": "区间法≤目标值满分每超1天扣2分", "data_source": "病案室"},
{"code": "IPR002", "name": "病历甲级率", "indicator_type": IndicatorType.QUALITY, "bs_dimension": BSCDimension.INTERNAL_PROCESS, "weight": 1.0, "max_score": 100, "target_value": 90, "target_unit": "%", "calculation_method": "甲级病历数/抽查病历数×100%", "assessment_method": "区间法", "data_source": "质控科"},
{"code": "IPR003", "name": "医疗事故/严重差错发生数", "indicator_type": IndicatorType.QUALITY, "bs_dimension": BSCDimension.INTERNAL_PROCESS, "weight": 1.0, "max_score": 100, "target_value": 0, "target_unit": "", "calculation_method": "医疗事故统计", "assessment_method": "一票否决/扣分法", "data_source": "医务科", "is_veto": True},
{"code": "IPR004", "name": "医院感染发生率", "indicator_type": IndicatorType.QUALITY, "bs_dimension": BSCDimension.INTERNAL_PROCESS, "weight": 1.0, "max_score": 100, "target_value": 5, "target_unit": "%", "calculation_method": "医院感染例数/出院人次×100%", "assessment_method": "目标参照法", "data_source": "院感科"},
{"code": "IPR005", "name": "抗菌药物使用强度", "indicator_type": IndicatorType.QUALITY, "bs_dimension": BSCDimension.INTERNAL_PROCESS, "weight": 1.0, "max_score": 100, "target_value": 40, "target_unit": "DDDs", "calculation_method": "抗菌药物累计DDD数/同期收治患者人天数×100", "assessment_method": "区间法", "data_source": "药剂科"},
# 学习与成长维度
{"code": "LRN001", "name": "发表论文数", "indicator_type": IndicatorType.QUANTITY, "bs_dimension": BSCDimension.LEARNING_GROWTH, "weight": 1.0, "max_score": 100, "target_value": 2, "target_unit": "篇/年", "calculation_method": "核心/统计源期刊发表论文数", "assessment_method": "加分法每篇加5分封顶20分", "data_source": "科教科"},
{"code": "LRN002", "name": "带教实习生/进修生人数", "indicator_type": IndicatorType.QUANTITY, "bs_dimension": BSCDimension.LEARNING_GROWTH, "weight": 1.0, "max_score": 100, "target_value": 5, "target_unit": "人/年", "calculation_method": "带教人数统计", "assessment_method": "目标参照法", "data_source": "科教科"},
{"code": "LRN003", "name": "参加院内外培训人次", "indicator_type": IndicatorType.QUANTITY, "bs_dimension": BSCDimension.LEARNING_GROWTH, "weight": 1.0, "max_score": 100, "target_value": 20, "target_unit": "人次/季", "calculation_method": "培训人次统计", "assessment_method": "区间法", "data_source": "人事科"},
{"code": "LRN004", "name": "科室内部业务学习次数", "indicator_type": IndicatorType.QUANTITY, "bs_dimension": BSCDimension.LEARNING_GROWTH, "weight": 1.0, "max_score": 100, "target_value": 4, "target_unit": "次/月", "calculation_method": "学习记录统计", "assessment_method": "核查法少1次扣2分", "data_source": "科室自查"},
# 手术科室专项指标
{"code": "SRG001", "name": "DRG组数", "indicator_type": IndicatorType.QUANTITY, "bs_dimension": BSCDimension.FINANCIAL, "weight": 1.0, "max_score": 100, "target_value": None, "target_unit": "", "calculation_method": "出院病例进入的DRG组数量", "assessment_method": "比较法", "data_source": "病案室、DRG分组器"},
{"code": "SRG002", "name": "CMI值", "indicator_type": IndicatorType.QUALITY, "bs_dimension": BSCDimension.FINANCIAL, "weight": 1.0, "max_score": 100, "target_value": 1.0, "target_unit": None, "calculation_method": "科室出院病例平均权重", "assessment_method": "比较法", "data_source": "病案室、DRG分组器"},
{"code": "SRG003", "name": "费用消耗指数", "indicator_type": IndicatorType.COST, "bs_dimension": BSCDimension.FINANCIAL, "weight": 1.0, "max_score": 100, "target_value": 1.0, "target_unit": None, "calculation_method": "本科室DRG平均费用/区域同级医院同DRG平均费用", "assessment_method": "目标参照法", "data_source": "医保办、财务科"},
{"code": "SRG004", "name": "时间消耗指数", "indicator_type": IndicatorType.EFFICIENCY, "bs_dimension": BSCDimension.FINANCIAL, "weight": 1.0, "max_score": 100, "target_value": 1.0, "target_unit": None, "calculation_method": "本科室DRG平均住院日/区域同级医院同DRG平均住院日", "assessment_method": "目标参照法", "data_source": "病案室"},
{"code": "SRG005", "name": "手术并发症发生率", "indicator_type": IndicatorType.QUALITY, "bs_dimension": BSCDimension.INTERNAL_PROCESS, "weight": 1.0, "max_score": 100, "target_value": 1, "target_unit": "%", "calculation_method": "手术并发症例数/手术人次×100%", "assessment_method": "区间法", "data_source": "医务科"},
{"code": "SRG006", "name": "非计划重返手术室率", "indicator_type": IndicatorType.QUALITY, "bs_dimension": BSCDimension.INTERNAL_PROCESS, "weight": 1.0, "max_score": 100, "target_value": 0.5, "target_unit": "%", "calculation_method": "非计划重返手术室人次/手术人次×100%", "assessment_method": "区间法", "data_source": "医务科"},
{"code": "SRG007", "name": "围手术期死亡率", "indicator_type": IndicatorType.QUALITY, "bs_dimension": BSCDimension.INTERNAL_PROCESS, "weight": 1.0, "max_score": 100, "target_value": 0, "target_unit": "%", "calculation_method": "围手术期死亡人次/手术人次×100%", "assessment_method": "一票否决", "data_source": "医务科", "is_veto": True},
# 医技科室专项指标
{"code": "MTT001", "name": "检验/检查报告准确率", "indicator_type": IndicatorType.QUALITY, "bs_dimension": BSCDimension.INTERNAL_PROCESS, "weight": 1.0, "max_score": 100, "target_value": 99.5, "target_unit": "%", "calculation_method": "准确报告数/总报告数×100%", "assessment_method": "每低0.1%扣2分", "data_source": "质控科、临床反馈"},
{"code": "MTT002", "name": "室内质控达标率", "indicator_type": IndicatorType.QUALITY, "bs_dimension": BSCDimension.INTERNAL_PROCESS, "weight": 1.0, "max_score": 100, "target_value": 100, "target_unit": "%", "calculation_method": "质控达标项次/总质控项次×100%", "assessment_method": "未达标项次扣分", "data_source": "科室自查记录"},
{"code": "MTT003", "name": "危急值及时报告率", "indicator_type": IndicatorType.QUALITY, "bs_dimension": BSCDimension.INTERNAL_PROCESS, "weight": 1.0, "max_score": 100, "target_value": 100, "target_unit": "%", "calculation_method": "及时报告危急值数/危急值总数×100%", "assessment_method": "每漏报/迟报1例扣5分", "data_source": "HIS系统追踪"},
{"code": "MTT004", "name": "门诊常规报告出具时间", "indicator_type": IndicatorType.EFFICIENCY, "bs_dimension": BSCDimension.INTERNAL_PROCESS, "weight": 1.0, "max_score": 100, "target_value": 2, "target_unit": "小时", "calculation_method": "报告出具时间-标本接收时间", "assessment_method": "超时率每超5%扣2分", "data_source": "LIS/RIS系统"},
{"code": "MTT005", "name": "急诊报告出具时间", "indicator_type": IndicatorType.EFFICIENCY, "bs_dimension": BSCDimension.INTERNAL_PROCESS, "weight": 1.0, "max_score": 100, "target_value": 30, "target_unit": "分钟", "calculation_method": "报告出具时间-标本接收时间", "assessment_method": "超时率每超5%扣2分", "data_source": "LIS/RIS系统"},
{"code": "MTT006", "name": "临床科室对医技服务满意度", "indicator_type": IndicatorType.SERVICE, "bs_dimension": BSCDimension.CUSTOMER, "weight": 1.0, "max_score": 100, "target_value": 90, "target_unit": "", "calculation_method": "内部满意度调查", "assessment_method": "区间法", "data_source": "内部满意度调查"},
# 行政科室专项指标
{"code": "ADM001", "name": "服务态度与响应及时性", "indicator_type": IndicatorType.SERVICE, "bs_dimension": BSCDimension.CUSTOMER, "weight": 1.0, "max_score": 100, "target_value": 90, "target_unit": "", "calculation_method": "临床科室满意度测评", "assessment_method": "问卷/投票评分", "data_source": "满意度调查"},
{"code": "ADM002", "name": "遵纪守法与廉洁自律", "indicator_type": IndicatorType.QUALITY, "bs_dimension": BSCDimension.INTERNAL_PROCESS, "weight": 1.0, "max_score": 100, "target_value": 100, "target_unit": "%", "calculation_method": "违规情况统计", "assessment_method": "扣分法(违规即扣)", "data_source": "党办/纪检监察室"},
{"code": "ADM003", "name": "工作计划与总结", "indicator_type": IndicatorType.QUALITY, "bs_dimension": BSCDimension.INTERNAL_PROCESS, "weight": 1.0, "max_score": 100, "target_value": 100, "target_unit": "%", "calculation_method": "按时提交率", "assessment_method": "目标参照法+检查扣分", "data_source": "院办"},
{"code": "ADM004", "name": "任务按时完成率", "indicator_type": IndicatorType.EFFICIENCY, "bs_dimension": BSCDimension.INTERNAL_PROCESS, "weight": 1.0, "max_score": 100, "target_value": 95, "target_unit": "%", "calculation_method": "按时完成任务数/总任务数×100%", "assessment_method": "核查法(任务逾期扣分)", "data_source": "院办"},
# 后勤科室专项指标
{"code": "LOG001", "name": "后勤保障及时率", "indicator_type": IndicatorType.EFFICIENCY, "bs_dimension": BSCDimension.INTERNAL_PROCESS, "weight": 1.0, "max_score": 100, "target_value": 95, "target_unit": "%", "calculation_method": "及时响应次数/总报修次数×100%", "assessment_method": "区间法", "data_source": "总务科"},
{"code": "LOG002", "name": "安全生产检查达标率", "indicator_type": IndicatorType.QUALITY, "bs_dimension": BSCDimension.INTERNAL_PROCESS, "weight": 1.0, "max_score": 100, "target_value": 100, "target_unit": "%", "calculation_method": "达标项次/检查项次×100%", "assessment_method": "扣分法", "data_source": "安全检查记录"},
{"code": "LOG003", "name": "设备完好率", "indicator_type": IndicatorType.QUALITY, "bs_dimension": BSCDimension.INTERNAL_PROCESS, "weight": 1.0, "max_score": 100, "target_value": 95, "target_unit": "%", "calculation_method": "完好设备数/设备总数×100%", "assessment_method": "区间法", "data_source": "设备科"},
]
# 模板数据
TEMPLATES_DATA = [
{
"template_code": "TPL_GENERAL",
"template_name": "平衡计分卡四维度通用考核方案",
"template_type": TemplateType.GENERAL,
"description": "基于平衡计分卡理论,整合财务、顾客、内部流程、学习成长四个维度,适用于全院各科室",
"dimension_weights": {"financial": 35, "customer": 30, "internal_process": 25, "learning_growth": 10},
"assessment_cycle": "monthly",
"indicators": [
{"code": "FIN001", "category": "收支管理", "weight": 10},
{"code": "FIN002", "category": "成本控制", "weight": 8},
{"code": "FIN003", "category": "成本控制", "weight": 7},
{"code": "FIN004", "category": "资产效率", "weight": 5},
{"code": "CUS001", "category": "患者满意度", "weight": 10},
{"code": "CUS002", "category": "患者满意度", "weight": 5},
{"code": "CUS003", "category": "服务可及性", "weight": 5},
{"code": "CUS004", "category": "投诉管理", "weight": 5},
{"code": "IPR001", "category": "医疗质量", "weight": 6},
{"code": "IPR002", "category": "医疗质量", "weight": 6},
{"code": "IPR003", "category": "医疗安全", "weight": 8},
{"code": "IPR004", "category": "院感控制", "weight": 5},
{"code": "IPR005", "category": "合理用药", "weight": 5},
{"code": "LRN001", "category": "科研教学", "weight": 4},
{"code": "LRN002", "category": "科研教学", "weight": 3},
{"code": "LRN003", "category": "人才培养", "weight": 3},
{"code": "LRN004", "category": "人才培养", "weight": 2},
]
},
{
"template_code": "TPL_SURGICAL",
"template_name": "临床手术科室RBRVS/DRG导向绩效方案",
"template_type": TemplateType.SURGICAL,
"description": "结合RBRVS和DRG理念体现技术难度、风险和工作量适用于外科、妇科、眼科等手术科室",
"dimension_weights": {"financial": 35, "customer": 20, "internal_process": 30, "learning_growth": 15},
"assessment_cycle": "monthly",
"indicators": [
{"code": "SRG001", "category": "财务与效率", "weight": 8},
{"code": "SRG002", "category": "财务与效率", "weight": 10},
{"code": "SRG003", "category": "财务与效率", "weight": 8},
{"code": "SRG004", "category": "财务与效率", "weight": 9},
{"code": "FIN001", "category": "财务与效率", "weight": 5},
{"code": "SRG005", "category": "质量与安全", "weight": 10},
{"code": "SRG006", "category": "质量与安全", "weight": 8},
{"code": "SRG007", "category": "质量与安全", "weight": 10},
{"code": "IPR002", "category": "质量与安全", "weight": 8},
{"code": "CUS001", "category": "患者与服务", "weight": 10},
{"code": "CUS004", "category": "患者与服务", "weight": 5},
{"code": "LRN001", "category": "学习与创新", "weight": 5},
{"code": "LRN002", "category": "学习与创新", "weight": 4},
]
},
{
"template_code": "TPL_MEDICAL_TECH",
"template_name": "医技科室质量效率双核心考核方案",
"template_type": TemplateType.MEDICAL_TECH,
"description": "以工作质量、报告准确性和内部服务效率为核心,兼顾成本控制,适用于检验科、放射科、超声科、药剂科等",
"dimension_weights": {"financial": 20, "customer": 30, "internal_process": 40, "learning_growth": 10},
"assessment_cycle": "monthly",
"indicators": [
{"code": "MTT001", "category": "工作质量与安全", "weight": 12},
{"code": "MTT002", "category": "工作质量与安全", "weight": 10},
{"code": "MTT003", "category": "工作质量与安全", "weight": 10},
{"code": "IPR003", "category": "工作质量与安全", "weight": 8},
{"code": "MTT004", "category": "内部服务效率", "weight": 8},
{"code": "MTT005", "category": "内部服务效率", "weight": 10},
{"code": "MTT006", "category": "内部服务效率", "weight": 8},
{"code": "FIN002", "category": "成本与资源管理", "weight": 10},
{"code": "LOG003", "category": "成本与资源管理", "weight": 8},
{"code": "LRN001", "category": "学科发展与服务", "weight": 5},
{"code": "LRN002", "category": "学科发展与服务", "weight": 5},
]
},
{
"template_code": "TPL_ADMIN",
"template_name": "行政后勤科室服务支持导向考核方案",
"template_type": TemplateType.ADMIN,
"description": "以保障临床、服务一线、管理效能为核心,侧重过程管理与内部客户满意度,适用于院办、党办、医务科、护理部、财务科等",
"dimension_weights": {"financial": 10, "customer": 40, "internal_process": 40, "learning_growth": 10},
"assessment_cycle": "quarterly",
"indicators": [
{"code": "ADM001", "category": "基本素质与服务质量", "weight": 20},
{"code": "ADM002", "category": "遵纪守法与廉洁自律", "weight": 15},
{"code": "ADM003", "category": "科室内部管理", "weight": 10},
{"code": "ADM004", "category": "制度建设与执行力", "weight": 15},
{"code": "CUS001", "category": "内部服务满意度", "weight": 20},
{"code": "LRN003", "category": "学习与成长", "weight": 10},
]
},
{
"template_code": "TPL_LOGISTICS",
"template_name": "后勤保障科室考核方案",
"template_type": TemplateType.LOGISTICS,
"description": "以后勤保障及时性、安全生产和设备完好率为核心,适用于总务科、设备科、基建科等",
"dimension_weights": {"financial": 20, "customer": 30, "internal_process": 40, "learning_growth": 10},
"assessment_cycle": "monthly",
"indicators": [
{"code": "LOG001", "category": "后勤保障", "weight": 20},
{"code": "LOG002", "category": "安全生产", "weight": 15},
{"code": "LOG003", "category": "设备管理", "weight": 15},
{"code": "ADM001", "category": "服务质量", "weight": 20},
{"code": "ADM004", "category": "任务执行", "weight": 15},
{"code": "LRN003", "category": "学习与成长", "weight": 10},
]
},
]
async def init_data():
"""初始化数据"""
engine = create_async_engine(settings.DATABASE_URL, echo=True)
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
async with async_session() as session:
# 创建指标
print("正在创建指标...")
indicator_map = {} # code -> indicator object
for ind_data in INDICATORS_DATA:
result = await session.execute(
select(Indicator).where(Indicator.code == ind_data["code"])
)
existing = result.scalar_one_or_none()
if existing:
indicator_map[ind_data["code"]] = existing
continue
indicator = Indicator(
code=ind_data["code"],
name=ind_data["name"],
indicator_type=ind_data["indicator_type"],
bs_dimension=ind_data["bs_dimension"],
weight=ind_data["weight"],
max_score=ind_data["max_score"],
target_value=ind_data.get("target_value"),
target_unit=ind_data.get("target_unit"),
calculation_method=ind_data.get("calculation_method"),
assessment_method=ind_data.get("assessment_method"),
deduction_standard=ind_data.get("deduction_standard"),
data_source=ind_data.get("data_source"),
is_veto=ind_data.get("is_veto", False),
is_active=True
)
session.add(indicator)
indicator_map[ind_data["code"]] = indicator
await session.commit()
print(f"已创建 {len(indicator_map)} 个指标")
# 创建模板
print("正在创建模板...")
for tpl_data in TEMPLATES_DATA:
result = await session.execute(
select(IndicatorTemplate).where(IndicatorTemplate.template_code == tpl_data["template_code"])
)
existing = result.scalar_one_or_none()
if existing:
print(f"模板 {tpl_data['template_code']} 已存在,跳过")
continue
template = IndicatorTemplate(
template_code=tpl_data["template_code"],
template_name=tpl_data["template_name"],
template_type=tpl_data["template_type"],
description=tpl_data["description"],
dimension_weights=json.dumps(tpl_data["dimension_weights"]),
assessment_cycle=tpl_data["assessment_cycle"],
is_active=True
)
session.add(template)
await session.flush()
# 添加指标关联
for idx, ind_ref in enumerate(tpl_data["indicators"]):
indicator = indicator_map.get(ind_ref["code"])
if not indicator:
print(f"警告:指标 {ind_ref['code']} 不存在")
continue
ti = TemplateIndicator(
template_id=template.id,
indicator_id=indicator.id,
category=ind_ref.get("category"),
weight=ind_ref.get("weight", 1.0),
sort_order=idx
)
session.add(ti)
print(f"已创建模板: {tpl_data['template_name']}")
await session.commit()
print("初始化完成!")
if __name__ == "__main__":
asyncio.run(init_data())