fix(followup-audio): keep entry visible during capability failures
This commit is contained in:
@@ -671,9 +671,14 @@
|
||||
<el-empty v-else description="请先保存诊单后查看" />
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane v-if="followupCapabilities?.enabled && formData.id" label="回访录音" name="followupAudio" lazy>
|
||||
<el-tab-pane v-if="formData.id" label="回访录音" name="followupAudio" lazy>
|
||||
<el-alert v-if="followupCapabilitiesLoading" title="正在检查回访录音状态…" type="info" :closable="false" show-icon />
|
||||
<div v-else-if="followupCapabilitiesError" role="alert">
|
||||
<el-alert :title="followupCapabilitiesError" type="error" :closable="false" show-icon />
|
||||
<el-button class="mt-3" @click="loadFollowupCapabilities">重新加载</el-button>
|
||||
</div>
|
||||
<FollowupAudioPanel
|
||||
v-if="visible && formData.id && followupCapabilities"
|
||||
v-else-if="visible && followupCapabilities?.enabled && followupCapabilitiesDiagnosisId === Number(formData.id)"
|
||||
:key="Number(formData.id)"
|
||||
ref="followupAudioRef"
|
||||
:diagnosis-id="Number(formData.id)"
|
||||
@@ -684,6 +689,13 @@
|
||||
:before-apply="canApplyFollowup"
|
||||
@applied="handleFollowupApplied"
|
||||
/>
|
||||
<el-alert
|
||||
v-else
|
||||
:title="followupCapabilities?.test_scope_allowed === false ? '当前诊单未开放回访录音' : '当前未启用回访录音,请联系管理员确认'"
|
||||
type="info"
|
||||
:closable="false"
|
||||
show-icon
|
||||
/>
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- 病历记录标签页(开方后自动显示) -->
|
||||
@@ -833,6 +845,9 @@ const prescriptionRef = ref()
|
||||
const dailyMatrixRef = ref<{ refresh?: () => Promise<void> | void } | null>(null)
|
||||
const followupAudioRef = ref<{ confirmLeave: () => Promise<boolean> } | null>(null)
|
||||
const followupCapabilities = ref<FollowupCapabilities | null>(null)
|
||||
const followupCapabilitiesLoading = ref(false)
|
||||
const followupCapabilitiesError = ref('')
|
||||
const followupCapabilitiesDiagnosisId = ref<number | null>(null)
|
||||
const basicSnapshot = ref('')
|
||||
let diagnosisGeneration = 0
|
||||
let capabilitiesRequest: AbortController | undefined
|
||||
@@ -1021,18 +1036,49 @@ async function handleFollowupApplied(diagnosisId: number) {
|
||||
if (generation === diagnosisGeneration) feedback.msgWarning('录音已采纳,但病历或日常记录刷新失败,请手动刷新查看')
|
||||
}
|
||||
}
|
||||
watch([visible, () => formData.value.id], async ([isVisible, id]) => {
|
||||
function resetFollowupCapabilities() {
|
||||
capabilitiesRequest?.abort()
|
||||
capabilitiesRequest = undefined
|
||||
followupCapabilities.value = null
|
||||
if (!isVisible || !id) return
|
||||
followupCapabilitiesDiagnosisId.value = null
|
||||
followupCapabilitiesLoading.value = false
|
||||
followupCapabilitiesError.value = ''
|
||||
}
|
||||
async function loadFollowupCapabilities(): Promise<void> {
|
||||
// A rapid second click must not create another request for the same context.
|
||||
if (followupCapabilitiesLoading.value) return
|
||||
resetFollowupCapabilities()
|
||||
const id = Number(formData.value.id)
|
||||
if (!visible.value || !id) return
|
||||
const generation = diagnosisGeneration
|
||||
const request = new AbortController()
|
||||
capabilitiesRequest = request
|
||||
followupCapabilitiesLoading.value = true
|
||||
const isCurrent = () => capabilitiesRequest === request && !request.signal.aborted
|
||||
&& generation === diagnosisGeneration && visible.value && Number(formData.value.id) === id
|
||||
try {
|
||||
const result = await followupAudioCapabilities(Number(id), request.signal)
|
||||
if (!request.signal.aborted && visible.value && String(formData.value.id) === String(id)) followupCapabilities.value = result
|
||||
} catch { /* Fail closed: an unavailable capability endpoint must not expose this feature. */ }
|
||||
})
|
||||
onBeforeUnmount(() => { diagnosisGeneration++; capabilitiesRequest?.abort() })
|
||||
const result = await followupAudioCapabilities(id, request.signal)
|
||||
if (!isCurrent()) return
|
||||
if (typeof result?.enabled !== 'boolean') throw new Error('Invalid capability response')
|
||||
followupCapabilities.value = result
|
||||
followupCapabilitiesDiagnosisId.value = id
|
||||
} catch {
|
||||
if (!isCurrent()) return
|
||||
// No endpoint failure (including permission denial) may mount the panel.
|
||||
followupCapabilitiesError.value = '回访录音状态加载失败,请重新加载;若仍失败,请联系管理员检查权限或服务状态'
|
||||
} finally {
|
||||
if (isCurrent()) {
|
||||
followupCapabilitiesLoading.value = false
|
||||
capabilitiesRequest = undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
watch([visible, () => formData.value.id], () => {
|
||||
// Invalidate synchronously so an old patient's capabilities never survive a switch.
|
||||
resetFollowupCapabilities()
|
||||
void loadFollowupCapabilities()
|
||||
}, { flush: 'sync' })
|
||||
onBeforeUnmount(() => { diagnosisGeneration++; resetFollowupCapabilities() })
|
||||
|
||||
/** 就诊卡创建来源(与 zyt_tcm_diagnosis.create_source 一致) */
|
||||
const createSourceOptions = [
|
||||
@@ -1360,7 +1406,7 @@ const open = async (type: string, id?: number) => {
|
||||
const generation = ++diagnosisGeneration
|
||||
submitting.value = false
|
||||
basicSnapshot.value = ''
|
||||
followupCapabilities.value = null
|
||||
resetFollowupCapabilities()
|
||||
formData.value.id = ''
|
||||
viewOnly.value = false
|
||||
mode.value = type
|
||||
@@ -1390,7 +1436,7 @@ const openViewOnly = async (id: number) => {
|
||||
const generation = ++diagnosisGeneration
|
||||
submitting.value = false
|
||||
basicSnapshot.value = ''
|
||||
followupCapabilities.value = null
|
||||
resetFollowupCapabilities()
|
||||
formData.value.id = ''
|
||||
viewOnly.value = true
|
||||
mode.value = 'edit'
|
||||
@@ -1490,8 +1536,7 @@ const handleOpenPrescription = () => {
|
||||
const handleClose = async () => {
|
||||
if (followupAudioRef.value && !await followupAudioRef.value.confirmLeave()) return
|
||||
diagnosisGeneration++
|
||||
capabilitiesRequest?.abort()
|
||||
followupCapabilities.value = null
|
||||
resetFollowupCapabilities()
|
||||
basicSnapshot.value = ''
|
||||
formRef.value?.resetFields()
|
||||
formData.value = {
|
||||
|
||||
Reference in New Issue
Block a user