import { computed, ref } from 'vue' export function createReceiptDetailDashboardModel({ detailForm, editableOtherFields, formatDateTime, formatScore, selectedReceipt }) { const previewZoom = ref(1) const previewRotation = ref(0) const previewTransform = computed(() => `scale(${previewZoom.value}) rotate(${previewRotation.value}deg)`) const previewPageLabel = computed(() => { const pageCount = Number(selectedReceipt.value?.page_count || 1) return `1 / ${Number.isFinite(pageCount) && pageCount > 0 ? pageCount : 1}` }) const ocrPreviewFields = computed(() => ( editableOtherFields.value .filter((field) => String(field?.label || field?.key || field?.value || '').trim()) .slice(0, 6) )) const basicInfoItems = computed(() => [ { label: '票据类型', value: fallback(detailForm.document_type_label) }, { label: '票据名称', value: fallback(detailForm.file_name) }, { label: '提交人', value: fallback(selectedReceipt.value?.owner_name || selectedReceipt.value?.owner || '当前用户') }, { label: '上传时间', value: formatDateTime(selectedReceipt.value?.uploaded_at) }, { label: '所属单据编号', value: fallback(selectedReceipt.value?.linked_claim_no, '未关联') }, { label: 'OCR 置信度', value: formatScore(selectedReceipt.value?.avg_score) } ]) const receiptStatusItems = computed(() => { const linked = selectedReceipt.value?.status === 'linked' return [ { label: '识别状态', value: '识别成功', tone: 'success' }, { label: '关联状态', value: selectedReceipt.value?.status_label || (linked ? '已关联' : '未关联'), tone: linked ? 'success' : 'warning' }, { label: '重复报销风险', value: '无风险', tone: 'success' }, { label: '归档状态', value: linked ? '待归档' : '未归档', tone: 'info' } ] }) const linkedClaimItems = computed(() => [ { label: '报销单编号', value: fallback(selectedReceipt.value?.linked_claim_no, '未关联') }, { label: '报销单名称', value: linkedClaimName.value }, { label: '费用类型', value: fallback(detailForm.scene_label) }, { label: '申请日期', value: dateOnly(selectedReceipt.value?.linked_at || selectedReceipt.value?.uploaded_at) }, { label: '审批状态', value: selectedReceipt.value?.status === 'linked' ? '已关联' : '待关联' }, { label: '是否已入账', value: '未入账' } ]) const operationLogs = computed(() => [ { time: formatDateTime(selectedReceipt.value?.uploaded_at), operator: fallback(selectedReceipt.value?.owner_name || selectedReceipt.value?.owner || '系统'), label: '上传票据' }, { time: formatDateTime(selectedReceipt.value?.uploaded_at), operator: '系统', label: `OCR识别,提取 ${editableOtherFields.value.length} 项要素` }, { time: formatDateTime(selectedReceipt.value?.linked_at || selectedReceipt.value?.uploaded_at), operator: selectedReceipt.value?.status === 'linked' ? '系统' : '待处理', label: selectedReceipt.value?.status === 'linked' ? `关联单据 ${selectedReceipt.value?.linked_claim_no || ''}` : '等待关联单据' } ]) const archiveInfoItems = computed(() => [ { label: '归档编号', value: archiveNo.value }, { label: '归档目录', value: `${dateOnly(selectedReceipt.value?.uploaded_at)} / ${fallback(detailForm.scene_label)}` }, { label: '保管期限', value: '10年' }, { label: '关联附件数量', value: selectedReceipt.value?.status === 'linked' ? '1' : '0' }, { label: '文件格式', value: fileFormat.value }, { label: '文件大小', value: fallback(selectedReceipt.value?.file_size_label || selectedReceipt.value?.size_label, '待统计') } ]) const linkedClaimName = computed(() => ( selectedReceipt.value?.linked_claim_no ? `${fallback(detailForm.scene_label)}票据归集` : '暂未关联报销单' )) const archiveNo = computed(() => ( selectedReceipt.value?.id ? `DA-${String(selectedReceipt.value.id).slice(0, 8).toUpperCase()}` : '待生成' )) const fileFormat = computed(() => { const fileName = String(detailForm.file_name || selectedReceipt.value?.file_name || '').trim() const suffix = fileName.includes('.') ? fileName.split('.').pop() : '' return suffix ? suffix.toUpperCase() : fallback(selectedReceipt.value?.preview_kind, '待识别') }) function adjustPreviewZoom(delta) { previewZoom.value = Math.min(1.8, Math.max(0.6, Number((previewZoom.value + delta).toFixed(2)))) } function resetPreviewView() { previewZoom.value = 1 previewRotation.value = 0 } function rotatePreview() { previewRotation.value = (previewRotation.value + 90) % 360 } return { adjustPreviewZoom, archiveInfoItems, basicInfoItems, linkedClaimItems, ocrPreviewFields, operationLogs, previewPageLabel, previewRotation, previewTransform, previewZoom, receiptStatusItems, resetPreviewView, rotatePreview } } function fallback(value, empty = '待补充') { const text = String(value || '').trim() return text || empty } function dateOnly(value) { const text = String(value || '').trim() return text ? text.slice(0, 10) : '待确认' }