feat: add durable ASR-to-patient extraction and guarded review
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { FollowupCapabilities, FollowupField, FollowupFields, FollowupReviewItem, FollowupValue } from '@/api/followupAudio'
|
||||
import type { FollowupCapabilities, FollowupField, FollowupFields, FollowupReviewItem, FollowupTaskDetail, FollowupTaskSummary, FollowupValue } from '@/api/followupAudio'
|
||||
|
||||
export const FOLLOWUP_CHUNK_BYTES = 2097152
|
||||
export const followupKindLabels = { diagnosis: '诊单资料', blood: '血糖 / 血压', diet: '饮食', exercise: '运动', tracking_note: '跟踪备注' }
|
||||
@@ -6,6 +6,31 @@ export const followupStatusLabels: Record<string, string> = {
|
||||
queued: '等待处理', running: '正在分析', review: '待人工审核', applied: '已采纳',
|
||||
failed: '处理失败', needs_reconciliation: '结果待核对', expired: '已过保留期'
|
||||
}
|
||||
const followupStageLabels: Record<string, string> = { transcribing: '正在转写', extracting: '正在提炼', validating: '正在校验', review: '待人工审核' }
|
||||
export function followupTaskStatus(task: Pick<FollowupTaskSummary, 'status' | 'stage'>): string {
|
||||
return (task.status === 'running' && followupStageLabels[task.stage]) || followupStatusLabels[task.status] || task.status
|
||||
}
|
||||
export function followupProgressText(task: FollowupTaskSummary): string {
|
||||
const progress = task.pipeline_progress
|
||||
const valid = progress && Number.isSafeInteger(progress.transcribed) && Number.isSafeInteger(progress.total)
|
||||
&& progress.total > 0 && progress.transcribed >= 0 && progress.transcribed <= progress.total
|
||||
return `${followupTaskStatus(task)}${valid ? ` · 转写片段 ${progress.transcribed} / ${progress.total}` : ''};人工审核前不会写入业务记录。`
|
||||
}
|
||||
export function retainedTranscriptNotice(task: FollowupTaskDetail): string {
|
||||
if (!task.transcript_available || !task.transcript.trim()) return ''
|
||||
if (task.status === 'failed') return '处理失败,已完成片段的转写仍可查看。保留转写不代表提炼成功,不能直接写入病历。'
|
||||
if (task.status === 'needs_reconciliation') return '结果待核对,已完成片段的转写仍可查看。请先核对上游结果,不要重复发送。'
|
||||
return ''
|
||||
}
|
||||
export function evidencePlaybackLabel(quote: FollowupReviewItem['evidence'][number]): string {
|
||||
if (typeof quote.start_ms !== 'number' || !Number.isFinite(quote.start_ms) || quote.start_ms < 0) return ''
|
||||
const timestamp = (ms: number) => { const seconds = Math.floor(ms / 1000); return `${Math.floor(seconds / 60)}:${String(seconds % 60).padStart(2, '0')}` }
|
||||
if (quote.position_type === 'segment') {
|
||||
if (!quote.segment_id || typeof quote.end_ms !== 'number' || !Number.isFinite(quote.end_ms) || quote.end_ms <= quote.start_ms) return ''
|
||||
return `回听片段 ${timestamp(quote.start_ms)}–${timestamp(quote.end_ms)}`
|
||||
}
|
||||
return `播放 ${timestamp(quote.start_ms)}`
|
||||
}
|
||||
export const cloneReviewItems = (items: FollowupReviewItem[]): FollowupReviewItem[] => JSON.parse(JSON.stringify(items))
|
||||
export function fieldText(value: FollowupValue | undefined, field: FollowupField): string {
|
||||
if (value === undefined || value === null || value === '' || (Array.isArray(value) && !value.length)) return '未记录'
|
||||
|
||||
Reference in New Issue
Block a user