Files
his/BUG548_ANALYSIS.md

3.3 KiB
Raw Blame History

Bug #548 分析报告

Title

【住院医生站-检验申请】修改申请单时,"发往科室"字段未能正确回显原有数据

根因定位

文件: openhis-ui-vue3/src/views/inpatientDoctor/home/components/order/applicationForm/laboratoryTests.vue

数据流

  1. 用户点击"修改"→ testApplication.vuehandleEdit 将 row 数据作为 editData 传给 LaboratoryTests 组件
  2. LaboratoryTestswatch(() => props.editData) 解析 descJson,将 form.targetDepartment 设为申请单原有的科室ID
  3. 同一 watch 内调用 applyEditTransferSelection() → 设置 transferValue.value = uniq已选项目ID数组
  4. transferValue 的变化触发了另一个 watch第341-346行→ 调用 projectWithDepartment(newValue, 1)
  5. projectWithDepartment 第294行const manualDept = type === 2 ? form.targetDepartment : ''type=1时取空字符串
  6. 第296行form.targetDepartment = ''清空了步骤2中刚设置好的科室值
  7. 后续逻辑329-336行仅在 type === 2(提交模式)下才保留用户手动选择的科室,type === 1(选择项目变化)时不恢复

根因

编辑模式下,applyEditTransferSelection 设置 transferValue 时触发了 watch → projectWithDepartment(arr, type=1) → 用 type !== 2 清空了 form.targetDepartmentdescJson 中保存的科室ID被覆盖为空字符串导致回显失败。

修复方案

在编辑初始化期间设置一个 isInitializing 标志,使 transferValue 的 watch 跳过 projectWithDepartment 调用。

修复结果: 成功8行改动

改动文件: openhis-ui-vue3/src/views/inpatientDoctor/home/components/order/applicationForm/laboratoryTests.vue

  1. 新增 isInitializing 标志ref(false)
  2. transferValue 的 watch 增加 if (isInitializing.value) return; 拦截
  3. applyEditTransferSelection() 中设置 transferValue 前后加 isInitializing 标志
  4. applicationListAll 的 watch 中设置 transferValue 前后也加 isInitializing 标志

二次修复isInitializing 时序问题)

二次根因

Vue 的 watch() 回调默认是异步刷新的(在下一个 microtask 执行)。前一轮修复使用了同步模式:

isInitializing.value = true
transferValue.value = uniq    // watcher 被排队,尚未执行
isInitializing.value = false  // 在 watcher 回调执行前已重置
// → watcher 触发时 isInitializing 已为 false → 拦截失效

导致 projectWithDepartment(newValue, 1) 仍然被调用,form.targetDepartment = '' 仍然清空了 descJson 中的科室值。

修复方案

applyEditTransferSelectionapplicationListAll watch 中,设置 transferValue 后使用 await nextTick() 确保 Vue 的 watcher 在 isInitializingtrue 的状态下执行完毕,然后再重置为 false

修复结果: 成功5行改动

改动文件: openhis-ui-vue3/src/views/inpatientDoctor/home/components/order/applicationForm/laboratoryTests.vue

  1. import 增加 nextTick
  2. applyEditTransferSelection 改为 async 函数,transferValue 赋值后加 await nextTick()
  3. applicationListAll 的 watch 回调改为 asynctransferValue 赋值后加 await nextTick()