feat(client): optimize first-leg order actions
This commit is contained in:
@@ -27,6 +27,7 @@ import {
|
||||
getMerchantOrderAddresses,
|
||||
getMerchantPricingChannels,
|
||||
importMerchantFirstLegOrders,
|
||||
submitMerchantFirstLegOrder,
|
||||
updateMerchantOrderAddress,
|
||||
uploadMerchantProductImage,
|
||||
type CustomerOrderAddress,
|
||||
@@ -72,6 +73,7 @@ const companyAuditLoaded = ref(false)
|
||||
const companySubmissionBlocked = computed(() => companyAuditLoaded.value && tenantStore.company.auditStatus !== 'ACTIVE')
|
||||
const canCreateOrder = computed(() => auth.hasPermission('order:first-leg:create'))
|
||||
const canEditOrder = computed(() => auth.hasPermission('order:first-leg:edit'))
|
||||
const canSubmitOrder = computed(() => auth.hasPermission('order:first-leg:submit'))
|
||||
const canConfirmInboundFee = computed(() => auth.hasPermission('order:first-leg:edit'))
|
||||
const availableWarehouses = computed(() => store.warehouses.filter((warehouse) => warehouse.warehouseType === 'DOMESTIC'))
|
||||
const availableDestinationWarehouses = computed(() => store.warehouses.filter((warehouse) => warehouse.warehouseType === form.destinationType))
|
||||
@@ -182,8 +184,10 @@ const tablePage = ref(1)
|
||||
const tablePageSize = ref(10)
|
||||
const downloadingMarks = ref(false)
|
||||
const exportingOrders = ref(false)
|
||||
const batchSubmitting = ref(false)
|
||||
const selectedOrders = ref<FirstLegOrder[]>([])
|
||||
const selectedOrderCount = computed(() => selectedOrders.value.length)
|
||||
const selectedDraftOrders = computed(() => selectedOrders.value.filter((order) => order.status === 'DRAFT'))
|
||||
const orderTableVersion = ref(0)
|
||||
const editorOpen = ref(false)
|
||||
const orderFormRef = ref<FormInstance>()
|
||||
@@ -1485,6 +1489,46 @@ function handleOrderSelectionChange(rows: FirstLegOrder[]) {
|
||||
selectedOrders.value = rows
|
||||
}
|
||||
|
||||
async function submitSelectedDraftOrders() {
|
||||
const drafts = selectedDraftOrders.value
|
||||
if (batchSubmitting.value || !drafts.length) return
|
||||
if (companySubmissionBlocked.value) {
|
||||
ElMessage.warning('企业资料审核通过后才能提交订单')
|
||||
return
|
||||
}
|
||||
try {
|
||||
await ElMessageBox.confirm(`确认提交选中的 ${drafts.length} 条草稿订单吗?`, '批量提交订单', {
|
||||
type: 'warning',
|
||||
confirmButtonText: '确认提交',
|
||||
cancelButtonText: '取消',
|
||||
})
|
||||
} catch (error) {
|
||||
if (error === 'cancel' || error === 'close') return
|
||||
throw error
|
||||
}
|
||||
|
||||
batchSubmitting.value = true
|
||||
try {
|
||||
const results = await Promise.allSettled(drafts.map((order) => submitMerchantFirstLegOrder(
|
||||
order.id,
|
||||
createIdempotencyKey(`first-leg-batch-submit-${order.id}`),
|
||||
)))
|
||||
const successCount = results.filter((result) => result.status === 'fulfilled').length
|
||||
const failures = results.filter((result): result is PromiseRejectedResult => result.status === 'rejected')
|
||||
await searchOrders(appliedFilters.value)
|
||||
if (!failures.length) {
|
||||
ElMessage.success(`已提交 ${successCount} 条草稿订单`)
|
||||
return
|
||||
}
|
||||
const firstReason = failures[0]?.reason
|
||||
const reason = firstReason instanceof Error ? firstReason.message : '提交失败'
|
||||
if (successCount > 0) ElMessage.warning(`${successCount} 条提交成功,${failures.length} 条失败:${reason}`)
|
||||
else ElMessage.error(`${failures.length} 条草稿订单提交失败:${reason}`)
|
||||
} finally {
|
||||
batchSubmitting.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function downloadShippingMarks() {
|
||||
if (downloadingMarks.value) return
|
||||
const orders = selectedOrders.value
|
||||
@@ -1816,12 +1860,7 @@ async function searchOrders(model: QueryModel) {
|
||||
<template>
|
||||
<section class="first-leg-page" :class="{ 'is-create-route': isCreatePage }">
|
||||
<template v-if="!isCreatePage">
|
||||
<QueryToolbar v-model="filters" class="first-leg-query-toolbar" :fields="queryFields" ariaLabel="订单查询" @search="searchOrders">
|
||||
<template #actions>
|
||||
<el-button class="query-export-button" type="primary" :loading="downloadingMarks" :disabled="selectedOrderCount === 0" @click="downloadShippingMarks"><Download :size="16" />下载唛头</el-button>
|
||||
<el-button class="query-export-button" type="primary" :loading="exportingOrders" :disabled="selectedOrderCount === 0" @click="exportOrderInformation"><Download :size="16" />导出订单信息</el-button>
|
||||
</template>
|
||||
</QueryToolbar>
|
||||
<QueryToolbar v-model="filters" class="first-leg-query-toolbar" :fields="queryFields" ariaLabel="订单查询" @search="searchOrders" />
|
||||
|
||||
<div class="client-card order-table-card">
|
||||
<div class="order-table-toolbar">
|
||||
@@ -1853,6 +1892,9 @@ async function searchOrders(model: QueryModel) {
|
||||
<el-button link class="column-settings-reset" @click="resetOrderColumns"><RotateCcw :size="17" />恢复默认</el-button>
|
||||
</div>
|
||||
</el-popover>
|
||||
<el-button :loading="downloadingMarks" :disabled="selectedOrderCount === 0" @click="downloadShippingMarks"><Download :size="16" />下载唛头</el-button>
|
||||
<el-button :loading="exportingOrders" :disabled="selectedOrderCount === 0" @click="exportOrderInformation"><Download :size="16" />导出订单信息</el-button>
|
||||
<el-button v-if="canSubmitOrder" :loading="batchSubmitting" :disabled="selectedDraftOrders.length === 0 || companySubmissionBlocked" @click="submitSelectedDraftOrders"><Send :size="17" />批量提交草稿</el-button>
|
||||
<el-button v-if="auth.hasPermission('order:first-leg:create')" @click="openBatchImport"><Upload :size="17" />批量导入订单</el-button>
|
||||
<el-button v-if="auth.hasPermission('order:first-leg:create')" type="primary" :loading="pageDataLoading" :disabled="pageDataLoading || availableWarehouses.length === 0" @click="openCreate"><FilePlus2 :size="17" />创建订单</el-button>
|
||||
</div>
|
||||
@@ -1878,7 +1920,7 @@ async function searchOrders(model: QueryModel) {
|
||||
<template #actions="{ row }">
|
||||
<div class="order-row-actions">
|
||||
<el-button link type="primary" @click="openDetail(row as FirstLegOrder)"><Eye :size="15" />详情</el-button>
|
||||
<el-button link type="primary" @click="openFeeConfirmation(row as FirstLegOrder)">确认计费重</el-button>
|
||||
<el-button v-if="canConfirmInboundFee && (row as FirstLegOrder).businessSummary.customerFeeConfirmationRequired" link type="primary" @click="openFeeConfirmation(row as FirstLegOrder)">确认计费重</el-button>
|
||||
<el-button v-if="canEditOrder && canClientEditFirstLegOrder((row as FirstLegOrder).status)" link type="primary" :loading="openingEditor" @click="openEdit(row as FirstLegOrder)"><Pencil :size="15" />编辑</el-button>
|
||||
<el-button v-if="eligibleCustomsDetail(row as FirstLegOrder)" link type="primary" @click="openCustomsDocuments(row as FirstLegOrder)"><FileText :size="15" />报关资料</el-button>
|
||||
</div>
|
||||
@@ -1944,7 +1986,7 @@ async function searchOrders(model: QueryModel) {
|
||||
<span>更新于 {{ formatDateTime(order.updatedAt) }}</span>
|
||||
<div>
|
||||
<el-button link type="primary" @click="openDetail(order)"><Eye :size="15" />详情</el-button>
|
||||
<el-button link type="primary" @click="openFeeConfirmation(order)">确认计费重</el-button>
|
||||
<el-button v-if="canConfirmInboundFee && order.businessSummary.customerFeeConfirmationRequired" link type="primary" @click="openFeeConfirmation(order)">确认计费重</el-button>
|
||||
<el-button v-if="canEditOrder && canClientEditFirstLegOrder(order.status)" link type="primary" :loading="openingEditor" @click="openEdit(order)"><Pencil :size="15" />编辑</el-button>
|
||||
<el-button v-if="eligibleCustomsDetail(order)" link type="primary" @click="openCustomsDocuments(order)"><FileText :size="15" />报关资料</el-button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user