feat(admin): complete customs from container detail

This commit is contained in:
2026-08-26 12:46:46 +08:00
parent 4088e36f74
commit 4a7a5ae5b6
3 changed files with 122 additions and 14 deletions
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { computed, onBeforeUnmount, reactive, watch } from 'vue'
import { Download, FileUp, TriangleAlert } from '@lucide/vue'
import { Check, Download, FileUp, TriangleAlert } from '@lucide/vue'
import { getApiErrorDetails } from '@/shared/api/http'
import StatusBadge from '@/shared/components/StatusBadge.vue'
import type { ContainerOverview, ContainerOverviewDocument, ContainerPdaPhoto } from '../types'
@@ -12,11 +12,13 @@ const props = defineProps<{
canManageCustoms: boolean
canManageException: boolean
documentBusy?: boolean
customsCompleting?: boolean
}>()
const emit = defineEmits<{
uploadDocument: [documentType: string]
downloadDocument: [document: ContainerOverviewDocument]
completeCustoms: [document: ContainerOverviewDocument]
manageException: []
}>()
@@ -33,6 +35,12 @@ const customsTypes = new Set(['DESTINATION_CLEARANCE', 'CUSTOMS_DECLARATION'])
function canUploadDocument(documentType: string) {
return downloadableTypes.has(documentType) ? props.canManageDocuments : customsTypes.has(documentType) && props.canManageCustoms
}
function documentStatusText(documentType: string) {
const document = documentsByType.value.get(documentType)
if (documentType !== 'CUSTOMS_DECLARATION') return document ? formatTime(document.uploadedAt) : '等待上传'
if (!document) return '第一步上传附件,第二步确认报关完成'
return document.completed ? '已确认报关完成' : '附件已上传,待确认报关完成'
}
const pdaProgress = computed(() => {
const pda = props.overview.pda
if (!pda || pda.itemCount <= 0) return 0
@@ -107,8 +115,8 @@ onBeforeUnmount(() => { photoGeneration += 1; revokePhotoUrls() })
<header><h3>业务资料</h3><span>{{ overview.documents.length }} 份</span></header>
<div class="document-grid compact-document-list">
<article v-for="item in documentTypes" :key="item.type" class="document-item">
<div><strong>{{ item.label }}</strong><span>{{ documentsByType.get(item.type)?.fileName || '未上传' }}</span><small>{{ documentsByType.get(item.type) ? formatTime(documentsByType.get(item.type)?.uploadedAt) : '等待上传' }}</small></div>
<div class="document-actions"><el-button v-if="documentsByType.get(item.type) && downloadableTypes.has(item.type)" size="small" :loading="documentBusy" @click="emit('downloadDocument', documentsByType.get(item.type)!)"><Download :size="15" />下载</el-button><el-button v-if="canUploadDocument(item.type)" size="small" @click="emit('uploadDocument', item.type)"><FileUp :size="15" />{{ documentsByType.get(item.type) ? '更新' : '上传' }}</el-button></div>
<div><strong>{{ item.label }}</strong><span>{{ documentsByType.get(item.type)?.fileName || '未上传' }}</span><small>{{ documentStatusText(item.type) }}</small></div>
<div class="document-actions"><el-button v-if="documentsByType.get(item.type) && downloadableTypes.has(item.type)" size="small" :loading="documentBusy" @click="emit('downloadDocument', documentsByType.get(item.type)!)"><Download :size="15" />下载</el-button><el-button v-if="canUploadDocument(item.type)" size="small" @click="emit('uploadDocument', item.type)"><FileUp :size="15" />{{ documentsByType.get(item.type) ? '更新附件' : '上传附件' }}</el-button><el-button v-if="item.type === 'CUSTOMS_DECLARATION' && canManageCustoms && documentsByType.get(item.type) && !documentsByType.get(item.type)?.completed" size="small" type="primary" :loading="customsCompleting" @click="emit('completeCustoms', documentsByType.get(item.type)!)"><Check :size="15" />确认报关完成</el-button></div>
</article>
</div>
</section>