From df3569ba2244b2acd799369405fafbb0035c3cd8 Mon Sep 17 00:00:00 2001 From: Misaka_Company Date: Mon, 18 May 2026 14:59:53 +0800 Subject: [PATCH] docs update single-code boxing UI --- docs/single-code-boxing-ui-states.html | 2104 ++++++++++++++++++++++++ docs/single-code-boxing-ui-v2.html | 1488 +++++++++++++++++ docs/单码装箱UI重构PRD.md | 279 ++++ 3 files changed, 3871 insertions(+) create mode 100644 docs/single-code-boxing-ui-states.html create mode 100644 docs/single-code-boxing-ui-v2.html create mode 100644 docs/单码装箱UI重构PRD.md diff --git a/docs/single-code-boxing-ui-states.html b/docs/single-code-boxing-ui-states.html new file mode 100644 index 0000000..810ba4f --- /dev/null +++ b/docs/single-code-boxing-ui-states.html @@ -0,0 +1,2104 @@ + + + + + +单码装箱模式 - UI 状态全览 + + + + +

单码装箱模式 — UI 状态全览

+

+ 源码:lib/pages/boxing_page.dart_BoxingPageState
+ 覆盖 BoxingMode.singleCode 下所有 UI 状态、状态机流转与交互细节 +

+ + + + +
+
0. 状态栏颜色图例
+
+
蓝色 — 等待/空闲
+
绿色 — 成功
+
红色 — 错误(无效码/数量超限/提交失败)
+
橙色 — 进行中(提交中/同步数据)
+
琥珀 — 警告(箱号重复/提交重复)
+
黄色 — 网络异常
+
+
+ + + + +
+
1. 状态机(_Phase 枚举)
+ +
+ waiting
等待扫码
+ → 扫码成功 → + scanned
已扫码,已自动填充
+ → 用户点击确认 → + submitting
正在提交…
+

+   成功,尚有剩余 → + 回到 scanned(箱号+1,数量=剩余) + / + 回到 waiting(全部装箱完毕)
+   失败 → + 停留在 scanned,显示错误覆盖 +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
_Phase触发条件主要 UI 效果
waiting初始化 / 重置 / 全部装箱完毕扫码区灰色占位;信息区灰色 "--";输入区禁用
scanned扫码成功且 API 返回有效数据扫码区绿色边框+总排号;信息区展示数据;输入区可编辑,自动填充箱号/数量
没有 submitted单码模式中,提交成功后直接进入新的 scanned 或 resetting waiting,不经 submitted 阶段
+
+ + + + +
+
2. UI 状态可视化
+

每个手机模型展示一个具体状态。底部状态栏颜色参考上方图例。

+ + +
+ +
+
2.1 等待扫码 (waiting) 初始状态
+
+
+

装箱编号

+
+ 单码装箱 P2 +
+
+
+ 📷 请扫描执行卡二维码 +
+
+
+ -- + -- + -- +
+
+
+ 已有箱数:-- + 最大箱号:-- +
+ +
+
+
+
+
+ + +
+
+ + +
+ +
+
+ +
+
+
+ 等待扫码 +
+
+
+ + +
+
2.2 已扫码-正常 (scanned, can submit) 最常见状态
+
+
+

装箱编号

+
+ 单码装箱 P2 +
+
+
+ ✅ ZP202605180001 已识别 +
+
+
+ PC-2605-A101 + WO-2026-0882 + 200件 +
+
+
+ 已有箱数:2箱 + 最大箱号:5 +
+ +
+
+
+
+
+ + +
+
+ + +
+ +
+
+ +
+
+
+ 数量已填入,请确认或修改 +
+
+
+ +
+ + +
+ +
+
2.3 已扫码+已分配 (with assigned boxes)
+
+
+

装箱编号

+
+ 单码装箱 P2 +
+
+
+ ✅ ZP202605180001 已识别 +
+
+
+ PC-2605-A101 + WO-2026-0882 + 200件 +
+
+
+ 已有箱数:3箱 + 最大箱号:7 +
+ +
+
+
+
+
已分配
+
+
+ 3号箱 + 数量 50 +
+ + +
+
+
+
+
+ 7号箱 + 数量 100 +
+ + +
+
+
+
+
+
+ + +
+
+ + +
+ +
+
+ +
+
+
+ 数量已填入,请确认或修改 +
+
+
+ + +
+
2.4 已分配行 - 编辑中 (editing assigned) 行内编辑
+
+
+

装箱编号

+
+ 单码装箱 P2 +
+
+
+ ✅ ZP202605180001 已识别 +
+
+
+ PC-2605-A101 + WO-2026-0882 + 200件 +
+
+
+ 已有箱数:3箱 + 最大箱号:7 +
+ +
+
+
+
+
已分配
+
+
+ 3号箱 + 数量 50 +
+ + +
+
+
+
+
+ 7号箱 + +
+ + +
+
+
+
+
+
+ + +
+
+ + +
+ +
+
+ + +
+
+
+ 数量已填入,请确认或修改 +
+
+
+ +
+ + +
+ +
+
2.5 已分配行 - 删除确认 (delete confirm) 行内确认
+
+
+

装箱编号

+
+ 单码装箱 P2 +
+
+
+ ✅ ZP202605180001 已识别 +
+
+
+ PC-2605-A101 + WO-2026-0882 + 200件 +
+
+
+ 已有箱数:2箱 + 最大箱号:5 +
+ +
+
+
+
+
已分配
+
+
+ 3号箱 + 数量 50 +
+ + +
+
+
+
+
+ 5号箱 + 数量 100 +
+ + +
+
+
+ 确认删除此条记录? + + +
+
+
+
+
+ + +
+
+ + +
+ +
+
+ +
+
+
+ 数量已填入,请确认或修改 +
+
+
+ + +
+
2.6 正在提交 (submitting) 按钮 loading
+
+
+

装箱编号

+
+ 单码装箱 P2 +
+
+
+ ✅ ZP202605180001 已识别 +
+
+
+ PC-2605-A101 + WO-2026-0882 + 200件 +
+
+
+ 已有箱数:2箱 + 最大箱号:5 +
+ +
+
+
+
+
+ + +
+
+ + +
+ +
+
+ +
+
+
+ 正在提交… +
+
+
+ +
+ + +
+ +
+
2.7 箱号重复 (duplicate box no) 琥珀色警告
+
+
+

装箱编号

+
+ 单码装箱 P2 +
+
+ + +
+ ✅ ZP202605180001 已识别 +
+
+
+ PC-2605-A101 + WO-2026-0882 + 200件 +
+
+
+ 已有箱数:2箱 + 最大箱号:5 +
+ +
+
+
+
+
+ + +
+
+ + +
+ +
+
+ +
+
+
+ 箱号 5 已存在,请重新输入 +
+
+
+ + +
+
2.8 数量超限 (quantity too high) 红色警告
+
+
+

装箱编号

+
+ 单码装箱 P2 +
+
+
+ ✅ ZP202605180001 已识别 +
+
+
+ PC-2605-A101 + WO-2026-0882 + 200件 +
+
+
+ 已有箱数:2箱 + 最大箱号:5 +
+ +
+
+
+
+
+ + +
+
+ + +
+ +
+
+ +
+
+
+ 超出可装数量上限 +
+
+
+ +
+ + +
+ +
+
2.9 已全部装箱完毕 (fully packed on scan) 红色覆盖
+
+
+

装箱编号

+
+ 单码装箱 P2 +
+
+
+ ✅ ZP202605180002 已识别 +
+
+
+ PC-2605-B202 + WO-2026-0901 + 100件 +
+
+
+ 已有箱数:3箱 + 最大箱号:3 +
+ +
+
+
+
+
+ + +
+
+ + +
+ +
+
+ +
+
+
+ 该总排号已全部装箱完毕 +
+
+
+ + +
+
2.10 无效码 (invalid code) 红色覆盖 2s
+
+
+

装箱编号

+
+ 单码装箱 P2 +
+
+ +
+ 📷 请扫描执行卡二维码 +
+
+
+ -- + -- + -- +
+
+
+ 已有箱数:-- + 最大箱号:-- +
+ +
+
+
+
+
+ + +
+
+ + +
+ +
+
+ +
+
+
+ 无效码,请重新扫描 +
+
+
+ +
+ + +
+ +
+
2.11 网络异常 (network error) 黄色覆盖 2s
+
+
+

装箱编号

+
+ 单码装箱 P2 +
+
+ +
+ 📷 请扫描执行卡二维码 +
+
+
+ -- + -- + -- +
+
+
+ 已有箱数:-- + 最大箱号:-- +
+ +
+
+
+
+
+ + +
+
+ + +
+ +
+
+ +
+
+
+ 网络异常,请检查网络连接 +
+
+
+ + +
+
2.12 提交失败 (submit failure) 红色覆盖 2s
+
+
+

装箱编号

+
+ 单码装箱 P2 +
+
+ +
+ ✅ ZP202605180001 已识别 +
+
+
+ PC-2605-A101 + WO-2026-0882 + 200件 +
+
+
+ 已有箱数:2箱 + 最大箱号:5 +
+ +
+
+
+
+
+ + +
+
+ + +
+ +
+
+ +
+
+
+ 服务器响应异常,请稍后重试 +
+
+
+ +
+ + +
+ +
+
2.13 提交重复 (duplicate on submit) 琥珀覆盖 2s
+
+
+

装箱编号

+
+ 单码装箱 P2 +
+
+ +
+ ✅ ZP202605180001 已识别 +
+
+
+ PC-2605-A101 + WO-2026-0882 + 200件 +
+
+
+ 已有箱数:2箱 + 最大箱号:7 +
+ +
+
+
+
+
+ + +
+
+ + +
+ +
+
+ +
+
+
+ 该总排号在箱号 5 已存在,请重新输入 +
+
+
+ + +
+
2.14 未配置 API (no API configured) 红色覆盖 2s
+
+
+

装箱编号

+
+ 单码装箱 P2 +
+
+ +
+ 📷 请扫描执行卡二维码 +
+
+
+ -- + -- + -- +
+
+
+ 已有箱数:-- + 最大箱号:-- +
+ +
+
+
+
+
+ + +
+
+ + +
+ +
+
+ +
+
+
+ 未配置 API 地址,请前往设置 +
+
+
+ +
+ + +
+ +
+
2.15 同步转运数据中 (auto processing) 橙色横幅
+
+
+

装箱编号

+
+ 单码装箱 P2 +
+
+ +
+ ✅ ZP202605180003 已识别 +
+
+
+ PC-2605-C303 + WO-2026-0920 + 300件 +
+
+
+ 已有箱数:0箱 + 最大箱号:0 +
+ +
+
+
+
+
+ + +
+
+ + +
+ +
+
+ +
+
+
+ 正在同步转运数据... +
+
+
+ + +
+
2.16 自动装箱警告 (auto warnings) 琥珀横幅
+
+
+

装箱编号

+
+ 单码装箱 P2 +
+
+ +
+ ✅ ZP202605180004 已识别 +
+
+
+ PC-2605-D404 + WO-2026-0931 + 150件 +
+
+
+ 已有箱数:1箱 + 最大箱号:3 +
+ +
+
+
+
+
+ + +
+
+ + +
+ +
+
+ +
+
+
+ 数量已填入,请确认或修改 +
+
+
+ +
+
+ + + + +
+
3. 提交按钮启用条件(_canSubmit)
+ +
+ 确认按钮的 enabled 状态由 _canSubmit 决定。当以下所有条件同时满足时,按钮启用: +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#条件代码表达式不满足时效果
1未处于提交中!_isSubmitting按钮显示 loading 转圈
2阶段为 scanned_phase == _Phase.scanned按钮灰色禁用
3已有总排号_zongpaiNo != null按钮灰色禁用
4箱号有效boxNo != null && boxNo > 0按钮灰色禁用
5数量有效qty != null && qty > 0按钮灰色禁用
6数量未超限!_quantityTooHigh(qty ≤ remaining)数量输入红色边框;状态栏红色 "超出可装数量上限"
7箱号不重复!_isDuplicateBoxNo箱号输入琥珀边框;琥珀横幅;状态栏琥珀色 "箱号 X 已存在"
+
+ + + + +
+
4. 状态栏覆盖机制(_showStatusOverride)
+ +
+ 方法签名:void _showStatusOverride(String text, StatusDotColor dot, Duration duration)

+ 大多数反馈状态通过此方法展示。调用后立即替换底部状态栏的 文字圆点颜色,并在 duration 到期后自动恢复为基础状态(由 _updateBaseStatus() 计算)。 +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
场景文字颜色持续时间
无效码无效码,请重新扫描红色2s
网络异常网络异常,请检查网络连接黄色2s
查询失败查询失败(或具体消息)红色2s
提交重复该总排号在箱号 X 已存在,请重新输入琥珀2s
提交失败提交失败(或具体消息)红色2s
未配置 API未配置 API 地址,请前往设置红色2s
装箱成功-继续请继续完成剩余数量装箱绿色1.5s
装箱成功-全部装箱成功绿色1.5s
全部装箱完毕该总排号已全部装箱完毕红色常驻(_statusOverride)
删除成功删除成功绿色1.5s
修改成功修改成功绿色1.5s
保存编辑-数量无效请输入有效数量红色2s
保存编辑-数量超限超出可装数量上限红色2s
同步转运数据正在同步转运数据...橙色常驻(直到处理结束)
+
+ + + + +
+
5. 自动填充逻辑(_applyAutoFill)
+ +
+ 扫码成功并获取 API 数据后自动触发。核心逻辑:填充箱号 = lastBoxNo+1 或 maxBoxNo+1填充数量 = 剩余可装数量;数量输入框自动全选并聚焦。 +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
情况箱号填充数量填充
首次扫码(无历史箱号)maxBoxNo + 1(通常为 1)erpQuantity - packedQuantity(全部剩余)
上次装箱后有继续lastBoxNo + 1剩余可装数量
已全部装箱完毕清空清空
+
+ + + + +
+
6. 已分配行操作详解
+ +
+ 每个 CurrentZongpaiBoxData 渲染为一行 _buildAssignedBoxRow。操作按钮在 view/edit 模式delete 确认模式 间切换。 +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
操作入口交互过程成功后效果
修改点击 ✏️行变橙色背景;数量文字→文本输入;显示 ✅保存 / ❌取消 按钮调用 updateBoxRecord;状态栏绿 "修改成功" 1.5s;自动刷新输入区
删除点击 🗑️行下方出现红色确认条 "确认删除此条记录?" [是] [否]调用 deleteBoxRecord;状态栏绿 "删除成功" 1.5s;行移除此数据
取消编辑点击 ❌ 或 "否"恢复 view 模式,不做 API 调用
+
+ + + + +
+
7. 模式切换(_cycleMode)
+ +
+ 触发方式:点击 Pill按下 P2 物理按键(Android KeyCode R1 / LogicalKey gameButtonRight1 / LogicalKey select)。
+ 切换时调用 _resetState() 清空所有状态,包括阶段、总排号、箱号输入等。 +
+ + + + + + + + + + + + + + + + + + + + + +
方向Pill 背景色标签
单码 → 多码橙色 Colors.orange.shade700多码凑箱
多码 → 单码蓝色 Colors.blue.shade700单码装箱
+
+ + + + +
+
8. 装箱详情页(BoxingDetailPage)
+ +
+ 源码:lib/pages/boxing_detail_page.dart
+ 通过点击主页面 "详情 →" 进入。传入 paichanNoexistingBoxes,按箱号分组展示每个箱内的总排号明细(总排号、工单号、数量/总量)。 +
+ +
+
+
装箱详情(导航页)
+
+
+

装箱详情  PC-2605-A101

+
+
+
+ 箱号 3 + 共 50 件 +
+
+
+ ZP202605180001 + WO-2026-0882 + 50/-- +
+
+ +
+ 箱号 7 + 共 100 件 +
+
+
+ ZP202605180001 + WO-2026-0882 + 100/-- +
+
+
+
+ 共 2 箱 +
+
+
+
+
+ + + + +
+
9. 关键状态字段速查表
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段类型说明
_modeBoxingModesingleCode / multiCode
_phase_Phase (enum)waiting / scanned(单码无 submitted)
_zongpaiNoString?当前总排号,null = 未扫码
_paichanNoString?来自 API 的排产号
_workOrderNoString?来自 API 的工单号
_erpQuantityint?来自 API 的 ERP 总数量
_currentZongpaiBoxesList<CurrentZongpaiBoxData>当前总排号已分配的箱号列表("已分配" 区数据源)
_existingBoxesList<BoxDetailData>该排产号所有已有箱号(详情页数据源)
_maxBoxNoint已有最大箱号,用于填充下一个箱号
_lastBoxNoint?上次提交的箱号(用于 continue 时 boxNo+1)
_editingBoxCurrentZongpaiBoxData?当前正在编辑的已分配行(null = 非编辑状态)
_isSubmittingbool正在提交 API 请求(禁用按钮、显示 loading 转圈)
_isDuplicateBoxNobool当前箱号是否和已有箱号重复
_editingAssignedItemIdint?正在编辑的已分配行 ID
_deletingAssignedItemIdint?待删除的已分配行 ID(显示确认条)
_statusOverrideTextString?覆盖状态栏文字(null = 使用基础状态文字)
_statusOverrideDotStatusDotColor?覆盖状态栏圆点颜色
_isAutoProcessingbool是否正在自动同步/装箱转运数据
+
+ + + + +
+
10. API 数据依赖
+ +
+ 所有核心信息来自 BoxInfoResult(方法:fetchBoxInfo),装箱操作依赖 saveBoxRecord / updateBoxRecord / deleteBoxRecord。 +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
API触发时机返回关键字段
fetchBoxInfo(zongpaiNo)扫码时paichanNo, workOrderNo, quantity, currentZongpaiBoxes, existingBoxes, maxBoxNo
saveBoxRecord(zongpaiNo, boxNo, quantity)首次添加装箱记录success, isDuplicate, boxItemId
updateBoxRecord(boxItemId, boxNo, quantity)修改已分配行 / 保存编辑success, isDuplicate
deleteBoxRecord(boxItemId)删除已分配行确认success
+
+ +
+ 生成时间:2026-05-18 · 源码:lib/pages/boxing_page.dart(2545行)
+ 相关模块:lib/pages/boxing_detail_page.dart · lib/widgets/status_bar.dart · lib/services/boxing_context.dart +
+ + + diff --git a/docs/single-code-boxing-ui-v2.html b/docs/single-code-boxing-ui-v2.html new file mode 100644 index 0000000..69ba195 --- /dev/null +++ b/docs/single-code-boxing-ui-v2.html @@ -0,0 +1,1488 @@ + + + + + +单码装箱 UI v2 — 重构布局 + + + + +
单码装箱 UI v2 — 重构布局
+
参考多码凑箱设计语言 · 竖向空间最优 · 固定底栏 + 可滚动已分配区
+ + +
+ + + + + + + + + + +
+ +
+ + +
+
场景1 · 等待扫码(初始状态)
+
+
+ 装箱编号 +
⇄ 单码装箱 P2
+
+ + +
+ 📷 + 请扫描执行卡二维码 +
+ + +
+
+ 排产号 — + 工单 — + — 件 +
+
+
+
+
+ 已有 — 箱 · 最大箱号 — + +
+
+ + +
+
+ 此总排号已分配 + 0 条 +
+
扫码后显示已分配箱号记录
+
+ + +
+
+
+ 箱号 + +
+
+ 数量 + +
+
+ +
+
+ +
+
+ 等待扫码 +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ +
+

v2 布局优化要点(对比原版)

+
    +
  • AppBar 44px:标题 + 模式徽章一行,去掉原版独占区域;蓝色 Pill 明确区分单码/多码
  • +
  • 扫码条 38px:从原版 ~52px 大卡片压缩为紧凑横条,等待/已识别两态颜色清晰
  • +
  • 排产信息 header 约 52px:左侧三行合并(排产号+工单+ERP件数 / 进度条 / 已有箱数),右侧固定醒目的详情按钮;原版散落两块约 80px,节省 ~28px
  • +
  • 已装入进度条:新增 3px 高度进度条直观显示已装/总量比例,不占额外空间
  • +
  • 已分配列表每行 40px:与多码设计对齐(序号+彩色条+箱号/扫码标注+件数+操作),可滚动
  • +
  • 全部装箱完毕仍保留明细:顶部绿色提示 + 进度条全绿 + 底栏禁用,列表继续展示已分配箱号,便于核对结果
  • +
  • 删除确认行内 28px 条:不弹框,与多码保持一致
  • +
  • 固定底栏:箱号输入 + 数量输入 + 确认按钮 横排一行(~50px),不参与滚动
  • +
  • 通知条 ~30px:橙/琥珀/蓝/绿四色语义,替代原版内嵌 banner,可叠加
  • +
  • 状态栏 28px:圆点 + 简短文字,去掉原版 ~38px 的高度
  • +
+
+ +
+

状态颜色含义

+
+
蓝 — 空闲/等待/正常
+
橙 — 提交中/同步中
+
绿 — 操作成功/装完
+
红 — 错误/超限
+
琥珀 — 警告/重复/编辑中
+
+
+ +
+

UI 结构(v2)

+
┌──────────────────────────────────────────┐ 44px +│ "装箱编号" [⇄ 单码装箱 P2] │ AppBar +├──────────────────────────────────────────┤ +│ [通知条] 可叠加显示,每条 ~30px │ 可选 +├──────────────────────────────────────────┤ 38px +│ ✓ ZP202605180001 已识别 │ 扫码条 +├──────────────────────────────────────────┤ ~52px +│ PC-2605-A101 WO-2026-0882 200件 [详情]│ +│ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ 进度条 │ info-bar +│ 已有 2箱 · 最大箱号 5 · 已装50/200 │ +├──────────────────────────────────────────┤ +│ 此总排号已分配 2 条 │ list-header +│ 1 ▌ 3号箱 本次扫码 50件 ✏🗑 │ 40px/行 +│ 2 ▌ 7号箱 本次扫码 100件 ✏🗑 │ +│ ... │ ← 可滚动区域 +├──────────────────────────────────────────┤ +│ 箱号[8] 数量[50 ] [确认] │ ~50px +├──────────────────────────────────────────┤ 28px +│ ● 数量已填入,请确认或修改 │ 状态栏 +└──────────────────────────────────────────┘
+
+ +
+ + + + diff --git a/docs/单码装箱UI重构PRD.md b/docs/单码装箱UI重构PRD.md new file mode 100644 index 0000000..4072de0 --- /dev/null +++ b/docs/单码装箱UI重构PRD.md @@ -0,0 +1,279 @@ +# 单码装箱页面 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` + +--- + +## 一、背景与目标 + +原单码装箱页面各区块自然堆叠,当已分配记录增多或通知条出现时,下方输入区会被挤出屏幕可视范围,操作体验差。同时,原版与多码凑箱在视觉语言上存在差异,两种模式切换后用户需要重新适应布局。 + +**重构目标:** + +1. 与多码凑箱采用统一的设计语言,降低双模式切换的认知成本 +2. 采用固定顶部 + 可滚动中间 + 固定底栏结构,无论已分配记录多少,输入区始终可见 +3. 在不损失信息量的前提下,压缩各区块高度,让屏幕展示更多有效内容 +4. 去掉返回按钮,简化底栏操作区 + +--- + +## 二、整体布局结构 + +### 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)不变