276 lines
24 KiB
Python
276 lines
24 KiB
Python
"""
|
||
初始化指标模板数据
|
||
|
||
根据考核指标模板文档初始化模板和指标数据
|
||
"""
|
||
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())
|