diff --git a/admin/src/api/followupAudio.ts b/admin/src/api/followupAudio.ts index bec5dbf37..864f92be5 100644 --- a/admin/src/api/followupAudio.ts +++ b/admin/src/api/followupAudio.ts @@ -84,6 +84,16 @@ export interface FollowupTaskSummary { pipeline_progress?: { transcribed: number; total: number } } export interface FollowupTaskDetail extends FollowupTaskSummary { + extraction_revision?: number + extraction_channel_roles?: FollowupChannelRoles + can_reextract?: boolean + reextract_block_reason?: string + role_check?: { + conflict: boolean + suggested_roles: FollowupChannelRoles + message: string + evidence: Array<{ channel: FollowupAudioChannel; start_ms: number; end_ms: number; text: string }> + } summary: string transcript: string transcript_segments?: FollowupTranscriptSegment[] @@ -132,6 +142,7 @@ export const followupAudioUploadComplete = (uploadId: string, signal?: AbortSign export const followupAudioCreate = (data: { diagnosis_id: number; upload_id: string; recorded_at: string; model_key: string; channel_roles?: FollowupChannelRoles }, signal?: AbortSignal) => post<{ task_id: number; status: string; reused?: boolean; reuse_message?: string }>('create', data, signal) export const followupAudioSaveDraft = (data: { id: number; version: number; items: FollowupReviewItem[]; channel_roles?: FollowupChannelRoles }, signal?: AbortSignal) => post('saveDraft', data, signal) export const followupAudioApply = (data: { id: number; version: number; items: FollowupReviewItem[] }, signal?: AbortSignal) => post<{ id: number; status: 'applied'; applied_items: unknown[] }>('apply', data, signal) +export const followupAudioReextract = (data: { id: number; version: number; channel_roles: Exclude }, signal?: AbortSignal) => post('reextract', data, signal) export const followupAudioDelete = (data: { id: number; version: number }, signal?: AbortSignal) => post<{ id: number; status: 'deleted'; version: number }>('delete', data, signal) export const followupAudioRetry = (id: number, signal?: AbortSignal) => post<{ id: number; status: string }>('retry', { id }, signal) /** The existing request interceptor puts the token in a header, never in the audio URL. */ diff --git a/admin/src/views/tcm/diagnosis/components/FollowupAudioPanel.vue b/admin/src/views/tcm/diagnosis/components/FollowupAudioPanel.vue index 15e7d14df..58b6d0664 100644 --- a/admin/src/views/tcm/diagnosis/components/FollowupAudioPanel.vue +++ b/admin/src/views/tcm/diagnosis/components/FollowupAudioPanel.vue @@ -57,13 +57,24 @@
{{ detail.status === 'applied' ? '已写入' : '已选' }} {{ selectedCount }} 项待核实 {{ pendingCount }} 项
-
+
{{ savedChannelRoles === 'left_service' ? '左客服端 / 右患者或家属端' : '右客服端 / 左患者或家属端' }} · 已确认修改

声道不等于已核实的说话人身份。角色标注不自动重新提炼;变更后保存草稿会取消全部采纳,须重新核对。

当前角色已确认,无需再次选择;只有左右标错时才需修改。

角色标注正在等待保存;保存后请逐项重新核对。

+
+ {{ detail.role_check?.conflict ? '声道角色与转写内容可能不一致' : '审核角色已修改,原提炼结果尚未更新' }} +

{{ detail.role_check?.message || '修改角色标注不会自动改变已生成的建议,可按核实后的角色重新提炼。' }}

+
{{ evidence.channel === 0 ? '左声道' : '右声道' }} · {{ audioTimestamp(evidence.start_ms) }}:{{ evidence.text }}回听依据
+

当前提炼依据:{{ extractionRoleLabel(extractionRoles) }}。{{ reextractTarget !== 'unconfirmed' ? `待确认的新角色:${extractionRoleLabel(reextractTarget)}。` : '请先回听并修改上方角色标注。' }}建议仅供核对,系统不会自动交换角色。

+ 确认角色并重新提炼 +

请先完成当前单项核对或取消编辑,等待审核草稿保存后再重新提炼。

+

{{ detail.reextract_block_reason }}

+

复用已完成的转写,不重复语音识别;旧结果保留,重新提炼不自动写入病例。

+
+

第 {{ (detail.extraction_revision || 0) + 1 }} 版提炼 · {{ extractionRoleLabel(extractionRoles) }} · 历史结果已保留