优化
This commit is contained in:
@@ -31,7 +31,6 @@ import {
|
||||
getTerminalDrayage,
|
||||
getTerminalDrayageHistory,
|
||||
recordTerminalDrayageEmptyReturn,
|
||||
recordTerminalDrayagePickup,
|
||||
scheduleTerminalDrayagePickup,
|
||||
selectTerminalDrayageFleet,
|
||||
type TerminalDrayageAction,
|
||||
@@ -188,7 +187,6 @@ const canCreate = computed(() => access.can('platform:firstleg:container:create'
|
||||
const canOverseasDocumentEdit = computed(() => access.can('platform:firstleg:terminal-drayage:document:edit'))
|
||||
const canFleetEdit = computed(() => access.can('platform:firstleg:terminal-drayage:fleet:edit'))
|
||||
const canPickupAppointmentEdit = computed(() => access.can('platform:firstleg:terminal-drayage:pickup-appointment:edit'))
|
||||
const canPickupConfirm = computed(() => access.can('platform:firstleg:terminal-drayage:pickup:confirm'))
|
||||
const canEmptyReturnConfirm = computed(() => access.can('platform:firstleg:terminal-drayage:empty-return:confirm'))
|
||||
const canSmartLoading = computed(() => access.can('platform:firstleg:smart-loading:list'))
|
||||
const canViewPreload = computed(() => access.can('platform:firstleg:preload:list'))
|
||||
@@ -281,10 +279,10 @@ function documentStatusText(status: ContainerDocumentStatus | null | undefined)
|
||||
function formatTime(value: string | null | undefined) { return value?.replace('T', ' ').slice(0, 16) || '—' }
|
||||
function drayageFor(containerBookingId: string) { return drayages.value[containerBookingId] }
|
||||
function drayageStatusText(status?: string | null) { return ({ WAITING_FOR_ARRIVAL: '待到港', ARRIVED: '已到港', PICKUP_SCHEDULED: '已约提柜', PICKED_UP: '已提柜', UNLOADED: '已卸柜', EMPTY_RETURNED: '已还柜' } as Record<string, string>)[status || ''] || status || '—' }
|
||||
function drayageActionText(action: TerminalDrayageAction) { return ({ SELECT_FLEET: '选择码头车队', SCHEDULE_PICKUP: '预约提柜', RECORD_PICKUP: '确认实际提柜', RECORD_EMPTY_RETURN: '确认还柜', SEND_PICKUP_EMAIL: '发送提柜邮件' } as Record<TerminalDrayageAction, string>)[action] }
|
||||
function drayageActionText(action: TerminalDrayageAction) { return ({ SELECT_FLEET: '选择码头车队', SCHEDULE_PICKUP: '预约提柜', RECORD_EMPTY_RETURN: '确认还柜', SEND_PICKUP_EMAIL: '发送提柜邮件' } as Record<TerminalDrayageAction, string>)[action] }
|
||||
function hasAction(row: ContainerWorkbenchRow, action: ContainerWorkbenchAction) { return Boolean(row.allowedActions?.includes(action)) }
|
||||
function canDrayage(row: ContainerWorkbenchRow, action: TerminalDrayageAction) {
|
||||
const permission = action === 'SELECT_FLEET' || action === 'SEND_PICKUP_EMAIL' ? canFleetEdit.value : action === 'SCHEDULE_PICKUP' ? canPickupAppointmentEdit.value : action === 'RECORD_PICKUP' ? canPickupConfirm.value : canEmptyReturnConfirm.value
|
||||
const permission = action === 'SELECT_FLEET' || action === 'SEND_PICKUP_EMAIL' ? canFleetEdit.value : action === 'SCHEDULE_PICKUP' ? canPickupAppointmentEdit.value : canEmptyReturnConfirm.value
|
||||
return Boolean(isOverseas.value && permission && hasAction(row, action) && drayageFor(row.id)?.allowedActions.includes(action))
|
||||
}
|
||||
function drayageWarningText(row: ContainerBookingResource) {
|
||||
@@ -559,9 +557,7 @@ async function saveDrayageAction() {
|
||||
const reason = drayageReason.value.trim() || undefined
|
||||
const next = drayageAction.value === 'SCHEDULE_PICKUP'
|
||||
? await scheduleTerminalDrayagePickup(row.id, { expectedVersion: current.version, pickupAppointmentAt: drayageActionAt.value, reason })
|
||||
: drayageAction.value === 'RECORD_PICKUP'
|
||||
? await recordTerminalDrayagePickup(row.id, { expectedVersion: current.version, actualAt: drayageActionAt.value, remark: reason })
|
||||
: await recordTerminalDrayageEmptyReturn(row.id, { expectedVersion: current.version, actualAt: drayageActionAt.value, remark: reason })
|
||||
: await recordTerminalDrayageEmptyReturn(row.id, { expectedVersion: current.version, actualAt: drayageActionAt.value, remark: reason })
|
||||
replaceDrayage(next); drayageActionOpen.value = false
|
||||
ElMessage.success(`${drayageActionText(drayageAction.value)}成功`)
|
||||
await loadRows()
|
||||
@@ -698,7 +694,7 @@ onMounted(async () => { await Promise.all([loadCustomers(), loadRows()]) })
|
||||
<section v-if="!loadError" id="container-workbench-results" class="surface-panel table-panel">
|
||||
<DataTable v-model:page="page" v-model:page-size="pageSize" :data="rows" :columns="columns" :total="total" :loading="loading" stripe preference-key="container-loading-table" empty-text="暂无货柜">
|
||||
<template #toolbar-actions><ContainerSimulationCreate dense v-if="isDomestic && canCreate" :load-warehouse-options="loadSimulationWarehouses" @created="loadRows" /></template>
|
||||
<template #actions="{ row }"><div class="row-actions density-actions"><el-button class="density-action" v-if="canView" size="small" type="primary" plain :aria-label="containerViewLabel(row as ContainerBookingResource)" @click="openDetail(row)">查看</el-button><template v-if="isDomestic"><el-button class="density-action" v-if="canEdit && hasAction(row as ContainerWorkbenchRow, 'EDIT_CONTAINER')" size="small" @click="openEdit(row)">编辑</el-button><el-button data-tone="primary" class="density-action" v-if="row.planStatus === 'EDITING' && canSmartLoading" size="small" type="primary" @click="goContainerProcess(row)">装柜</el-button><el-button class="density-action" v-else-if="row.planStatus === 'LOADING' && canViewPreload" size="small" type="primary" plain @click="goContainerProcess(row)">预装清单</el-button><el-button class="density-action" v-else-if="row.planStatus === 'COMPLETED' && canViewLoadingList" size="small" type="primary" plain @click="goContainerProcess(row)">装柜清单</el-button></template><el-button data-tone="primary" class="density-action" v-if="canDrayage(row as ContainerWorkbenchRow, 'RECORD_EMPTY_RETURN')" size="small" type="primary" @click="openDrayageAction(row as ContainerBookingResource, 'RECORD_EMPTY_RETURN')">确认还柜</el-button><el-button data-tone="primary" class="density-action" v-if="canDrayage(row as ContainerWorkbenchRow, 'SEND_PICKUP_EMAIL')" size="small" type="primary" :loading="drayageSavingIds.includes(row.id)" @click="sendPickupEmail(row as ContainerWorkbenchRow)">发送邮件</el-button><el-dropdown v-if="canView" trigger="click" @command="handleMoreAction($event, row)"><el-button class="density-action" size="small" plain aria-label="更多货柜操作" title="更多货柜操作"><MoreHorizontal :size="16" /></el-button><template #dropdown><el-dropdown-menu><el-dropdown-item command="overview">轨迹与日志</el-dropdown-item><template v-if="isOverseas"><el-dropdown-item command="email-history">邮件记录</el-dropdown-item><el-dropdown-item command="drayage-history">码头拖车记录</el-dropdown-item><el-dropdown-item v-if="canDrayage(row as ContainerWorkbenchRow, 'SCHEDULE_PICKUP')" command="drayage:SCHEDULE_PICKUP">预约提柜</el-dropdown-item><el-dropdown-item v-if="canDrayage(row as ContainerWorkbenchRow, 'RECORD_PICKUP')" command="drayage:RECORD_PICKUP">确认实际提柜</el-dropdown-item><el-dropdown-item v-if="canOverseasDocumentEdit && hasAction(row as ContainerWorkbenchRow, 'MANAGE_DESTINATION_DOCUMENTS')" command="documents">清关 / DO / PU</el-dropdown-item></template><el-dropdown-item v-if="isDomestic && canEdit && hasAction(row as ContainerWorkbenchRow, 'EDIT_CONTAINER') && row.sourceType === 'SIMULATION' && !row.oceanBookingId" command="link">关联已放舱订舱</el-dropdown-item></el-dropdown-menu></template></el-dropdown></div></template>
|
||||
<template #actions="{ row }"><div class="row-actions density-actions"><el-button class="density-action" v-if="canView" size="small" type="primary" plain :aria-label="containerViewLabel(row as ContainerBookingResource)" @click="openDetail(row)">查看</el-button><template v-if="isDomestic"><el-button class="density-action" v-if="canEdit && hasAction(row as ContainerWorkbenchRow, 'EDIT_CONTAINER')" size="small" @click="openEdit(row)">编辑</el-button><el-button data-tone="primary" class="density-action" v-if="row.planStatus === 'EDITING' && canSmartLoading" size="small" type="primary" @click="goContainerProcess(row)">装柜</el-button><el-button class="density-action" v-else-if="row.planStatus === 'LOADING' && canViewPreload" size="small" type="primary" plain @click="goContainerProcess(row)">预装清单</el-button><el-button class="density-action" v-else-if="row.planStatus === 'COMPLETED' && canViewLoadingList" size="small" type="primary" plain @click="goContainerProcess(row)">装柜清单</el-button></template><el-button data-tone="primary" class="density-action" v-if="canDrayage(row as ContainerWorkbenchRow, 'RECORD_EMPTY_RETURN')" size="small" type="primary" @click="openDrayageAction(row as ContainerBookingResource, 'RECORD_EMPTY_RETURN')">确认还柜</el-button><el-button data-tone="primary" class="density-action" v-if="canDrayage(row as ContainerWorkbenchRow, 'SEND_PICKUP_EMAIL')" size="small" type="primary" :loading="drayageSavingIds.includes(row.id)" @click="sendPickupEmail(row as ContainerWorkbenchRow)">发送邮件</el-button><el-dropdown v-if="canView" trigger="click" @command="handleMoreAction($event, row)"><el-button class="density-action" size="small" plain aria-label="更多货柜操作" title="更多货柜操作"><MoreHorizontal :size="16" /></el-button><template #dropdown><el-dropdown-menu><el-dropdown-item command="overview">轨迹与日志</el-dropdown-item><template v-if="isOverseas"><el-dropdown-item command="email-history">邮件记录</el-dropdown-item><el-dropdown-item command="drayage-history">码头拖车记录</el-dropdown-item><el-dropdown-item v-if="canDrayage(row as ContainerWorkbenchRow, 'SCHEDULE_PICKUP')" command="drayage:SCHEDULE_PICKUP">预约提柜</el-dropdown-item><el-dropdown-item v-if="canOverseasDocumentEdit && hasAction(row as ContainerWorkbenchRow, 'MANAGE_DESTINATION_DOCUMENTS')" command="documents">清关 / DO / PU</el-dropdown-item></template><el-dropdown-item v-if="isDomestic && canEdit && hasAction(row as ContainerWorkbenchRow, 'EDIT_CONTAINER') && row.sourceType === 'SIMULATION' && !row.oceanBookingId" command="link">关联已放舱订舱</el-dropdown-item></el-dropdown-menu></template></el-dropdown></div></template>
|
||||
<template #emptyReturnWarning="{ row }"><el-tag :type="drayageWarningType(row as ContainerBookingResource)" effect="light" :title="drayageWarningTitle(row as ContainerBookingResource)">{{ drayageWarningText(row as ContainerBookingResource) }}</el-tag></template>
|
||||
<template #cabinet="{ row }"><strong>{{ row.cabinetNo }}</strong><small>系统生成</small></template>
|
||||
<template #oceanBooking="{ row }"><span v-if="row.oceanBookingId"><strong>{{ row.billOfLadingNo || '已关联订舱' }}</strong><small>{{ row.containerNo ? `集装箱号:${row.containerNo}` : '集装箱号:待补录' }}</small></span><span v-else>未关联</span></template>
|
||||
@@ -749,7 +745,7 @@ onMounted(async () => { await Promise.all([loadCustomers(), loadRows()]) })
|
||||
</AppDialog>
|
||||
|
||||
<AppDialog class="admin-density-dialog" v-model="drayageActionOpen" :title="drayageActionText(drayageAction)" width="min(520px, calc(100vw - 28px))" :confirm-text="drayageActionText(drayageAction)" cancel-text="取消" :confirm-loading="drayageActionSaving" :confirm-disabled="!drayageActionAt" @confirm="saveDrayageAction">
|
||||
<el-form class="density-form" label-position="top"><el-form-item :label="drayageAction === 'SCHEDULE_PICKUP' ? '预约提柜时间' : drayageAction === 'RECORD_PICKUP' ? '实际提柜时间' : '实际还柜时间'" required><el-date-picker v-model="drayageActionAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" placeholder="请选择时间" /></el-form-item><el-form-item label="原因/备注"><el-input v-model="drayageReason" type="textarea" :rows="3" maxlength="500" show-word-limit placeholder="选填" /></el-form-item></el-form>
|
||||
<el-form class="density-form" label-position="top"><el-form-item :label="drayageAction === 'SCHEDULE_PICKUP' ? '预约提柜时间' : '实际还柜时间'" required><el-date-picker v-model="drayageActionAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" placeholder="请选择时间" /></el-form-item><el-form-item label="原因/备注"><el-input v-model="drayageReason" type="textarea" :rows="3" maxlength="500" show-word-limit placeholder="选填" /></el-form-item></el-form>
|
||||
<LoadErrorState v-if="drayageActionError" compact :title="`${drayageActionText(drayageAction)}失败`" :message="drayageActionError.message" :show-retry="false"><template #details><ApiErrorMeta :details="drayageActionError" /></template></LoadErrorState>
|
||||
</AppDialog>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user