This commit is contained in:
2026-09-04 14:41:29 +08:00
parent 688eddfa77
commit 44eb8d17f2
5 changed files with 13 additions and 82 deletions
@@ -242,7 +242,7 @@ describe('WeightOcrPanel confirmation behavior', () => {
expect(card.get('.weight-card__facts').text()).toContain('库位A01 · 待上架')
})
it('renders the authoritative whole-inbound reservation summary and an empty reserved slot', async () => {
it('keeps whole-inbound reservation guidance out of the panel and shows location on each weight card', async () => {
vi.mocked(getWeightWorkspace).mockResolvedValue({
...workspace,
palletLocationGuide: {
@@ -260,13 +260,9 @@ describe('WeightOcrPanel confirmation behavior', () => {
const wrapper = mountPanel()
await flushPromises()
const guide = wrapper.get('.putaway-guide')
expect(guide.text()).toContain('整票预留库位')
expect(guide.text()).toContain('A01 / A02 / A03')
expect(guide.text()).toContain('预留槽位数3')
expect(guide.text()).toContain('实际托数2')
expect(guide.text()).toContain('预留空位数1')
expect(guide.text()).toContain('A03预留空位本票预留空位')
expect(wrapper.find('.putaway-guide').exists()).toBe(false)
expect(wrapper.text()).not.toContain('整票上架引导')
expect(wrapper.get('.weight-card__facts').text()).toContain('库位A01 · 待上架')
})
it('does not render a full-width placeholder when no whole-inbound guide exists', async () => {
@@ -296,7 +292,7 @@ describe('WeightOcrPanel confirmation behavior', () => {
expect(wrapper.text()).toContain('A0 临时溢出位')
expect(wrapper.get('.weight-card__facts').text()).toContain('库位A0 · 待上架 · A0 临时溢出位')
expect(wrapper.get('.putaway-guide__slots li').classes()).toContain('is-overflow')
expect(wrapper.find('.putaway-guide').exists()).toBe(false)
})
it.each([
@@ -372,8 +368,7 @@ describe('WeightOcrPanel confirmation behavior', () => {
)
expect(getWeightWorkspace).toHaveBeenCalledTimes(2)
expect(wrapper.findAll('.weight-card')).toHaveLength(0)
expect(wrapper.get('.putaway-guide').text()).toContain('预留空位数1')
expect(wrapper.get('.putaway-guide').text()).toContain('A01预留空位本票预留空位')
expect(wrapper.find('.putaway-guide').exists()).toBe(false)
})
it('keeps the image and server workspace visible when deletion fails', async () => {
@@ -35,14 +35,12 @@ describe('WeightOcrPanel contract', () => {
expect(source).toContain('货物重量')
expect(source).toContain('palletTareWeightKg')
expect(source).toContain('netWeightKg')
expect(source).toContain('slot.palletSequence')
expect(source).toContain('row.locationCode')
expect(source).toContain('row.sharedOverflow')
expect(source).toContain('putawayStatusLabel(row.slotStatus)')
expect(source).toContain('workspace.palletLocationGuide.reservedSlotCount')
expect(source).toContain('workspace.palletLocationGuide.actualPalletCount')
expect(source).toContain('workspace.palletLocationGuide.reservedEmptySlotCount')
expect(source).toContain('本票预留空位')
expect(source).not.toContain('class="putaway-guide"')
expect(source).not.toContain('整票上架引导')
expect(source).not.toContain('整票预留库位')
expect(source).not.toContain('尚未分配整票预留库位')
expect(source).not.toContain('class="weight-card__putaway"')
expect(source).toContain('<div><dt>库位</dt><dd')
@@ -24,7 +24,6 @@ import {
} from '../api/weightOcr'
import type {
WeightPalletOption,
WeightPutawaySlotStatus,
WeightResultResource,
WeightWorkspaceResource,
} from '../types'
@@ -194,17 +193,6 @@ function putawayStatusLabel(status: WeightResultResource['slotStatus']) {
} as const)[status as Exclude<WeightResultResource['slotStatus'], null>] || '未分配'
}
function putawayStatusType(status: WeightResultResource['slotStatus']) {
if (status === 'TRANSFERRED') return 'success'
if (status === 'BOUND') return 'warning'
if (status === 'RELEASED') return 'info'
return 'info'
}
function guideSlotStatusType(status: WeightPutawaySlotStatus) {
return putawayStatusType(status)
}
function hasWeightDraftChanged(row: WeightResultResource) {
const draft = weightDrafts.value[row.id]
if (!draft) return false
@@ -557,37 +545,6 @@ defineExpose({ reload: loadWorkspace })
</LoadErrorState>
<template v-else>
<section v-if="workspace?.palletLocationGuide" class="putaway-guide" aria-labelledby="putaway-guide-title">
<div class="putaway-guide__heading">
<div>
<span class="putaway-guide__eyebrow">整票上架引导</span>
<h4 id="putaway-guide-title">整票预留库位</h4>
</div>
<div class="putaway-guide__metrics" aria-label="整票库位汇总">
<div><span>预留库位</span><strong>{{ workspace.palletLocationGuide.slots.map((slot) => slot.locationCode).join(' / ') }}</strong></div>
<div><span>预留槽位数</span><strong>{{ workspace.palletLocationGuide.reservedSlotCount }}</strong></div>
<div><span>实际托数</span><strong>{{ workspace.palletLocationGuide.actualPalletCount }}</strong></div>
<div><span>预留空位数</span><strong>{{ workspace.palletLocationGuide.reservedEmptySlotCount }}</strong></div>
</div>
</div>
<ol class="putaway-guide__slots" aria-label="整票预留槽位">
<li
v-for="slot in workspace.palletLocationGuide.slots"
:key="slot.reservationId"
:class="{ 'is-empty': slot.slotStatus === 'RESERVED_EMPTY', 'is-overflow': slot.sharedOverflow }"
>
<div class="putaway-guide__slot-title">
<strong>{{ slot.locationCode }}</strong>
<el-tag size="small" effect="light" :type="guideSlotStatusType(slot.slotStatus)">
{{ putawayStatusLabel(slot.slotStatus) }}
</el-tag>
</div>
<span v-if="slot.palletSequence != null">第 {{ slot.palletSequence }} 托 · {{ slot.palletCode || '托盘编码未记录' }}</span>
<span v-else>本票预留空位</span>
<small v-if="slot.sharedOverflow">A0 临时溢出位</small>
</li>
</ol>
</section>
<LoadErrorState
v-if="palletError"
title="可选托盘加载失败"
@@ -734,23 +691,6 @@ defineExpose({ reload: loadWorkspace })
.weight-summary strong { color: #067647; font-size: 16px; }
.visually-hidden-input { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
.weight-action-error { margin-bottom: 14px; }
.putaway-guide { margin: 14px 0 18px; padding: 16px; border: 1px solid #84caff; border-radius: 8px; background: #f5fbff; }
.putaway-guide__heading { display: flex; align-items: flex-start; justify-content: space-between; gap: 24px; }
.putaway-guide__eyebrow { color: #175cd3; font-size: 11px; font-weight: 700; letter-spacing: .08em; }
.putaway-guide h4 { margin: 3px 0 0; color: #102a56; font-size: 18px; }
.putaway-guide__metrics { display: grid; grid-template-columns: minmax(180px, 1.8fr) repeat(3, minmax(90px, .6fr)); gap: 10px; flex: 1; max-width: 820px; }
.putaway-guide__metrics div { display: grid; min-width: 0; gap: 3px; padding: 9px 11px; border-radius: 6px; background: #fff; box-shadow: 0 1px 2px rgb(16 24 40 / 6%); }
.putaway-guide__metrics span { color: #667085; font-size: 11px; }
.putaway-guide__metrics strong { color: #101828; font-size: 15px; overflow-wrap: anywhere; }
.putaway-guide__slots { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 10px; margin: 14px 0 0; padding: 0; list-style: none; }
.putaway-guide__slots li { display: grid; gap: 5px; min-width: 0; padding: 11px; border: 1px solid #b2ddff; border-radius: 6px; background: #fff; }
.putaway-guide__slots li.is-empty { border-style: dashed; background: #f9fafb; }
.putaway-guide__slots li.is-overflow { border-color: #fec84b; background: #fffaeb; }
.putaway-guide__slot-title { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.putaway-guide__slot-title strong { color: #1849a9; font-size: 20px; }
.putaway-guide__slots li.is-overflow .putaway-guide__slot-title strong { color: #93370d; }
.putaway-guide__slots li > span { color: #475467; font-size: 12px; overflow-wrap: anywhere; }
.putaway-guide__slots small { width: fit-content; color: #93370d; font-weight: 600; }
.weight-list { min-height: 0; margin-top: 14px; }
.weight-empty { display: flex; min-height: 0; align-items: center; gap: 10px; padding: 4px 0 0; color: var(--cc-muted); }
.weight-empty strong { color: #344054; font-size: 14px; }
@@ -783,9 +723,6 @@ defineExpose({ reload: loadWorkspace })
.pallet-picker :deep(.el-select) { width: 100%; }
.weight-heading__actions :deep(.el-button) { width: 100%; min-height: 44px; }
.weight-summary-group { width: 100%; justify-content: space-between; }
.putaway-guide__heading { flex-direction: column; }
.putaway-guide__metrics { width: 100%; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.putaway-guide__metrics div:first-child { grid-column: 1 / -1; }
.weight-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}