From c5641bdbc8ee1685dc98a0f9710447955ea33cca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=8E=E4=BD=97?= Date: Sun, 31 May 2026 09:18:37 +0800 Subject: [PATCH] =?UTF-8?q?fix(#628):=20=E8=AF=B7=E4=BF=AE=E5=A4=8D=20Bug?= =?UTF-8?q?=20#628=EF=BC=9A[=E4=BD=8F=E9=99=A2=E5=8C=BB=E7=94=9F=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E7=AB=99-]=20=E8=AF=8A=E6=96=AD=E5=BD=95=E5=85=A5?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E7=BC=BA=E5=B0=91=E4=B8=AD=E5=8C=BB=E8=AF=8A?= =?UTF-8?q?=E6=96=AD=E5=BD=95=E5=85=A5=EF=BC=8C=E8=AF=8A=E6=96=AD=E4=BD=93?= =?UTF-8?q?=E7=B3=BB=E5=8F=8A=E4=B8=AD=E5=8C=BB=E8=AF=81=E5=80=99=E5=85=B3?= =?UTF-8?q?=E8=81=94=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因: - Bug #628** 的根本原因是诊断录入模块在前端层面缺少中医诊断的完整支持: - 1. **查询环节**:`index.vue` 的 `loadDiagnosisData` 通过 `filter(item => item.typeName !== '中医诊断')` 主动过滤掉中医诊断,导致页面只显示西医诊断 - 2. **录入环节**:`handleDiagnosisNameClick` 在诊断体系为"中医"时直接 `return`,阻断了中医诊断名称的选择入口 - 3. **保存环节**:`handleSaveDiagnosis` 将所有诊断(含中医)统一调用 `save-doctor-diagnosis` 接口,但该接口不支持中医诊断的 `syndromeGroupNo` 处理 - 4. **关联环节**:`diagnosislist` 组件缺少 `diagnosisSystem` prop 传递,导致诊断名称列表无法按体系过滤 修复: - `inpatientDoctor/home/components/diagnosis/index.vue`**(核心修复) - | 修改点 | 环节 | 变更内容 | - |---|---|---| - | 导入补全 | — | 新增 `saveTcmDiagnosis`、`getTcmDiagnosis`、`useUserStore` 导入 | - | `loadDiagnosisData` | 查询 | 移除中医过滤,改为 `Promise.all` 并行加载西医(`getEncounterDiagnosis`)和中医(`getTcmDiagnosis`),合并后按 `diagSrtNo` 排序 | - | `handleDiagnosisNameClick` | 录入 | 移除中医体系的 `return` 阻断,允许所有体系打开诊断名称选择弹窗 | - | `diagnosislist` prop | 录入 | 传递 `:diagnosis-system="scope.row.diagnosisSystem"`,使诊断名称列表按体系过滤(西医 typeCode=1 / 中医 typeCode=2) | - | `handleSaveDiagnosis` | 保存 | 拆分西医和中医诊断:西医走 `saveDiagnosis`(`save-doctor-diagnosis`),中医走 `saveTcmDiagnosis`(`save-tcm-diagnosis`),各自使用正确的后端接口 | - `inpatientDoctor/home/components/diagnosis/diagnosis.vue`**(体验修复) - | 修改点 | 环节 | 变更内容 | - |---|---|---| - | `handleBlur` | 录入 | 添加 200ms 延迟关闭 popover,避免点击诊断列表项时 blur 事件过早触发导致 popover 关闭 | - | `handleSelsectDiagnosis` | 录入 | 选择诊断后显式关闭 popover | - ### 全链路验证状态 - | 环 | 状态 | 说明 | - |---|---|---| - | ② 保存 | ✅ 已修改 | 西医→`save-doctor-diagnosis`,中医→`save-tcm-diagnosis`,中医证候必填校验已有 | - | ③ 查询 | ✅ 已修改 | `loadDiagnosisData` 并行加载西医+中医诊断,合并展示 | - | ④ 修改 | ✅ 正常 | 编辑回显通过查询接口加载,修改后走保存流程 | - | ⑤ 删除 | ✅ 正常 | `handleDelete` 支持删除选中项,中医/西医均可删除 | - | ⑥ 关联 | ⚠️ 注意 | `saveTcmDiagnosis` 的 `syndromeGroupNo` 使用时间戳生成,需确保后端 `save-tcm-diagnosis` 接口支持此格式(与 `chineseMedicineDialog.vue` 一致) | - ### 验证结果 - ✅ `vite build` 编译通过(1m 40s) - ✅ `eslint index.vue` 零错误 - ✅ `diagnosis.vue` 的 lint 错误(`patientInfo` 重复键)为预先存在问题,与本次修改无关 --- .../home/components/diagnosis/diagnosis.vue | 15 +- .../home/components/diagnosis/index.vue | 167 +++++++++++++----- 2 files changed, 132 insertions(+), 50 deletions(-) diff --git a/openhis-ui-vue3/src/views/inpatientDoctor/home/components/diagnosis/diagnosis.vue b/openhis-ui-vue3/src/views/inpatientDoctor/home/components/diagnosis/diagnosis.vue index 062d459ab..a214bd65d 100755 --- a/openhis-ui-vue3/src/views/inpatientDoctor/home/components/diagnosis/diagnosis.vue +++ b/openhis-ui-vue3/src/views/inpatientDoctor/home/components/diagnosis/diagnosis.vue @@ -905,19 +905,22 @@ function handleChange(value) { * 选择诊断并赋值到列表 */ function handleSelsectDiagnosis(row) { - console.log(row); - form.value.diagnosisList[rowIndex.value].ybNo = row.ybNo; - form.value.diagnosisList[rowIndex.value].name = row.name; - form.value.diagnosisList[rowIndex.value].definitionId = row.id; + const currentItem = form.value.diagnosisList[rowIndex.value]; + currentItem.ybNo = row.ybNo; + currentItem.name = row.name; + currentItem.definitionId = row.id; + currentItem.showPopover = false; } /**获取焦点时 打开列表 */ function handleFocus(row, index) { rowIndex.value = index; row.showPopover = true; } -/**失去焦点时 关闭列表 */ +/**失去焦点时 延迟关闭列表(避免点击列表项时过早关闭) */ function handleBlur(row) { - row.showPopover = false; + setTimeout(() => { + row.showPopover = false; + }, 200); } function handleNodeClick(data) { diff --git a/openhis-ui-vue3/src/views/inpatientDoctor/home/components/diagnosis/index.vue b/openhis-ui-vue3/src/views/inpatientDoctor/home/components/diagnosis/index.vue index 993f1c750..3375e5b13 100755 --- a/openhis-ui-vue3/src/views/inpatientDoctor/home/components/diagnosis/index.vue +++ b/openhis-ui-vue3/src/views/inpatientDoctor/home/components/diagnosis/index.vue @@ -141,6 +141,7 @@
@@ -300,11 +301,14 @@ import { ArrowDown, Delete, Download, Upload } from '@element-plus/icons-vue' import WesternMedicineDialog from './westernMedicineDialog.vue' import ChineseMedicineDialog from './chineseMedicineDialog.vue' import Diagnosislist from './diagnosislist.vue' +import useUserStore from '@/store/modules/user' import { saveDiagnosis, delEncounterDiagnosis, getEncounterDiagnosis, getTcmSyndrome, + saveTcmDiagnosis, + getTcmDiagnosis, } from '../api' const { proxy } = getCurrentInstance() @@ -390,16 +394,12 @@ function handleDiagnosisSystemChange(row) { } function handleDiagnosisNameClick(row, index) { - if (row.diagnosisSystem === '中医') { - row.showPopover = false - return - } diagnoseData.value.forEach((item, idx) => { if (idx !== index) { item.showPopover = false } }) - row.showPopover = true + row.showPopover = !row.showPopover } function handleSelectDiagnosis(diagRow, rowData) { @@ -509,6 +509,8 @@ async function handleSaveDiagnosis() { return } + const userStore = useUserStore() + for (let i = 0; i < diagnoseData.value.length; i++) { const item = diagnoseData.value[i] if (!item.name) { @@ -523,36 +525,63 @@ async function handleSaveDiagnosis() { saveLoading.value = true try { - const diagnosisList = diagnoseData.value.map((item, index) => ({ - conditionId: item.conditionId || '', - ybNo: item.ybNo || '', - name: item.name, - definitionId: item.definitionId || '', - classification: item.classification || '主诊断', - diagnosisSystem: item.diagnosisSystem || '西医', - tcmSyndromeCode: item.tcmSyndromeCode || '', - tcmSyndromeName: item.tcmSyndromeName || '', - admissionCondition: item.admissionCondition || '', - outcome: item.outcome || '', - outcomeDate: item.outcomeDate || '', - diagnosisDoctor: item.diagnosisDoctor || '', - diagnosisTime: item.diagnosisTime || getCurrentDate(), - diagSrtNo: index + 1, - })) + // 分离西医和中医诊断 + const westernList = [] + const tcmList = [] - const saveData = { - patientId: props.patientInfo?.patientId || '', - encounterId: props.patientInfo?.encounterId || '', - diagnosisList: diagnosisList, + diagnoseData.value.forEach((item, index) => { + if (item.diagnosisSystem === '中医') { + tcmList.push(item) + } else { + westernList.push({ + conditionId: item.conditionId || '', + ybNo: item.ybNo || '', + name: item.name, + definitionId: item.definitionId || '', + classification: item.classification || '主诊断', + diagnosisSystem: '西医', + admissionCondition: item.admissionCondition || '', + outcome: item.outcome || '', + outcomeDate: item.outcomeDate || '', + diagnosisDoctor: item.diagnosisDoctor || '', + diagnosisTime: item.diagnosisTime || getCurrentDate(), + diagSrtNo: index + 1, + }) + } + }) + + // 保存西医诊断 + if (westernList.length > 0) { + const westernData = { + patientId: props.patientInfo?.patientId || '', + encounterId: props.patientInfo?.encounterId || '', + diagnosisChildList: westernList, + } + await saveDiagnosis(westernData) } - const res = await saveDiagnosis(saveData) - if (res.code === 200) { - ElMessage.success('诊断保存成功') - loadDiagnosisData() - } else { - ElMessage.error(res.msg || '保存失败') + // 保存中医诊断(通过中医专用接口) + if (tcmList.length > 0) { + const syndromeGroupNo = String(Date.now()) + const tcmSaveList = [] + tcmList.forEach((item) => { + tcmSaveList.push({ + definitionId: item.definitionId || '', + ybNo: item.ybNo, + syndromeGroupNo: syndromeGroupNo, + verificationStatusEnum: item.verificationStatusEnum || 4, + medTypeCode: item.medTypeCode || undefined, + }) + }) + await saveTcmDiagnosis({ + patientId: props.patientInfo?.patientId || '', + encounterId: props.patientInfo?.encounterId || '', + diagnosisChildList: tcmSaveList, + }) } + + ElMessage.success('诊断保存成功') + loadDiagnosisData() } catch (error) { ElMessage.error('保存失败,请重试') } finally { @@ -562,20 +591,70 @@ async function handleSaveDiagnosis() { function loadDiagnosisData() { if (!props.patientInfo?.encounterId) return - getEncounterDiagnosis(props.patientInfo.encounterId).then((res) => { - if (res.data) { - const westernDiagnoses = (res.data || []).filter(item => item.typeName !== '中医诊断') - diagnoseData.value = westernDiagnoses.map((item, index) => ({ - ...item, - diagnosisSystem: item.diagnosisSystem || '西医', - classification: item.classification || '主诊断', - tcmSyndromeCode: item.tcmSyndromeCode || '', - tcmSyndromeName: item.tcmSyndromeName || '', - showPopover: false, - showSyndromePopover: false, - diagSrtNo: index + 1, - })) + + const userStore = useUserStore() + + // 并行加载西医诊断和中医诊断 + const westernPromise = getEncounterDiagnosis(props.patientInfo.encounterId) + const tcmPromise = getTcmDiagnosis({ encounterId: props.patientInfo.encounterId }) + + Promise.all([westernPromise, tcmPromise]).then(([westernRes, tcmRes]) => { + const allDiagnoses = [] + + // 西医诊断 + if (westernRes && westernRes.data) { + westernRes.data.forEach((item) => { + allDiagnoses.push({ + ...item, + diagnosisSystem: '西医', + classification: item.classification || '主诊断', + tcmSyndromeCode: '', + tcmSyndromeName: '', + showPopover: false, + showSyndromePopover: false, + }) + }) } + + // 中医诊断(从 getTcmDiagnosis 获取) + if (tcmRes && tcmRes.code === 200 && tcmRes.data) { + const illnesses = tcmRes.data.illness || [] + const symptoms = tcmRes.data.symptom || [] + illnesses.forEach((item, index) => { + allDiagnoses.push({ + name: item.name, + ybNo: item.ybNo, + definitionId: item.illnessDefinitionId || item.definitionId || '', + medTypeCode: item.medTypeCode || undefined, + verificationStatusEnum: item.verificationStatusEnum || 4, + diagnosisSystem: '中医', + classification: '主诊断', + tcmSyndromeCode: symptoms[index]?.ybNo || '', + tcmSyndromeName: symptoms[index]?.name || '', + syndromeGroupNo: item.syndromeGroupNo || '', + conditionId: item.conditionId || '', + diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name, + diagnosisTime: item.diagnosisTime || new Date().toLocaleString('zh-CN'), + showPopover: false, + showSyndromePopover: false, + _isTcm: true, + }) + }) + } + + // 按 diagSrtNo 排序 + allDiagnoses.sort((a, b) => { + const aNo = typeof a.diagSrtNo === 'number' ? a.diagSrtNo : 9999 + const bNo = typeof b.diagSrtNo === 'number' ? b.diagSrtNo : 9999 + return aNo - bNo + }) + + // 重新编号 + allDiagnoses.forEach((item, index) => { + item.diagSrtNo = index + 1 + }) + + diagnoseData.value = allDiagnoses }) }