优化
This commit is contained in:
@@ -4,6 +4,7 @@ import { useRouter } from 'vue-router'
|
||||
import { Boxes, Check, Eye, FileText, FileUp, ListChecks, MoreHorizontal, Pencil, Sparkles, TriangleAlert } from '@lucide/vue'
|
||||
import { ElMessage, type FormInstance, type FormRules, type UploadFile } from 'element-plus'
|
||||
import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
||||
import { listPlatformTenants, type PlatformTenantResource } from '@/modules/iam'
|
||||
import { listAllPlatformWarehouses, type PlatformWarehouseSummaryResource } from '@/modules/warehouses'
|
||||
import { listPlatformPartners, type PlatformPartnerResource } from '@/modules/master-data'
|
||||
import { listOceanBookings, type OceanBookingResource } from '@/modules/ocean-bookings'
|
||||
@@ -21,12 +22,14 @@ import ContainerOverviewPanel from '../components/ContainerOverviewPanel.vue'
|
||||
import { cancelContainerException, completeContainerClearance, downloadContainerDocument, downloadContainerPdaPhoto, getContainer, getContainerClearance, getContainerOverview, listContainers, markContainerException, updateContainer, updateContainerTransport, uploadContainerClearance, uploadContainerDocument } from '../api/platformContainerLoading'
|
||||
import type { ContainerBookingResource, ContainerDocumentType, ContainerOverview, ContainerOverviewDocument, ContainerPdaPhoto, ContainerPlanStatus, ContainerSaveRequest } from '../types'
|
||||
|
||||
type Filters = QueryModel & { keyword: string; containerType: string; status: ContainerPlanStatus | ''; sailingRange: string[] }
|
||||
type Filters = QueryModel & { customerId: string; keyword: string; containerType: string; status: ContainerPlanStatus | ''; sailingRange: string[] }
|
||||
type ContainerForm = ContainerSaveRequest & { id: string; version: number }
|
||||
|
||||
const router = useRouter()
|
||||
const access = useAccessPreviewStore()
|
||||
const rows = ref<ContainerBookingResource[]>([])
|
||||
const customers = ref<PlatformTenantResource[]>([])
|
||||
const customersLoading = ref(false)
|
||||
const warehouses = ref<PlatformWarehouseSummaryResource[]>([])
|
||||
const destinationWarehouses = ref<PlatformWarehouseSummaryResource[]>([])
|
||||
const partners = ref<PlatformPartnerResource[]>([])
|
||||
@@ -40,7 +43,7 @@ const businessOptionsError = ref('')
|
||||
const page = ref(1)
|
||||
const pageSize = ref(20)
|
||||
const total = ref(0)
|
||||
const filters = ref<Filters>({ keyword: '', containerType: '', status: '', sailingRange: [] })
|
||||
const filters = ref<Filters>({ customerId: '', keyword: '', containerType: '', status: '', sailingRange: [] })
|
||||
const applied = ref<Filters>({ ...filters.value })
|
||||
const detailOpen = ref(false)
|
||||
const detailLoading = ref(false)
|
||||
@@ -132,6 +135,7 @@ const shippingCompanyValue = computed(() => form.shippingCompanyId || (form.ship
|
||||
const destinationWarehouseValue = computed(() => form.destinationWarehouseCode || (form.destinationWarehouseName ? `name:${form.destinationWarehouseName}` : ''))
|
||||
|
||||
const queryFields = computed<QueryField[]>(() => [
|
||||
{ key: 'customerId', type: 'select', label: '客户', width: 220, placeholder: '全部客户', options: customers.value.filter((customer) => customer.status === 'ACTIVE').map((customer) => ({ label: customer.legalName?.trim() || 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: ['20GP', '40GP', '40HQ', '45HQ'].map((value) => ({ label: value, value })), 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': '排柜状态' } },
|
||||
@@ -234,6 +238,17 @@ async function loadWarehouses() {
|
||||
catch (error) { warehouseError.value = getApiErrorDetails(error, '装柜仓库加载失败') }
|
||||
finally { warehouseLoading.value = false }
|
||||
}
|
||||
async function loadCustomers() {
|
||||
customersLoading.value = true
|
||||
try {
|
||||
const result = await listPlatformTenants({ page: 1, size: 200, status: 'ACTIVE' })
|
||||
customers.value = result.records.filter((customer) => customer.status === 'ACTIVE')
|
||||
} catch {
|
||||
customers.value = []
|
||||
} finally {
|
||||
customersLoading.value = false
|
||||
}
|
||||
}
|
||||
async function loadBusinessOptions() {
|
||||
businessOptionsLoading.value = true
|
||||
businessOptionsError.value = ''
|
||||
@@ -267,7 +282,7 @@ async function loadRows() {
|
||||
const [from, to] = applied.value.sailingRange || []
|
||||
try {
|
||||
const result = await listContainers({
|
||||
page: page.value, size: pageSize.value, keyword: applied.value.keyword.trim() || undefined,
|
||||
page: page.value, size: pageSize.value, customerId: applied.value.customerId || undefined, keyword: applied.value.keyword.trim() || undefined,
|
||||
containerType: applied.value.containerType || undefined,
|
||||
status: applied.value.status, estimatedSailingFrom: from ? `${from}T00:00:00` : undefined,
|
||||
estimatedSailingTo: to ? `${to}T23:59:59` : undefined,
|
||||
@@ -428,7 +443,7 @@ function goContainerProcess(source: object) {
|
||||
watch([page, pageSize], ([nextPage, nextSize], [previousPage, previousSize]) => {
|
||||
if (nextPage !== previousPage || nextSize !== previousSize) void loadRows()
|
||||
})
|
||||
onMounted(() => { void Promise.all([loadWarehouses(), loadBusinessOptions(), loadRows()]) })
|
||||
onMounted(() => { void Promise.all([loadCustomers(), loadWarehouses(), loadBusinessOptions(), loadRows()]) })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useRouter } from 'vue-router'
|
||||
import { Plus, RefreshCw, Save, Sparkles, Trash2, Upload } from '@lucide/vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
||||
import { listPlatformTenants, type PlatformTenantResource } from '@/modules/iam'
|
||||
import AdminPage from '@/shared/components/AdminPage.vue'
|
||||
import ApiErrorMeta from '@/shared/components/ApiErrorMeta.vue'
|
||||
import AppDialog from '@/shared/components/AppDialog.vue'
|
||||
@@ -33,6 +34,8 @@ import type {
|
||||
const access = useAccessPreviewStore()
|
||||
const router = useRouter()
|
||||
const containers = ref<ContainerBookingResource[]>([])
|
||||
const customers = ref<PlatformTenantResource[]>([])
|
||||
const customersLoading = ref(false)
|
||||
const selectedContainerId = ref('')
|
||||
const plan = ref<SmartLoadingPlan | null>(null)
|
||||
const candidates = ref<SmartLoadingCandidate[]>([])
|
||||
@@ -47,7 +50,7 @@ const assignOpen = ref(false)
|
||||
const selectedCandidate = ref<SmartLoadingCandidate | null>(null)
|
||||
const assignForm = reactive({ packageCount: 1 })
|
||||
const quantityDrafts = reactive<Record<string, number>>({})
|
||||
const query = ref<QueryModel>({ orderKeyword: '', containerKeyword: '', status: '' })
|
||||
const query = ref<QueryModel>({ customerId: '', orderKeyword: '', containerKeyword: '', status: '' })
|
||||
const appliedQuery = ref<QueryModel>({ ...query.value })
|
||||
let selectionRequest = 0
|
||||
|
||||
@@ -70,7 +73,8 @@ const displayedVolumePercent = computed(() => percentage(volumePercent.value))
|
||||
const displayedWeightPercent = computed(() => percentage(weightPercent.value))
|
||||
|
||||
const queryFields = computed<QueryField[]>(() => [
|
||||
{ key: 'orderKeyword', type: 'input', label: '订单或货物', placeholder: '订单号、入库单、客户、货物', width: 250 },
|
||||
{ key: 'customerId', type: 'select', label: '客户', placeholder: '全部客户', width: 220, options: customers.value.filter((customer) => customer.status === 'ACTIVE').map((customer) => ({ label: customer.legalName?.trim() || customer.tenantName, value: String(customer.id) })), props: { filterable: true, loading: customersLoading.value } },
|
||||
{ key: 'orderKeyword', type: 'input', label: '订单或货物', placeholder: '订单号、入库单、货物', width: 250 },
|
||||
{ key: 'containerKeyword', type: 'input', label: '柜次', placeholder: '柜次号、集装箱号、目的仓', width: 230 },
|
||||
{ key: 'status', type: 'select', label: '柜次状态', width: 160, options: [
|
||||
{ label: '待装柜', value: 'WAIT_LOADING' },
|
||||
@@ -91,10 +95,14 @@ const filteredContainers = computed(() => {
|
||||
})
|
||||
})
|
||||
const filteredCandidates = computed(() => {
|
||||
const customerId = String(appliedQuery.value.customerId || '')
|
||||
const keyword = String(appliedQuery.value.orderKeyword || '').trim().toLowerCase()
|
||||
if (!keyword) return candidates.value
|
||||
return candidates.value.filter((item) => [item.orderNo, item.inboundCode, item.customerName, item.goodsName]
|
||||
.some((value) => String(value || '').toLowerCase().includes(keyword)))
|
||||
return candidates.value.filter((item) => {
|
||||
if (customerId && item.accountId !== customerId) return false
|
||||
if (!keyword) return true
|
||||
return [item.orderNo, item.inboundCode, item.goodsName]
|
||||
.some((value) => String(value || '').toLowerCase().includes(keyword))
|
||||
})
|
||||
})
|
||||
|
||||
function preferredContainerId() {
|
||||
@@ -216,6 +224,17 @@ async function loadAll(preserved: Record<string, number> = {}) {
|
||||
}
|
||||
}
|
||||
async function load() { await loadAll() }
|
||||
async function loadCustomers() {
|
||||
customersLoading.value = true
|
||||
try {
|
||||
const result = await listPlatformTenants({ page: 1, size: 200, status: 'ACTIVE' })
|
||||
customers.value = result.records.filter((customer) => customer.status === 'ACTIVE')
|
||||
} catch {
|
||||
customers.value = []
|
||||
} finally {
|
||||
customersLoading.value = false
|
||||
}
|
||||
}
|
||||
async function selectContainer(containerId: string) {
|
||||
if (selectedContainerId.value === containerId) return
|
||||
selectedContainerId.value = containerId
|
||||
@@ -324,7 +343,7 @@ async function mutate(
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(load)
|
||||
onMounted(() => { void load(); void loadCustomers() })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -139,6 +139,7 @@ export interface ContainerPage {
|
||||
export interface ContainerQuery {
|
||||
page: number
|
||||
size: number
|
||||
customerId?: string
|
||||
keyword?: string
|
||||
containerNo?: string
|
||||
cabinetNo?: string
|
||||
|
||||
Reference in New Issue
Block a user