优化
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
import { computed, onActivated, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { CircleCheckBig, Eye, Ruler, SearchCheck } from '@lucide/vue'
|
||||
import { CircleCheckBig, Eye, Link2, Ruler, SearchCheck } from '@lucide/vue'
|
||||
import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
||||
import { listPlatformTenants, type PlatformTenantResource } from '@/modules/iam'
|
||||
import { listPlatformWarehouses } from '@/modules/warehouses'
|
||||
@@ -12,6 +12,7 @@ import ApiErrorMeta from '@/shared/components/ApiErrorMeta.vue'
|
||||
import DataTable, { type DataTableColumn } from '@/shared/components/DataTable.vue'
|
||||
import ListPageLayout from '@/shared/components/ListPageLayout.vue'
|
||||
import LoadErrorState from '@/shared/components/LoadErrorState.vue'
|
||||
import InboundCodeRelationshipDrawer from '@/shared/components/InboundCodeRelationshipDrawer.vue'
|
||||
import QueryToolbar, { type QueryField, type QueryModel } from '@/shared/components/QueryToolbar.vue'
|
||||
import { listPlatformInbounds } from '../core/api'
|
||||
import type { InboundOrderSummary } from '../core/types'
|
||||
@@ -44,6 +45,8 @@ const warehouseOptions = ref<Array<{ label: string; value: string }>>([])
|
||||
const selectedInbound = ref<InboundOrderSummary | null>(null)
|
||||
const measurementDialogOpen = ref(false)
|
||||
const reviewDialogOpen = ref(false)
|
||||
const relationshipOpen = ref(false)
|
||||
const relationshipInboundCode = ref('')
|
||||
const batchReviewLoading = ref(false)
|
||||
const selectedReviewRows = ref<InboundOrderSummary[]>([])
|
||||
let requestSerial = 0
|
||||
@@ -190,6 +193,13 @@ function openDetail(row: InboundOrderSummary) {
|
||||
void router.push({ name: 'unified-order-detail', params: { orderId: row.orderId }, query: { tenantId: row.tenantId } })
|
||||
}
|
||||
|
||||
function openRelationship(row: InboundOrderSummary) {
|
||||
const code = row.inboundCode?.trim()
|
||||
if (!code) return
|
||||
relationshipInboundCode.value = code
|
||||
relationshipOpen.value = true
|
||||
}
|
||||
|
||||
function handleTaskChanged() {
|
||||
reviewDialogOpen.value = false
|
||||
selectedInbound.value = null
|
||||
@@ -224,12 +234,12 @@ async function batchApproveMeasurements() {
|
||||
successCount += 1
|
||||
if (!approval.initialPricingSucceeded) {
|
||||
pricingWarnings.push(
|
||||
`${row.inboundCode || row.id}:${approval.initialPricingMessage || '费用初算未生成'}`,
|
||||
`${row.inboundCode || '入仓码待补充'}:${approval.initialPricingMessage || '费用初算未生成'}`,
|
||||
)
|
||||
}
|
||||
} catch (error) {
|
||||
failureCount += 1
|
||||
failures.push(getApiErrorDetails(error, `${row.inboundCode || row.id} 审核失败`).message)
|
||||
failures.push(getApiErrorDetails(error, `${row.inboundCode || '入仓码待补充'} 审核失败`).message)
|
||||
}
|
||||
}
|
||||
await loadTasks()
|
||||
@@ -329,7 +339,7 @@ onBeforeUnmount(() => { disposed = true; requestSerial += 1; optionsRequestSeria
|
||||
<span v-if="!access.can(actionPermission) && (!access.can('platform:firstleg:inbound:view') || !(row as InboundOrderSummary).orderId)" class="muted-action">无操作权限</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #inboundCode="{ row }"><strong>{{ text((row as InboundOrderSummary).inboundCode) }}</strong></template>
|
||||
<template #inboundCode="{ row }"><div class="inbound-code-cell"><strong>{{ text((row as InboundOrderSummary).inboundCode) }}</strong><el-button v-if="(row as InboundOrderSummary).inboundCode" link type="primary" @click="openRelationship(row as InboundOrderSummary)"><Link2 :size="14" />关联数据</el-button></div></template>
|
||||
<template #processStatus="{ row }"><el-tag effect="light">{{ inboundStatusLabel((row as InboundOrderSummary).processStatus, inboundProcessStatusLabels) }}</el-tag></template>
|
||||
<template #measureReviewStatus="{ row }">{{ inboundStatusLabel((row as InboundOrderSummary).measureReviewStatus, inboundReviewStatusLabels) }}</template>
|
||||
<template #expectedArrivalAt="{ row }">{{ formatDate((row as InboundOrderSummary).expectedArrivalAt) }}</template>
|
||||
@@ -352,7 +362,7 @@ onBeforeUnmount(() => { disposed = true; requestSerial += 1; optionsRequestSeria
|
||||
<el-dialog
|
||||
v-if="isReview"
|
||||
v-model="reviewDialogOpen"
|
||||
:title="selectedInbound ? `${taskLabel} · ${selectedInbound.inboundCode || selectedInbound.id}` : taskLabel"
|
||||
:title="selectedInbound ? `${taskLabel} · ${selectedInbound.inboundCode || '入仓码待补充'}` : taskLabel"
|
||||
width="min(1180px, calc(100vw - 32px))"
|
||||
top="4vh"
|
||||
destroy-on-close
|
||||
@@ -381,6 +391,7 @@ onBeforeUnmount(() => { disposed = true; requestSerial += 1; optionsRequestSeria
|
||||
@submitted="handleMeasurementSubmitted"
|
||||
@closed="clearSelectedInbound"
|
||||
/>
|
||||
<InboundCodeRelationshipDrawer v-if="relationshipOpen" v-model="relationshipOpen" :inbound-code="relationshipInboundCode" :can-read-base="access.can('platform:order:list')" :can-read-loading="access.can('platform:firstleg:smart-loading:list')" :can-read-overseas="access.can('platform:overseas-warehouse:inventory:list')" />
|
||||
</AdminPage>
|
||||
</template>
|
||||
|
||||
@@ -391,6 +402,8 @@ onBeforeUnmount(() => { disposed = true; requestSerial += 1; optionsRequestSeria
|
||||
.row-actions .el-button { margin: 0; }
|
||||
.primary-cell { display: grid; gap: 3px; min-width: 0; }
|
||||
.primary-cell strong, .primary-cell span { overflow-wrap: anywhere; }
|
||||
.inbound-code-cell { display: grid; gap: 3px; min-width: 0; }
|
||||
.inbound-code-cell .el-button { width: fit-content; margin: 0; padding: 0; }
|
||||
.primary-cell span, .muted-action { color: var(--cc-muted); font-size: 12px; }
|
||||
@media (max-width: 520px) {
|
||||
.row-actions { align-items: stretch; flex-direction: column; }
|
||||
|
||||
@@ -35,7 +35,7 @@ const revision = ref(0)
|
||||
let requestSerial = 0
|
||||
let disposed = false
|
||||
|
||||
const title = computed(() => detail.value?.summary.inboundCode || props.inboundId)
|
||||
const title = computed(() => detail.value?.summary.inboundCode || '入仓码待补充')
|
||||
const canViewMeasurement = computed(() => access.can('platform:firstleg:inbound:measure:view'))
|
||||
const statusLabel = computed(() => inboundStatusLabel(detail.value?.summary.processStatus, inboundProcessStatusLabels, '未知状态'))
|
||||
|
||||
|
||||
@@ -22,7 +22,8 @@ describe('InboundMeasurementDialog', () => {
|
||||
})
|
||||
|
||||
it('shows the inbound code once in the dialog title and not as a second body heading', () => {
|
||||
expect(source).toContain('`测量 · ${props.inboundCode?.trim() || props.inboundId}`')
|
||||
expect(source).toContain("`测量 · ${props.inboundCode?.trim() || '入仓码待补充'}`")
|
||||
expect(source).not.toContain('props.inboundCode?.trim() || props.inboundId')
|
||||
expect(source).toContain(':title="title"')
|
||||
expect(panelSource).not.toContain('<span>入仓码</span>')
|
||||
expect(panelSource).not.toContain('<strong>{{ detail.inboundCode')
|
||||
|
||||
@@ -19,7 +19,7 @@ const emit = defineEmits<{
|
||||
}>()
|
||||
|
||||
const measurementPanelRef = ref<InstanceType<typeof InboundMeasurementPanel> | null>(null)
|
||||
const title = computed(() => `测量 · ${props.inboundCode?.trim() || props.inboundId}`)
|
||||
const title = computed(() => `测量 · ${props.inboundCode?.trim() || '入仓码待补充'}`)
|
||||
|
||||
async function mayClose() {
|
||||
if (!measurementPanelRef.value?.isDirty) return true
|
||||
|
||||
@@ -115,7 +115,7 @@ const sourceLabel = computed(() => ({ THIRD_PARTY: '第三方设备', MANUAL: '
|
||||
|
||||
const { captureBaseline } = useUnsavedWorkRegistration({
|
||||
key: 'p2-inbound-measurement-editor',
|
||||
label: computed(() => `入库单 ${detail.value?.inboundCode || props.inboundId} 的测量草稿`),
|
||||
label: computed(() => `入仓码 ${detail.value?.inboundCode || '待补充'} 的测量草稿`),
|
||||
isOpen: registrationOpen,
|
||||
model: form,
|
||||
requiredPermission,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { ChevronDown, ChevronUp, ClipboardCheck, Eye, Printer, RefreshCw, SlidersHorizontal } from '@lucide/vue'
|
||||
import { ChevronDown, ChevronUp, ClipboardCheck, Eye, Link2, Printer, RefreshCw, SlidersHorizontal } from '@lucide/vue'
|
||||
import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
||||
import { getApiErrorDetails, type ApiErrorDetails } from '@/shared/api/http'
|
||||
import AdminPage from '@/shared/components/AdminPage.vue'
|
||||
@@ -10,6 +10,7 @@ import ApiErrorMeta from '@/shared/components/ApiErrorMeta.vue'
|
||||
import DataTable, { type DataTableColumn } from '@/shared/components/DataTable.vue'
|
||||
import ListPageLayout from '@/shared/components/ListPageLayout.vue'
|
||||
import LoadErrorState from '@/shared/components/LoadErrorState.vue'
|
||||
import InboundCodeRelationshipDrawer from '@/shared/components/InboundCodeRelationshipDrawer.vue'
|
||||
import QueryToolbar, { type QueryField, type QueryModel } from '@/shared/components/QueryToolbar.vue'
|
||||
import { firstLegBusinessTypeLabel, firstLegContainerModeLabel, firstLegDestinationTypeLabel, firstLegTaxModeLabel } from '@/shared/utils/firstLegBusinessLabels'
|
||||
import { listPlatformTenants, type PlatformTenantResource } from '@/modules/iam'
|
||||
@@ -42,6 +43,8 @@ const pageSize = ref(20)
|
||||
const loading = ref(false)
|
||||
const loadError = ref<ApiErrorDetails | null>(null)
|
||||
const printingInboundId = ref('')
|
||||
const relationshipOpen = ref(false)
|
||||
const relationshipInboundCode = ref('')
|
||||
const result = ref({ records: [] as InboundOrderSummary[], total: 0 })
|
||||
const filters = ref<FilterModel>({ customerId: '', inboundCode: '', warehouseId: '', deliveryWarehouseId: '', processStatus: '', orderStatus: '', measureReviewStatus: '', customerName: '', destinationCode: '', feeStatus: '', feeReviewStatus: '', holdFlag: '', expectedArrivalRange: [] })
|
||||
const appliedFilters = ref<FilterModel>({ ...filters.value, expectedArrivalRange: [] })
|
||||
@@ -286,6 +289,7 @@ function openDetail(row: InboundOrderSummary) {
|
||||
}
|
||||
void router.push({ name: 'unified-order-detail', params: { orderId: row.orderId }, query: { tenantId: row.tenantId } })
|
||||
}
|
||||
function openRelationship(row: InboundOrderSummary) { const code = row.inboundCode?.trim(); if (!code) return; relationshipInboundCode.value = code; relationshipOpen.value = true }
|
||||
async function printCartonLabels(row: InboundOrderSummary) {
|
||||
if (printingInboundId.value) return
|
||||
printingInboundId.value = row.id
|
||||
@@ -294,7 +298,7 @@ async function printCartonLabels(row: InboundOrderSummary) {
|
||||
const url = URL.createObjectURL(blob)
|
||||
const anchor = document.createElement('a')
|
||||
anchor.href = url
|
||||
anchor.download = `${row.inboundCode || row.id}-${row.totalPackageCount || '整单'}件-箱唛.pdf`
|
||||
anchor.download = `${row.inboundCode || '入仓码待补充'}-${row.totalPackageCount || '整单'}件-箱唛.pdf`
|
||||
anchor.click()
|
||||
URL.revokeObjectURL(url)
|
||||
ElMessage.success('箱唛已生成,重复打印将继续使用原箱号')
|
||||
@@ -413,7 +417,7 @@ onBeforeUnmount(() => { disposed = true; loadRequestId += 1; customerRequestId +
|
||||
<DataTable v-model:page="page" v-model:page-size="pageSize" :data="result.records" :columns="columns" preference-key="inbound-orders-table" :loading="loading" :total="result.total" :page-sizes="[20, 50, 100]" row-key="id" :empty-text="listEmptyText" aria-label="入库单列表">
|
||||
<template #pagination-left>当前显示 {{ currentPageCount }} 条 · 共 {{ result.total }} 条</template>
|
||||
<template #actions="{ row }"><div v-if="access.can('platform:firstleg:inbound:view')" class="row-actions"><el-button size="small" type="primary" :disabled="!(row as InboundOrderSummary).orderId" @click="openDetail(row as InboundOrderSummary)"><ClipboardCheck :size="15" />处理</el-button><el-button size="small" plain type="primary" :loading="printingInboundId === (row as InboundOrderSummary).id" :disabled="Boolean(printingInboundId)" @click="printCartonLabels(row as InboundOrderSummary)"><Printer :size="15" />打印箱唛</el-button><el-button size="small" plain type="primary" :disabled="!(row as InboundOrderSummary).orderId" @click="openDetail(row as InboundOrderSummary)"><Eye :size="15" />查看</el-button></div><span v-else class="muted-action">无查看权限</span></template>
|
||||
<template #inbound="{ row }"><strong>{{ text((row as InboundOrderSummary).inboundCode) }}</strong></template>
|
||||
<template #inbound="{ row }"><div class="inbound-code-cell"><strong>{{ text((row as InboundOrderSummary).inboundCode) }}</strong><el-button v-if="(row as InboundOrderSummary).inboundCode" link type="primary" @click="openRelationship(row as InboundOrderSummary)"><Link2 :size="14" />关联数据</el-button></div></template>
|
||||
<template #processStatus="{ row }"><el-tag :type="statusType((row as InboundOrderSummary).processStatus)" effect="light">{{ statusLabel((row as InboundOrderSummary).processStatus) }}</el-tag></template>
|
||||
<template #orderStatus="{ row }">{{ codeLabel((row as InboundOrderSummary).orderStatusSnapshot, inboundOrderStatusLabels) }}</template>
|
||||
<template #measureReviewStatus="{ row }">{{ codeLabel((row as InboundOrderSummary).measureReviewStatus, measureReviewLabels) }}</template>
|
||||
@@ -456,12 +460,13 @@ onBeforeUnmount(() => { disposed = true; loadRequestId += 1; customerRequestId +
|
||||
</DataTable>
|
||||
</section>
|
||||
</ListPageLayout>
|
||||
|
||||
<InboundCodeRelationshipDrawer v-if="relationshipOpen" v-model="relationshipOpen" :inbound-code="relationshipInboundCode" :can-read-base="access.can('platform:order:list')" :can-read-loading="access.can('platform:firstleg:smart-loading:list')" :can-read-overseas="access.can('platform:overseas-warehouse:inventory:list')" />
|
||||
</AdminPage>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.inbound-orders-page { min-width: 0; }
|
||||
.inbound-code-cell { display: grid; gap: 3px; min-width: 0; }.inbound-code-cell .el-button { width: fit-content; margin: 0; padding: 0; }
|
||||
.inbound-query-toolbar { align-items: stretch; border-radius: 8px; background: #f8fafc; }
|
||||
.inbound-tabs { display: flex; width: max-content; max-width: 100%; min-width: 0; overflow-x: auto; border-bottom: 2px solid var(--cc-border); scrollbar-width: none; }
|
||||
.inbound-tabs::-webkit-scrollbar { display: none; }
|
||||
|
||||
@@ -246,9 +246,9 @@ defineExpose({ confirmApprove, isPending, canReview, actionLoading })
|
||||
:customer-id="customerId"
|
||||
:inbound-id="inboundId"
|
||||
:file-id="row.intelligentImageFileId"
|
||||
:alt="`箱规 ${row.boxCode || row.itemNo || row.id} 的测量图片`"
|
||||
:alt="`箱规 ${row.boxCode || row.itemNo || '箱规编码待补充'} 的测量图片`"
|
||||
empty-text="无图片"
|
||||
@open="openImagePreview(row.intelligentImageFileId, row.boxCode || row.itemNo || row.id)"
|
||||
@open="openImagePreview(row.intelligentImageFileId, row.boxCode || row.itemNo || '箱规编码待补充')"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
Reference in New Issue
Block a user