refactor(inhospitalnursestation): 优化入院护士站应用的数据库查询性能

- 将CTE查询重构为子查询以提高执行效率
- 为位置和医生查询添加LIMIT 1约束以减少数据量
- 移除不必要的GROUP BY子句以简化查询逻辑
- 在前端组件中实现异步数据加载和错误处理机制
- 使用可选链操作符处理空值情况避免报错
- 添加防抖机制解决单击双击冲突问题
- 优化患者列表和床位列表的并行加载逻辑
- 清理调试用的console.log语句并替换为有意义的信息
This commit is contained in:
2026-01-19 22:36:04 +08:00
parent aa3beb848b
commit 803e4d0bb5
14 changed files with 234 additions and 171 deletions

View File

@@ -1,10 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试合并11111</title>
</head>
<body>
</body>
</html>

View File

@@ -224,27 +224,6 @@
</select> </select>
<select id="selectAdmissionPatientInfo" <select id="selectAdmissionPatientInfo"
resultType="com.openhis.web.inhospitalnursestation.dto.AdmissionPatientInfoDto"> resultType="com.openhis.web.inhospitalnursestation.dto.AdmissionPatientInfoDto">
WITH locations AS (SELECT ael.encounter_id,
ael.start_time,
al.form_enum,
al.id AS location_id,
al."name" AS location_name
FROM adm_encounter_location ael
LEFT JOIN adm_location al
ON ael.location_id = al.id
AND al.delete_flag = '0'
WHERE ael.status_enum = #{active}
AND ael.delete_flag = '0'),
practitioners AS (SELECT aep.encounter_id,
aep.type_code,
pra.id AS practitioner_id,
pra."name" AS practitioner_name
FROM adm_encounter_participant aep
LEFT JOIN adm_practitioner pra
ON aep.practitioner_id = pra.id
AND pra.delete_flag = '0'
WHERE aep.status_enum = #{active}
AND aep.delete_flag = '0')
SELECT ae.id AS encounter_id, SELECT ae.id AS encounter_id,
ae.bus_no, ae.bus_no,
ae.priority_enum, ae.priority_enum,
@@ -273,27 +252,84 @@
fc.contract_name, fc.contract_name,
diagnosis.condition_names diagnosis.condition_names
FROM adm_encounter ae FROM adm_encounter ae
LEFT JOIN locations AS bed LEFT JOIN (
ON bed.encounter_id = ae.id SELECT ael.encounter_id,
AND bed.form_enum = #{bed} ael.start_time,
LEFT JOIN locations AS house al.id AS location_id,
ON house.encounter_id = ae.id al."name" AS location_name
AND house.form_enum = #{house} FROM adm_encounter_location ael
LEFT JOIN locations AS ward LEFT JOIN adm_location al ON ael.location_id = al.id AND al.delete_flag = '0'
ON ward.encounter_id = ae.id WHERE ael.status_enum = #{active}
AND ward.form_enum = #{ward} AND ael.delete_flag = '0'
LEFT JOIN practitioners AS primaryNurse AND ael.form_enum = #{bed}
ON primaryNurse.encounter_id = ae.id LIMIT 1
AND primaryNurse.type_code = #{primaryNurse} ) AS bed ON bed.encounter_id = ae.id
LEFT JOIN practitioners AS attendingDoctor LEFT JOIN (
ON attendingDoctor.encounter_id = ae.id SELECT ael.encounter_id,
AND attendingDoctor.type_code = #{attendingDoctor} al.id AS location_id,
LEFT JOIN practitioners AS admittingDoctor al."name" AS location_name
ON admittingDoctor.encounter_id = ae.id FROM adm_encounter_location ael
AND admittingDoctor.type_code = #{admittingDoctor} LEFT JOIN adm_location al ON ael.location_id = al.id AND al.delete_flag = '0'
LEFT JOIN practitioners AS chiefDoctor WHERE ael.status_enum = #{active}
ON chiefDoctor.encounter_id = ae.id AND ael.delete_flag = '0'
AND chiefDoctor.type_code = #{chiefDoctor} AND ael.form_enum = #{house}
LIMIT 1
) AS house ON house.encounter_id = ae.id
LEFT JOIN (
SELECT ael.encounter_id,
al.id AS location_id,
al."name" AS location_name
FROM adm_encounter_location ael
LEFT JOIN adm_location al ON ael.location_id = al.id AND al.delete_flag = '0'
WHERE ael.status_enum = #{active}
AND ael.delete_flag = '0'
AND ael.form_enum = #{ward}
LIMIT 1
) AS ward ON ward.encounter_id = ae.id
LEFT JOIN (
SELECT aep.encounter_id,
pra.id AS practitioner_id,
pra."name" AS practitioner_name
FROM adm_encounter_participant aep
LEFT JOIN adm_practitioner pra ON aep.practitioner_id = pra.id AND pra.delete_flag = '0'
WHERE aep.status_enum = #{active}
AND aep.delete_flag = '0'
AND aep.type_code = #{primaryNurse}
LIMIT 1
) AS primaryNurse ON primaryNurse.encounter_id = ae.id
LEFT JOIN (
SELECT aep.encounter_id,
pra.id AS practitioner_id,
pra."name" AS practitioner_name
FROM adm_encounter_participant aep
LEFT JOIN adm_practitioner pra ON aep.practitioner_id = pra.id AND pra.delete_flag = '0'
WHERE aep.status_enum = #{active}
AND aep.delete_flag = '0'
AND aep.type_code = #{attendingDoctor}
LIMIT 1
) AS attendingDoctor ON attendingDoctor.encounter_id = ae.id
LEFT JOIN (
SELECT aep.encounter_id,
pra.id AS practitioner_id,
pra."name" AS practitioner_name
FROM adm_encounter_participant aep
LEFT JOIN adm_practitioner pra ON aep.practitioner_id = pra.id AND pra.delete_flag = '0'
WHERE aep.status_enum = #{active}
AND aep.delete_flag = '0'
AND aep.type_code = #{admittingDoctor}
LIMIT 1
) AS admittingDoctor ON admittingDoctor.encounter_id = ae.id
LEFT JOIN (
SELECT aep.encounter_id,
pra.id AS practitioner_id,
pra."name" AS practitioner_name
FROM adm_encounter_participant aep
LEFT JOIN adm_practitioner pra ON aep.practitioner_id = pra.id AND pra.delete_flag = '0'
WHERE aep.status_enum = #{active}
AND aep.delete_flag = '0'
AND aep.type_code = #{chiefDoctor}
LIMIT 1
) AS chiefDoctor ON chiefDoctor.encounter_id = ae.id
LEFT JOIN adm_organization ao LEFT JOIN adm_organization ao
ON ao.id = ae.organization_id ON ao.id = ae.organization_id
AND ao.delete_flag = '0' AND ao.delete_flag = '0'
@@ -307,47 +343,17 @@
LEFT JOIN fin_contract fc LEFT JOIN fin_contract fc
ON aa.contract_no = fc.bus_no ON aa.contract_no = fc.bus_no
AND fc.delete_flag = '0' AND fc.delete_flag = '0'
LEFT JOIN (SELECT aed.encounter_id, LEFT JOIN (
SELECT aed.encounter_id,
STRING_AGG(ccd.name, ', ') AS condition_names STRING_AGG(ccd.name, ', ') AS condition_names
FROM adm_encounter_diagnosis aed FROM adm_encounter_diagnosis aed
INNER JOIN cli_condition cc INNER JOIN cli_condition cc ON cc.id = aed.condition_id AND cc.delete_flag = '0'
ON cc.id = aed.condition_id INNER JOIN cli_condition_definition ccd ON ccd.id = cc.definition_id AND ccd.delete_flag = '0'
AND cc.delete_flag = '0'
INNER JOIN cli_condition_definition ccd
ON ccd.id = cc.definition_id
AND ccd.delete_flag = '0'
WHERE aed.delete_flag = '0' WHERE aed.delete_flag = '0'
GROUP BY aed.encounter_id) AS diagnosis GROUP BY aed.encounter_id
ON ae.id = diagnosis.encounter_id ) AS diagnosis ON ae.id = diagnosis.encounter_id
WHERE ae.id = #{encounterId} WHERE ae.id = #{encounterId}
AND ae.delete_flag = '0' AND ae.delete_flag = '0'
GROUP BY ae.id,
ae.bus_no,
ae.priority_enum,
ae.organization_id,
ae.start_time,
bed.start_time,
bed.location_id,
bed.location_name,
house.location_id,
house.location_name,
ward.location_id,
ward.location_name,
primaryNurse.practitioner_id,
primaryNurse.practitioner_name,
attendingDoctor.practitioner_id,
attendingDoctor.practitioner_name,
admittingDoctor.practitioner_id,
admittingDoctor.practitioner_name,
chiefDoctor.practitioner_id,
chiefDoctor.practitioner_name,
ao."name",
ap."name",
ap.gender_enum,
ap.birth_date,
ap.phone,
fc.contract_name,
diagnosis.condition_names
</select> </select>
<select id="getAmount" resultType="com.openhis.web.inhospitalnursestation.dto.EncounterAccountDto"> <select id="getAmount" resultType="com.openhis.web.inhospitalnursestation.dto.EncounterAccountDto">
SELECT aa.id, SELECT aa.id,

View File

@@ -347,7 +347,7 @@ const printForm = () => {
}; };
function handleClick() { function handleClick() {
console.log('112313413'); console.log('住院记录表单点击事件触发');
} }
const resetFun = (data) => { const resetFun = (data) => {

View File

@@ -582,7 +582,7 @@ function submitForm() {
console.log('params11========>', JSON.stringify(params)); console.log('params11========>', JSON.stringify(params));
orgRef.value.validate((valid) => { orgRef.value.validate((valid) => {
if (valid) { if (valid) {
console.log('99999999'); console.log('表单验证通过,准备提交数据');
if (form.busNoParent) { if (form.busNoParent) {
if (form.formEnum == 4) { if (form.formEnum == 4) {

View File

@@ -59,12 +59,12 @@ const doRegistering = (row: any) => {
// }) // })
/* 取消 */ /* 取消 */
const cancelAct = () => { const cancelAct = () => {
console.log('121231'); console.log('取消患者列表对话框操作');
} }
/* 保存,登记 */ /* 保存,登记 */
const handleSubmit = () => { const handleSubmit = () => {
console.log('121231'); console.log('提交患者列表对话框操作');
} }
defineExpose({}) defineExpose({})

View File

@@ -544,7 +544,7 @@ function handleDatePickerChange() {
// 清空 // 清空
const onClear = () => { const onClear = () => {
console.log('1111111111'); console.log('费用明细查询条件已清空');
const today = new Date(); const today = new Date();
dateRangeValue.value = [formatDateStr(today, 'YYYY-MM-DD'), formatDateStr(today, 'YYYY-MM-DD')]; dateRangeValue.value = [formatDateStr(today, 'YYYY-MM-DD'), formatDateStr(today, 'YYYY-MM-DD')];

View File

@@ -44,8 +44,8 @@
> >
<div class="bed-card__body"> <div class="bed-card__body">
<div> <div>
<div class="bed-card__title" :title="item.houseName + '-' + item.bedName"> <div class="bed-card__title" :title="(item.houseName || '-') + '-' + (item.bedName || '-')">
{{ item.houseName + '-' + item.bedName }} {{ (item.houseName || '-') + '-' + (item.bedName || '-') }}
</div> </div>
<div class="bed-tag" :class="getBedTagClass(item)"> <div class="bed-tag" :class="getBedTagClass(item)">
{{ item.bedStatus_enumText }} {{ item.bedStatus_enumText }}
@@ -130,6 +130,8 @@ const initInfoOptions = ref<InitInfoOptions>({
priorityOptions: [], priorityOptions: [],
wardListOptions: [], wardListOptions: [],
}); });
// 用于处理单击/双击冲突
let clickTimer = null;
let loadingInstance: any = undefined; let loadingInstance: any = undefined;
// 入院病区loading // 入院病区loading
const selectHosLoding = ref(true); const selectHosLoding = ref(true);
@@ -223,29 +225,38 @@ const queryParams = ref<{
bedStatus: '', // 这个字段现在只用于床位查询,不再用于患者列表查询 bedStatus: '', // 这个字段现在只用于床位查询,不再用于患者列表查询
}); });
const ininData = () => { const ininData = async () => {
Promise.all([ try {
getInit().then((res) => { // 先获取初始化数据
initInfoOptions.value = res.data; const initRes = await getInit();
priorityOptions.value = res.data.priorityOptions || []; initInfoOptions.value = initRes.data;
return res; priorityOptions.value = initRes.data.priorityOptions || [];
}),
getPractitionerWard().then((res) => { // 然后获取科室数据
const wardRes = await getPractitionerWard();
selectHosLoding.value = false; selectHosLoding.value = false;
queryParams.value.wardId = res[0].id; queryParams.value.wardId = wardRes[0]?.id || '';
initInfoOptions.value.wardListOptions = res; initInfoOptions.value.wardListOptions = wardRes;
return changeWardLocationId(res[0].id, true); // 传入 true 表示初始化阶段,不调用 getList
}), // 获取病房数据
]).then(() => { if (wardRes[0]?.id) {
await changeWardLocationId(wardRes[0].id, true); // 传入 true 表示初始化阶段,不调用 getList
}
// 最后获取列表数据
getList(); getList();
}); } catch (error) {
console.error('初始化数据失败:', error);
// 即使某个请求失败,也要尝试加载列表
getList();
}
}; };
onMounted(() => { onMounted(() => {
ininData(); ininData();
}); });
const refreshTap = () => { const refreshTap = async () => {
ininData(); await ininData();
}; };
defineExpose({ state, refreshTap }); defineExpose({ state, refreshTap });
@@ -257,23 +268,32 @@ const filteredBadList = computed(() => {
return badList.value.filter((item) => item.bedStatus == bedStatusFilter.value); return badList.value.filter((item) => item.bedStatus == bedStatusFilter.value);
}); });
const getList = () => { const getList = async () => {
loadingInstance = ElLoading.service({ fullscreen: true }); loadingInstance = ElLoading.service({ fullscreen: true });
getPatientList();
// 床位查询不使用encounterStatus参数只使用基本的查询参数 try {
const bedQueryParams = { // 并行获取患者列表和床位列表
const [patientData, bedRes] = await Promise.all([
getPatientList(),
getBedInfo({
...queryParams.value, ...queryParams.value,
encounterStatus: undefined, // 移除encounterStatus确保不影响床位列表查询 encounterStatus: undefined, // 移除encounterStatus确保不影响床位列表查询
}; })
]);
getBedInfo(bedQueryParams).then((res) => { // 更新床位列表
badList.value = bedRes.data.records;
} catch (error) {
console.error('获取列表数据失败:', error);
} finally {
if (loadingInstance) {
loadingInstance.close(); loadingInstance.close();
badList.value = res.data.records; }
}); }
}; };
// 重置查询条件 // 重置查询条件
function resetQuery() { async function resetQuery() {
// 不重置入院病区 // 不重置入院病区
const resetParams = { const resetParams = {
...queryParams.value, ...queryParams.value,
@@ -288,7 +308,7 @@ function resetQuery() {
bedStatus: '', bedStatus: '',
}; };
bedStatusFilter.value = ''; bedStatusFilter.value = '';
getList(); await getList();
} }
// 入院病区下拉选 // 入院病区下拉选
function changeWardLocationId(id: string | number, isInit = false) { function changeWardLocationId(id: string | number, isInit = false) {
@@ -302,41 +322,72 @@ function changeWardLocationId(id: string | number, isInit = false) {
selectHoouseLoding.value = false; selectHoouseLoding.value = false;
wardLocationList.value = res; wardLocationList.value = res;
if (!isInit) { if (!isInit) {
getList(); // 在非初始化情况下,需要同时更新患者列表和床位列表
getPatientList();
// 床位查询不使用encounterStatus参数只使用基本的查询参数
const bedQueryParams = {
...queryParams.value,
encounterStatus: undefined, // 移除encounterStatus确保不影响床位列表查询
};
getBedInfo(bedQueryParams).then((bedRes) => {
badList.value = bedRes.data.records;
});
} }
return res; return res;
}); });
} }
// 入院病房下拉选 // 入院病房下拉选
const onHosHouse = () => { const onHosHouse = async () => {
getList(); await getList();
}; };
// 住院状态下拉选 // 住院状态下拉选
const onHosStatus = () => { const onHosStatus = async () => {
getList(); await getList();
}; };
// 获新入院患者列表 // 获新入院患者列表
function getPatientList() { async function getPatientList() {
// 为患者列表查询创建一个新的参数对象不包含bedStatus // 为患者列表查询创建一个新的参数对象不包含bedStatus
const patientQueryParams = { const patientQueryParams = {
...queryParams.value, ...queryParams.value,
bedStatus: undefined, // 移除bedStatus确保不影响患者列表查询 bedStatus: undefined, // 移除bedStatus确保不影响患者列表查询
}; };
getPendingInfo(patientQueryParams).then((res) => { try {
const res = await getPendingInfo(patientQueryParams);
loading.value = false; loading.value = false;
patientList.value = res.data.records; patientList.value = res.data.records;
total.value = res.data.total; total.value = res.data.total;
}); return res;
} catch (error) {
console.error('获取患者列表失败:', error);
throw error;
}
} }
const handleTransferInOk = () => { const handleTransferInOk = async () => {
transferInDialogVisible.value = false; transferInDialogVisible.value = false;
getList(); await getList();
}; };
function handleCardClick(item: any, index: number) {} // 单击患者卡片事件 - 直接触发入科选床界面
function handleCardClick(item: any, index: number) {
if (item.encounterStatus == 2) {
ElMessage({
message: '请分配病床!',
type: 'warning',
grouping: true,
showClose: true,
});
} else {
pendingInfo.value = {
...item,
entranceType: 1,
};
// 双击患者卡片事件 transferInDialogVisible.value = true;
}
}
// 双击患者卡片事件 - 保持原有逻辑
function handleCardDblClick(item: any) { function handleCardDblClick(item: any) {
if (item.encounterStatus == 2) { if (item.encounterStatus == 2) {
ElMessage({ ElMessage({
@@ -367,8 +418,8 @@ function handleDragStart(event: DragEvent, item: any) {
} }
} }
function handleQuery() { async function handleQuery() {
getList(); await getList();
} }
// 拖拽结束事件 // 拖拽结束事件

View File

@@ -17,7 +17,7 @@
<div class="patient-info"> <div class="patient-info">
<div style="display: flex; align-items: center; margin-bottom: 16px"> <div style="display: flex; align-items: center; margin-bottom: 16px">
<div style="margin-right: 36px; font-size: 18px; font-weight: 700"> <div style="margin-right: 36px; font-size: 18px; font-weight: 700">
{{ props.pendingInfo.houseName + '-' + props.pendingInfo.bedName }} {{ (props.pendingInfo.houseName || '-') + '-' + (props.pendingInfo.bedName || '-') }}
</div> </div>
<div style="border-radius: 50px; border: 2px solid slategray; padding: 4px 12px"> <div style="border-radius: 50px; border: 2px solid slategray; padding: 4px 12px">
{{ props.pendingInfo.contractName }} {{ props.pendingInfo.contractName }}

View File

@@ -746,25 +746,42 @@ function handleGetDRMedication() {
}); });
} }
const initData = () => { const initData = async () => {
getInit().then((res) => { try {
initInfoOptions.value = res.data; // 并行获取初始化数据和科室数据
const [initRes, wardRes] = await Promise.all([
getInit(),
getPractitionerWard()
]);
// 处理初始化数据
initInfoOptions.value = initRes.data;
// 处理科室数据
queryParams.value.wardId = wardRes[0]?.id || '';
initInfoOptions.value.wardListOptions = wardRes;
// 获取病房数据
if (wardRes[0]?.id) {
changeWardLocationId(wardRes[0].id);
}
// 最后获取患者列表
getPatientList(); getPatientList();
}); } catch (error) {
getPractitionerWard().then((res) => { console.error('初始化数据失败:', error);
queryParams.value.wardId = res[0].id; // 即使初始化失败,也要尝试加载患者列表
initInfoOptions.value.wardListOptions = res; getPatientList();
changeWardLocationId(res[0].id); }
});
}; };
// 初始化加载患者列表 // 初始化加载患者列表
onMounted(() => { onMounted(async () => {
initData(); await initData();
}); });
const refreshTap = () => { const refreshTap = async () => {
console.log('22222223'); console.log('刷新转科/出院页面数据');
initData(); await initData();
}; };
defineExpose({ refreshTap }); defineExpose({ refreshTap });
</script> </script>

View File

@@ -44,16 +44,15 @@ const thirdRef = ref();
onBeforeMount(() => {}); onBeforeMount(() => {});
onMounted(() => {}); onMounted(() => {});
defineExpose({ state }); defineExpose({ state });
const test = () => { const test = async () => {
nextTick(() => { await nextTick();
if (activeTabName.value == 'first') { if (activeTabName.value == 'first') {
firstRef?.value?.refreshTap(); await firstRef?.value?.refreshTap();
} else if (activeTabName.value == 'second') { } else if (activeTabName.value == 'second') {
secondRef?.value?.refreshTap(); await secondRef?.value?.refreshTap();
} else if (activeTabName.value == 'third') { } else if (activeTabName.value == 'third') {
thirdRef?.value?.refreshTap(); await thirdRef?.value?.refreshTap();
} }
});
}; };
const activeTabName = ref('first'); const activeTabName = ref('first');

View File

@@ -496,7 +496,7 @@ const dateChange = () => {
}; };
// 计算时间 // 计算时间
rulesFrom.value.recordTime = computed(() => { rulesFrom.value.recordTime = computed(() => {
console.log('11111111111111'); console.log('操作记录时间计算', rulesFrom.value.date + ' ' + rulesFrom.value.time);
return rulesFrom.value.date + ' ' + rulesFrom.value.time; return rulesFrom.value.date + ' ' + rulesFrom.value.time;
}); });

View File

@@ -274,7 +274,7 @@ function init1(data) {
* 点击患者列表行 获取患者体温单数据 * 点击患者列表行 获取患者体温单数据
*/ */
function viewPatient(row) { function viewPatient(row) {
console.log('1232312123221231'); console.log('查看患者体温单数据', row.patientName);
patientInfo.value = row; patientInfo.value = row;
console.log('点击患者列表行 获取患者体温单数据', row); console.log('点击患者列表行 获取患者体温单数据', row);

View File

@@ -557,7 +557,7 @@ watch(
queryParams.value.dispenseTimeETime = newQuery.occurrenceTimeETime + ' 23:59:59'; queryParams.value.dispenseTimeETime = newQuery.occurrenceTimeETime + ' 23:59:59';
} }
queryParams.value.flag = 1; queryParams.value.flag = 1;
console.log('11111111111111'); console.log('药品明细查询参数已设置完成');
// 执行查询 // 执行查询
getList(); getList();

View File

@@ -218,7 +218,7 @@ watch(
if (currentMonth < birthMonth || (currentMonth === birthMonth && currentDay < birthDay)) { if (currentMonth < birthMonth || (currentMonth === birthMonth && currentDay < birthDay)) {
age--; age--;
} }
console.log('22222222'); console.log('计算患者年龄完成:', age);
form.value.age = age; form.value.age = age;
} }