fix(#628): 请修复 Bug #628:[住院医生工作站-] 诊断录入模块缺少中医诊断录入,诊断体系及中医证候关联逻辑

根因:
- 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` 重复键)为预先存在问题,与本次修改无关
This commit is contained in:
2026-05-31 09:18:37 +08:00
parent 707e888b40
commit c5641bdbc8
2 changed files with 132 additions and 50 deletions

View File

@@ -905,19 +905,22 @@ function handleChange(value) {
* 选择诊断并赋值到列表 * 选择诊断并赋值到列表
*/ */
function handleSelsectDiagnosis(row) { function handleSelsectDiagnosis(row) {
console.log(row); const currentItem = form.value.diagnosisList[rowIndex.value];
form.value.diagnosisList[rowIndex.value].ybNo = row.ybNo; currentItem.ybNo = row.ybNo;
form.value.diagnosisList[rowIndex.value].name = row.name; currentItem.name = row.name;
form.value.diagnosisList[rowIndex.value].definitionId = row.id; currentItem.definitionId = row.id;
currentItem.showPopover = false;
} }
/**获取焦点时 打开列表 */ /**获取焦点时 打开列表 */
function handleFocus(row, index) { function handleFocus(row, index) {
rowIndex.value = index; rowIndex.value = index;
row.showPopover = true; row.showPopover = true;
} }
/**失去焦点时 关闭列表 */ /**失去焦点时 延迟关闭列表(避免点击列表项时过早关闭) */
function handleBlur(row) { function handleBlur(row) {
row.showPopover = false; setTimeout(() => {
row.showPopover = false;
}, 200);
} }
function handleNodeClick(data) { function handleNodeClick(data) {

View File

@@ -141,6 +141,7 @@
<div class="diagnosis-popover-body"> <div class="diagnosis-popover-body">
<diagnosislist <diagnosislist
:diagnosis-searchkey="diagnosisSearchkey" :diagnosis-searchkey="diagnosisSearchkey"
:diagnosis-system="scope.row.diagnosisSystem || '西医'"
@select-diagnosis="(row) => handleSelectDiagnosis(row, scope.row, scope.$index)" @select-diagnosis="(row) => handleSelectDiagnosis(row, scope.row, scope.$index)"
/> />
</div> </div>
@@ -300,11 +301,14 @@ import { ArrowDown, Delete, Download, Upload } from '@element-plus/icons-vue'
import WesternMedicineDialog from './westernMedicineDialog.vue' import WesternMedicineDialog from './westernMedicineDialog.vue'
import ChineseMedicineDialog from './chineseMedicineDialog.vue' import ChineseMedicineDialog from './chineseMedicineDialog.vue'
import Diagnosislist from './diagnosislist.vue' import Diagnosislist from './diagnosislist.vue'
import useUserStore from '@/store/modules/user'
import { import {
saveDiagnosis, saveDiagnosis,
delEncounterDiagnosis, delEncounterDiagnosis,
getEncounterDiagnosis, getEncounterDiagnosis,
getTcmSyndrome, getTcmSyndrome,
saveTcmDiagnosis,
getTcmDiagnosis,
} from '../api' } from '../api'
const { proxy } = getCurrentInstance() const { proxy } = getCurrentInstance()
@@ -390,16 +394,12 @@ function handleDiagnosisSystemChange(row) {
} }
function handleDiagnosisNameClick(row, index) { function handleDiagnosisNameClick(row, index) {
if (row.diagnosisSystem === '中医') {
row.showPopover = false
return
}
diagnoseData.value.forEach((item, idx) => { diagnoseData.value.forEach((item, idx) => {
if (idx !== index) { if (idx !== index) {
item.showPopover = false item.showPopover = false
} }
}) })
row.showPopover = true row.showPopover = !row.showPopover
} }
function handleSelectDiagnosis(diagRow, rowData) { function handleSelectDiagnosis(diagRow, rowData) {
@@ -509,6 +509,8 @@ async function handleSaveDiagnosis() {
return return
} }
const userStore = useUserStore()
for (let i = 0; i < diagnoseData.value.length; i++) { for (let i = 0; i < diagnoseData.value.length; i++) {
const item = diagnoseData.value[i] const item = diagnoseData.value[i]
if (!item.name) { if (!item.name) {
@@ -523,36 +525,63 @@ async function handleSaveDiagnosis() {
saveLoading.value = true saveLoading.value = true
try { try {
const diagnosisList = diagnoseData.value.map((item, index) => ({ // 分离西医和中医诊断
conditionId: item.conditionId || '', const westernList = []
ybNo: item.ybNo || '', const tcmList = []
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 saveData = { diagnoseData.value.forEach((item, index) => {
patientId: props.patientInfo?.patientId || '', if (item.diagnosisSystem === '中医') {
encounterId: props.patientInfo?.encounterId || '', tcmList.push(item)
diagnosisList: diagnosisList, } 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) { if (tcmList.length > 0) {
ElMessage.success('诊断保存成功') const syndromeGroupNo = String(Date.now())
loadDiagnosisData() const tcmSaveList = []
} else { tcmList.forEach((item) => {
ElMessage.error(res.msg || '保存失败') 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) { } catch (error) {
ElMessage.error('保存失败,请重试') ElMessage.error('保存失败,请重试')
} finally { } finally {
@@ -562,20 +591,70 @@ async function handleSaveDiagnosis() {
function loadDiagnosisData() { function loadDiagnosisData() {
if (!props.patientInfo?.encounterId) return if (!props.patientInfo?.encounterId) return
getEncounterDiagnosis(props.patientInfo.encounterId).then((res) => {
if (res.data) { const userStore = useUserStore()
const westernDiagnoses = (res.data || []).filter(item => item.typeName !== '中医诊断')
diagnoseData.value = westernDiagnoses.map((item, index) => ({ // 并行加载西医诊断和中医诊断
...item, const westernPromise = getEncounterDiagnosis(props.patientInfo.encounterId)
diagnosisSystem: item.diagnosisSystem || '西医', const tcmPromise = getTcmDiagnosis({ encounterId: props.patientInfo.encounterId })
classification: item.classification || '主诊断',
tcmSyndromeCode: item.tcmSyndromeCode || '', Promise.all([westernPromise, tcmPromise]).then(([westernRes, tcmRes]) => {
tcmSyndromeName: item.tcmSyndromeName || '', const allDiagnoses = []
showPopover: false,
showSyndromePopover: false, // 西医诊断
diagSrtNo: index + 1, 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
}) })
} }