#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Bug #318 历史数据修复脚本 为已存在但未生成手术医嘱的手术申请单补齐数据 """ import psycopg2 import json import random import string from datetime import datetime # 数据库连接配置 DB_CONFIG = { "host": "47.116.196.11", "port": 15432, "database": "postgresql", "user": "postgresql", "password": "postgresql", # 请根据实际情况修改 } def generate_bus_no(): """生成4位随机bus_no""" return "".join(random.choices(string.digits, k=4)) def check_repair_needed(conn): """检查需要修复的记录数""" cursor = conn.cursor() sql = """ SELECT COUNT(*) FROM doc_request_form rf LEFT JOIN wor_service_request sr ON sr.prescription_no = rf.prescription_no AND sr.delete_flag = '0' WHERE rf.type_code = 'PROCEDURE' AND rf.delete_flag = '0' AND sr.id IS NULL """ cursor.execute(sql) count = cursor.fetchone()[0] cursor.close() return count def get_repair_list(conn): """获取需要修复的手术申请单列表""" cursor = conn.cursor() sql = """ SELECT rf.id, rf.prescription_no, rf.encounter_id, rf.patient_id, rf.requester_id, rf.create_time, rf.org_id, rf.desc_json FROM doc_request_form rf LEFT JOIN wor_service_request sr ON sr.prescription_no = rf.prescription_no AND sr.delete_flag = '0' WHERE rf.type_code = 'PROCEDURE' AND rf.delete_flag = '0' AND sr.id IS NULL ORDER BY rf.create_time DESC """ cursor.execute(sql) results = cursor.fetchall() cursor.close() return results def parse_surgery_info(desc_json): """解析手术信息""" if not desc_json: return {} try: if isinstance(desc_json, str): return json.loads(desc_json) return desc_json except: return {} def repair_service_request(conn, repair_list): """修复手术医嘱(ServiceRequest)""" cursor = conn.cursor() insert_sql = """ INSERT INTO wor_service_request ( bus_no, prescription_no, status_enum, generate_source_enum, therapy_enum, quantity, unit_code, category_enum, patient_id, requester_id, encounter_id, authored_time, org_id, content_json, delete_flag, create_time, create_by, tenant_id ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) RETURNING id """ new_requests = [] for record in repair_list: ( rf_id, prescription_no, encounter_id, patient_id, requester_id, create_time, org_id, desc_json, ) = record # 解析手术信息 surgery_info = parse_surgery_info(desc_json) content_json = ( json.dumps(surgery_info, ensure_ascii=False) if surgery_info else None ) # 生成bus_no bus_no = generate_bus_no() # 插入ServiceRequest cursor.execute( insert_sql, ( bus_no, # bus_no prescription_no, # prescription_no 1, # status_enum: 1-待签发 1, # generate_source_enum: 1-医生处方 2, # therapy_enum: 2-临时医嘱 1, # quantity "次", # unit_code 4, # category_enum: 4-手术 patient_id, # patient_id requester_id, # requester_id encounter_id, # encounter_id create_time, # authored_time org_id, # org_id content_json, # content_json "0", # delete_flag create_time, # create_time requester_id, # create_by 1, # tenant_id ), ) service_request_id = cursor.fetchone()[0] new_requests.append( { "service_request_id": service_request_id, "bus_no": bus_no, "prescription_no": prescription_no, "patient_id": patient_id, "encounter_id": encounter_id, "requester_id": requester_id, "create_time": create_time, "org_id": org_id, "surgery_info": surgery_info, } ) conn.commit() cursor.close() return new_requests def repair_charge_items(conn, new_requests): """修复收费项目(ChargeItem)""" cursor = conn.cursor() insert_sql = """ INSERT INTO adm_charge_item ( bus_no, status_enum, generate_source_enum, patient_id, context_enum, encounter_id, enterer_id, entered_date, service_table, service_id, product_table, requesting_org_id, quantity_value, quantity_unit, unit_price, total_price, delete_flag, create_time, create_by, tenant_id ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) """ for req in new_requests: surgery_info = req["surgery_info"] # 手术费用 surgery_fee = 0 if surgery_info and "surgeryFee" in surgery_info: try: surgery_fee = float(surgery_info["surgeryFee"]) except: surgery_fee = 0 # 插入手术费用收费项目 cursor.execute( insert_sql, ( "CI" + req["bus_no"], # bus_no 1, # status_enum: 1-草稿 1, # generate_source_enum: 1-医生处方 req["patient_id"], # patient_id 3, # context_enum: 3-诊疗 req["encounter_id"], # encounter_id req["requester_id"], # enterer_id req["create_time"], # entered_date "wor_service_request", # service_table req["service_request_id"], # service_id "wor_activity_definition", # product_table req["org_id"], # requesting_org_id 1, # quantity_value "次", # quantity_unit surgery_fee, # unit_price surgery_fee, # total_price "0", # delete_flag req["create_time"], # create_time req["requester_id"], # create_by 1, # tenant_id ), ) # 麻醉费用(如果存在且大于0) anesthesia_fee = 0 if surgery_info and "anesthesiaFee" in surgery_info: try: anesthesia_fee = float(surgery_info["anesthesiaFee"]) except: anesthesia_fee = 0 if anesthesia_fee > 0: cursor.execute( insert_sql, ( "CI" + req["bus_no"] + "_A", # bus_no 1, # status_enum 1, # generate_source_enum req["patient_id"], # patient_id 3, # context_enum req["encounter_id"], # encounter_id req["requester_id"], # enterer_id req["create_time"], # entered_date "wor_service_request", # service_table req["service_request_id"], # service_id "wor_activity_definition", # product_table req["org_id"], # requesting_org_id 1, # quantity_value "次", # quantity_unit anesthesia_fee, # unit_price anesthesia_fee, # total_price "0", # delete_flag req["create_time"], # create_time req["requester_id"], # create_by 1, # tenant_id ), ) conn.commit() cursor.close() def verify_repair(conn): """验证修复结果""" cursor = conn.cursor() # 统计手术医嘱数量 cursor.execute(""" SELECT COUNT(*) FROM wor_service_request WHERE category_enum = 4 AND delete_flag = '0' """) service_request_count = cursor.fetchone()[0] # 统计收费项目数量 cursor.execute(""" SELECT COUNT(*) FROM adm_charge_item ci WHERE ci.service_table = 'wor_service_request' AND EXISTS ( SELECT 1 FROM wor_service_request sr WHERE sr.id = ci.service_id AND sr.category_enum = 4 ) """) charge_item_count = cursor.fetchone()[0] cursor.close() return service_request_count, charge_item_count def main(): """主函数""" print("=" * 60) print("Bug #318 历史数据修复脚本") print("=" * 60) print() try: # 连接数据库 print("正在连接数据库...") conn = psycopg2.connect(**DB_CONFIG) print("✓ 数据库连接成功") print() # 步骤1:检查需要修复的记录数 print("步骤1: 检查需要修复的记录...") need_repair_count = check_repair_needed(conn) print(f"✓ 发现 {need_repair_count} 条需要修复的手术申请单") print() if need_repair_count == 0: print("没有需要修复的数据,退出") return # 步骤2:获取修复列表 print("步骤2: 获取修复列表...") repair_list = get_repair_list(conn) print(f"✓ 获取到 {len(repair_list)} 条记录") print() # 步骤3:修复ServiceRequest print("步骤3: 生成手术医嘱(ServiceRequest)...") new_requests = repair_service_request(conn, repair_list) print(f"✓ 成功生成 {len(new_requests)} 条手术医嘱") print() # 步骤4:修复ChargeItem print("步骤4: 生成收费项目(ChargeItem)...") repair_charge_items(conn, new_requests) print(f"✓ 成功生成收费项目") print() # 步骤5:验证修复结果 print("步骤5: 验证修复结果...") service_count, charge_count = verify_repair(conn) print(f"✓ 当前手术医嘱总数: {service_count}") print(f"✓ 当前手术收费项目总数: {charge_count}") print() print("=" * 60) print("✓ 修复完成!") print("=" * 60) except Exception as e: print(f"✗ 错误: {e}") import traceback traceback.print_exc() finally: if "conn" in locals(): conn.close() print("\n数据库连接已关闭") if __name__ == "__main__": main()