Merge develop into test - sync latest code

This commit is contained in:
2026-04-10 12:31:19 +08:00
1255 changed files with 107256 additions and 24904 deletions

26
scripts/api_check.sh Normal file
View File

@@ -0,0 +1,26 @@
#!/bin/bash
# 诊断脚本 - 检查API返回
echo "=========================================="
echo "API 诊断工具"
echo "=========================================="
echo ""
# 请替换为实际的token和服务器地址
SERVER_URL="http://192.168.110.252:18080"
ENCOUNTER_ID="2038823905749327873"
echo "1. 检查 doctor-station API:"
echo "URL: ${SERVER_URL}/openhis/doctor-station/advice/request-base-info?encounterId=${ENCOUNTER_ID}"
echo ""
echo "2. 检查 reg-doctorstation API:"
echo "URL: ${SERVER_URL}/openhis/reg-doctorstation/advice-manage/reg-request-base-info?encounterId=${ENCOUNTER_ID}"
echo ""
echo "请在浏览器中访问上述URL查看返回的JSON数据"
echo ""
echo "需要确认:"
echo " - 是否有 adviceType=4 的记录?"
echo " - adviceName 是否有值?"
echo " - 手术医嘱是否包含在返回数据中?"

120
scripts/api_test.py Normal file
View File

@@ -0,0 +1,120 @@
#!/usr/bin/env python3
"""
直接调用 API 检查返回数据
"""
import requests
import json
import sys
# 配置
BASE_URL = "http://192.168.110.252:18080/openhis"
ENCOUNTER_ID = "2038823905749327873"
# 尝试不登录直接访问(如果允许)
# 或者需要添加 token
def check_api():
"""检查 API 返回"""
print("=" * 80)
print("直接调用 API 检查")
print("=" * 80)
print()
# 如果有 token请在这里设置
headers = {
# "Authorization": "Bearer YOUR_TOKEN_HERE",
"Content-Type": "application/json"
}
# 检查 doctor-station API
print("1. 检查 doctor-station API:")
url = f"{BASE_URL}/doctor-station/advice/request-base-info"
params = {"encounterId": ENCOUNTER_ID}
try:
print(f" URL: {url}")
print(f" 参数: {params}")
print()
response = requests.get(url, params=params, headers=headers, timeout=10)
print(f" 状态码: {response.status_code}")
if response.status_code == 200:
data = response.json()
print(f" 返回 code: {data.get('code')}")
print(f" 返回 msg: {data.get('msg')}")
print()
if data.get("code") == 200:
records = data.get("data", [])
print(f" 记录总数: {len(records)}")
print()
# 查找手术医嘱 (adviceType=4)
surgery_records = []
for record in records:
if record.get("adviceType") == 4 or record.get("categoryEnum") == 4:
surgery_records.append(record)
print(f" 手术医嘱数量: {len(surgery_records)}")
print()
if surgery_records:
print(" 手术医嘱详情:")
for idx, record in enumerate(surgery_records, 1):
print(f"\n [{idx}]:")
print(f" requestId: {record.get('requestId')}")
print(f" adviceType: {record.get('adviceType')}")
print(f" adviceName: {record.get('adviceName')}")
print(f" categoryEnum: {record.get('categoryEnum')}")
content = record.get("contentJson", "{}")
if content:
try:
content_obj = (
json.loads(content)
if isinstance(content, str)
else content
)
print(
f" contentJson.surgeryName: {content_obj.get('surgeryName', 'N/A')}"
)
except:
print(f" contentJson: {content[:100]}...")
else:
print(" ✗ 未找到手术医嘱 (adviceType=4)")
print()
print(" 可能原因:")
print(" 1. 后端代码未正确部署")
print(" 2. 浏览器缓存了旧数据")
print(" 3. SQL 未生效")
# 打印所有记录查看 adviceType 分布
print()
print(" 所有记录的 adviceType 分布:")
type_count = {}
for record in records:
atype = record.get("adviceType")
type_count[atype] = type_count.get(atype, 0) + 1
for atype, count in sorted(type_count.items()):
print(f" adviceType={atype}: {count}")
else:
print(f" ✗ 返回错误: {data}")
else:
print(f" ✗ 请求失败: {response.status_code}")
print(f" 返回: {response.text[:500]}")
print()
print(" 可能需要登录 token请修改脚本添加 Authorization header")
except Exception as e:
print(f" ✗ 请求异常: {e}")
print()
print(" 请确认:")
print(" 1. 服务器地址是否正确")
print(" 2. 网络是否连通")
print(" 3. 是否需要登录 token")
if __name__ == "__main__":
check_api()

4
scripts/build.bat Normal file
View File

@@ -0,0 +1,4 @@
cd /d D:\his\openhis-server-new
call mvn clean package -DskipTests
echo Build complete!
pause

View File

@@ -0,0 +1,60 @@
import psycopg2
import sys
sys.stdout.reconfigure(encoding="utf-8")
conn = psycopg2.connect(
host="192.168.110.252",
port=15432,
database="postgresql",
user="postgresql",
password="Jchl1528",
)
cursor = conn.cursor()
cursor.execute("SET search_path TO hisdev, public")
print("=" * 80)
print("检查手术医嘱的 activity_id 和 advice_name")
print("=" * 80)
print()
# 查询手术医嘱的 activity_id
cursor.execute("""
SELECT
sr.id,
sr.prescription_no,
sr.activity_id,
ad.name as activity_name,
sr.content_json
FROM wor_service_request sr
LEFT JOIN wor_activity_definition ad ON ad.id = sr.activity_id AND ad.delete_flag = '0'
WHERE sr.category_enum = 4
AND sr.delete_flag = '0'
AND sr.encounter_id = 2038823905749327873
""")
rows = cursor.fetchall()
for row in rows:
print(f"医嘱ID: {row[0]}")
print(f"单号: {row[1]}")
print(f"activity_id: {row[2]}")
print(f"activity_name: {row[3]}")
if row[4]:
import json
try:
content = json.loads(row[4]) if isinstance(row[4], str) else row[4]
print(f"手术名称: {content.get('surgeryName', 'N/A')}")
except:
print(f"content_json: {row[4][:100]}")
print("-" * 80)
print()
print("问题SQL查询使用 activity_id 关联 wor_activity_definition 获取 advice_name")
print("但手术医嘱的 activity_id 可能为 null 或指向不存在的记录!")
print()
print("解决方案:应该从 content_json 中解析 surgeryName 作为 advice_name")
cursor.close()
conn.close()

View File

@@ -0,0 +1,71 @@
import requests
import json
# API配置
BASE_URL = "http://192.168.110.252:18080/openhis"
ENCOUNTER_ID = "2038823905749327873"
print("=" * 80)
print("API 返回数据检查")
print("=" * 80)
print()
# 检查 doctor-station API
print("1. 检查 doctor-station API:")
print(
f" URL: {BASE_URL}/doctor-station/advice/request-base-info?encounterId={ENCOUNTER_ID}"
)
print()
try:
response = requests.get(
f"{BASE_URL}/doctor-station/advice/request-base-info",
params={"encounterId": ENCOUNTER_ID},
timeout=10,
)
print(f" 状态码: {response.status_code}")
if response.status_code == 200:
data = response.json()
if data.get("code") == 200:
records = data.get("data", [])
print(f" 返回记录数: {len(records)}")
print()
# 查找手术医嘱 (adviceType=4)
surgery_records = [
r
for r in records
if r.get("adviceType") == 4 or r.get("categoryEnum") == 4
]
print(f" 手术医嘱数量: {len(surgery_records)}")
print()
for record in surgery_records:
print(f" 手术医嘱详情:")
print(f" - requestId: {record.get('requestId')}")
print(f" - adviceType: {record.get('adviceType')}")
print(f" - adviceName: {record.get('adviceName')}")
print(f" - categoryEnum: {record.get('categoryEnum')}")
print(
f" - contentJson: {record.get('contentJson', '')[:100] if record.get('contentJson') else 'None'}..."
)
print()
else:
print(f" 返回错误: {data.get('msg')}")
else:
print(f" 请求失败: {response.status_code}")
except Exception as e:
print(f" 请求异常: {e}")
print()
print("=" * 80)
print("诊断建议:")
print("=" * 80)
print()
print("如果手术医嘱未显示,可能原因:")
print(" 1. adviceType 仍为 3 (不是 4)")
print(" 2. adviceName 为空")
print(" 3. 前端过滤逻辑排除了该记录")
print(" 4. API返回了数据但前端未正确渲染")
print()

View File

@@ -0,0 +1,115 @@
import psycopg2
import sys
sys.stdout.reconfigure(encoding="utf-8")
conn = psycopg2.connect(
host="192.168.110.252",
port=15432,
database="postgresql",
user="postgresql",
password="Jchl1528",
)
cursor = conn.cursor()
cursor.execute("SET search_path TO hisdev, public")
print("检查SQL查询的列顺序...")
print()
cursor.execute("""
SELECT
3 AS advice_type, -- 0
'test-id' AS request_id, -- 1
'test-key' AS unique_key, -- 2
123 AS requester_id, -- 3
NOW() AS request_time, -- 4
'1' AS biz_request_flag, -- 5
'{}' AS content_json, -- 6
null AS skin_test_flag, -- 7
null AS inject_flag, -- 8
null AS group_id, -- 9
'test-name' AS advice_name, -- 10
'' AS volume, -- 11
'' AS lot_number, -- 12
1 AS quantity, -- 13
'' AS unit_code, -- 14
1 AS status_enum, -- 15
'' AS method_code, -- 16
'' AS rate_code, -- 17
NULL AS dose, -- 18
'' AS dose_unit_code, -- 19
'ci-id' AS charge_item_id, -- 20
100 AS total_price, -- 21
1 AS charge_status, -- 22
'pos-id' AS position_id, -- 23
'pos-name' AS position_name, -- 24
null AS dispense_per_duration, -- 25
1 AS part_percent, -- 26
'' AS condition_definition_name, -- 27
COALESCE(null, 2) AS therapyEnum, -- 28 <- 这里
99 AS sort_number, -- 29
null AS based_on_id -- 30
""")
row = cursor.fetchone()
print(f"therapyEnum 列索引: 28, 值: {row[28]}")
print()
# 现在用实际的SQL查询
cursor.execute("""
SELECT
3 AS advice_type,
T1.id AS request_id,
T1.id || '-3' AS unique_key,
T1.requester_id AS requester_id,
T1.create_time AS request_time,
CASE WHEN T1.requester_id = 1980296166230962178 THEN '1' ELSE '0' END AS biz_request_flag,
T1.content_json AS content_json,
null AS skin_test_flag,
null AS inject_flag,
null AS group_id,
COALESCE(T2.NAME, T1.content_json::jsonb->>'surgeryName') AS advice_name,
'' AS volume,
'' AS lot_number,
T1.quantity AS quantity,
T1.unit_code AS unit_code,
T1.status_enum AS status_enum,
'' AS method_code,
'' AS rate_code,
NULL AS dose,
'' AS dose_unit_code,
T3.id AS charge_item_id,
T3.total_price AS total_price,
T3.status_enum AS charge_status,
ao.id AS position_id,
ao.name AS position_name,
null AS dispense_per_duration,
1 AS part_percent,
'' AS condition_definition_name,
COALESCE(T1.therapy_enum, 2) AS therapyEnum,
99 AS sort_number,
T1.based_on_id AS based_on_id
FROM wor_service_request AS T1
LEFT JOIN wor_activity_definition AS T2
ON T2.ID = T1.activity_id AND T2.delete_flag = '0'
LEFT JOIN adm_charge_item AS T3 ON T3.service_id = T1.ID AND T3.delete_flag = '0' AND
T3.service_table = 'wor_service_request'
LEFT JOIN adm_organization AS ao ON ao.ID = T1.org_id AND ao.delete_flag = '0'
WHERE T1.delete_flag = '0' AND T1.generate_source_enum = 1
AND T1.parent_id IS NULL
AND T1.encounter_id = 2038823905749327873
AND T1.category_enum = 4
""")
row = cursor.fetchone()
if row:
print("实际查询结果:")
print(f" advice_name (索引10): {row[10]}")
print(f" therapyEnum (索引28): {row[28]}")
print(f" status_enum (索引15): {row[15]}")
else:
print("未找到记录")
cursor.close()
conn.close()

40
scripts/check_columns.py Normal file
View File

@@ -0,0 +1,40 @@
import psycopg2
import sys
sys.stdout.reconfigure(encoding="utf-8")
conn = psycopg2.connect(
host="192.168.110.252",
port=15432,
database="postgresql",
user="postgresql",
password="Jchl1528",
)
cursor = conn.cursor()
cursor.execute("SET search_path TO hisdev, public")
print("doc_request_form 表字段:")
cursor.execute("""
SELECT column_name
FROM information_schema.columns
WHERE table_schema = 'hisdev'
AND table_name = 'doc_request_form'
ORDER BY ordinal_position
""")
for row in cursor.fetchall():
print(f" {row[0]}")
print("\nwor_service_request 表字段:")
cursor.execute("""
SELECT column_name
FROM information_schema.columns
WHERE table_schema = 'hisdev'
AND table_name = 'wor_service_request'
ORDER BY ordinal_position
""")
for row in cursor.fetchall():
print(f" {row[0]}")
cursor.close()
conn.close()

63
scripts/check_db.py Normal file
View File

@@ -0,0 +1,63 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import psycopg2
import json
from datetime import datetime
DB_CONFIG = {
"host": "192.168.110.252",
"port": 15432,
"database": "postgresql",
"user": "postgresql",
"password": "Jchl1528",
"options": "-c search_path=hisdev",
}
def check_surgery():
conn = None
try:
print("Connecting to database...")
conn = psycopg2.connect(**DB_CONFIG)
cursor = conn.cursor()
print("Connected!\n")
# Query recent surgery advice
cursor.execute("""
SELECT
id,
content_json::jsonb->>'surgeryName' as surgery_name,
content_json::jsonb->>'surgeryCode' as surgery_code,
create_time
FROM wor_service_request
WHERE category_enum = 4
AND delete_flag = '0'
ORDER BY create_time DESC
LIMIT 3
""")
rows = cursor.fetchall()
print("=" * 60)
print("Surgery Advice Check")
print("=" * 60)
if not rows:
print("No surgery advice found!")
else:
for row in rows:
print(f"\nID: {row[0]}")
print(f"surgeryName: {row[1] if row[1] else 'EMPTY'}")
print(f"surgeryCode: {row[2] if row[2] else 'EMPTY'}")
print(f"create_time: {row[3]}")
cursor.close()
except Exception as e:
print(f"Error: {e}")
finally:
if conn:
conn.close()
if __name__ == "__main__":
check_surgery()

59
scripts/check_empty.py Normal file
View File

@@ -0,0 +1,59 @@
import psycopg2
DB_CONFIG = {
"host": "192.168.110.252",
"port": 15432,
"database": "postgresql",
"user": "postgresql",
"password": "Jchl1528",
"options": "-c search_path=hisdev",
}
def check():
conn = None
try:
conn = psycopg2.connect(**DB_CONFIG)
cursor = conn.cursor()
print("=" * 80)
print("Records WITHOUT surgeryName (need fix)")
print("=" * 80)
cursor.execute("""
SELECT
wsr.id,
wsr.activity_id,
wsr.create_time,
cs.surgery_name,
cs.surgery_code
FROM wor_service_request wsr
LEFT JOIN cli_surgery cs ON cs.id = wsr.activity_id
WHERE wsr.category_enum = 4
AND wsr.delete_flag = '0'
AND (wsr.content_json::jsonb->>'surgeryName' IS NULL OR wsr.content_json::jsonb->>'surgeryName' = '')
ORDER BY wsr.create_time DESC
""")
rows = cursor.fetchall()
print(f"\nTotal: {len(rows)} records\n")
for row in rows:
print(f"ID: {row[0]}")
print(f" activity_id: {row[1]}")
print(f" create_time: {row[2]}")
print(f" cli_surgery.surgery_name: {'[HAS]' if row[3] else '[NULL]'}")
print(f" cli_surgery.surgery_code: {'[HAS]' if row[4] else '[NULL]'}")
print()
cursor.close()
except Exception as e:
print(f"Error: {e}")
finally:
if conn:
conn.close()
if __name__ == "__main__":
check()

246
scripts/check_filter.py Normal file
View File

@@ -0,0 +1,246 @@
import psycopg2
import json
import sys
sys.stdout.reconfigure(encoding="utf-8")
conn = psycopg2.connect(
host="192.168.110.252",
port=15432,
database="postgresql",
user="postgresql",
password="Jchl1528",
)
cursor = conn.cursor()
cursor.execute("SET search_path TO hisdev, public")
print("=" * 80)
print("检查前端过滤条件")
print("=" * 80)
print()
encounter_id = 2038823905749327873
practitioner_id = 1980296166230962178
# 查询所有数据
cursor.execute(
"""
(SELECT 1 AS advice_type,
T1.id AS request_id,
T1.id || '-1' AS unique_key,
T1.practitioner_id AS requester_id,
T1.create_time AS request_time,
CASE WHEN T1.practitioner_id = %s THEN '1' ELSE '0' END AS biz_request_flag,
T1.content_json AS content_json,
T1.skin_test_flag AS skin_test_flag,
T1.infusion_flag AS inject_flag,
T1.group_id AS group_id,
T2.NAME AS advice_name,
T3.total_volume AS volume,
T1.lot_number AS lot_number,
T1.quantity AS quantity,
T1.unit_code AS unit_code,
T1.status_enum AS status_enum,
T1.method_code AS method_code,
T1.rate_code AS rate_code,
T1.dose AS dose,
T1.dose_unit_code AS dose_unit_code,
T4.id AS charge_item_id,
T4.total_price AS total_price,
T4.status_enum AS charge_status,
al.id AS position_id,
al.name AS position_name,
T1.dispense_per_duration AS dispense_per_duration,
T2.part_percent AS part_percent,
ccd.name AS condition_definition_name,
T1.therapy_enum AS therapyEnum,
T1.sort_number AS sort_number,
T1.based_on_id AS based_on_id
FROM med_medication_request AS T1
LEFT JOIN med_medication_definition AS T2 ON T2.ID = T1.medication_id
AND T2.delete_flag = '0'
LEFT JOIN med_medication AS T3 ON T3.medication_def_id = T2.ID
AND T3.delete_flag = '0'
LEFT JOIN adm_charge_item AS T4 ON T4.service_id = T1.ID AND T4.delete_flag = '0' AND
T4.service_table = 'med_medication_request'
LEFT JOIN adm_location AS al ON al.ID = T1.perform_location AND al.delete_flag = '0'
LEFT JOIN cli_condition AS cc ON cc.id = T1.condition_id AND cc.delete_flag = '0'
LEFT JOIN cli_condition_definition AS ccd ON ccd.id = cc.definition_id
WHERE T1.delete_flag = '0' AND T1.tcm_flag = 0 AND T1.generate_source_enum = 1
AND T1.encounter_id = %s
AND T1.refund_medicine_id IS NULL)
UNION ALL
(SELECT 2 AS advice_type,
T1.id AS request_id,
T1.id || '-2' AS unique_key,
T1.requester_id AS requester_id,
T1.create_time AS request_time,
CASE WHEN T1.requester_id = %s THEN '1' ELSE '0' END AS biz_request_flag,
T1.content_json AS content_json,
null AS skin_test_flag,
null AS inject_flag,
null AS group_id,
T2.NAME AS advice_name,
T2.SIZE AS volume,
T1.lot_number AS lot_number,
T1.quantity AS quantity,
T1.unit_code AS unit_code,
T1.status_enum AS status_enum,
'' AS method_code,
T1.rate_code AS rate_code,
NULL AS dose,
'' AS dose_unit_code,
T3.id AS charge_item_id,
T3.total_price AS total_price,
T3.status_enum AS charge_status,
al.id AS position_id,
al.name AS position_name,
null AS dispense_per_duration,
T2.part_percent AS part_percent,
'' AS condition_definition_name,
2 AS therapyEnum,
99 AS sort_number,
T1.based_on_id AS based_on_id
FROM wor_device_request AS T1
LEFT JOIN adm_device_definition AS T2 ON T2.ID = T1.device_def_id
AND T2.delete_flag = '0'
LEFT JOIN adm_charge_item AS T3
ON T3.service_id = T1.ID AND T3.delete_flag = '0' AND
T3.service_table = 'wor_device_request'
LEFT JOIN adm_location AS al ON al.ID = T1.perform_location AND al.delete_flag = '0'
WHERE T1.delete_flag = '0' AND T1.generate_source_enum = 1
AND T1.encounter_id = %s
AND T1.refund_device_id IS NULL)
UNION ALL
(SELECT 3 AS advice_type,
T1.id AS request_id,
T1.id || '-3' AS unique_key,
T1.requester_id AS requester_id,
T1.create_time AS request_time,
CASE WHEN T1.requester_id = %s THEN '1' ELSE '0' END AS biz_request_flag,
T1.content_json AS content_json,
null AS skin_test_flag,
null AS inject_flag,
null AS group_id,
COALESCE(T2.NAME, T1.content_json::jsonb->>'surgeryName') AS advice_name,
'' AS volume,
'' AS lot_number,
T1.quantity AS quantity,
T1.unit_code AS unit_code,
T1.status_enum AS status_enum,
'' AS method_code,
'' AS rate_code,
NULL AS dose,
'' AS dose_unit_code,
T3.id AS charge_item_id,
T3.total_price AS total_price,
T3.status_enum AS charge_status,
ao.id AS position_id,
ao.name AS position_name,
null AS dispense_per_duration,
1 AS part_percent,
'' AS condition_definition_name,
T1.therapy_enum AS therapyEnum,
99 AS sort_number,
T1.based_on_id AS based_on_id
FROM wor_service_request AS T1
LEFT JOIN wor_activity_definition AS T2
ON T2.ID = T1.activity_id
AND T2.delete_flag = '0'
LEFT JOIN adm_charge_item AS T3 ON T3.service_id = T1.ID AND T3.delete_flag = '0' AND
T3.service_table = 'wor_service_request'
LEFT JOIN adm_organization AS ao ON ao.ID = T1.org_id AND ao.delete_flag = '0'
WHERE T1.delete_flag = '0' AND T1.generate_source_enum = 1
AND T1.parent_id IS NULL
AND T1.encounter_id = %s)
ORDER BY status_enum
""",
(
practitioner_id,
encounter_id,
practitioner_id,
encounter_id,
practitioner_id,
encounter_id,
),
)
rows = cursor.fetchall()
print(f"查询到 {len(rows)} 条记录")
print()
# 模拟前端过滤
print("模拟前端过滤逻辑:")
print()
# 前端过滤条件
therapy_enum_filter = "" # 不过滤
order_class_code_filter = "" # 不过滤(全部)
order_status_filter = "" # 不过滤
filtered_count = 0
for i, row in enumerate(rows):
advice_type = row[0] # SQL中的 advice_type
request_id = row[1]
unique_key = row[2]
advice_name = row[10]
therapy_enum = row[25]
status_enum = row[14]
# 模拟前端的 adviceType 赋值
# 从前端代码看adviceType 应该等于 SQL 的 advice_type
item_advice_type = advice_type # 1=药品, 2=耗材, 3=项目
# 模拟过滤
therapy_match = not therapy_enum_filter or str(therapy_enum_filter) == str(
therapy_enum
)
class_match = not order_class_code_filter or str(order_class_code_filter) == str(
item_advice_type
)
status_match = not order_status_filter or (
str(order_status_filter) == str(status_enum) and request_id
)
if therapy_match and class_match and status_match:
filtered_count += 1
type_names = {1: "药品", 2: "耗材", 3: "诊疗/手术"}
type_name = type_names.get(advice_type, f"类型{advice_type}")
print(
f"✓ 第{i + 1}条通过过滤: advice_type={advice_type}({type_name}), advice_name={advice_name}, therapyEnum={therapy_enum}, status={status_enum}"
)
print()
print(f"过滤后剩余: {filtered_count}")
print()
# 检查手术医嘱
cursor.execute(
"""
SELECT
id,
category_enum,
COALESCE(
(SELECT name FROM wor_activity_definition WHERE id = sr.activity_id AND delete_flag = '0'),
sr.content_json::jsonb->>'surgeryName'
) as advice_name,
therapy_enum,
status_enum
FROM wor_service_request sr
WHERE category_enum = 4
AND delete_flag = '0'
AND encounter_id = %s
""",
(encounter_id,),
)
print("手术医嘱详情:")
for row in cursor.fetchall():
print(
f" ID: {row[0]}, category_enum: {row[1]}(手术), advice_name: {row[2]}, therapy_enum: {row[3]}, status: {row[4]}"
)
cursor.close()
conn.close()

View File

@@ -0,0 +1,113 @@
import psycopg2
import json
DB_CONFIG = {
"host": "192.168.110.252",
"port": 15432,
"database": "postgresql",
"user": "postgresql",
"password": "Jchl1528",
"options": "-c search_path=hisdev",
}
def check_new_records():
conn = None
try:
print("Connecting to database...")
conn = psycopg2.connect(**DB_CONFIG)
cursor = conn.cursor()
print("Connected!\n")
print("=" * 80)
print("New Surgery Records Check")
print("=" * 80)
# Check specific IDs
ids = ["2039583488323280897", "2039583488231006210"]
for id in ids:
cursor.execute(
"""
SELECT
wsr.id,
wsr.category_enum,
wsr.activity_id,
wsr.content_json::jsonb->>'surgeryName' as surgery_name,
wsr.content_json::jsonb->>'surgeryCode' as surgery_code,
wsr.content_json as full_json,
wsr.create_time,
cs.surgery_name as cli_surgery_name,
cs.surgery_code as cli_surgery_code
FROM wor_service_request wsr
LEFT JOIN cli_surgery cs ON cs.id = wsr.activity_id
WHERE wsr.id = %s
""",
(id,),
)
row = cursor.fetchone()
if row:
print(f"\nRecord ID: {row[0]}")
print(f" category_enum: {row[1]}")
print(f" activity_id: {row[2]}")
print(
f" surgeryName from content_json: {row[3] if row[3] else 'EMPTY'}"
)
print(
f" surgeryCode from content_json: {row[4] if row[4] else 'EMPTY'}"
)
print(f" cli_surgery_name: {row[7] if row[7] else 'N/A'}")
print(f" create_time: {row[6]}")
if row[5]:
try:
content = json.loads(row[5])
print(f" Full content_json keys: {list(content.keys())}")
except:
print(f" Raw content_json: {row[5][:100]}")
else:
print(f"\nRecord {id} not found!")
# Check most recent 3 surgery records
print("\n" + "=" * 80)
print("Most Recent 3 Surgery Records")
print("=" * 80)
cursor.execute("""
SELECT
wsr.id,
wsr.category_enum,
wsr.activity_id,
wsr.content_json::jsonb->>'surgeryName' as surgery_name,
wsr.content_json::jsonb->>'surgeryCode' as surgery_code,
wsr.create_time,
cs.surgery_name as cli_surgery_name
FROM wor_service_request wsr
LEFT JOIN cli_surgery cs ON cs.id = wsr.activity_id
WHERE wsr.category_enum = 4
AND wsr.delete_flag = '0'
ORDER BY wsr.create_time DESC
LIMIT 3
""")
rows = cursor.fetchall()
for row in rows:
print(f"\nID: {row[0]}")
print(f" surgeryName: {row[3] if row[3] else 'EMPTY'}")
print(f" surgeryCode: {row[4] if row[4] else 'EMPTY'}")
print(f" cli_surgery_name: {row[6] if row[6] else 'N/A'}")
print(f" create_time: {row[5]}")
cursor.close()
except Exception as e:
print(f"Error: {e}")
import traceback
traceback.print_exc()
finally:
if conn:
conn.close()
if __name__ == "__main__":
check_new_records()

View File

@@ -0,0 +1,105 @@
import psycopg2
import sys
sys.stdout.reconfigure(encoding="utf-8")
conn = psycopg2.connect(
host="192.168.110.252",
port=15432,
database="postgresql",
user="postgresql",
password="Jchl1528",
)
cursor = conn.cursor()
cursor.execute("SET search_path TO hisdev, public")
print("=" * 80)
print("直接检查 ServiceRequest 数据")
print("=" * 80)
print()
# 直接查询表数据
cursor.execute("""
SELECT
id,
category_enum,
content_json,
activity_id
FROM wor_service_request
WHERE encounter_id = 2038823905749327873
AND delete_flag = '0'
AND parent_id IS NULL
""")
print("原始数据:")
for row in cursor.fetchall():
print(f" ID: {row[0]}")
print(f" category_enum: {row[1]}")
print(f" activity_id: {row[3]}")
if row[2]:
import json
try:
content = json.loads(row[2]) if isinstance(row[2], str) else row[2]
print(f" content_json.surgeryName: {content.get('surgeryName', 'N/A')}")
except:
print(f" content_json: {row[2][:100]}")
print()
print()
print("=" * 80)
print("测试 COALESCE 语法")
print("=" * 80)
print()
# 测试 COALESCE 语法
cursor.execute("""
SELECT
id,
COALESCE(category_enum, 3) as advice_type,
COALESCE(content_json::jsonb->>'surgeryName', '默认值') as surgery_name
FROM wor_service_request
WHERE category_enum = 4
AND delete_flag = '0'
LIMIT 1
""")
row = cursor.fetchone()
if row:
print(f"COALESCE 测试:")
print(f" ID: {row[0]}")
print(f" advice_type: {row[1]}")
print(f" surgery_name: {row[2]}")
else:
print("未找到记录")
print()
print("=" * 80)
print("检查 activity_definition 关联")
print("=" * 80)
print()
# 检查 activity_definition
cursor.execute("""
SELECT
sr.id,
sr.activity_id,
ad.name as activity_name,
COALESCE(ad.name, sr.content_json::jsonb->>'surgeryName') as coalesce_name
FROM wor_service_request sr
LEFT JOIN wor_activity_definition ad ON ad.id = sr.activity_id AND ad.delete_flag = '0'
WHERE sr.category_enum = 4
AND sr.delete_flag = '0'
AND sr.encounter_id = 2038823905749327873
""")
for row in cursor.fetchall():
print(f" ServiceRequest ID: {row[0]}")
print(f" activity_id: {row[1]}")
print(f" activity_name: {row[2]}")
print(f" coalesce_name: {row[3]}")
print()
cursor.close()
conn.close()

View File

@@ -0,0 +1,160 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
诊断脚本:检查手术医嘱是否正确保存和显示
"""
import psycopg2
import json
from datetime import datetime
# 数据库配置
DB_CONFIG = {
"host": "localhost",
"port": 5432,
"database": "his",
"user": "postgres",
"password": "postgres",
}
def check_surgery_advice():
"""检查最近保存的手术医嘱"""
try:
conn = psycopg2.connect(**DB_CONFIG)
cursor = conn.cursor()
print("=" * 80)
print("手术医嘱诊断报告")
print("=" * 80)
print(f"查询时间: {datetime.now()}")
print()
# 1. 查询最近的手术医嘱category_enum = 4
print("1. 查询最近保存的手术医嘱:")
print("-" * 80)
cursor.execute("""
SELECT
id,
category_enum,
activity_id,
content_json,
patient_id,
encounter_id,
create_time
FROM wor_service_request
WHERE category_enum = 4
AND delete_flag = '0'
ORDER BY create_time DESC
LIMIT 5
""")
rows = cursor.fetchall()
if not rows:
print("⚠️ 没有找到手术医嘱记录category_enum = 4")
else:
for row in rows:
print(f"\n手术医嘱 ID: {row[0]}")
print(f" category_enum: {row[1]}")
print(f" activity_id: {row[2]}")
print(f" patient_id: {row[4]}")
print(f" encounter_id: {row[5]}")
print(f" create_time: {row[6]}")
# 解析 content_json
try:
content = json.loads(row[3]) if row[3] else {}
surgery_name = content.get("surgeryName", "NOT FOUND")
surgery_code = content.get("surgeryCode", "NOT FOUND")
print(f" content_json.surgeryName: {surgery_name}")
print(f" content_json.surgeryCode: {surgery_code}")
if surgery_name == "NOT FOUND" or not surgery_name:
print(" ❌ 警告: content_json 中没有 surgeryName")
else:
print(" ✅ surgeryName 已正确保存")
except Exception as e:
print(f" ❌ 解析 content_json 失败: {e}")
print(f" 原始内容: {row[3]}")
print("\n" + "=" * 80)
# 2. 测试 SQL 查询是否能正确获取 advice_name
print("\n2. 测试 SQL 查询是否能正确获取手术名称:")
print("-" * 80)
cursor.execute("""
SELECT
wsr.id,
COALESCE(wad.NAME, wsr.content_json::jsonb->>'surgeryName', wsr.content_json::jsonb->>'adviceName') AS advice_name,
wsr.content_json::jsonb->>'surgeryName' AS surgery_name_from_json,
wad.NAME AS activity_name,
wsr.category_enum
FROM wor_service_request wsr
LEFT JOIN wor_activity_definition wad ON wad.ID = wsr.activity_id AND wad.delete_flag = '0'
WHERE wsr.category_enum = 4
AND wsr.delete_flag = '0'
ORDER BY wsr.create_time DESC
LIMIT 5
""")
rows = cursor.fetchall()
if not rows:
print("⚠️ 没有找到手术医嘱记录")
else:
for row in rows:
print(f"\n手术医嘱 ID: {row[0]}")
print(f" COALESCE advice_name: {row[1]}")
print(f" surgeryName from JSON: {row[2]}")
print(f" activity_definition name: {row[3]}")
print(f" category_enum: {row[4]}")
if not row[1]:
print(" ❌ 警告: advice_name 为空!")
else:
print(" ✅ advice_name 可以正确获取")
print("\n" + "=" * 80)
# 3. 检查是否存在 activity_id 对应的 wor_activity_definition
print("\n3. 检查手术医嘱的 activity_id 关联:")
print("-" * 80)
cursor.execute("""
SELECT
wsr.id,
wsr.activity_id,
wad.id AS def_id,
wad.name AS def_name,
CASE WHEN wad.id IS NULL THEN 'MISSING' ELSE 'OK' END AS status
FROM wor_service_request wsr
LEFT JOIN wor_activity_definition wad ON wad.ID = wsr.activity_id
WHERE wsr.category_enum = 4
AND wsr.delete_flag = '0'
ORDER BY wsr.create_time DESC
LIMIT 5
""")
rows = cursor.fetchall()
for row in rows:
status_icon = "" if row[4] == "OK" else ""
print(
f"{status_icon} service_request.id={row[0]}, activity_id={row[1]}, definition={row[3] or 'NULL'}"
)
print("\n" + "=" * 80)
print("诊断完成")
print("=" * 80)
cursor.close()
conn.close()
except Exception as e:
print(f"❌ 诊断失败: {e}")
import traceback
traceback.print_exc()
if __name__ == "__main__":
check_surgery_advice()

117
scripts/check_surgery_db.py Normal file
View File

@@ -0,0 +1,117 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import psycopg2
import json
from datetime import datetime
DB_CONFIG = {
"host": "192.168.110.252",
"port": 15432,
"database": "postgresql",
"user": "postgresql",
"password": "Jchl1528",
"options": "-c search_path=hisdev",
}
def check_surgery_advice():
conn = None
try:
print("Connecting to database...")
conn = psycopg2.connect(**DB_CONFIG)
cursor = conn.cursor()
print("Connected!\n")
print("=" * 80)
print("Surgery Advice Diagnostic Report")
print("=" * 80)
print(f"Time: {datetime.now()}")
print()
# 1. Query recent surgery advice
print("1. Recent surgery advice records:")
print("-" * 80)
cursor.execute("""
SELECT
id,
category_enum,
activity_id,
content_json::jsonb->>'surgeryName' as surgery_name,
content_json::jsonb->>'surgeryCode' as surgery_code,
create_time
FROM wor_service_request
WHERE category_enum = 4
AND delete_flag = '0'
ORDER BY create_time DESC
LIMIT 5
""")
rows = cursor.fetchall()
if not rows:
print("No surgery advice found (category_enum = 4)")
else:
for row in rows:
print(f"\nID: {row[0]}")
print(f" category_enum: {row[1]}")
print(f" activity_id: {row[2]}")
print(f" surgeryName from JSON: {row[3]}")
print(f" surgeryCode from JSON: {row[4]}")
print(f" create_time: {row[5]}")
if not row[3]:
print(" WARNING: surgeryName is EMPTY!")
else:
print(" OK: surgeryName exists")
print("\n" + "=" * 80)
# 2. Test SQL COALESCE query
print("\n2. Testing SQL COALESCE query:")
print("-" * 80)
cursor.execute("""
SELECT
wsr.id,
COALESCE(wad.NAME, wsr.content_json::jsonb->>'surgeryName', wsr.content_json::jsonb->>'adviceName') AS advice_name,
wsr.content_json::jsonb->>'surgeryName' AS surgery_name_from_json,
wad.NAME AS activity_name,
wsr.activity_id
FROM wor_service_request wsr
LEFT JOIN wor_activity_definition wad ON wad.ID = wsr.activity_id AND wad.delete_flag = '0'
WHERE wsr.category_enum = 4
AND wsr.delete_flag = '0'
ORDER BY wsr.create_time DESC
LIMIT 5
""")
rows = cursor.fetchall()
for row in rows:
print(f"\nID: {row[0]}")
print(f" COALESCE advice_name: {row[1]}")
print(f" surgeryName from JSON: {row[2]}")
print(f" activity_definition name: {row[3]}")
print(f" activity_id: {row[4]}")
if not row[1]:
print(" WARNING: advice_name is EMPTY!")
else:
print(" OK: advice_name exists")
print("\n" + "=" * 80)
print("Diagnostic complete")
print("=" * 80)
cursor.close()
except Exception as e:
print(f"ERROR: {e}")
import traceback
traceback.print_exc()
finally:
if conn:
conn.close()
if __name__ == "__main__":
check_surgery_advice()

View File

@@ -0,0 +1,83 @@
import psycopg2
import sys
sys.stdout.reconfigure(encoding="utf-8")
conn = psycopg2.connect(
host="192.168.110.252",
port=15432,
database="postgresql",
user="postgresql",
password="Jchl1528",
)
cursor = conn.cursor()
cursor.execute("SET search_path TO hisdev, public")
print("=" * 80)
print("检查手术医嘱的详细信息")
print("=" * 80)
print()
# 查询手术医嘱的详细信息
cursor.execute("""
SELECT
id,
prescription_no,
category_enum,
status_enum,
patient_id,
encounter_id,
activity_id,
generate_source_enum,
content_json,
create_time
FROM wor_service_request
WHERE prescription_no = 'OP202603311433'
AND delete_flag = '0'
""")
row = cursor.fetchone()
if row:
print("手术医嘱详细信息:")
print(f" ID: {row[0]}")
print(f" 单号: {row[1]}")
print(f" category_enum: {row[2]} (4=手术)")
print(f" status_enum: {row[3]} (1=待签发)")
print(f" patient_id: {row[4]}")
print(f" encounter_id: {row[5]}")
print(f" activity_id: {row[6]}")
print(f" generate_source_enum: {row[7]} (1=医生处方)")
print(f" content_json: {row[8]}")
print(f" create_time: {row[9]}")
else:
print("未找到手术医嘱")
print()
print("=" * 80)
# 查询该就诊的所有医嘱
cursor.execute("""
SELECT
id,
prescription_no,
category_enum,
status_enum,
activity_id
FROM wor_service_request
WHERE encounter_id = 2038823905749327873
AND delete_flag = '0'
ORDER BY category_enum, create_time DESC
""")
rows = cursor.fetchall()
print(f"就诊ID 2038823905749327873 的所有医嘱(共{len(rows)}条):")
for row in rows:
cat_names = {1: "西药", 2: "耗材", 3: "诊疗", 4: "手术"}
cat_name = cat_names.get(row[2], f"类型{row[2]}")
print(
f" ID: {row[0]}, 单号: {row[1]}, 类型: {cat_name}({row[2]}), 状态: {row[3]}, activity_id: {row[4]}"
)
cursor.close()
conn.close()

View File

@@ -0,0 +1,53 @@
import psycopg2
import sys
sys.stdout.reconfigure(encoding="utf-8")
conn = psycopg2.connect(
host="192.168.110.252",
port=15432,
database="postgresql",
user="postgresql",
password="Jchl1528",
)
cursor = conn.cursor()
cursor.execute("SET search_path TO hisdev, public")
print("wor_service_request therapy相关列:")
cursor.execute("""
SELECT column_name
FROM information_schema.columns
WHERE table_schema = 'hisdev'
AND table_name = 'wor_service_request'
AND column_name LIKE '%therapy%'
""")
for row in cursor.fetchall():
print(f" {row[0]}")
print()
print("med_medication_request therapy相关列:")
cursor.execute("""
SELECT column_name
FROM information_schema.columns
WHERE table_schema = 'hisdev'
AND table_name = 'med_medication_request'
AND column_name LIKE '%therapy%'
""")
for row in cursor.fetchall():
print(f" {row[0]}")
print()
print("wor_device_request therapy相关列:")
cursor.execute("""
SELECT column_name
FROM information_schema.columns
WHERE table_schema = 'hisdev'
AND table_name = 'wor_device_request'
AND column_name LIKE '%therapy%'
""")
for row in cursor.fetchall():
print(f" {row[0]}")
cursor.close()
conn.close()

View File

@@ -0,0 +1,111 @@
import psycopg2
import json
DB_CONFIG = {
"host": "192.168.110.252",
"port": 15432,
"database": "postgresql",
"user": "postgresql",
"password": "Jchl1528",
"options": "-c search_path=hisdev",
}
def diagnose():
conn = None
try:
conn = psycopg2.connect(**DB_CONFIG)
cursor = conn.cursor()
print("=" * 80)
print("Diagnosis: Surgery Data Flow")
print("=" * 80)
# 1. Find latest cli_surgery records
print("\n1. Latest cli_surgery records:")
print("-" * 80)
cursor.execute("""
SELECT id, surgery_name, surgery_code, surgery_no, create_time
FROM cli_surgery
WHERE delete_flag = '0'
ORDER BY create_time DESC
LIMIT 3
""")
rows = cursor.fetchall()
for row in rows:
print(f"ID: {row[0]}")
print(f" surgery_name: {'[HAS VALUE]' if row[1] else '[NULL/EMPTY]'}")
print(f" surgery_code: {'[HAS VALUE]' if row[2] else '[NULL/EMPTY]'}")
# 2. Check corresponding wor_service_request
print("\n2. Check wor_service_request:")
print("-" * 80)
for cli_id, cli_name, cli_code, cli_no, cli_time in rows:
cursor.execute(
"""
SELECT
wsr.id,
wsr.content_json::jsonb->>'surgeryName' as surgery_name_json,
wsr.content_json::jsonb->>'surgeryCode' as surgery_code_json,
wsr.create_time
FROM wor_service_request wsr
WHERE wsr.activity_id = %s
AND wsr.category_enum = 4
AND wsr.delete_flag = '0'
""",
(cli_id,),
)
wsr_row = cursor.fetchone()
if wsr_row:
print(f"cli_surgery ID: {cli_id}")
print(
f" cli_surgery surgery_name: {'[HAS VALUE]' if cli_name else '[NULL]'}"
)
print(
f" cli_surgery surgery_code: {'[HAS VALUE]' if cli_code else '[NULL]'}"
)
print(f" wor_service_request ID: {wsr_row[0]}")
print(
f" wor_service_request surgeryName: {'[HAS VALUE]' if wsr_row[1] else '[NULL/EMPTY]'}"
)
print(
f" wor_service_request surgeryCode: {'[HAS VALUE]' if wsr_row[2] else '[NULL/EMPTY]'}"
)
if not wsr_row[1] and cli_name:
print(
f" *** PROBLEM: cli_surgery has name but wor_service_request does NOT! ***"
)
else:
print(
f"cli_surgery ID: {cli_id} - No matching wor_service_request found!"
)
# 3. Statistics
print("\n3. Statistics:")
print("-" * 80)
cursor.execute("""
SELECT COUNT(*)
FROM wor_service_request
WHERE category_enum = 4
AND delete_flag = '0'
AND (content_json::jsonb->>'surgeryName' IS NULL OR content_json::jsonb->>'surgeryName' = '')
""")
count = cursor.fetchone()[0]
print(f" Surgery advice without surgeryName: {count}")
cursor.close()
except Exception as e:
print(f"Error: {e}")
finally:
if conn:
conn.close()
if __name__ == "__main__":
diagnose()

182
scripts/execute_repair.py Normal file
View File

@@ -0,0 +1,182 @@
import psycopg2
import json
import sys
# 设置UTF-8编码
sys.stdout.reconfigure(encoding="utf-8")
# 数据库连接
conn = psycopg2.connect(
host="192.168.110.252",
port=15432,
database="postgresql",
user="postgresql",
password="Jchl1528",
)
cursor = conn.cursor()
# 设置schema
cursor.execute("SET search_path TO hisdev, public")
conn.commit()
# 1. 查询需要修复的记录数
print("=" * 60)
print("Bug #318 历史数据修复")
print("=" * 60)
print()
print("步骤1: 查询需要修复的手术申请单...")
cursor.execute("""
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
""")
count = cursor.fetchone()[0]
print(f"✓ 发现 {count} 条需要修复的手术申请单")
print()
if count == 0:
print("没有需要修复的数据")
else:
# 2. 查看部分记录详情
print("步骤2: 查看部分记录详情...")
cursor.execute("""
SELECT rf.id, rf.prescription_no, rf.encounter_id, rf.patient_id, rf.create_time
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
LIMIT 5
""")
rows = cursor.fetchall()
for row in rows:
print(
f" ID: {row[0]}, 单号: {row[1]}, 就诊: {row[2]}, 患者: {row[3]}, 时间: {row[4]}"
)
print()
# 3. 执行修复 - 生成ServiceRequest
print("步骤3: 生成手术医嘱ServiceRequest...")
cursor.execute("""
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
)
SELECT
LPAD(FLOOR(RANDOM() * 10000)::TEXT, 4, '0'),
rf.prescription_no,
1, 1, 2, 1, '', 4,
rf.patient_id, rf.requester_id, rf.encounter_id, rf.create_time,
rf.org_id, rf.desc_json, '0', rf.create_time, rf.requester_id, 1
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
RETURNING id, prescription_no
""")
new_requests = cursor.fetchall()
print(f"✓ 成功生成 {len(new_requests)} 条手术医嘱")
print()
# 4. 生成ChargeItem
print("步骤4: 生成收费项目ChargeItem...")
# 获取刚插入的ServiceRequest
prescription_nos = [r[1] for r in new_requests]
if prescription_nos:
cursor.execute(
"""
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
)
SELECT
'CI' || sr.bus_no, 1, 1, sr.patient_id, 3, sr.encounter_id,
sr.requester_id, sr.create_time, 'wor_service_request', sr.id,
'wor_activity_definition', sr.org_id, 1, '',
COALESCE((sr.content_json::jsonb->>'surgeryFee')::numeric, 0),
COALESCE((sr.content_json::jsonb->>'surgeryFee')::numeric, 0),
'0', sr.create_time, sr.requester_id, 1
FROM wor_service_request sr
WHERE sr.prescription_no = ANY(%s)
AND sr.category_enum = 4
AND sr.delete_flag = '0'
""",
(prescription_nos,),
)
# 麻醉费用
cursor.execute(
"""
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
)
SELECT
'CI' || sr.bus_no || '_A', 1, 1, sr.patient_id, 3, sr.encounter_id,
sr.requester_id, sr.create_time, 'wor_service_request', sr.id,
'wor_activity_definition', sr.org_id, 1, '',
(sr.content_json::jsonb->>'anesthesiaFee')::numeric,
(sr.content_json::jsonb->>'anesthesiaFee')::numeric,
'0', sr.create_time, sr.requester_id, 1
FROM wor_service_request sr
WHERE sr.prescription_no = ANY(%s)
AND sr.category_enum = 4
AND sr.delete_flag = '0'
AND sr.content_json::jsonb->>'anesthesiaFee' IS NOT NULL
AND (sr.content_json::jsonb->>'anesthesiaFee')::numeric > 0
""",
(prescription_nos,),
)
print(f"✓ 成功生成收费项目")
print()
# 5. 验证结果
print("步骤5: 验证修复结果...")
cursor.execute("""
SELECT COUNT(*) FROM wor_service_request
WHERE category_enum = 4 AND delete_flag = '0'
""")
service_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_count = cursor.fetchone()[0]
print(f"✓ 手术医嘱总数: {service_count}")
print(f"✓ 手术收费项目总数: {charge_count}")
print()
# 提交事务
conn.commit()
print("=" * 60)
print("✓ 修复完成!")
print("=" * 60)
cursor.close()
conn.close()

271
scripts/final_check.py Normal file
View File

@@ -0,0 +1,271 @@
import psycopg2
import json
import sys
sys.stdout.reconfigure(encoding="utf-8")
conn = psycopg2.connect(
host="192.168.110.252",
port=15432,
database="postgresql",
user="postgresql",
password="Jchl1528",
)
cursor = conn.cursor()
cursor.execute("SET search_path TO hisdev, public")
print("=" * 80)
print("检查手术医嘱的完整数据")
print("=" * 80)
print()
# 检查手术医嘱的所有字段
cursor.execute("""
SELECT
sr.id,
sr.prescription_no,
sr.category_enum,
sr.status_enum,
sr.therapy_enum,
sr.patient_id,
sr.encounter_id,
sr.requester_id,
sr.activity_id,
sr.quantity,
sr.unit_code,
sr.content_json,
sr.generate_source_enum,
sr.delete_flag,
sr.parent_id,
sr.create_time
FROM wor_service_request sr
WHERE sr.category_enum = 4
AND sr.delete_flag = '0'
AND sr.encounter_id = 2038823905749327873
""")
rows = cursor.fetchall()
print(f"手术医嘱数量: {len(rows)}")
print()
for row in rows:
print(f"ID: {row[0]}")
print(f"单号: {row[1]}")
print(f"category_enum: {row[2]} (4=手术)")
print(f"status_enum: {row[3]} (1=待签发)")
print(f"therapy_enum: {row[4]}")
print(f"patient_id: {row[5]}")
print(f"encounter_id: {row[6]}")
print(f"requester_id: {row[7]}")
print(f"activity_id: {row[8]}")
print(f"quantity: {row[9]}")
print(f"unit_code: {row[10]}")
print(f"content_json: {row[11][:100] if row[11] else 'None'}...")
print(f"generate_source_enum: {row[12]}")
print(f"delete_flag: {row[13]}")
print(f"parent_id: {row[14]}")
print(f"create_time: {row[15]}")
print("-" * 80)
print()
# 检查是否有parent_id不为null的记录子医嘱
print("检查是否有子医嘱parent_id不为null")
cursor.execute("""
SELECT COUNT(*)
FROM wor_service_request sr
WHERE sr.encounter_id = 2038823905749327873
AND sr.parent_id IS NOT NULL
AND sr.delete_flag = '0'
""")
parent_count = cursor.fetchone()[0]
print(f"子医嘱数量: {parent_count}")
print()
# 检查SQL查询返回的完整数据模拟getRegRequestBaseInfo
print("=" * 80)
print("模拟完整的API查询包含所有UNION")
print("=" * 80)
print()
practitioner_id = 1980296166230962178
encounter_id = 2038823905749327873
# 使用完整的SQL查询包含COALESCE修复
cursor.execute(
"""
(SELECT 1 AS advice_type,
T1.id AS request_id,
T1.id || '-1' AS unique_key,
T1.practitioner_id AS requester_id,
T1.create_time AS request_time,
CASE WHEN T1.practitioner_id = %s THEN '1' ELSE '0' END AS biz_request_flag,
T1.content_json AS content_json,
T1.skin_test_flag AS skin_test_flag,
T1.infusion_flag AS inject_flag,
T1.group_id AS group_id,
T2.NAME AS advice_name,
T3.total_volume AS volume,
T1.lot_number AS lot_number,
T1.quantity AS quantity,
T1.unit_code AS unit_code,
T1.status_enum AS status_enum,
T1.method_code AS method_code,
T1.rate_code AS rate_code,
T1.dose AS dose,
T1.dose_unit_code AS dose_unit_code,
T4.id AS charge_item_id,
T4.total_price AS total_price,
T4.status_enum AS charge_status,
al.id AS position_id,
al.name AS position_name,
T1.dispense_per_duration AS dispense_per_duration,
T2.part_percent AS part_percent,
ccd.name AS condition_definition_name,
COALESCE(T1.therapy_enum, 1) AS therapyEnum,
T1.sort_number AS sort_number,
T1.based_on_id AS based_on_id
FROM med_medication_request AS T1
LEFT JOIN med_medication_definition AS T2 ON T2.ID = T1.medication_id
AND T2.delete_flag = '0'
LEFT JOIN med_medication AS T3 ON T3.medication_def_id = T2.ID
AND T3.delete_flag = '0'
LEFT JOIN adm_charge_item AS T4 ON T4.service_id = T1.ID AND T4.delete_flag = '0' AND
T4.service_table = 'med_medication_request'
LEFT JOIN adm_location AS al ON al.ID = T1.perform_location AND al.delete_flag = '0'
LEFT JOIN cli_condition AS cc ON cc.id = T1.condition_id AND cc.delete_flag = '0'
LEFT JOIN cli_condition_definition AS ccd ON ccd.id = cc.definition_id
WHERE T1.delete_flag = '0' AND T1.tcm_flag = 0 AND T1.generate_source_enum = 1
AND T1.encounter_id = %s
AND T1.refund_medicine_id IS NULL)
UNION ALL
(SELECT 2 AS advice_type,
T1.id AS request_id,
T1.id || '-2' AS unique_key,
T1.requester_id AS requester_id,
T1.create_time AS request_time,
CASE WHEN T1.requester_id = %s THEN '1' ELSE '0' END AS biz_request_flag,
T1.content_json AS content_json,
null AS skin_test_flag,
null AS inject_flag,
null AS group_id,
T2.NAME AS advice_name,
T2.SIZE AS volume,
T1.lot_number AS lot_number,
T1.quantity AS quantity,
T1.unit_code AS unit_code,
T1.status_enum AS status_enum,
'' AS method_code,
T1.rate_code AS rate_code,
NULL AS dose,
'' AS dose_unit_code,
T3.id AS charge_item_id,
T3.total_price AS total_price,
T3.status_enum AS charge_status,
al.id AS position_id,
al.name AS position_name,
null AS dispense_per_duration,
T2.part_percent AS part_percent,
'' AS condition_definition_name,
COALESCE(T1.therapy_enum, 2) AS therapyEnum,
99 AS sort_number,
T1.based_on_id AS based_on_id
FROM wor_device_request AS T1
LEFT JOIN adm_device_definition AS T2 ON T2.ID = T1.device_def_id
AND T2.delete_flag = '0'
LEFT JOIN adm_charge_item AS T3
ON T3.service_id = T1.ID AND T3.delete_flag = '0' AND
T3.service_table = 'wor_device_request'
LEFT JOIN adm_location AS al ON al.ID = T1.perform_location AND al.delete_flag = '0'
WHERE T1.delete_flag = '0' AND T1.generate_source_enum = 1
AND T1.encounter_id = %s
AND T1.refund_device_id IS NULL)
UNION ALL
(SELECT 3 AS advice_type,
T1.id AS request_id,
T1.id || '-3' AS unique_key,
T1.requester_id AS requester_id,
T1.create_time AS request_time,
CASE WHEN T1.requester_id = %s THEN '1' ELSE '0' END AS biz_request_flag,
T1.content_json AS content_json,
null AS skin_test_flag,
null AS inject_flag,
null AS group_id,
COALESCE(T2.NAME, T1.content_json::jsonb->>'surgeryName') AS advice_name,
'' AS volume,
'' AS lot_number,
T1.quantity AS quantity,
T1.unit_code AS unit_code,
T1.status_enum AS status_enum,
'' AS method_code,
'' AS rate_code,
NULL AS dose,
'' AS dose_unit_code,
T3.id AS charge_item_id,
T3.total_price AS total_price,
T3.status_enum AS charge_status,
ao.id AS position_id,
ao.name AS position_name,
null AS dispense_per_duration,
1 AS part_percent,
'' AS condition_definition_name,
COALESCE(T1.therapy_enum, 2) AS therapyEnum,
99 AS sort_number,
T1.based_on_id AS based_on_id
FROM wor_service_request AS T1
LEFT JOIN wor_activity_definition AS T2
ON T2.ID = T1.activity_id
AND T2.delete_flag = '0'
LEFT JOIN adm_charge_item AS T3 ON T3.service_id = T1.ID AND T3.delete_flag = '0' AND
T3.service_table = 'wor_service_request'
LEFT JOIN adm_organization AS ao ON ao.ID = T1.org_id AND ao.delete_flag = '0'
WHERE T1.delete_flag = '0' AND T1.generate_source_enum = 1
AND T1.parent_id IS NULL
AND T1.encounter_id = %s)
ORDER BY status_enum
""",
(
practitioner_id,
encounter_id,
practitioner_id,
encounter_id,
practitioner_id,
encounter_id,
),
)
api_rows = cursor.fetchall()
print(f"API返回数据总数: {len(api_rows)}")
print()
# 检查手术医嘱advice_type=3
surgery_rows = [r for r in api_rows if r[0] == 3]
print(f"手术医嘱advice_type=3数量: {len(surgery_rows)}")
print()
for row in surgery_rows:
advice_name = row[10]
therapy_enum = row[25]
status = row[14]
print(f" advice_name: {advice_name}")
print(f" therapyEnum: {therapy_enum} (2=临时)")
print(f" status_enum: {status}")
print()
cursor.close()
conn.close()
print("=" * 80)
print("结论:")
if len(surgery_rows) > 0:
print(f"✓ API查询返回了 {len(surgery_rows)} 条手术医嘱")
print("✓ advice_name 已正确返回")
print("✓ therapyEnum 默认为 2 (临时)")
print()
print("如果前端仍不显示,问题可能:")
print(" 1. 前端缓存 - 请清除浏览器缓存")
print(" 2. 代码未正确部署 - 请检查实际运行的代码版本")
print(" 3. 前端过滤逻辑 - 请检查浏览器控制台网络请求返回的数据")
else:
print("✗ API查询未返回手术医嘱")
print(" 请检查数据库数据或SQL条件")

126
scripts/fix_content_json.py Normal file
View File

@@ -0,0 +1,126 @@
import psycopg2
import json
import sys
sys.stdout.reconfigure(encoding="utf-8")
conn = psycopg2.connect(
host="192.168.110.252",
port=15432,
database="postgresql",
user="postgresql",
password="Jchl1528",
)
cursor = conn.cursor()
cursor.execute("SET search_path TO hisdev, public")
print("=" * 80)
print("修复手术医嘱 content_json 为 null 的问题")
print("=" * 80)
print()
# 1. 查询所有 content_json 为 null 的手术医嘱
cursor.execute("""
SELECT
id,
prescription_no,
content_json
FROM wor_service_request
WHERE category_enum = 4
AND delete_flag = '0'
AND content_json IS NULL
""")
rows = cursor.fetchall()
print(f"发现 {len(rows)} 条 content_json 为 null 的手术医嘱")
print()
# 2. 从对应的手术申请单获取 desc_json 并更新
cursor.execute("""
SELECT
sr.id,
sr.prescription_no,
rf.desc_json
FROM wor_service_request sr
JOIN doc_request_form rf ON rf.prescription_no = sr.prescription_no
WHERE sr.category_enum = 4
AND sr.delete_flag = '0'
AND sr.content_json IS NULL
AND rf.delete_flag = '0'
""")
fix_rows = cursor.fetchall()
print(f"找到 {len(fix_rows)} 条可以修复的记录")
print()
# 3. 更新 content_json
update_count = 0
for row in fix_rows:
service_id = row[0]
prescription_no = row[1]
desc_json = row[2]
if desc_json:
try:
# 解析 desc_json
if isinstance(desc_json, str):
desc_data = json.loads(desc_json)
else:
desc_data = desc_json
# 构建 content_json
content_data = {
"surgeryName": desc_data.get("surgeryName", ""),
"surgeryCode": desc_data.get("surgeryCode", ""),
"surgeryFee": desc_data.get("surgeryFee", "0"),
"anesthesiaFee": desc_data.get("anesthesiaFee", "0"),
"plannedTime": desc_data.get("plannedTime", ""),
"surgeryIndication": desc_data.get("surgeryIndication", ""),
"preoperativeDiagnosis": desc_data.get("preoperativeDiagnosis", ""),
}
content_json = json.dumps(content_data, ensure_ascii=False)
# 更新数据库
cursor.execute(
"""
UPDATE wor_service_request
SET content_json = %s
WHERE id = %s
""",
(content_json, service_id),
)
update_count += 1
print(f"✓ 更新 ID={service_id}, 单号={prescription_no}")
except Exception as e:
print(f"✗ 更新失败 ID={service_id}: {e}")
conn.commit()
print()
print(f"✓ 成功修复 {update_count} 条记录")
print()
# 4. 验证修复结果
cursor.execute("""
SELECT
id,
prescription_no,
content_json
FROM wor_service_request
WHERE category_enum = 4
AND delete_flag = '0'
AND content_json IS NULL
""")
remaining = cursor.fetchall()
print(f"剩余 {len(remaining)} 条 content_json 为 null 的记录")
cursor.close()
conn.close()
print()
print("=" * 80)
print("修复完成!请刷新医嘱列表页面查看效果。")
print("=" * 80)

90
scripts/fix_remaining.py Normal file
View File

@@ -0,0 +1,90 @@
import psycopg2
DB_CONFIG = {
"host": "192.168.110.252",
"port": 15432,
"database": "postgresql",
"user": "postgresql",
"password": "Jchl1528",
"options": "-c search_path=hisdev",
}
def fix():
conn = None
try:
conn = psycopg2.connect(**DB_CONFIG)
cursor = conn.cursor()
print("=" * 80)
print("Fixing remaining surgery records")
print("=" * 80)
# Count before
cursor.execute("""
SELECT COUNT(*)
FROM wor_service_request
WHERE category_enum = 4
AND delete_flag = '0'
AND (content_json::jsonb->>'surgeryName' IS NULL OR content_json::jsonb->>'surgeryName' = '')
""")
before = cursor.fetchone()[0]
print(f"\nBefore fix: {before} records without surgeryName")
# Execute fix
cursor.execute("""
UPDATE wor_service_request wsr
SET content_json =
COALESCE(
(wsr.content_json::jsonb || jsonb_build_object(
'surgeryName', cs.surgery_name,
'surgeryCode', COALESCE(cs.surgery_code, '')
))::text,
jsonb_build_object(
'surgeryName', cs.surgery_name,
'surgeryCode', COALESCE(cs.surgery_code, '')
)::text
)
FROM cli_surgery cs
WHERE wsr.category_enum = 4
AND wsr.delete_flag = '0'
AND (wsr.content_json::jsonb->>'surgeryName' IS NULL OR wsr.content_json::jsonb->>'surgeryName' = '')
AND cs.id = wsr.activity_id
AND cs.surgery_name IS NOT NULL
AND cs.delete_flag = '0'
""")
fixed = cursor.rowcount
conn.commit()
print(f"Fixed: {fixed} records")
# Count after
cursor.execute("""
SELECT COUNT(*)
FROM wor_service_request
WHERE category_enum = 4
AND delete_flag = '0'
AND (content_json::jsonb->>'surgeryName' IS NULL OR content_json::jsonb->>'surgeryName' = '')
""")
after = cursor.fetchone()[0]
print(f"After fix: {after} records without surgeryName")
if after == 0:
print("\n*** ALL RECORDS FIXED! ***")
else:
print(f"\n*** {after} records still need attention ***")
cursor.close()
except Exception as e:
print(f"Error: {e}")
if conn:
conn.rollback()
finally:
if conn:
conn.close()
if __name__ == "__main__":
fix()

View File

@@ -0,0 +1,206 @@
import psycopg2
import sys
sys.stdout.reconfigure(encoding="utf-8")
# 数据库连接
conn = psycopg2.connect(
host="192.168.110.252",
port=15432,
database="postgresql",
user="postgresql",
password="Jchl1528",
)
cursor = conn.cursor()
cursor.execute("SET search_path TO hisdev, public")
conn.commit()
print("=" * 80)
print("查询患者:王俊彭 (病历号: PN0000000038)")
print("=" * 80)
print()
# 1. 查询患者基本信息和就诊ID
print("步骤1: 查询患者基本信息...")
cursor.execute("""
SELECT
p.id as patient_id,
p.name as patient_name,
e.id as encounter_id,
e.create_time as encounter_time
FROM adm_patient p
LEFT JOIN adm_encounter e ON e.patient_id = p.id
WHERE p.name = '王俊彭'
ORDER BY e.create_time DESC
LIMIT 5
""")
patient_rows = cursor.fetchall()
if not patient_rows:
print("✗ 未找到患者信息")
else:
for row in patient_rows:
print(
f" 患者ID: {row[0]}, 姓名: {row[1]}, 就诊ID: {row[2]}, 就诊时间: {row[3]}"
)
# 获取最新的就诊ID
encounter_id = patient_rows[0][2]
patient_id = patient_rows[0][0]
print(f"\n使用就诊ID: {encounter_id}")
print()
# 2. 查询手术申请单
print("步骤2: 查询手术申请单...")
cursor.execute(
"""
SELECT
id,
prescription_no,
type_code,
name,
create_time,
desc_json
FROM doc_request_form
WHERE encounter_id = %s
AND type_code = 'PROCEDURE'
AND delete_flag = '0'
ORDER BY create_time DESC
""",
(encounter_id,),
)
request_forms = cursor.fetchall()
if not request_forms:
print("✗ 未找到手术申请单")
else:
print(f"✓ 找到 {len(request_forms)} 条手术申请单:")
for rf in request_forms:
print(
f" 申请单ID: {rf[0]}, 单号: {rf[1]}, 类型: {rf[2]}, 名称: {rf[3]}, 时间: {rf[4]}"
)
if rf[5]:
try:
import json
desc = json.loads(rf[5])
surgery_name = desc.get("surgeryName", "N/A")
surgery_fee = desc.get("surgeryFee", "N/A")
print(f" -> 手术名称: {surgery_name}, 手术费用: {surgery_fee}")
except:
print(f" -> 手术详情: {rf[5][:100]}")
print()
# 3. 查询手术医嘱ServiceRequest
print("步骤3: 查询手术医嘱ServiceRequest...")
cursor.execute(
"""
SELECT
id,
prescription_no,
status_enum,
category_enum,
patient_id,
encounter_id,
create_time,
content_json
FROM wor_service_request
WHERE patient_id = %s
AND category_enum = 4
AND delete_flag = '0'
ORDER BY create_time DESC
""",
(patient_id,),
)
service_requests = cursor.fetchall()
if not service_requests:
print("✗ 未找到手术医嘱")
print("\n⚠️ 问题确认:有手术申请单但没有对应的手术医嘱!")
else:
print(f"✓ 找到 {len(service_requests)} 条手术医嘱:")
for sr in service_requests:
status_text = {1: "待签发", 2: "已签发", 3: "已执行"}.get(
sr[2], f"状态{sr[2]}"
)
print(
f" 医嘱ID: {sr[0]}, 单号: {sr[1]}, 状态: {status_text}, 就诊ID: {sr[5]}, 时间: {sr[6]}"
)
print()
# 4. 查询收费项目
print("步骤4: 查询收费项目ChargeItem...")
cursor.execute(
"""
SELECT
id,
bus_no,
status_enum,
total_price,
service_id
FROM adm_charge_item
WHERE patient_id = %s
AND service_table = 'wor_service_request'
AND delete_flag = '0'
ORDER BY create_time DESC
""",
(patient_id,),
)
charge_items = cursor.fetchall()
if not charge_items:
print("✗ 未找到收费项目")
else:
print(f"✓ 找到 {len(charge_items)} 条收费项目:")
for ci in charge_items:
print(f" 收费ID: {ci[0]}, 单号: {ci[1]}, 金额: {ci[3]}, 关联医嘱: {ci[4]}")
print()
# 5. 查询医嘱列表(用于对比)
print("步骤5: 查询该患者的所有医嘱...")
cursor.execute(
"""
SELECT
category_enum,
status_enum,
count(*) as count
FROM wor_service_request
WHERE patient_id = %s
AND delete_flag = '0'
GROUP BY category_enum, status_enum
ORDER BY category_enum
""",
(patient_id,),
)
categories = cursor.fetchall()
if categories:
print("✓ 医嘱统计:")
cat_names = {1: "西药", 2: "耗材", 3: "诊疗", 4: "手术"}
stat_names = {1: "待签发", 2: "已签发", 3: "已执行"}
for cat in categories:
cat_name = cat_names.get(cat[0], f"类型{cat[0]}")
stat_name = stat_names.get(cat[1], f"状态{cat[1]}")
print(f" {cat_name} - {stat_name}: {cat[2]}")
print()
print("=" * 80)
# 问题诊断
if request_forms and not service_requests:
print("\n🔴 问题确认:")
print(" ✓ 手术申请单存在doc_request_form")
print(" ✗ 手术医嘱不存在wor_service_request")
print("\n 结论:保存手术申请单时未生成手术医嘱")
print(" 原因:代码修复可能未生效或未部署到生产环境")
elif service_requests:
print("\n✅ 数据正常:")
print(" ✓ 手术申请单存在")
print(" ✓ 手术医嘱存在")
print("\n 请在医嘱TAB页面查看是否能显示")
print()
cursor.close()
conn.close()

View File

@@ -0,0 +1,39 @@
#!/bin/bash
# ============================================
# OpenHIS 后端编译脚本(增加内存)
# ============================================
cd /d D:\his\openhis-server-new
echo "============================================"
echo "开始编译 OpenHIS 后端"
echo "============================================"
echo.
:: 设置更大的堆内存给 Maven
echo "[1/3] 清理旧的编译文件..."
set MAVEN_OPTS=-Xmx4g -XX:MaxMetaspaceSize=512m
call mvn clean -q
if errorlevel 1 (
echo 清理失败!
pause
exit /b 1
)
echo "[2/3] 编译打包(跳过测试)..."
set MAVEN_OPTS=-Xmx4g -XX:MaxMetaspaceSize=512m -XX:+UseG1GC
call mvn package -DskipTests -q
if errorlevel 1 (
echo 编译失败!
pause
exit /b 1
)
echo "[3/3] 编译完成!"
echo.
echo "============================================"
echo 请手动重启后端服务
echo ============================================
pause

View File

@@ -0,0 +1,31 @@
@echo off
chcp 65001 >nul
echo ============================================
echo 重新编译部署 OpenHIS 后端
echo ============================================
echo.
cd /d D:\his\openhis-server-new
echo [1/3] 清理旧的编译文件...
call mvn clean -q
if errorlevel 1 (
echo 清理失败!
pause
exit /b 1
)
echo [2/3] 编译打包(跳过测试)...
call mvn package -DskipTests -q
if errorlevel 1 (
echo 编译失败!
pause
exit /b 1
)
echo [3/3] 编译完成!
echo.
echo ============================================
echo 请手动重启后端服务
echo ============================================
pause

351
scripts/repair_bug_318.py Normal file
View File

@@ -0,0 +1,351 @@
#!/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()

102
scripts/test-device-api.js Normal file
View File

@@ -0,0 +1,102 @@
const { chromium } = require('playwright');
const fs = require('fs');
async function testDeviceApi() {
const browser = await chromium.launch({
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox']
});
const context = await browser.newContext({
viewport: { width: 1920, height: 2000 }
});
const page = await context.newPage();
try {
const baseUrl = 'http://localhost:18080';
// Step 1: 登录获取token
console.log('[Step 1] 登录获取token...');
const loginRes = await page.evaluate(async (baseUrl) => {
const res = await fetch(`${baseUrl}/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: 'admin', password: 'admin123' })
});
return res.json();
}, baseUrl);
console.log('[Step 1] 登录结果:', loginRes.code === 200 ? '成功' : '失败');
if (loginRes.code !== 200) {
console.error('[Error] 登录失败:', loginRes.msg);
return;
}
// Step 2: 调用getDeviceList API
console.log('[Step 2] 调用耗材列表API...');
const apiRes = await page.evaluate(async (baseUrl) => {
const res = await fetch(`${baseUrl}/data-dictionary/device/information-page?pageNo=1&pageSize=100&searchKey=&statusEnum=2`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + localStorage.getItem('token')
}
});
return res.json();
}, baseUrl);
console.log('[Step 2] API响应状态:', apiRes.code);
if (apiRes.code === 200 && apiRes.data && apiRes.data.records) {
console.log(`\n[Step 3] 获取到 ${apiRes.data.records.length} 条耗材记录`);
// 保存完整数据到文件
fs.writeFileSync('device_api_response.json', JSON.stringify(apiRes.data, null, 2));
console.log('[Step 3] 完整数据已保存到 device_api_response.json');
// 分析前5条记录
console.log('\n[Step 4] 分析前5条记录的价格字段:');
apiRes.data.records.slice(0, 5).forEach((item, index) => {
console.log(`\n记录 ${index + 1}:`);
console.log(' - name:', item.name);
console.log(' - busNo:', item.busNo);
console.log(' - price:', item.price);
console.log(' - retailPrice:', item.retailPrice);
console.log(' - purchasePrice:', item.purchasePrice);
console.log(' - maximumRetailPrice:', item.maximumRetailPrice);
// 检查所有包含price的字段
const priceFields = Object.keys(item).filter(k =>
k.toLowerCase().includes('price') || k.toLowerCase().includes('amount')
);
console.log(' - 所有价格相关字段:', priceFields);
});
// 统计有多少条记录有价格
const withRetailPrice = apiRes.data.records.filter(item =>
item.retailPrice !== undefined && item.retailPrice !== null && item.retailPrice !== ''
).length;
const withPrice = apiRes.data.records.filter(item =>
item.price !== undefined && item.price !== null && item.price !== ''
).length;
console.log(`\n[Step 5] 数据统计:`);
console.log(` - 总记录数: ${apiRes.data.records.length}`);
console.log(` - 有retailPrice的记录: ${withRetailPrice}`);
console.log(` - 有price的记录: ${withPrice}`);
console.log(` - 无任何价格的记录: ${apiRes.data.records.length - Math.max(withRetailPrice, withPrice)}`);
} else {
console.error('[Error] API调用失败:', apiRes.msg || '未知错误');
}
} catch (error) {
console.error('[Error]', error.message);
} finally {
await browser.close();
}
}
testDeviceApi();

View File

@@ -0,0 +1,116 @@
import psycopg2
import sys
sys.stdout.reconfigure(encoding="utf-8")
conn = psycopg2.connect(
host="192.168.110.252",
port=15432,
database="postgresql",
user="postgresql",
password="Jchl1528",
)
cursor = conn.cursor()
cursor.execute("SET search_path TO hisdev, public")
print("=" * 80)
print("测试 DoctorStation SQL (模拟 doctor-station API)")
print("=" * 80)
print()
encounter_id = 2038823905749327873
practitioner_id = 1980296166230962178
# 使用修改后的 SQL 查询(第三部分 - ServiceRequest
cursor.execute(
"""
SELECT
COALESCE(T1.category_enum, 3) AS advice_type,
T1.id AS request_id,
T1.id || '-3' AS unique_key,
'' AS prescription_no,
T1.requester_id AS requester_id,
T1.create_time AS request_time,
CASE WHEN T1.requester_id = %s THEN '1' ELSE '0' END AS biz_request_flag,
T1.content_json AS content_json,
null AS skin_test_flag,
null AS inject_flag,
null AS group_id,
COALESCE(T2.NAME, T1.content_json::jsonb->>'surgeryName', T1.content_json::jsonb->>'adviceName') AS advice_name,
'' AS volume,
'' AS lot_number,
T1.quantity AS quantity,
T1.unit_code AS unit_code,
T1.status_enum AS status_enum,
'' AS method_code,
'' AS rate_code,
NULL AS dose,
'' AS dose_unit_code,
T3.id AS charge_item_id,
T3.total_price AS total_price,
T3.status_enum AS charge_status,
ao.id AS position_id,
ao.name AS position_name,
null AS dispense_per_duration,
1 AS part_percent,
'' AS condition_definition_name,
99 AS sort_number,
T1.based_on_id AS based_on_id,
T1.category_enum AS category_enum
FROM wor_service_request AS T1
LEFT JOIN wor_activity_definition AS T2
ON T2.ID = T1.activity_id
AND T2.delete_flag = '0'
LEFT JOIN adm_charge_item AS T3 ON T3.service_id = T1.ID AND T3.delete_flag = '0' AND
T3.service_table = 'wor_service_request'
LEFT JOIN adm_organization AS ao ON ao.ID = T1.org_id AND ao.delete_flag = '0'
WHERE T1.delete_flag = '0' AND T1.generate_source_enum = 1
AND T1.parent_id IS NULL
AND T1.encounter_id = %s
ORDER BY T1.status_enum
""",
(practitioner_id, encounter_id),
)
rows = cursor.fetchall()
print(f"查询到 {len(rows)} 条 ServiceRequest 记录")
print()
for row in rows:
advice_type = row[0]
request_id = row[1]
advice_name = row[10]
category_enum = row[25]
print(f"request_id: {request_id}")
print(f" advice_type: {advice_type} (应该=4)")
print(f" category_enum: {category_enum}")
print(f" advice_name: {advice_name}")
print(f" advice_name是否为空: {advice_name is None or advice_name == ''}")
print()
# 特别检查手术医嘱
surgery_rows = [r for r in rows if r[24] == 4] # category_enum = 4
print(f"手术医嘱 (category_enum=4) 数量: {len(surgery_rows)}")
print()
if surgery_rows:
for row in surgery_rows:
print(f"✓ 手术医嘱:")
print(f" request_id: {row[1]}")
print(f" advice_type: {row[0]} (应该=4)")
print(f" advice_name: {row[10]}")
print(
f" 是否通过前端过滤: {'否 (adviceName为空)' if not row[10] or row[10].strip() == '' else ''}"
)
else:
print("✗ 未找到手术医嘱")
print()
print("可能原因:")
print(" 1. SQL COALESCE 语法错误")
print(" 2. content_json 中没有 surgeryName 字段")
print(" 3. 数据未正确保存")
cursor.close()
conn.close()

View File

@@ -0,0 +1,214 @@
import psycopg2
import json
import sys
sys.stdout.reconfigure(encoding="utf-8")
conn = psycopg2.connect(
host="192.168.110.252",
port=15432,
database="postgresql",
user="postgresql",
password="Jchl1528",
)
cursor = conn.cursor()
cursor.execute("SET search_path TO hisdev, public")
print("=" * 80)
print("模拟前端处理逻辑,检查是否会报错")
print("=" * 80)
print()
encounter_id = 2038823905749327873
practitioner_id = 1980296166230962178
# 查询所有数据UNION ALL 三部分)
cursor.execute(
"""
(SELECT 1 AS advice_type,
T1.id AS request_id,
T1.id || '-1' AS unique_key,
T1.practitioner_id AS requester_id,
T1.create_time AS request_time,
CASE WHEN T1.practitioner_id = %s THEN '1' ELSE '0' END AS biz_request_flag,
T1.content_json AS content_json,
T1.skin_test_flag AS skin_test_flag,
T1.infusion_flag AS inject_flag,
T1.group_id AS group_id,
T2.NAME AS advice_name,
T3.total_volume AS volume,
T1.lot_number AS lot_number,
T1.quantity AS quantity,
T1.unit_code AS unit_code,
T1.status_enum AS status_enum,
T1.method_code AS method_code,
T1.rate_code AS rate_code,
T1.dose AS dose,
T1.dose_unit_code AS dose_unit_code,
T4.id AS charge_item_id,
T4.total_price AS total_price,
T4.status_enum AS charge_status,
al.id AS position_id,
al.name AS position_name,
T1.dispense_per_duration AS dispense_per_duration,
T2.part_percent AS part_percent,
ccd.name AS condition_definition_name,
T1.therapy_enum AS therapyEnum,
T1.sort_number AS sort_number,
T1.based_on_id AS based_on_id
FROM med_medication_request AS T1
LEFT JOIN med_medication_definition AS T2 ON T2.ID = T1.medication_id
AND T2.delete_flag = '0'
LEFT JOIN med_medication AS T3 ON T3.medication_def_id = T2.ID
AND T3.delete_flag = '0'
LEFT JOIN adm_charge_item AS T4 ON T4.service_id = T1.ID AND T4.delete_flag = '0' AND
T4.service_table = 'med_medication_request'
LEFT JOIN adm_location AS al ON al.ID = T1.perform_location AND al.delete_flag = '0'
LEFT JOIN cli_condition AS cc ON cc.id = T1.condition_id AND cc.delete_flag = '0'
LEFT JOIN cli_condition_definition AS ccd ON ccd.id = cc.definition_id
WHERE T1.delete_flag = '0' AND T1.tcm_flag = 0 AND T1.generate_source_enum = 1
AND T1.encounter_id = %s
AND T1.refund_medicine_id IS NULL)
UNION ALL
(SELECT 2 AS advice_type,
T1.id AS request_id,
T1.id || '-2' AS unique_key,
T1.requester_id AS requester_id,
T1.create_time AS request_time,
CASE WHEN T1.requester_id = %s THEN '1' ELSE '0' END AS biz_request_flag,
T1.content_json AS content_json,
null AS skin_test_flag,
null AS inject_flag,
null AS group_id,
T2.NAME AS advice_name,
T2.SIZE AS volume,
T1.lot_number AS lot_number,
T1.quantity AS quantity,
T1.unit_code AS unit_code,
T1.status_enum AS status_enum,
'' AS method_code,
T1.rate_code AS rate_code,
NULL AS dose,
'' AS dose_unit_code,
T3.id AS charge_item_id,
T3.total_price AS total_price,
T3.status_enum AS charge_status,
al.id AS position_id,
al.name AS position_name,
null AS dispense_per_duration,
T2.part_percent AS part_percent,
'' AS condition_definition_name,
2 AS therapyEnum,
99 AS sort_number,
T1.based_on_id AS based_on_id
FROM wor_device_request AS T1
LEFT JOIN adm_device_definition AS T2 ON T2.ID = T1.device_def_id
AND T2.delete_flag = '0'
LEFT JOIN adm_charge_item AS T3
ON T3.service_id = T1.ID AND T3.delete_flag = '0' AND
T3.service_table = 'wor_device_request'
LEFT JOIN adm_location AS al ON al.ID = T1.perform_location AND al.delete_flag = '0'
WHERE T1.delete_flag = '0' AND T1.generate_source_enum = 1
AND T1.encounter_id = %s
AND T1.refund_device_id IS NULL)
UNION ALL
(SELECT 3 AS advice_type,
T1.id AS request_id,
T1.id || '-3' AS unique_key,
T1.requester_id AS requester_id,
T1.create_time AS request_time,
CASE WHEN T1.requester_id = %s THEN '1' ELSE '0' END AS biz_request_flag,
T1.content_json AS content_json,
null AS skin_test_flag,
null AS inject_flag,
null AS group_id,
COALESCE(T2.NAME, T1.content_json::jsonb->>'surgeryName') AS advice_name,
'' AS volume,
'' AS lot_number,
T1.quantity AS quantity,
T1.unit_code AS unit_code,
T1.status_enum AS status_enum,
'' AS method_code,
'' AS rate_code,
NULL AS dose,
'' AS dose_unit_code,
T3.id AS charge_item_id,
T3.total_price AS total_price,
T3.status_enum AS charge_status,
ao.id AS position_id,
ao.name AS position_name,
null AS dispense_per_duration,
1 AS part_percent,
'' AS condition_definition_name,
T1.therapy_enum AS therapyEnum,
99 AS sort_number,
T1.based_on_id AS based_on_id
FROM wor_service_request AS T1
LEFT JOIN wor_activity_definition AS T2
ON T2.ID = T1.activity_id
AND T2.delete_flag = '0'
LEFT JOIN adm_charge_item AS T3 ON T3.service_id = T1.ID AND T3.delete_flag = '0' AND
T3.service_table = 'wor_service_request'
LEFT JOIN adm_organization AS ao ON ao.ID = T1.org_id AND ao.delete_flag = '0'
WHERE T1.delete_flag = '0' AND T1.generate_source_enum = 1
AND T1.parent_id IS NULL
AND T1.encounter_id = %s)
ORDER BY status_enum
""",
(
practitioner_id,
encounter_id,
practitioner_id,
encounter_id,
practitioner_id,
encounter_id,
),
)
rows = cursor.fetchall()
print(f"查询到 {len(rows)} 条记录")
print()
# 模拟前端处理
error_count = 0
success_count = 0
for i, row in enumerate(rows):
request_id = row[1]
unique_key = row[2]
advice_name = row[10]
content_json = row[6]
try:
# 模拟前端JSON.parse(item.contentJson)
if content_json is None or content_json == "":
parsed_content = {}
else:
parsed_content = (
json.loads(content_json)
if isinstance(content_json, str)
else content_json
)
success_count += 1
# 检查手术医嘱
if unique_key.endswith("-3") and advice_name:
print(f"✓ 第{i + 1}条: advice_type=3 (ServiceRequest)")
print(f" request_id: {request_id}")
print(f" advice_name: {advice_name}")
print(f" content_json解析成功")
print()
except Exception as e:
error_count += 1
print(f"✗ 第{i + 1}条报错: {e}")
print(f" request_id: {request_id}")
print(f" content_json: {content_json}")
print()
print(f"成功: {success_count}, 失败: {error_count}")
cursor.close()
conn.close()

106
scripts/test_sql.py Normal file
View File

@@ -0,0 +1,106 @@
import psycopg2
import json
import sys
sys.stdout.reconfigure(encoding="utf-8")
conn = psycopg2.connect(
host="192.168.110.252",
port=15432,
database="postgresql",
user="postgresql",
password="Jchl1528",
)
cursor = conn.cursor()
cursor.execute("SET search_path TO hisdev, public")
print("=" * 80)
print("使用实际部署的SQL查询数据")
print("=" * 80)
print()
practitioner_id = 1980296166230962178
encounter_id = 2038823905749327873
# 只查询第三部分ServiceRequest使用COALESCE
cursor.execute(
"""
SELECT
3 AS advice_type,
T1.id AS request_id,
T1.id || '-3' AS unique_key,
T1.requester_id AS requester_id,
T1.create_time AS request_time,
CASE WHEN T1.requester_id = %s THEN '1' ELSE '0' END AS biz_request_flag,
T1.content_json AS content_json,
null AS skin_test_flag,
null AS inject_flag,
null AS group_id,
COALESCE(T2.NAME, T1.content_json::jsonb->>'surgeryName') AS advice_name,
'' AS volume,
'' AS lot_number,
T1.quantity AS quantity,
T1.unit_code AS unit_code,
T1.status_enum AS status_enum,
'' AS method_code,
'' AS rate_code,
NULL AS dose,
'' AS dose_unit_code,
T3.id AS charge_item_id,
T3.total_price AS total_price,
T3.status_enum AS charge_status,
ao.id AS position_id,
ao.name AS position_name,
null AS dispense_per_duration,
1 AS part_percent,
'' AS condition_definition_name,
COALESCE(T1.therapy_enum, 2) AS therapyEnum,
99 AS sort_number,
T1.based_on_id AS based_on_id
FROM wor_service_request AS T1
LEFT JOIN wor_activity_definition AS T2
ON T2.ID = T1.activity_id
AND T2.delete_flag = '0'
LEFT JOIN adm_charge_item AS T3 ON T3.service_id = T1.ID AND T3.delete_flag = '0' AND
T3.service_table = 'wor_service_request'
LEFT JOIN adm_organization AS ao ON ao.ID = T1.org_id AND ao.delete_flag = '0'
WHERE T1.delete_flag = '0' AND T1.generate_source_enum = 1
AND T1.parent_id IS NULL
AND T1.encounter_id = %s
ORDER BY T1.status_enum
""",
(practitioner_id, encounter_id),
)
rows = cursor.fetchall()
print(f"查询到 {len(rows)} 条 ServiceRequest 记录")
print()
for row in rows:
advice_name = row[10]
therapy_enum = row[25]
status = row[14]
content_json = row[6]
print(f"advice_name: {advice_name}")
print(f"therapyEnum: {therapy_enum} (类型: {type(therapy_enum)})")
print(f"status_enum: {status}")
print(f"content_json: {content_json[:80] if content_json else 'None'}...")
print("-" * 80)
print()
print("结论:")
if len(rows) > 0 and rows[0][10] and rows[0][25] is not None:
print("✓ SQL查询正常数据完整")
print(" - advice_name 已正确返回")
print(" - therapyEnum 已正确返回")
print()
print("如果前端仍不显示,请检查:")
print(" 1. 浏览器控制台的网络请求返回值")
print(" 2. 前端代码是否正确处理了数据")
else:
print("✗ SQL查询有问题")
cursor.close()
conn.close()

115
scripts/verify_fix.py Normal file
View File

@@ -0,0 +1,115 @@
import psycopg2
import sys
sys.stdout.reconfigure(encoding="utf-8")
conn = psycopg2.connect(
host="192.168.110.252",
port=15432,
database="postgresql",
user="postgresql",
password="Jchl1528",
)
cursor = conn.cursor()
cursor.execute("SET search_path TO hisdev, public")
print("=" * 80)
print("验证修复后的数据模拟新SQL查询")
print("=" * 80)
print()
encounter_id = 2038823905749327873
practitioner_id = 1980296166230962178
# 使用修改后的SQL逻辑
cursor.execute(
"""
SELECT
3 AS advice_type,
T1.id AS request_id,
T1.id || '-3' AS unique_key,
T1.requester_id AS requester_id,
T1.create_time AS request_time,
CASE WHEN T1.requester_id = %s THEN '1' ELSE '0' END AS biz_request_flag,
T1.content_json AS content_json,
null AS skin_test_flag,
null AS inject_flag,
null AS group_id,
COALESCE(T2.NAME, T1.content_json::jsonb->>'surgeryName') AS advice_name,
'' AS volume,
'' AS lot_number,
T1.quantity AS quantity,
T1.unit_code AS unit_code,
T1.status_enum AS status_enum,
'' AS method_code,
'' AS rate_code,
NULL AS dose,
'' AS dose_unit_code,
T3.id AS charge_item_id,
T3.total_price AS total_price,
T3.status_enum AS charge_status,
ao.id AS position_id,
ao.name AS position_name,
null AS dispense_per_duration,
1 AS part_percent,
'' AS condition_definition_name,
T1.therapy_enum AS therapyEnum,
99 AS sort_number,
T1.based_on_id AS based_on_id
FROM wor_service_request AS T1
LEFT JOIN wor_activity_definition AS T2
ON T2.ID = T1.activity_id
AND T2.delete_flag = '0'
LEFT JOIN adm_charge_item AS T3 ON T3.service_id = T1.ID AND T3.delete_flag = '0' AND
T3.service_table = 'wor_service_request'
LEFT JOIN adm_organization AS ao ON ao.ID = T1.org_id AND ao.delete_flag = '0'
WHERE T1.delete_flag = '0' AND T1.generate_source_enum = 1
AND T1.parent_id IS NULL
AND T1.encounter_id = %s
ORDER BY T1.status_enum
""",
(practitioner_id, encounter_id),
)
rows = cursor.fetchall()
print(f"查询到 {len(rows)} 条记录:")
print()
for row in rows:
print(f"advice_type: {row[0]}")
print(f"request_id: {row[1]}")
print(f"unique_key: {row[2]}")
print(f"advice_name: {row[10]} ← 关键字段") # advice_name是第11个字段索引10
print(f"content_json: {row[6][:80] if row[6] else None}...")
print(f"status_enum: {row[14]}")
print(f"therapyEnum: {row[25]}")
print("-" * 80)
print()
# 检查手术医嘱
cursor.execute(
"""
SELECT
id,
prescription_no,
COALESCE(
(SELECT name FROM wor_activity_definition WHERE id = sr.activity_id AND delete_flag = '0'),
sr.content_json::jsonb->>'surgeryName'
) as advice_name,
status_enum,
content_json::jsonb->>'surgeryName' as surgery_name
FROM wor_service_request sr
WHERE category_enum = 4
AND delete_flag = '0'
AND encounter_id = %s
""",
(encounter_id,),
)
print("直接查询手术医嘱:")
for row in cursor.fetchall():
print(f" ID: {row[0]}, 单号: {row[1]}, advice_name: {row[2]}, 状态: {row[3]}")
cursor.close()
conn.close()

View File

@@ -0,0 +1,19 @@
@echo off
echo ============================================
echo 手动编译 OpenHIS 后端
echo ============================================
echo.
echo 请在命令行中依次执行以下命令:
echo.
echo 1. 进入项目目录
echo cd /d D:\his\openhis-server-new
echo.
echo 2. 清理并编译
echo mvn clean package -DskipTests
echo.
echo 3. 等待编译完成约5-10分钟
echo.
echo 4. 重启后端服务
echo.
echo ============================================
pause