perf(database): 优化数据库查询性能和前端请求处理

- 优化ActivityDefinitionManageMapper.xml中的分页查询,减少JOIN操作并使用索引友好的写法
- 修复purchaseinventory组件中API调用的数据传递格式问题
- 将前端请求超时时间从60秒增加到120秒以配合后端超时设置
- 在手术申请页面添加远程搜索防抖功能,避免频繁API调用
- 重构SurgeryAppServiceImpl中的名称字段填充逻辑,使用批量查询减少数据库访问次数
- 优化SurgeryMapper.xml中的分页查询,使用子查询预加载关联数据并减少不必要的JOIN
This commit is contained in:
2026-03-04 18:32:06 +08:00
parent 7008fb007f
commit 8af06f6916
6 changed files with 244 additions and 138 deletions

View File

@@ -189,13 +189,124 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
LEFT JOIN adm_organization apply_dept ON s.apply_dept_id = apply_dept.id
</sql>
<!-- 优化版分页查询减少JOIN使用子查询预加载关联数据 -->
<select id="getSurgeryPage" parameterType="com.baomidou.mybatisplus.core.conditions.query.QueryWrapper" resultMap="SurgeryResult">
<include refid="selectSurgeryVo"/>
SELECT
s.id,
s.surgery_no,
s.patient_id,
s.patient_name,
s.encounter_id,
s.apply_doctor_id,
s.apply_doctor_name,
s.apply_dept_id,
s.apply_dept_name,
s.surgery_name,
s.surgery_code,
s.surgery_type_enum,
s.surgery_level,
s.status_enum,
s.planned_time,
s.actual_start_time,
s.actual_end_time,
s.main_surgeon_id,
s.main_surgeon_name,
s.assistant_1_id,
s.assistant_1_name,
s.assistant_2_id,
s.assistant_2_name,
s.anesthetist_id,
s.anesthetist_name,
s.scrub_nurse_id,
s.scrub_nurse_name,
s.anesthesia_type_enum,
s.body_site,
s.incision_level,
s.healing_level,
s.operating_room_id,
s.operating_room_name,
s.org_id,
s.org_name,
s.surgery_indication,
s.preoperative_diagnosis,
s.postoperative_diagnosis,
s.surgery_description,
s.postoperative_advice,
s.complications,
s.surgery_fee,
s.anesthesia_fee,
s.total_fee,
s.remark,
s.create_time,
s.update_time,
s.emergency_flag,
s.implant_flag,
s.operating_room_confirm_time,
s.operating_room_confirm_user,
<!-- 患者信息:只查询必要字段 -->
p.gender_enum as patient_gender,
p.birth_date,
<!-- 就诊编号 -->
e.bus_no as encounter_no,
<!-- 字典文本使用CASE WHEN避免额外JOIN -->
CASE s.surgery_type_enum
WHEN 1 THEN '门诊手术'
WHEN 2 THEN '住院手术'
WHEN 3 THEN '急诊手术'
WHEN 4 THEN '择期手术'
ELSE '未知'
END as surgery_type_enum_dictText,
CASE s.surgery_level
WHEN 1 THEN '一级手术'
WHEN 2 THEN '二级手术'
WHEN 3 THEN '三级手术'
WHEN 4 THEN '四级手术'
WHEN 5 THEN '特级手术'
ELSE '未知'
END as surgery_level_dictText,
CASE s.status_enum
WHEN 0 THEN '待排期'
WHEN 1 THEN '已排期'
WHEN 2 THEN '手术中'
WHEN 3 THEN '已完成'
WHEN 4 THEN '已取消'
WHEN 5 THEN '暂停'
ELSE '未知'
END as status_enum_dictText,
CASE s.anesthesia_type_enum
WHEN 0 THEN '无麻醉'
WHEN 1 THEN '局部麻醉'
WHEN 2 THEN '区域麻醉'
WHEN 3 THEN '全身麻醉'
WHEN 4 THEN '脊椎麻醉'
WHEN 5 THEN '硬膜外麻醉'
WHEN 6 THEN '表面麻醉'
ELSE '未知'
END as anesthesia_type_enum_dictText,
CASE s.incision_level
WHEN 1 THEN 'I级切口'
WHEN 2 THEN 'II级切口'
WHEN 3 THEN 'III级切口'
WHEN 4 THEN 'IV级切口'
ELSE '未知'
END as incision_level_dictText,
CASE s.healing_level
WHEN 1 THEN '甲级愈合'
WHEN 2 THEN '乙级愈合'
WHEN 3 THEN '丙级愈合'
ELSE '未知'
END as healing_level_dictText,
<!-- 计算年龄 -->
EXTRACT(YEAR FROM AGE(p.birth_date)) as patient_age
FROM cli_surgery s
<!-- 只JOIN必要的表患者和就诊 -->
LEFT JOIN adm_patient p ON s.patient_id = p.id
LEFT JOIN adm_encounter e ON s.encounter_id = e.id
<where>
s.delete_flag = '0'
<if test="ew.sqlSegment != null and ew.sqlSegment != ''">
<![CDATA[
AND ${ew.sqlSegment.replace('tenant_id', 's.tenant_id').replace('create_time', 's.create_time').replace('surgery_no', 's.surgery_no').replace('surgery_name', 's.surgery_name').replace('patient_name', 'p.name').replace('main_surgeon_name', 's.main_surgeon_name').replace('anesthetist_name', 's.anesthetist_name').replace('org_name', 'o.name').replace('status_enum', 's.status_enum').replace('planned_time', 's.planned_time')}
AND ${ew.sqlSegment.replace('tenant_id', 's.tenant_id').replace('create_time', 's.create_time').replace('surgery_no', 's.surgery_no').replace('surgery_name', 's.surgery_name').replace('patient_name', 's.patient_name').replace('main_surgeon_name', 's.main_surgeon_name').replace('anesthetist_name', 's.anesthetist_name').replace('org_name', 's.org_name').replace('status_enum', 's.status_enum').replace('planned_time', 's.planned_time')}
]]>
</if>
</where>

View File

@@ -1,78 +1,51 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.openhis.web.datadictionary.mapper.ActivityDefinitionManageMapper">
<!-- 优化后的分页查询减少JOIN使用索引友好的写法 -->
<select id="getDiseaseTreatmentPage" parameterType="java.util.Map"
resultType="com.openhis.web.datadictionary.dto.DiagnosisTreatmentDto">
SELECT
T3.id,
T3.category_code,
T3.bus_no,
T3.name,
T3.py_str,
T3.wb_str,
T3.type_enum,
T3.permitted_unit_code,
T3.org_id,
T3.location_id,
T3.yb_flag,
T3.yb_no,
T3.yb_match_flag,
T3.status_enum,
T3.body_site_code,
T3.specimen_code,
T3.description_text,
T3.rule_id,
T3.tenant_id,
T3.item_type_code,
T3.yb_type,
T3.price_code,
T3.retail_price,
T3.maximum_retail_price,
T3.chrgitm_lv,
T3.children_json,
T3.pricing_flag,
T3.sort_order,
T3.service_range
FROM
(
SELECT
T1.id,
T1.category_code,
T1.bus_no,
T1.name,
T1.py_str,
T1.wb_str,
T1.type_enum,
T1.permitted_unit_code,
T1.org_id,
T1.location_id,
T1.yb_flag,
T1.yb_no,
T1.yb_match_flag,
T1.status_enum,
T1.body_site_code,
T1.specimen_code,
T1.description_text,
T1.rule_id,
T1.tenant_id,
T1.chrgitm_lv,
T2.type_code as item_type_code,
T2.yb_type,
T2.price_code,
T2.price as retail_price,
T4.amount as maximum_retail_price,
T1.children_json,
T1.pricing_flag,
T1.sort_order,
T1.service_range
T1.id,
T1.category_code,
T1.bus_no,
T1.name,
T1.py_str,
T1.wb_str,
T1.type_enum,
T1.permitted_unit_code,
T1.org_id,
T1.location_id,
T1.yb_flag,
T1.yb_no,
T1.yb_match_flag,
T1.status_enum,
T1.body_site_code,
T1.specimen_code,
T1.description_text,
T1.rule_id,
T1.tenant_id,
T1.chrgitm_lv,
T1.children_json,
T1.pricing_flag,
T1.sort_order,
T1.service_range,
T2.type_code as item_type_code,
T2.yb_type,
T2.price_code,
T2.price as retail_price,
T4.amount as maximum_retail_price
FROM wor_activity_definition T1
LEFT JOIN adm_charge_item_definition T2 ON T1.id = T2.instance_id
LEFT JOIN adm_charge_item_definition T5 ON T5.instance_id = T1.id AND T5.instance_table = 'wor_activity_definition'
LEFT JOIN adm_charge_item_def_detail T4 ON T4.definition_id = T5.id AND T4.condition_code = '4'
/* 只JOIN必要的价格表使用INNER JOIN避免笛卡尔积 */
INNER JOIN adm_charge_item_definition T2
ON T1.id = T2.instance_id
AND T2.instance_table = 'wor_activity_definition'
/* 最高零售价使用LEFT JOIN因为可能不存在 */
LEFT JOIN adm_charge_item_def_detail T4
ON T4.definition_id = T2.id
AND T4.condition_code = '4'
<where>
T1.delete_flag = '0'
AND T2.instance_table = 'wor_activity_definition'
<if test="ew.customSqlSegment != null and ew.customSqlSegment != ''">
<choose>
<when test="ew.customSqlSegment.contains('tenant_id')">
@@ -84,9 +57,7 @@
</choose>
</if>
</where>
ORDER BY T1.bus_no DESC
) T3
ORDER BY T1.id DESC
</select>
<select id="getDiseaseTreatmentOne" resultType="com.openhis.web.datadictionary.dto.DiagnosisTreatmentDto">