10 KiB
单码装箱页面 UI 重构 PRD
文档版本:v2.0
更新日期:2026-05-18
涉及页面:lib/pages/boxing_page.dart(BoxingMode.singleCode)
参考设计:多码凑箱 UI v2(multi-code-boxing-ui-v2.html)
产出物:single-code-boxing-ui-v2.html
一、背景与目标
原单码装箱页面各区块自然堆叠,当已分配记录增多或通知条出现时,下方输入区会被挤出屏幕可视范围,操作体验差。同时,原版与多码凑箱在视觉语言上存在差异,两种模式切换后用户需要重新适应布局。
重构目标:
- 与多码凑箱采用统一的设计语言,降低双模式切换的认知成本
- 采用固定顶部 + 可滚动中间 + 固定底栏结构,无论已分配记录多少,输入区始终可见
- 在不损失信息量的前提下,压缩各区块高度,让屏幕展示更多有效内容
- 去掉返回按钮,简化底栏操作区
二、整体布局结构
v1(原版)布局
AppBar(~52px)
扫码卡片(~52px)
信息区 - 排产号+工单+件数(~30px)
信息区 - 已有箱数+最大箱号+详情(~28px)
分隔线
已分配列表(自然高度,不可滚动)
输入区 - 箱号+数量+确认(~48px)
操作行 - 返回按钮(~48px)
状态栏(~38px)
问题:各区全部占据固定高度,列表一旦有 3 条以上记录,输入区就会被推出屏幕,需要手动滚动才能操作。
v2(重构后)布局
AppBar(44px) ← 固定顶部
[通知条 × N](每条 ~30px) ← 可选,固定
扫码条(38px) ← 固定
排产信息栏(~52px) ← 固定
━━━━━━━━━━━━━━━━━━━━━━━━━
已分配列表(弹性高度) ← 可滚动区域
━━━━━━━━━━━━━━━━━━━━━━━━━
输入行(~50px) ← 固定底栏
状态栏(28px) ← 固定底栏
输入行与状态栏固定于底部,任何情况下都不会因列表增长而被遮挡。
三、各区块改动详情
3.1 AppBar
| 项目 | v1 | v2 |
|---|---|---|
| 高度 | ~52px | 44px |
| 标题 | 装箱编号,大号字体 |
装箱编号,15px/700 |
| 模式标识 | 独占一行的大模式按钮区 | 右侧蓝色 Pill ⇄ 单码装箱 P2,与标题同行 |
| 模式颜色 | 蓝色 | 蓝色(单码),橙色(多码),与多码对称 |
Pill 点击或按 P2 物理键切换模式,行为不变。
3.2 通知条(Notice Banner)
替代原版内嵌式 banner 组件,统一为横条形通知,可多条叠加显示。
| 颜色 | 触发场景 |
|---|---|
| 🟠 橙色 | 正在同步转运数据 |
| 🟡 琥珀色 | 箱号重复警告 / 忽略无效码 |
| 🔵 蓝色 | 排产号切换提示 |
| 🟢 绿色 | 全部装箱完毕提示 |
| 🔴 红色 | 数量超限 / 提交失败 / 严重错误 |
每条高度约 30px(含 6px 上下 padding),字号 12px,图标 + 文字,border-bottom: 1px 与下方区域隔开。
3.3 扫码条
| 项目 | v1 | v2 |
|---|---|---|
| 高度 | ~52px 卡片 | 38px 横条 |
| 等待态 | 灰色圆角卡片,居中文字 | 灰底横条,📷 图标 + 文字 |
| 已识别态 | 绿色边框卡片 + 大号总排号 | 绿底横条,✓ 绿圆 + 总排号 + 已识别 徽章 |
3.4 排产信息栏(info-bar)
原版将排产号/工单/件数与已有箱数分为两个分散区块,共约 80px。v2 合并为一个紧凑的 header-bar,高度约 52px。左侧包含三层信息,右侧固定放置醒目的详情按钮:
左侧第一层:[排产号] [工单号] [ERP总件数] 右侧:[📋 详情]
左侧第二层:[进度条 ████████░░░░░░░░] ← 新增
左侧第三层:[已有X箱 · 最大箱号Y · 已装A/B]
新增:装箱进度条
- 高度 3px,不单独占行,嵌在第一层与第三层之间
- 进度 = 已装件数 / ERP 总件数
- 未完成时为蓝色(
#1565c0),全部装完后变绿色(#2e7d32)
详情入口
- 放在排产信息栏最右侧,与三层信息垂直居中
- 使用图标 + 文案的描边按钮样式,正常态为蓝色浅底,空状态置灰不可点击
空状态(未扫码)时,所有字段显示为灰色占位符 —,详情按钮置灰不可点击。
3.5 已分配列表
原版已分配记录直接堆叠在页面中间,无法滚动。v2 改为弹性高度可滚动区域,与多码凑箱的「已装入本箱」列表结构完全一致。
列表头(sticky,滚动时吸顶):
已分配(此总排号) 2 条
每行结构(高度 40px):
[序号] [彩色竖条] [箱号 / 来源标注] [件数] [✏️] [🗑]
| 元素 | 说明 |
|---|---|
| 序号 | 10px 灰色,右对齐 |
| 彩色竖条 | 宽 3px,高 22px;绿=正常,琥珀=编辑中,红=待删除 |
| 箱号 | 13px/700,如「3 号箱」 |
| 来源标注 | 10px 灰色,如「本次扫码」 |
| 件数 | 13px/600,右对齐 |
| 操作按钮 | ✏️ 编辑 / 🗑 删除,各 28×28px |
空状态文案:扫码后显示已分配箱号记录 / 本次扫码尚未分配箱号
全部装箱完毕时,顶部显示绿色通知 已全部装箱完毕,无需操作,进度条变为绿色满格,输入区禁用;已分配列表继续显示具体箱号和件数明细,避免用户只能看到完成提示却无法核对装箱结果。
行内编辑态
点击 ✏️ 后该行变为编辑态(琥珀色背景 #fff8e1),件数文字变为输入框,操作按钮变为 ✓ 保存 / ✕ 取消。其他行保持正常可交互。
删除确认态
点击 🗑 后该行背景变红(#ffebee),行下方展开一条 28px 确认条:
确认删除 X 号箱记录? [删除] [取消]
不弹出 Dialog,行内展开,减少视觉干扰。
3.6 固定底栏(输入区)
原版输入区含三个独立行:箱号+数量+确认(~48px)、返回按钮(~48px)。
v2 改动:
- 箱号、数量、确认按钮合并为单行(高度 ~50px)
- 移除返回按钮
- 正在提交时:两个输入框禁用,确认按钮替换为 loading 转圈
输入行布局:
[箱号] [ 8 ] [数量] [ 50 ] [确认]
| 元素 | 规格 |
|---|---|
| 标签 | 11px/700,紧贴输入框左侧 |
| 箱号输入 | 宽 52px,高 34px,居中,18px/800 |
| 数量输入 | 宽 70px,高 34px,居中,16px/800 |
| 确认按钮 | 高 34px,蓝底白字,14px/700 |
输入状态对应边框色:
| 状态 | 箱号输入框边框 | 数量输入框边框 | 确认按钮 |
|---|---|---|---|
| 正常可提交 | 蓝色 | 蓝色 | 可点击 |
| 箱号重复 | 琥珀色 | 正常 | 禁用 |
| 数量超限 | 正常 | 红色 | 禁用 |
| 提交中 | 禁用灰 | 禁用灰 | loading 转圈 |
| 等待扫码 | 禁用灰 | 禁用灰 | 禁用 |
边界规则: 当提交后刚好装完(剩余数量变为 0)时,输入框中残留的上一次提交数量不应触发“数量超限”;此时按“全部装箱完毕”状态处理,确认按钮禁用。
3.7 状态栏
| 项目 | v1 | v2 |
|---|---|---|
| 高度 | ~38px | 28px |
| 内容 | 状态圆点 + 文字 | 同,字号压缩至 11px |
| 背景 | #EEEEEE |
#f5f5f5 |
圆点颜色语义(与多码统一):
| 颜色 | 状态 |
|---|---|
| 🔵 蓝 | 等待/空闲/数量已填入 |
| 🟠 橙 | 提交中 / 同步中 |
| 🟢 绿 | 操作成功 / 全部装完 |
| 🔴 红 | 错误(无效码 / 超限 / 提交失败) |
| 🟡 琥珀 | 警告(箱号重复 / 编辑中) |
四、场景状态清单
| # | 场景 | 通知条 | 扫码条 | 列表 | 输入行 | 状态栏点 |
|---|---|---|---|---|---|---|
| 1 | 等待扫码 | 无 | 灰色等待 | 空 | 全禁用 | 🔵 |
| 2 | 已扫码(无历史分配) | 无 | 绿色已识别 | 空 | 自动填充,可编辑 | 🔵 |
| 3 | 已扫码 + 已有分配记录 | 无 | 绿色已识别 | 显示分配行 | 自动填充下一箱 | 🔵 |
| 4 | 已分配行 — 编辑中 | 无 | 绿色已识别 | 目标行琥珀背景 + 输入 | 正常 | 🟡 |
| 5 | 已分配行 — 删除确认 | 无 | 绿色已识别 | 目标行红背景 + 确认条 | 正常 | 🔴 |
| 6 | 正在提交 | 无 | 绿色已识别 | 正常 | 全禁用 + loading | 🟠 |
| 7 | 箱号重复 | 🟡 琥珀警告 | 绿色已识别 | 正常 | 箱号框红框,确认禁用 | 🟡 |
| 8 | 数量超限 | 🔴 红色警告 | 绿色已识别 | 正常 | 数量框红框,确认禁用 | 🔴 |
| 9 | 全部装箱完毕 | 🟢 绿色提示 | 绿色已识别 | 显示已分配明细 | 全禁用,进度条全绿 | 🟢 |
| 10 | 自动同步中 | 🟠 同步 + 🟡 忽略 | 绿色已识别 | 正常,不可操作 | 全禁用 | 🟠 |
五、垂直空间节省汇总
| 区块 | v1 高度 | v2 高度 | 节省 |
|---|---|---|---|
| AppBar | ~52px | 44px | 8px |
| 扫码区 | ~52px | 38px | 14px |
| 排产信息 | ~80px(两块) | ~52px(合并) | 28px |
| 已分配行/条 | ~52px/条 | 40px/条 | 12px/条 |
| 通知条 | ~36px | ~30px | 6px/条 |
| 操作行(返回) | ~48px | 0(已移除) | 48px |
| 状态栏 | ~38px | 28px | 10px |
固定区域合计节省约 114px,相当于屏幕高度约 1/7,可多展示约 2~3 条已分配记录。
六、与多码凑箱的设计统一点
以下组件与多码凑箱在样式、尺寸、行为上完全一致,无差异:
- AppBar 高度与 Pill 组件(颜色区分模式)
- 通知条(Notice Banner)的结构与色彩语义
- 已分配/已装入列表的行高、彩色竖条、序号、操作按钮
- 行内编辑(输入框 + ✓/✕)与删除确认条
- 状态栏高度、圆点颜色语义
- 底栏的 loading 转圈形态
七、不在本次范围内的改动
- 装箱详情页(
boxing_detail_page.dart)布局不变 - 状态机逻辑(
_Phase枚举、_applyAutoFill、API 调用时机)不变 - 物理按键 P2 切换模式行为不变
- 所有字段数据来源(
BoxInfoResult、saveBoxRecord等 API)不变