style(admin): unify dialog layouts and dense readonly presentation

This commit is contained in:
2026-10-20 10:11:31 +08:00
parent 7ff7c9914f
commit 3267679758
214 changed files with 10931 additions and 2654 deletions
@@ -685,6 +685,17 @@ describe('WeightOcrPanel confirmation behavior', () => {
await openWeightDialog(wrapper)
await dialogWeightInput().setValue('286.125')
const expand = document.body.querySelector<HTMLButtonElement>('button[aria-label="展开全屏"]')
expect(expand).not.toBeNull()
await new DOMWrapper(expand!).trigger('click')
await flushPromises()
expect(document.body.querySelector('.el-dialog.is-fullscreen')).not.toBeNull()
expect(dialogWeightInput().element.value).toBe('286.125')
const collapse = document.body.querySelector<HTMLButtonElement>('button[aria-label="退出全屏"]')
await new DOMWrapper(collapse!).trigger('click')
await flushPromises()
expect(dialogWeightInput().element.value).toBe('286.125')
expect(confirmWeightResult).not.toHaveBeenCalled()
await dialogConfirmButton().trigger('click')
await flushPromises()
@@ -649,14 +649,15 @@ defineExpose({ reload: loadWorkspace })
<AppDialog class="admin-density-dialog"
v-model="previewOpen"
title="确认称重图片"
:title="workspace?.inboundCode ? `确认称重图片 · ${workspace.inboundCode}` : '确认称重图片'"
:loading="previewLoading"
:confirm-loading="Boolean(previewResult && isActionLoading('confirm', previewResult.id))"
:confirm-disabled="previewConfirmDisabled"
:show-confirm="Boolean(previewResult && previewCanConfirm && (previewResult.recognitionStatus !== 'CONFIRMED' || reviewCorrectionEnabled))"
:confirm-text="previewConfirmText"
confirm-type="success"
width="min(640px, calc(100vw - 28px))"
width="min(920px, calc(100vw - 28px))"
fullscreenable
@confirm="previewResult && confirmResult(previewResult, true)"
>
<LoadErrorState
@@ -668,37 +669,44 @@ defineExpose({ reload: loadWorkspace })
>
<template #details><ApiErrorMeta :details="previewError" /></template>
</LoadErrorState>
<template v-else-if="previewResult">
<div v-else-if="previewResult" class="weight-preview-layout">
<img v-if="previewUrl" class="weight-preview" :src="previewUrl" alt="当前入库单的称重图片" />
<div class="weight-key-facts" aria-label="称重关键数据">
<div><span>托盘类型</span><strong>{{ previewResult.palletType || '未记录类型' }}</strong></div>
<div><span>当前托盘皮重</span><strong>{{ formatWeight(previewResult.palletTareWeightKg) }}</strong></div>
<div><span>OCR 识别毛重</span><strong>{{ formatWeight(previewResult.ocrWeightValue, previewResult.ocrWeightUnit || 'KG') }}</strong></div>
</div>
<div v-if="weightDrafts[previewResult.id]" class="preview-weight">
<label>
<span>确认含托盘毛重</span>
<el-input-number
v-model="weightDrafts[previewResult.id].value"
aria-label="当前图片确认重量"
:min="minimumWeight[weightDrafts[previewResult.id].unit]"
:max="maximumSafeWeight"
:precision="3"
:controls="false"
:disabled="Boolean(activeAction) || !previewInputEditable" placeholder="请输入确认重量" />
</label>
<el-segmented
v-model="weightDrafts[previewResult.id].unit"
aria-label="当前图片重量单位"
:options="['KG', 'LB']"
:disabled="Boolean(activeAction) || !previewInputEditable"
/>
</div>
<label v-if="reviewCorrectionEnabled && previewResult.recognitionStatus === 'CONFIRMED' && weightDrafts[previewResult.id]" class="correction-reason">
<span>修改原因 *</span>
<el-input v-model="weightDrafts[previewResult.id].reason" type="textarea" :rows="3" maxlength="500" show-word-limit placeholder="请填写本次毛重修正原因" />
</label>
</template>
<section class="density-dialog-section" data-tone="work">
<h3 class="density-dialog-section__title">称重数据</h3>
<table class="density-table density-table--editable weight-confirm-table" aria-label="称重关键数据">
<colgroup><col class="weight-confirm-label-column" /><col /></colgroup>
<tbody>
<tr><th scope="row"><span>托盘类型</span></th><td>{{ previewResult.palletType || '未记录类型' }}</td></tr>
<tr><th scope="row">当前托盘皮重</th><td>{{ formatWeight(previewResult.palletTareWeightKg) }}</td></tr>
<tr><th scope="row">OCR 识别毛重</th><td>{{ formatWeight(previewResult.ocrWeightValue, previewResult.ocrWeightUnit || 'KG') }}</td></tr>
<template v-if="weightDrafts[previewResult.id]">
<tr><th scope="row"><label for="weight-confirm-value">确认含托盘毛重</label></th><td>
<el-input-number
id="weight-confirm-value"
v-model="weightDrafts[previewResult.id].value"
aria-label="当前图片确认重量"
:min="minimumWeight[weightDrafts[previewResult.id].unit]"
:max="maximumSafeWeight"
:precision="3"
:controls="false"
:disabled="Boolean(activeAction) || !previewInputEditable" placeholder="请输入确认重量" />
</td></tr>
<tr><th scope="row">重量单位</th><td>
<el-segmented
v-model="weightDrafts[previewResult.id].unit"
aria-label="当前图片重量单位"
:options="['KG', 'LB']"
:disabled="Boolean(activeAction) || !previewInputEditable"
/>
</td></tr>
<tr v-if="reviewCorrectionEnabled && previewResult.recognitionStatus === 'CONFIRMED'"><th scope="row"><label for="weight-correction-reason">修改原因 *</label></th><td>
<el-input id="weight-correction-reason" v-model="weightDrafts[previewResult.id].reason" type="textarea" :rows="3" maxlength="500" show-word-limit placeholder="请填写本次毛重修正原因" />
</td></tr>
</template>
</tbody>
</table>
</section>
</div>
</AppDialog>
</section>
</template>
@@ -744,14 +752,9 @@ defineExpose({ reload: loadWorkspace })
.weight-data-table .weight-net-value { color: #16875b; font-weight: 750; }
.weight-location { display: inline-block; padding: 3px 7px; border: 1px solid #e2e8f2; border-radius: 5px; background: #f3f6fb; color: #53627a; }
.weight-preview { display: block; width: 100%; max-height: min(50vh, 460px); object-fit: contain; border-radius: 6px; background: #f2f4f7; }
.weight-key-facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--admin-space-3, 8px) var(--admin-space-5, 12px); margin-top: var(--admin-space-3, 8px); padding: var(--admin-space-3, 8px) 0; border-block: 1px solid var(--cc-border); }
.weight-key-facts div { display: grid; min-width: 0; gap: var(--admin-space-1, 4px); }
.weight-key-facts span { color: var(--cc-muted); font-size: var(--admin-font-caption, 12px); }
.weight-key-facts strong { color: #101828; font-size: var(--admin-font-section, 14px); }
.preview-weight { display: grid; grid-template-columns: minmax(0, 1fr) 120px; align-items: end; gap: var(--admin-space-5, 12px); margin-top: 14px; }
.preview-weight label { display: grid; gap: var(--admin-space-2, 6px); color: #475467; font-size: var(--admin-font-caption, 12px); }
.preview-weight :deep(.el-input-number), .preview-weight :deep(.el-segmented) { width: 100%; }
.correction-reason { display: grid; gap: var(--admin-space-2, 6px); margin-top: 14px; color: #475467; font-size: var(--admin-font-caption, 12px); }
.weight-preview-layout { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(320px, 1fr); align-items: start; gap: var(--admin-space-5, 12px); }
.weight-confirm-table { table-layout: fixed; }
.weight-confirm-label-column { width: 42%; }
@media (max-width: 720px) {
.weight-heading { flex-direction: column; }
@@ -761,13 +764,11 @@ defineExpose({ reload: loadWorkspace })
.weight-heading__actions :deep(.el-button) { width: 100%; min-height: 44px; }
.weight-summary-group { width: 100%; justify-content: space-between; }
.weight-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.weight-preview-layout { grid-template-columns: 1fr; }
}
@media (max-width: 360px) {
.weight-grid { grid-template-columns: 1fr; }
.preview-weight { grid-template-columns: 1fr; }
.weight-key-facts { grid-template-columns: 1fr 1fr; gap: 12px; }
.weight-key-facts strong { font-size: 15px; }
.weight-card__facts div { align-items: flex-start; flex-direction: column; gap: 2px; }
.weight-card__facts dd { text-align: left; }
}