From f702d1b988706f803301b37a8814e821b3008849 Mon Sep 17 00:00:00 2001 From: wujinliang <2318309077@qq.com> Date: Tue, 25 Aug 2026 17:43:00 +0800 Subject: [PATCH] 1 --- .../pages/ContainersView.vue | 4 ++-- .../measurement/InboundMeasurementPanel.vue | 23 ++++++++++++++++++- .../pages/OceanBookingDetailView.vue | 10 ++++++-- .../pages/OceanBookingsView.vue | 5 ++-- .../pallets/pages/PalletsView.vue | 2 -- 5 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/modules/container-loading/pages/ContainersView.vue b/src/modules/container-loading/pages/ContainersView.vue index f0165d05..b259e8e8 100644 --- a/src/modules/container-loading/pages/ContainersView.vue +++ b/src/modules/container-loading/pages/ContainersView.vue @@ -161,8 +161,8 @@ const destinationWarehouseValue = computed(() => form.destinationWarehouseCode | const queryFields = computed(() => [ { key: 'customerId', type: 'select', label: '客户', width: 220, placeholder: '全部客户', options: customers.value.filter((customer) => customer.status === 'ACTIVE').map((customer) => ({ label: customer.tenantName, value: String(customer.id) })), props: { filterable: true, loading: customersLoading.value } }, { key: 'keyword', type: 'input', label: '关键词', width: 220, placeholder: '柜次号、集装箱号或提单号', props: { 'aria-label': '关键词', maxlength: 128 } }, - { key: 'containerType', type: 'select', label: '柜型', width: 140, options: CONTAINER_SPECIFICATIONS.map((item) => ({ label: item.type, value: item.type })), props: { 'aria-label': '柜型' } }, - { key: 'status', type: 'select', label: '排柜状态', width: 150, options: [{ label: '待装柜', value: 'WAIT_LOADING' }, { label: '预装柜中', value: 'EDITING' }, { label: '拣货中', value: 'LOADING' }, { label: '装柜完成', value: 'COMPLETED' }], props: { 'aria-label': '排柜状态' } }, + { key: 'containerType', type: 'select', label: '柜型', width: 140, placeholder: '请选择箱型', options: CONTAINER_SPECIFICATIONS.map((item) => ({ label: item.type, value: item.type })), props: { 'aria-label': '柜型' } }, + { key: 'status', type: 'select', label: '排柜状态', width: 150, placeholder: '请选择货柜状态', options: [{ label: '待装柜', value: 'WAIT_LOADING' }, { label: '预装柜中', value: 'EDITING' }, { label: '拣货中', value: 'LOADING' }, { label: '装柜完成', value: 'COMPLETED' }], props: { 'aria-label': '排柜状态' } }, { key: 'sailingRange', type: 'daterange', label: '预计开船', width: 260, props: { 'aria-label': '预计开船日期范围' } }, ]) const columns: DataTableColumn[] = [ diff --git a/src/modules/inbounds/measurement/InboundMeasurementPanel.vue b/src/modules/inbounds/measurement/InboundMeasurementPanel.vue index ae2e9e66..0177d691 100644 --- a/src/modules/inbounds/measurement/InboundMeasurementPanel.vue +++ b/src/modules/inbounds/measurement/InboundMeasurementPanel.vue @@ -294,6 +294,16 @@ function validateDraft() { form.items.forEach((item, index) => { const itemErrors: string[] = [] if (!Number.isInteger(item.packageCount) || item.packageCount < 1 || item.packageCount > 1_000_000) itemErrors.push('箱数必须是 1 至 1,000,000 的整数') + const dimensions = [ + ['长', item.lengthCm], + ['宽', item.widthCm], + ['高', item.heightCm], + ] as const + for (const [label, value] of dimensions) { + if (!Number.isFinite(value) || value <= 0) itemErrors.push(`${label}必须是大于 0 的有效数值`) + else if (value > 999_999_999.999) itemErrors.push(`${label}超出系统允许上限 999,999,999.999 cm`) + else if (Math.abs(value * 1000 - Math.round(value * 1000)) > 1e-6) itemErrors.push(`${label}最多保留 3 位小数`) + } if (itemErrors.length) errors[item.clientKey] = itemErrors.map((message) => `第 ${index + 1} 条:${message}`) }) if (general.length) errors.general = general @@ -310,7 +320,17 @@ function validateDraft() { } function setOperationError(error: unknown, fallback: string) { - const details = getApiErrorDetails(error, fallback) + const source = getApiErrorDetails(error, fallback) + const numericOverflow = /data truncation|out of range|numeric value|decimal|数值.*(过大|超出)|尺寸.*(过大|超限)/i.test(source.message) + const largestItem = numericOverflow + ? [...form.items].sort((left, right) => Math.max(right.lengthCm, right.widthCm, right.heightCm) - Math.max(left.lengthCm, left.widthCm, left.heightCm))[0] + : undefined + const details = numericOverflow ? { + ...source, + message: largestItem + ? `箱规尺寸或箱数超出系统允许范围,请检查箱号 ${largestItem.boxCode || largestItem.itemNo}(${formatNumber(largestItem.lengthCm)} × ${formatNumber(largestItem.widthCm)} × ${formatNumber(largestItem.heightCm)} cm)后重试` + : '箱规尺寸或箱数超出系统允许范围,请检查长、宽、高和箱数后重试', + } : source const conflict = details.message.includes('版本已变化') || details.message.includes('并发修改') conflictDetected.value = conflict @@ -361,6 +381,7 @@ async function saveDraft() { async function submitForReview() { if (!maySubmit.value || !form.measurementId) return + if (!validateDraft()) return if (isDirty.value) { ElMessage.warning('请先保存当前修改,再提交审核') return diff --git a/src/modules/ocean-bookings/pages/OceanBookingDetailView.vue b/src/modules/ocean-bookings/pages/OceanBookingDetailView.vue index 005d2535..f9f586b5 100644 --- a/src/modules/ocean-bookings/pages/OceanBookingDetailView.vue +++ b/src/modules/ocean-bookings/pages/OceanBookingDetailView.vue @@ -4,6 +4,7 @@ import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'elem import { useRoute, useRouter } from 'vue-router' import { ArrowLeft, Plus, Save, Trash2 } from '@lucide/vue' import { useAccessPreviewStore } from '@/core/access/accessPreview' +import { useWorkspaceTabsStore } from '@/core/workspace-tabs/workspaceTabs' import { getApiErrorDetails } from '@/shared/api/http' import LoadErrorState from '@/shared/components/LoadErrorState.vue' import ApiErrorMeta from '@/shared/components/ApiErrorMeta.vue' @@ -52,6 +53,7 @@ const containerKindOptions = [ const route = useRoute() const router = useRouter() const access = useAccessPreviewStore() +const workspace = useWorkspaceTabsStore() const id = computed(() => String(route.params.bookingId || '')) const isNew = computed(() => route.name === 'ocean-booking-create' || id.value === 'new') const detail = ref(null) @@ -220,8 +222,12 @@ async function save() { const saved = isNew.value ? await createOceanBooking({ expectedVersion: 0, data: payload }) : await updateOceanBookingDraft(id.value, { expectedVersion: detail.value?.version || 0, data: payload }) - ElMessage.success('订舱草稿已保存') - if (isNew.value) await router.replace(`/ocean-bookings/${saved.id}`) + ElMessage.success(isNew.value ? `订舱创建成功:${saved.bookingNo || saved.id}` : '订舱草稿已保存') + if (isNew.value) { + workspace.removeByIds(['ocean-booking-create']) + await router.replace('/ocean-bookings') + return + } applyDetail(saved) } catch (cause) { actionError.value = getApiErrorDetails(cause) } finally { saving.value = false } diff --git a/src/modules/ocean-bookings/pages/OceanBookingsView.vue b/src/modules/ocean-bookings/pages/OceanBookingsView.vue index e2fb1a7b..29b218b7 100644 --- a/src/modules/ocean-bookings/pages/OceanBookingsView.vue +++ b/src/modules/ocean-bookings/pages/OceanBookingsView.vue @@ -1,5 +1,5 @@