增加客户退税回执确认交互
This commit is contained in:
@@ -33,6 +33,8 @@ export interface MerchantCustomsDocument {
|
|||||||
inboundCodes: string[]
|
inboundCodes: string[]
|
||||||
frozen: boolean
|
frozen: boolean
|
||||||
completion: MerchantCustomsFile | null
|
completion: MerchantCustomsFile | null
|
||||||
|
receiptStatus: 'PENDING' | 'CONFIRMED' | 'REJECTED' | null
|
||||||
|
receiptRejectReason: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MerchantCustomsContainer {
|
export interface MerchantCustomsContainer {
|
||||||
@@ -47,6 +49,7 @@ export interface MerchantCustomsContainer {
|
|||||||
version: number
|
version: number
|
||||||
taxRefundCount: number
|
taxRefundCount: number
|
||||||
coveredTaxRefundCount: number
|
coveredTaxRefundCount: number
|
||||||
|
actualBoxCount: number
|
||||||
inbounds: MerchantCustomsInbound[]
|
inbounds: MerchantCustomsInbound[]
|
||||||
documents: MerchantCustomsDocument[]
|
documents: MerchantCustomsDocument[]
|
||||||
startedAt?: string | null
|
startedAt?: string | null
|
||||||
@@ -190,6 +193,24 @@ export function downloadMerchantCustomsCompletion(document: MerchantCustomsDocum
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function confirmMerchantCustomsReceipt(document: MerchantCustomsDocument) {
|
||||||
|
return apiRequest<MerchantCustomsContainer>({
|
||||||
|
method: 'POST',
|
||||||
|
url: `/merchant/v1/customs/documents/${encodedId(document.documentId)}/receipt/confirm`,
|
||||||
|
headers: { 'Idempotency-Key': createIdempotencyKey(`merchant-customs-receipt-confirm-${document.documentId}`) },
|
||||||
|
data: { expectedVersion: document.completion?.version ?? 0, confirm: true, remark: null },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function rejectMerchantCustomsReceipt(document: MerchantCustomsDocument, reason: string) {
|
||||||
|
return apiRequest<MerchantCustomsContainer>({
|
||||||
|
method: 'POST',
|
||||||
|
url: `/merchant/v1/customs/documents/${encodedId(document.documentId)}/receipt/reject`,
|
||||||
|
headers: { 'Idempotency-Key': createIdempotencyKey(`merchant-customs-receipt-reject-${document.documentId}`) },
|
||||||
|
data: { expectedVersion: document.completion?.version ?? 0, confirm: false, remark: reason },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export function merchantCustomsErrorMeta(error: unknown): ApiErrorMeta | null {
|
export function merchantCustomsErrorMeta(error: unknown): ApiErrorMeta | null {
|
||||||
if (!(error instanceof ApiError)) return null
|
if (!(error instanceof ApiError)) return null
|
||||||
return { code: error.code, requestId: error.requestId ?? null, traceId: error.traceId ?? null }
|
return { code: error.code, requestId: error.requestId ?? null, traceId: error.traceId ?? null }
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ import { Download, FileText, LockKeyhole, Pencil, Trash2, Upload } from '@lucide
|
|||||||
import {
|
import {
|
||||||
MERCHANT_CUSTOMS_STATUS_LABELS,
|
MERCHANT_CUSTOMS_STATUS_LABELS,
|
||||||
deleteMerchantCustomsDocument,
|
deleteMerchantCustomsDocument,
|
||||||
|
confirmMerchantCustomsReceipt,
|
||||||
downloadMerchantCustomsCompletion,
|
downloadMerchantCustomsCompletion,
|
||||||
downloadMerchantCustomsSource,
|
downloadMerchantCustomsSource,
|
||||||
getMerchantCustomsForOrder,
|
getMerchantCustomsForOrder,
|
||||||
merchantCustomsErrorMessage,
|
merchantCustomsErrorMessage,
|
||||||
replaceMerchantCustomsDocument,
|
replaceMerchantCustomsDocument,
|
||||||
|
rejectMerchantCustomsReceipt,
|
||||||
updateMerchantCustomsDocumentInbounds,
|
updateMerchantCustomsDocumentInbounds,
|
||||||
uploadMerchantCustomsDocument,
|
uploadMerchantCustomsDocument,
|
||||||
validateMerchantCustomsFile,
|
validateMerchantCustomsFile,
|
||||||
@@ -207,6 +209,32 @@ async function downloadFile(document: MerchantCustomsDocument, kind: 'source' |
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function confirmReceipt(document: MerchantCustomsDocument) {
|
||||||
|
try {
|
||||||
|
await ElMessageBox.confirm('确认已核对整份报关行回执吗?确认后将进入整柜报关完成汇总。', '确认报关行回执', { type: 'warning' })
|
||||||
|
mutating.value = true
|
||||||
|
await confirmMerchantCustomsReceipt(document)
|
||||||
|
ElMessage.success('回执确认成功')
|
||||||
|
await loadDetail()
|
||||||
|
} catch (error) {
|
||||||
|
if (error === 'cancel' || error === 'close') return
|
||||||
|
ElMessage.error(merchantCustomsErrorMessage(error, '回执确认失败'))
|
||||||
|
} finally { mutating.value = false }
|
||||||
|
}
|
||||||
|
|
||||||
|
async function rejectReceipt(document: MerchantCustomsDocument) {
|
||||||
|
try {
|
||||||
|
const reason = await ElMessageBox.prompt('请填写打回原因', '打回报关行回执', { inputValidator: (value) => value.trim() ? true : '请输入打回原因' })
|
||||||
|
mutating.value = true
|
||||||
|
await rejectMerchantCustomsReceipt(document, reason.value)
|
||||||
|
ElMessage.success('回执已打回')
|
||||||
|
await loadDetail()
|
||||||
|
} catch (error) {
|
||||||
|
if (error === 'cancel' || error === 'close') return
|
||||||
|
ElMessage.error(merchantCustomsErrorMessage(error, '回执打回失败'))
|
||||||
|
} finally { mutating.value = false }
|
||||||
|
}
|
||||||
|
|
||||||
function formatDateTime(value: string | null | undefined) {
|
function formatDateTime(value: string | null | undefined) {
|
||||||
if (!value) return '-'
|
if (!value) return '-'
|
||||||
const date = new Date(value)
|
const date = new Date(value)
|
||||||
@@ -246,6 +274,10 @@ function formatSize(bytes: number) {
|
|||||||
<span>资料覆盖</span>
|
<span>资料覆盖</span>
|
||||||
<strong>{{ detail.coveredTaxRefundCount }} / {{ detail.taxRefundCount }} 票</strong>
|
<strong>{{ detail.coveredTaxRefundCount }} / {{ detail.taxRefundCount }} 票</strong>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<span>实际箱数</span>
|
||||||
|
<strong>{{ detail.actualBoxCount }}</strong>
|
||||||
|
</div>
|
||||||
<el-tag :type="statusTagType" effect="light">{{ merchantStatusLabel }}</el-tag>
|
<el-tag :type="statusTagType" effect="light">{{ merchantStatusLabel }}</el-tag>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
@@ -286,7 +318,12 @@ function formatSize(bytes: number) {
|
|||||||
</div>
|
</div>
|
||||||
<div class="customs-document-actions">
|
<div class="customs-document-actions">
|
||||||
<el-button link type="primary" :loading="downloadingKey === `${item.documentId}:source`" @click="downloadFile(item, 'source')"><Download :size="15" />源文件</el-button>
|
<el-button link type="primary" :loading="downloadingKey === `${item.documentId}:source`" @click="downloadFile(item, 'source')"><Download :size="15" />源文件</el-button>
|
||||||
<el-button v-if="detail.status === 'COMPLETED' && item.completion" link type="success" :loading="downloadingKey === `${item.documentId}:completion`" @click="downloadFile(item, 'completion')"><Download :size="15" />完成文件</el-button>
|
<el-button v-if="item.completion" link type="success" :loading="downloadingKey === `${item.documentId}:completion`" @click="downloadFile(item, 'completion')"><Download :size="15" />报关行回执</el-button>
|
||||||
|
<template v-if="item.completion && item.receiptStatus !== 'CONFIRMED' && detail.status === 'DECLARING'">
|
||||||
|
<el-button link type="success" :disabled="mutating" @click="confirmReceipt(item)">确认整份回执</el-button>
|
||||||
|
<el-button link type="danger" :disabled="mutating" @click="rejectReceipt(item)">打回回执</el-button>
|
||||||
|
</template>
|
||||||
|
<el-tag v-if="item.completion" size="small" :type="item.receiptStatus === 'CONFIRMED' ? 'success' : item.receiptStatus === 'REJECTED' ? 'danger' : 'warning'">{{ item.receiptStatus === 'CONFIRMED' ? '已确认' : item.receiptStatus === 'REJECTED' ? `已打回:${item.receiptRejectReason || '待补充'}` : '待确认' }}</el-tag>
|
||||||
<template v-if="canEdit && !locked && !item.frozen">
|
<template v-if="canEdit && !locked && !item.frozen">
|
||||||
<el-button link type="primary" :disabled="mutating" @click="beginEditInbounds(item)"><Pencil :size="15" />改关联</el-button>
|
<el-button link type="primary" :disabled="mutating" @click="beginEditInbounds(item)"><Pencil :size="15" />改关联</el-button>
|
||||||
<el-button link type="primary" :disabled="mutating" @click="chooseReplacement(item)"><Upload :size="15" />覆盖</el-button>
|
<el-button link type="primary" :disabled="mutating" @click="chooseReplacement(item)"><Upload :size="15" />覆盖</el-button>
|
||||||
|
|||||||
Reference in New Issue
Block a user