This commit is contained in:
2026-10-20 23:34:11 +08:00
parent f155976f52
commit 13e4aa56ec
321 changed files with 6756 additions and 2110 deletions
@@ -1,4 +1,5 @@
<script setup lang="ts">
import '@/styles/adminWorkbench.css'
import InlineHelp from '@/shared/components/InlineHelp.vue'
import '@/styles/adminDensity.css'
import { appointmentReturnTarget } from '@/modules/appointment-calendar'
@@ -94,13 +95,13 @@ function back() { void router.push(appointmentReturnTarget(route.query) || { nam
onMounted(load)
</script>
<template><OverseasDetailShell class="admin-density" dense title="入库单详情" reference-label="入库单号" :reference-value="referenceValue" back-label="返回入库单" :back-text="appointmentReturnTarget(route.query) ? '返回预约工作' : '返回列表'" domain="入库单详情" :pending="false" :status-text="detail ? status(detail.status) : '加载中'" @back="back">
<template><OverseasDetailShell workbench class="admin-density" dense title="入库单详情" reference-label="入库单号" :reference-value="referenceValue" back-label="返回入库单" :back-text="appointmentReturnTarget(route.query) ? '返回预约工作' : '返回列表'" domain="入库单详情" :pending="false" :status-text="detail ? status(detail.status) : '加载中'" @back="back">
<LoadErrorState v-if="loadError" title="入库单详情加载失败" :message="loadError.message" :loading="loading" @retry="load"><template #details><ApiErrorMeta :details="loadError" /></template></LoadErrorState>
<template v-else><section v-loading="loading" class="detail-section" aria-label="入库单基本信息"><div class="detail-groups"><section v-for="group in summaryGroups" :key="group.title" class="detail-group" :aria-label="group.title"><h2>{{ group.title }}</h2><dl class="detail-fields density-fields"><div v-for="label in group.fields" :key="label"><dt>{{ label }}</dt><dd>{{ fieldValues[label] }}</dd></div></dl></section></div></section>
<section class="detail-section pallet-section" aria-labelledby="inbound-pallet-heading"><div class="section-heading"><div><h2 id="inbound-pallet-heading">入库单托盘明细<InlineHelp title="托盘明细说明"><p>PDA 合托后,参与合托的入库单会分别展示同一托盘及本单对应箱数;A0 为系统共享溢出位。</p></InlineHelp></h2></div><span class="section-count">{{ palletRows.length }} 条</span></div><div class="detail-table-wrap"><DataTable :data="palletRows" :columns="palletColumns" column-settings-mode="hide" row-key="id" empty-text="暂无托盘明细"><template #actions="{ row }"><el-button class="density-action" size="small" :disabled="moveSaving || moveLocationsLoading || !(row as typeof palletRows[number]).palletNo || (row as typeof palletRows[number]).palletNo === '—' || (row as typeof palletRows[number]).palletVersion == null" @click="openMove(row as typeof palletRows[number])">移库</el-button></template></DataTable></div></section>
<section class="detail-section pallet-section" aria-labelledby="inbound-pallet-heading"><div class="section-heading"><div><h2 id="inbound-pallet-heading">入库单托盘明细<InlineHelp title="托盘明细说明"><p>PDA 合托后,参与合托的入库单会分别展示同一托盘及本单对应箱数;A0 为系统共享溢出位。</p></InlineHelp></h2></div><span class="section-count">{{ palletRows.length }} 条</span></div><div class="detail-table-wrap"><div class="workbench-table"><DataTable :data="palletRows" :columns="palletColumns" column-settings-mode="hide" row-key="id" empty-text="暂无托盘明细"><template #actions="{ row }"><el-button class="density-action" size="small" :disabled="moveSaving || moveLocationsLoading || !(row as typeof palletRows[number]).palletNo || (row as typeof palletRows[number]).palletNo === '—' || (row as typeof palletRows[number]).palletVersion == null" @click="openMove(row as typeof palletRows[number])">移库</el-button></template></DataTable></div></div></section>
<section class="detail-section appointment-section" aria-labelledby="inbound-appointment-heading"><div class="compact-section-heading"><h2 id="inbound-appointment-heading">预约与排车</h2></div><dl class="detail-fields appointment-fields density-fields"><div v-for="label in appointmentFields" :key="label" :class="{ 'is-wide': label === '备注' }"><dt>{{ label }}</dt><dd>{{ fieldValues[label] }}</dd></div></dl></section>
<section class="detail-section fee-section" aria-labelledby="inbound-fees-heading"><div class="compact-section-heading"><h2 id="inbound-fees-heading">应收费用明细</h2><span>费用结果以服务端为准</span></div><div class="detail-table-wrap"><DataTable :data="[]" :columns="feeColumns" column-settings-mode="hide" empty-text="当前入库计划详情接口未提供应收费用" /></div><footer class="fee-total"><span>应收费用合计(USD)</span><strong>—</strong></footer></section></template>
</OverseasDetailShell><AppDialog v-model="moveOpen" class="admin-density-dialog" :title="`托盘移库 · ${moveRow?.palletNo || '—'}`" width="min(560px, calc(100vw - 28px))" fullscreenable confirm-text="提交移库" :confirm-loading="moveSaving" :confirm-disabled="moveLocationsLoading || !!moveLocationError || !targetLocationCode || !moveReason.trim()" @confirm="submitMove"><div class="density-dialog-sections">
<section class="detail-section fee-section" aria-labelledby="inbound-fees-heading"><div class="compact-section-heading"><h2 id="inbound-fees-heading">应收费用明细</h2><span>费用结果以服务端为准</span></div><div class="detail-table-wrap"><div class="workbench-table"><DataTable :data="[]" :columns="feeColumns" column-settings-mode="hide" empty-text="当前入库计划详情接口未提供应收费用" /></div></div><footer class="fee-total"><span>应收费用合计(USD)</span><strong>—</strong></footer></section></template>
</OverseasDetailShell><AppDialog v-model="moveOpen" class="admin-density-dialog admin-workbench is-dialog" :title="`托盘移库 · ${moveRow?.palletNo || '—'}`" width="min(560px, calc(100vw - 28px))" fullscreenable confirm-text="提交移库" :confirm-loading="moveSaving" :confirm-disabled="moveLocationsLoading || !!moveLocationError || !targetLocationCode || !moveReason.trim()" @confirm="submitMove"><div class="density-dialog-sections">
<section class="density-dialog-section" data-tone="source" aria-label="移库来源"><h3 class="density-dialog-section__title">来源信息</h3><table class="density-table"><tbody><tr><th scope="row">入库单号</th><td>{{ referenceValue }}</td></tr><tr><th scope="row">托盘号</th><td>{{ moveRow?.palletNo || '—' }}</td></tr></tbody></table></section>
<LoadErrorState v-if="moveLocationError" compact title="可用库位加载失败" :message="moveLocationError.message" :loading="moveLocationsLoading" @retry="loadMoveLocations"><template #details><ApiErrorMeta :details="moveLocationError" /></template></LoadErrorState>
<LoadErrorState v-if="moveError" compact title="移库未完成" :message="moveError.message" :show-retry="false"><template #details><ApiErrorMeta :details="moveError" /></template></LoadErrorState>
@@ -111,14 +112,14 @@ onMounted(load)
</div></AppDialog></template>
<style scoped>
.detail-section { min-width: 0; padding: 0; border: 0; background: #fff; }
.detail-group h2 { margin: 0 0 var(--admin-space-3); color: var(--cc-text); font-size: var(--admin-font-section); }
.compact-section-heading { display:flex; min-height:42px; align-items:center; justify-content:space-between; gap:var(--admin-space-5); padding:var(--admin-space-2) var(--admin-space-5); border-bottom:1px solid var(--cc-border); }
.compact-section-heading h2 { margin:0; color:var(--cc-text); font-size:var(--admin-font-section); }
.compact-section-heading span { color:var(--cc-muted); font-size:var(--admin-font-caption); }
.fee-section { overflow:hidden; }.fee-total { display:flex; min-height:44px; align-items:center; justify-content:flex-end; gap:40px; margin:0 var(--admin-space-5) var(--admin-space-4); padding:var(--admin-space-3) var(--admin-space-5); border:1px solid var(--cc-border); border-top:0; }.fee-total strong { min-width:120px; font-size:var(--admin-font-section); }
.pallet-section { overflow: hidden; }.section-heading { display:flex; min-height:50px; align-items:center; justify-content:space-between; gap:var(--admin-space-5); padding:var(--admin-space-3) var(--admin-space-5); border-bottom:1px solid var(--cc-border); }.pallet-section h2 { margin: 0 0 var(--admin-space-1); color: var(--cc-text); font-size: var(--admin-font-section); }.pallet-note { margin: 0; color: var(--cc-muted); font-size: var(--admin-font-caption); }.section-count { flex:0 0 auto; color:var(--cc-muted); font-size:var(--admin-font-caption); font-variant-numeric:tabular-nums; }
.appointment-section,.fee-section { border-top:1px solid var(--cc-border); }
.detail-section { min-width: 0; padding: 0; border: 0; background: var(--workbench-surface); }
.detail-group h2 { margin: 0 0 var(--admin-space-3); color: var(--workbench-text); font-size: var(--admin-font-section); }
.compact-section-heading { display:flex; min-height:42px; align-items:center; justify-content:space-between; gap:var(--admin-space-5); padding:var(--admin-space-2) var(--admin-space-5); border-bottom:1px solid var(--workbench-border); }
.compact-section-heading h2 { margin:0; color:var(--workbench-text); font-size:var(--admin-font-section); }
.compact-section-heading span { color:var(--workbench-muted); font-size:var(--admin-font-caption); }
.fee-section { overflow:hidden; }.fee-total { display:flex; min-height:44px; align-items:center; justify-content:flex-end; gap:40px; margin:0 var(--admin-space-5) var(--admin-space-4); padding:var(--admin-space-3) var(--admin-space-5); border:1px solid var(--workbench-border); border-top:0; }.fee-total strong { min-width:120px; font-size:var(--admin-font-section); }
.pallet-section { overflow: hidden; }.section-heading { display:flex; min-height:50px; align-items:center; justify-content:space-between; gap:var(--admin-space-5); padding:var(--admin-space-3) var(--admin-space-5); border-bottom:1px solid var(--workbench-border); }.pallet-section h2 { margin: 0 0 var(--admin-space-1); color: var(--workbench-text); font-size: var(--admin-font-section); }.pallet-note { margin: 0; color: var(--workbench-muted); font-size: var(--admin-font-caption); }.section-count { flex:0 0 auto; color:var(--workbench-muted); font-size:var(--admin-font-caption); font-variant-numeric:tabular-nums; }
.appointment-section,.fee-section { border-top:1px solid var(--workbench-border); }
.appointment-section { padding:0 var(--admin-space-5) var(--admin-space-4); }
.appointment-section .compact-section-heading { margin:0 calc(0px - var(--admin-space-5)) var(--admin-space-3); }
.appointment-fields { grid-template-columns:repeat(4,minmax(0,1fr)); }
@@ -127,9 +128,9 @@ onMounted(load)
@media(max-width:1200px){.detail-fields,.appointment-fields{grid-template-columns:repeat(2,minmax(0,1fr))}.appointment-fields > .is-wide{grid-column:span 2}}
.detail-groups { display: grid; grid-template-columns: minmax(0, 1fr); }
.detail-group { min-width: 0; padding: var(--admin-space-3) var(--admin-space-5) var(--admin-space-4); border-bottom: 1px solid var(--cc-border); }
.detail-group { min-width: 0; padding: var(--admin-space-3) var(--admin-space-5) var(--admin-space-4); border-bottom: 1px solid var(--workbench-border); }
.detail-fields { --admin-field-label-width: 108px; grid-template-columns: repeat(5, minmax(0, 1fr)); }
:deep(.density-detail-header) { border-bottom: 1px solid var(--cc-border); }
:deep(.density-detail-header) { border-bottom: 1px solid var(--workbench-border); }
.detail-table-wrap { padding:var(--admin-space-3) var(--admin-space-5) var(--admin-space-4); }
.fee-section .detail-table-wrap { padding-bottom:0; }