fix(diagnosis): 修复中医诊断弹窗数据残留、重复及表格数据不一致问题

问题:
  1. 中医诊断弹窗关闭后重新打开,右侧诊断详情区仍显示已删除的诊断
  2. 诊断详情区出现重复的诊断数据
  3. 弹窗显示的中医诊断在诊断表格中不显示(两边数据不一致)
This commit is contained in:
wangjian963
2026-06-23 14:27:01 +08:00
parent ff105d0800
commit 9689e4610a
2 changed files with 101 additions and 23 deletions

View File

@@ -169,24 +169,36 @@ const selectedDisease = ref(false);
const { proxy } = getCurrentInstance();
const emit = defineEmits(['close']);
// 请求序列号,防止异步回调竞态导致数据重复
let openSeq = 0;
// 获取诊断类型字典
const { diag_type } = proxy.useDict('diag_type');
function handleOpen() {
// 递增序列号,使之前未完成的异步回调失效
const currentSeq = ++openSeq;
console.log('[addDiagnosisDialog] handleOpen() 触发, seq=', currentSeq, 'updateZy长度=', props.updateZy.length);
// 获取诊断列表
getTcmCondition().then((res) => {
// 仅当是最新请求时才更新数据
if (currentSeq !== openSeq) return;
conditionList.value = res.data.records;
console.log('[addDiagnosisDialog] 诊断列表加载完成, 条数=', res.data.records?.length);
});
// 清空数据
// 清空数据(同步清空,确保每次打开弹窗都是干净的状态)
tcmDiagonsisSaveList.value = [];
tcmDiagonsisList.value = [];
syndromeSelected.value = true; // 设置为true允许添加新的诊断
console.log('[addDiagnosisDialog] 列表已清空, tcmDiagonsisList.length=', tcmDiagonsisList.value.length);
// 如果是修改模式,加载传入的诊断数据
if (props.updateZy.length > 0) {
console.log('[addDiagnosisDialog] 编辑模式, 从updateZy加载数据:', JSON.stringify(props.updateZy));
props.updateZy.forEach((item) => {
let updateIds = item.updateId.split("-");
let name = item.name.split("-");
@@ -218,14 +230,33 @@ function handleOpen() {
});
syndromeSelected.value = true;
});
console.log('[addDiagnosisDialog] 编辑模式加载完成, tcmDiagonsisList=', JSON.stringify(tcmDiagonsisList.value));
} else {
// 不是修改模式,加载已保存的中医诊断
console.log('[addDiagnosisDialog] 新增模式, 从API加载已有诊断, encounterId=', props.patientInfo?.encounterId);
if (props.patientInfo && props.patientInfo.encounterId) {
getTcmDiagnosis({ encounterId: props.patientInfo.encounterId }).then((res) => {
// 添加时间戳参数防止浏览器缓存,确保每次打开弹窗都获取最新数据
getTcmDiagnosis({ encounterId: props.patientInfo.encounterId, _t: Date.now() }).then((res) => {
// 仅当是最新请求时才更新数据,防止旧回调污染列表
if (currentSeq !== openSeq) {
console.log('[addDiagnosisDialog] API响应被丢弃(seq不匹配), currentSeq=', currentSeq, 'openSeq=', openSeq);
return;
}
console.log('[addDiagnosisDialog] API返回 getTcmDiagnosis, code=', res.code, 'illness条数=', res.data?.illness?.length);
if (res.code === 200 && res.data.illness && res.data.illness.length > 0) {
// 用于去重的集合:疾病名+证候名
const seenPairs = new Set();
res.data.illness.forEach((item, index) => {
const symptom = res.data.symptom[index];
if (symptom) {
const pairKey = item.name + '|' + symptom.name;
// 如果已存在完全相同的疾病+证候组合,跳过(防止数据库中已有重复数据显示多次)
if (seenPairs.has(pairKey)) {
console.log('[addDiagnosisDialog] 跳过重复已有诊断: illness=', item.name, 'symptom=', symptom.name, 'syndromeGroupNo=', item.syndromeGroupNo);
return;
}
seenPairs.add(pairKey);
console.log('[addDiagnosisDialog] 添加已有诊断: illness=', item.name, 'symptom=', symptom.name, 'syndromeGroupNo=', item.syndromeGroupNo);
// 添加到显示列表
tcmDiagonsisList.value.push({
conditionName: item.name,
@@ -233,7 +264,7 @@ function handleOpen() {
syndromeGroupNo: item.syndromeGroupNo,
isExisting: true // 标记为已存在
});
// 添加到保存列表
tcmDiagonsisSaveList.value.push(
{
@@ -257,8 +288,13 @@ function handleOpen() {
);
}
});
console.log('[addDiagnosisDialog] 加载完成, tcmDiagonsisList=', JSON.stringify(tcmDiagonsisList.value));
} else {
console.log('[addDiagnosisDialog] 没有已有诊断数据');
}
}).catch(err => {
// 忽略过期请求的错误
if (currentSeq !== openSeq) return;
console.error('加载已保存的中医诊断失败:', err);
});
}
@@ -268,14 +304,16 @@ function handleOpen() {
// 点击诊断列表处理,点击以后才显示证候列表
// vxe-table v4 cell-click 事件参数为 { row, column, rowIndex, ... },需解构获取实际行数据
function handleClickRow({ row }) {
console.log('[addDiagnosisDialog] handleClickRow 触发, row.name=', row.name, 'syndromeSelected=', syndromeSelected.value, 'listLength=', tcmDiagonsisList.value.length);
if (syndromeSelected.value || tcmDiagonsisList.value.length == 0) {
syndromeSelected.value = false;
selectedDisease.value = true;
timestamp.value = Date.now();
console.log('[addDiagnosisDialog] 添加新诊断: disease=', row.name, 'syndromeGroupNo=', timestamp.value);
getTcmSyndrome().then((res) => {
syndromeList.value = res.data.records;
});
// 添加新的诊断
tcmDiagonsisSaveList.value.push({
definitionId: row.id,
@@ -290,22 +328,23 @@ function handleClickRow({ row }) {
syndromeGroupNo: timestamp.value,
isExisting: false // 标记为新增
});
console.log('[addDiagnosisDialog] 添加后 tcmDiagonsisList=', JSON.stringify(tcmDiagonsisList.value));
}
}
// vxe-table v4 cell-click 事件参数为 { row, column, rowIndex, ... },需解构获取实际行数据
function clickSyndromeRow({ row }) {
// 检查是否已存在完全相同的诊断和证候
// 检查是否已存在完全相同的诊断和证候(包括已保存的和当前新增的)
let flag = true;
const currentConditionName = tcmDiagonsisList.value[tcmDiagonsisList.value.length - 1].conditionName;
tcmDiagonsisList.value.forEach(item => {
if (item.conditionName === currentConditionName && item.syndromeName === row.name) {
proxy.$modal.msgWarning('不能存在完全相同的诊断和证候');
flag = false;
}
});
if (flag) {
tcmDiagonsisSaveList.value.push({
definitionId: row.id,
@@ -321,29 +360,33 @@ function clickSyndromeRow({ row }) {
// 删除诊断
function removeDiagnosis(row, index) {
console.log('[addDiagnosisDialog] removeDiagnosis 触发, row=', JSON.stringify(row), 'index=', index);
tcmDiagonsisList.value.splice(index, 1);
tcmDiagonsisSaveList.value = tcmDiagonsisSaveList.value.filter((item) => {
return item.syndromeGroupNo !== row.syndromeGroupNo;
});
console.log('[addDiagnosisDialog] 删除后 tcmDiagonsisList=', JSON.stringify(tcmDiagonsisList.value));
}
function save() {
// 只保存新增的诊断,过滤掉已存在的
const newDiagnosisList = tcmDiagonsisSaveList.value.filter(item => !item.isExisting);
console.log('[addDiagnosisDialog] save() 触发, newDiagnosisList长度=', newDiagnosisList.length, 'updateZy长度=', props.updateZy.length);
if (newDiagnosisList.length === 0) {
proxy.$modal.msgWarning('没有新增的诊断需要保存');
return;
}
if (props.updateZy.length > 0) {
// 修改模式
console.log('[addDiagnosisDialog] 调用 updateTcmDiagnosis');
updateTcmDiagnosis({
patientId: props.patientInfo.patientId,
encounterId: props.patientInfo.encounterId,
diagnosisChildList: newDiagnosisList,
}).then((res) => {
console.log('[addDiagnosisDialog] updateTcmDiagnosis 响应, code=', res.code);
if (res.code == 200) {
emit('close');
proxy.$modal.msgSuccess('诊断已保存');
@@ -351,11 +394,13 @@ function save() {
});
} else {
// 新增模式
console.log('[addDiagnosisDialog] 调用 saveTcmDiagnosis');
saveTcmDiagnosis({
patientId: props.patientInfo.patientId,
encounterId: props.patientInfo.encounterId,
diagnosisChildList: newDiagnosisList,
}).then((res) => {
console.log('[addDiagnosisDialog] saveTcmDiagnosis 响应, code=', res.code);
if (res.code == 200) {
emit('close');
proxy.$modal.msgSuccess('诊断已保存');
@@ -367,13 +412,15 @@ function save() {
function submit() {
// 检查是否有新增的诊断
const hasNewDiagnosis = tcmDiagonsisSaveList.value.some(item => !item.isExisting);
console.log('[addDiagnosisDialog] submit() 触发, hasNewDiagnosis=', hasNewDiagnosis, 'syndromeSelected=', syndromeSelected.value);
if (!hasNewDiagnosis) {
// 如果没有新增诊断,直接关闭
console.log('[addDiagnosisDialog] 无新增诊断,直接关闭弹窗');
emit('close');
return;
}
if (syndromeSelected.value || tcmDiagonsisSaveList.value.length % 2 == 0) {
save();
} else {
@@ -381,6 +428,7 @@ function submit() {
}
}
function close() {
console.log('[addDiagnosisDialog] close() 触发 (弹窗@close事件)');
emit('close');
}
</script>

View File

@@ -539,17 +539,25 @@ async function getList() {
});
emits('diagnosisSave', false);
}
// 获取现有诊断的排序号集合,用于判断是否重复
const existingDiagSrtNoSet = new Set(form.value.diagnosisList.map(item => item.diagSrtNo));
// 收集已有中医诊断的 syndromeGroupNo用于去重
const existingTcmGroups = new Set(
form.value.diagnosisList
.filter(item => item.typeName === '中医诊断' && item.syndromeGroupNo)
.map(item => item.syndromeGroupNo)
);
const tcmRes = await getTcmDiagnosis({ encounterId: props.patientInfo.encounterId });
console.log('[diagnosis] getList() getTcmDiagnosis 返回, code=', tcmRes.code, 'illness条数=', tcmRes.data?.illness?.length);
if (tcmRes.code == 200) {
if (tcmRes.data.illness.length > 0) {
tcmRes.data.illness.forEach((item, index) => {
// 如果该排序号的诊断已存在,则跳过(避免重复添加)
if (existingDiagSrtNoSet.has(item.diagSrtNo)) {
// 使用 syndromeGroupNo 去重,避免与西医诊断的 diagSrtNo 冲突
if (existingTcmGroups.has(item.syndromeGroupNo)) {
console.log('[diagnosis] getList() 跳过重复中医诊断, syndromeGroupNo=', item.syndromeGroupNo, 'name=', item.name);
return;
}
existingTcmGroups.add(item.syndromeGroupNo);
console.log('[diagnosis] getList() 添加中医诊断到表格: illness=', item.name, 'symptom=', tcmRes.data.symptom[index]?.name, 'syndromeGroupNo=', item.syndromeGroupNo);
form.value.diagnosisList.push({
name: item.name + '-' + tcmRes.data.symptom[index].name,
diagSrtNo: item.diagSrtNo,
@@ -564,8 +572,6 @@ async function getList() {
symptomDefinitionId : tcmRes.data.symptom[index].definitionId,
symptomYbNo: tcmRes.data.symptom[index].ybNo,
});
// 添加后更新集合
existingDiagSrtNoSet.add(item.diagSrtNo);
});
}
emits('diagnosisSave', false);
@@ -734,6 +740,7 @@ function handleAddDiagnosis() {
// 添加中医诊断
function handleAddTcmDiagonsis() {
console.log('[diagnosis] handleAddTcmDiagonsis() 触发, 清空updateZy并打开弹窗');
updateZy.value = [];
openAddDiagnosisDialog.value = true;
}
@@ -742,8 +749,10 @@ function handleAddTcmDiagonsis() {
* 删除诊断
*/
function handleDeleteDiagnosis(row, index) {
console.log('[diagnosis] handleDeleteDiagnosis 触发, row=', JSON.stringify({name: row.name, conditionId: row.conditionId, syndromeGroupNo: row.syndromeGroupNo, typeName: row.typeName}));
if (row.conditionId) {
delEncounterDiagnosis(row.conditionId).then((res) => {
console.log('[diagnosis] delEncounterDiagnosis 响应, code=', res.code);
if (res.code == 200) {
proxy.$modal.msgSuccess('删除成功');
getList();
@@ -751,11 +760,21 @@ function handleDeleteDiagnosis(row, index) {
}
});
} else if (row.syndromeGroupNo) {
deleteTcmDiagnosis(row.syndromeGroupNo).then(() => {
getList();
getTree();
console.log('[diagnosis] 调用 deleteTcmDiagnosis, syndromeGroupNo=', row.syndromeGroupNo);
deleteTcmDiagnosis(row.syndromeGroupNo).then((res) => {
console.log('[diagnosis] deleteTcmDiagnosis 响应, code=', res?.code, 'msg=', res?.msg);
if (res.code == 200) {
proxy.$modal.msgSuccess('删除成功');
getList();
getTree();
} else {
proxy.$modal.msgError(res?.msg || '删除失败,请稍后重试');
}
}).catch(() => {
proxy.$modal.msgError('删除请求失败,请检查网络');
});
} else {
console.log('[diagnosis] 本地删除(未保存的诊断), index=', index);
form.value.diagnosisList.splice(index, 1);
// 删除后不重新计算排序号,保持用户设置的排序不变
emits('diagnosisSave', false);
@@ -961,11 +980,20 @@ function handleInfectiousDiseaseReport() {
* 关闭诊断弹窗
*/
function closeDiagnosisDialog(str) {
console.log('[diagnosis] closeDiagnosisDialog 触发, str=', str, 'openAddDiagnosisDialog=', openAddDiagnosisDialog.value, 'openDiagnosis=', openDiagnosis.value);
if (str === 'success') {
proxy.$modal.msgSuccess('操作成功');
}
// 防止重复调用导致并发 getList()
if (!openAddDiagnosisDialog.value && !openDiagnosis.value) {
console.log('[diagnosis] closeDiagnosisDialog 跳过(弹窗已关闭)');
return;
}
openAddDiagnosisDialog.value = false;
openDiagnosis.value = false;
// 清理 updateZy避免编辑模式数据残留
updateZy.value = [];
console.log('[diagnosis] 弹窗关闭, updateZy已清空, 开始刷新列表');
getList();
getTree();
}
@@ -1010,6 +1038,7 @@ function closeDiagnosisPopover(row) {
/**获取焦点时 打开列表 */
function handleFocus(row, index) {
if(row.typeName==='中医诊断'){
console.log('[diagnosis] handleFocus 触发(编辑中医诊断), row.name=', row.name, 'syndromeGroupNo=', row.syndromeGroupNo);
updateZy.value = [];
updateZy.value.push({
illnessDefinitionId: row.illnessDefinitionId,
@@ -1021,6 +1050,7 @@ function handleFocus(row, index) {
diagSrtNo: row.diagSrtNo,
name:row.name,
});
console.log('[diagnosis] updateZy 已设置, 打开编辑弹窗');
openAddDiagnosisDialog.value = true;
}else{
// 关闭其他行的弹窗