diff --git a/docs/single-code-boxing-ui-v2.html b/docs/single-code-boxing-ui-v2.html
index 69ba195..0e888a2 100644
--- a/docs/single-code-boxing-ui-v2.html
+++ b/docs/single-code-boxing-ui-v2.html
@@ -189,7 +189,7 @@ body {
flex-shrink: 0;
}
.scan-code {
- font-size: 13px;
+ font-size: 20px;
font-weight: 700;
color: var(--text);
flex: 1;
@@ -197,6 +197,14 @@ body {
text-overflow: ellipsis;
white-space: nowrap;
}
+.scan-zongpai-extra {
+ font-size: 11px;
+ color: var(--text-2);
+ font-weight: 500;
+ flex-shrink: 0;
+ white-space: nowrap;
+ margin-right: 4px;
+}
.scan-badge {
font-size: 10px;
font-weight: 700;
@@ -216,7 +224,7 @@ body {
display: flex;
flex-direction: column;
position: relative;
- padding: 8px 86px 8px 12px;
+ padding: 8px 12px 8px 12px;
border-bottom: 1px solid var(--border);
flex-shrink: 0;
background: #fafafa;
@@ -248,13 +256,19 @@ body {
white-space: nowrap;
}
+/* 进度条+详情同行 */
+.progress-with-detail {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
/* 进度条 */
.progress-wrap {
+ flex: 1;
height: 3px;
background: #e0e0e0;
border-radius: 2px;
overflow: hidden;
- margin: 2px 0;
}
.progress-fill {
height: 100%;
@@ -264,29 +278,13 @@ body {
}
.progress-fill.full { background: var(--green); }
-.info-row2 {
- display: flex;
- align-items: center;
- gap: 4px;
-}
-.info-meta-text {
- font-size: 11px;
- color: var(--text-3);
- flex: 1;
-}
-.info-meta-text .hl { color: var(--amber); font-weight: 700; }
-.info-meta-text .packed { color: var(--blue); font-weight: 600; }
-
.detail-link {
- position: absolute;
- right: 12px;
- top: 50%;
- transform: translateY(-50%);
display: inline-flex;
align-items: center;
- gap: 4px;
- height: 34px;
- font-size: 12px;
+ justify-content: center;
+ height: 28px;
+ min-width: 48px;
+ font-size: 11px;
font-weight: 700;
color: var(--blue);
background: var(--blue-lt);
@@ -309,10 +307,21 @@ body {
cursor: default;
}
+.info-row2 {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+}
+.info-meta-text {
+ font-size: 11px;
+ color: var(--text-3);
+ flex: 1;
+}
+.info-meta-text .hl { color: var(--amber); font-weight: 700; }
+.info-meta-text .packed { color: var(--blue); font-weight: 600; }
+
/* 空状态的 info-bar */
.info-bar.empty .info-paichan,
-.info-bar.empty .info-wo,
-.info-bar.empty .info-erp,
.info-bar.empty .info-meta-text { color: #ccc; }
/* ── 已分配列表区 (可滚动) ── */
@@ -661,15 +670,15 @@ body {
排产号 —
- 工单 —
- — 件
-
@@ -718,6 +727,7 @@ body {
@@ -725,15 +735,15 @@ body {
PC-2605-A101
- WO-2026-0882
- 200 件
-
-
+
已有 1 箱 · 最大箱号 2 · 已装 50/200
-
@@ -781,21 +791,22 @@ body {
PC-2605-A101
- WO-2026-0882
- 200 件
-
-
+
已有 3 箱 · 最大箱号 7 · 已装 150/200
-
@@ -866,21 +877,22 @@ body {
PC-2605-A101
- WO-2026-0882
- 200 件
-
-
+
已有 3 箱 · 最大箱号 7 · 已装 150/200
-
@@ -951,21 +963,22 @@ body {
PC-2605-A101
- WO-2026-0882
- 200 件
-
@@ -1041,21 +1054,22 @@ body {
PC-2605-A101
- WO-2026-0882
- 200 件
-
@@ -1109,21 +1123,22 @@ body {
PC-2605-A101
- WO-2026-0882
- 200 件
-
@@ -1175,21 +1190,22 @@ body {
PC-2605-A101
- WO-2026-0882
- 200 件
-
-
+
已有 1 箱 · 最大箱号 2 · 剩余可装 150
-
@@ -1241,21 +1257,22 @@ body {
PC-2605-B202
- WO-2026-0901
- 100 件
-
-
+
已有 3 箱 · 最大箱号 3 · 100/100 已装完
-
@@ -1347,21 +1364,22 @@ body {
PC-2605-A101
- WO-2026-0882
- 200 件
-
-
+
已有 3 箱 · 最大箱号 7 · 已装 150/200
-
@@ -1456,10 +1474,10 @@ body {
│ "装箱编号" [⇄ 单码装箱 P2] │ AppBar
├──────────────────────────────────────────┤
│ [通知条] 可叠加显示,每条 ~30px │ 可选
-├──────────────────────────────────────────┤ 38px
-│ ✓ ZP202605180001 已识别 │ 扫码条
-├──────────────────────────────────────────┤ ~52px
-│ PC-2605-A101 WO-2026-0882 200件 [详情]│
+├──────────────────────────────────────────┤ ~50px
+│ ✓ ZP202605180001 WO-0882 / 200件 已识别 │ 扫码条
+├──────────────────────────────────────────┤ ~45px
+│ PC-2605-A101 [详情] │
│ ▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ 进度条 │ info-bar
│ 已有 2箱 · 最大箱号 5 · 已装50/200 │
├──────────────────────────────────────────┤
diff --git a/lib/pages/boxing_page.dart b/lib/pages/boxing_page.dart
index 4369e3b..616040c 100644
--- a/lib/pages/boxing_page.dart
+++ b/lib/pages/boxing_page.dart
@@ -1305,10 +1305,15 @@ class _BoxingPageState extends State
with WidgetsBindingObserver {
onKeyEvent: _onKeyEvent,
child: Scaffold(
appBar: AppBar(
- title: const Text('装箱编号'),
+ title: Row(
+ children: [
+ const Text('装箱编号'),
+ const SizedBox(width: 8),
+ _buildModePill(),
+ ],
+ ),
toolbarHeight: 44,
titleSpacing: 12,
- actions: [_buildModePill(), const SizedBox(width: 8)],
),
body: Column(
children: [
@@ -1446,27 +1451,10 @@ class _BoxingPageState extends State with WidgetsBindingObserver {
);
}
- Widget _buildSingleCodeBody(ColorScheme colorScheme) {
- final isWaiting = _phase == _Phase.waiting && _zongpaiNo == null;
- final isFinished =
- _phase == _Phase.scanned &&
- _zongpaiNo != null &&
- _remainingQuantity <= 0;
-
- return Column(
- children: [
- _buildSingleScanBar(isWaiting),
- _buildSingleInfoBar(isWaiting, colorScheme),
- _buildSingleAssignedList(isWaiting, isFinished),
- _buildSingleBottomArea(isWaiting || isFinished),
- ],
- );
- }
-
Widget _buildSingleScanBar(bool isWaiting) {
if (isWaiting) {
return Container(
- height: 38,
+ height: 50,
padding: const EdgeInsets.symmetric(horizontal: 12),
decoration: BoxDecoration(
color: Colors.grey.shade100,
@@ -1486,7 +1474,7 @@ class _BoxingPageState extends State with WidgetsBindingObserver {
}
return Container(
- height: 38,
+ height: 50,
padding: const EdgeInsets.symmetric(horizontal: 12),
decoration: BoxDecoration(
color: Colors.green.shade50,
@@ -1499,23 +1487,17 @@ class _BoxingPageState extends State with WidgetsBindingObserver {
Expanded(
child: Text(
_zongpaiNo ?? '',
- style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w700),
+ style: const TextStyle(fontSize: 20, fontWeight: FontWeight.w700),
overflow: TextOverflow.ellipsis,
),
),
- Container(
- padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 1),
- decoration: BoxDecoration(
- color: Colors.green.shade100,
- borderRadius: BorderRadius.circular(8),
- ),
- child: Text(
- '已识别',
- style: TextStyle(
- fontSize: 10,
- fontWeight: FontWeight.w700,
- color: Colors.green.shade700,
- ),
+ const SizedBox(width: 8),
+ Text(
+ '${_workOrderNo ?? "--"} / ${_erpQuantity ?? 0}件 / 已装$_packedQuantity',
+ style: const TextStyle(
+ fontSize: 15,
+ fontWeight: FontWeight.w500,
+ color: Colors.black54,
),
),
],
@@ -1523,6 +1505,23 @@ class _BoxingPageState extends State with WidgetsBindingObserver {
);
}
+ Widget _buildSingleCodeBody(ColorScheme colorScheme) {
+ final isWaiting = _phase == _Phase.waiting && _zongpaiNo == null;
+ final isFinished =
+ _phase == _Phase.scanned &&
+ _zongpaiNo != null &&
+ _remainingQuantity <= 0;
+
+ return Column(
+ children: [
+ _buildSingleScanBar(isWaiting),
+ _buildSingleInfoBar(isWaiting, colorScheme),
+ _buildSingleAssignedList(isWaiting, isFinished),
+ _buildSingleBottomArea(isWaiting || isFinished),
+ ],
+ );
+ }
+
Widget _buildSingleInfoBar(bool isWaiting, ColorScheme colorScheme) {
final total = _erpQuantity ?? 0;
final packed = isWaiting ? 0 : _packedQuantity;
@@ -1531,90 +1530,68 @@ class _BoxingPageState extends State with WidgetsBindingObserver {
final detailEnabled = !isWaiting && _existingBoxes.isNotEmpty;
return Container(
- padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
+ padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
decoration: BoxDecoration(
color: Colors.grey.shade50,
border: Border(bottom: BorderSide(color: Colors.grey.shade300)),
),
- child: Row(
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- Expanded(
- child: Column(
- mainAxisSize: MainAxisSize.min,
- children: [
- Row(
- children: [
- Expanded(
- child: Text(
+ child: IntrinsicHeight(
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.stretch,
+ children: [
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Row(
+ children: [
+ Text(
isWaiting ? '排产号 --' : (_paichanNo ?? '--'),
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w700,
- color: isWaiting
- ? Colors.grey.shade400
- : Colors.black87,
+ color: isWaiting ? Colors.grey.shade400 : Colors.black87,
),
overflow: TextOverflow.ellipsis,
),
- ),
- const SizedBox(width: 8),
- Text(
- isWaiting ? '工单 --' : (_workOrderNo ?? '--'),
- style: TextStyle(
- fontSize: 12,
- color: isWaiting
- ? Colors.grey.shade400
- : Colors.black54,
+ const SizedBox(width: 10),
+ Expanded(
+ child: Text(
+ isWaiting
+ ? '已有 -- 箱 · 最大箱号 --'
+ : '已有 ${_existingBoxes.length} 箱 · 最大箱号 $_maxBoxNo',
+ style: TextStyle(
+ fontSize: 10,
+ color: isWaiting
+ ? Colors.grey.shade400
+ : Colors.grey.shade600,
+ ),
+ overflow: TextOverflow.ellipsis,
+ textAlign: TextAlign.right,
+ ),
+ ),
+ ],
+ ),
+ const SizedBox(height: 4),
+ ClipRRect(
+ borderRadius: BorderRadius.circular(2),
+ child: LinearProgressIndicator(
+ value: progress,
+ minHeight: 3,
+ backgroundColor: Colors.grey.shade300,
+ valueColor: AlwaysStoppedAnimation(
+ finished ? Colors.green.shade700 : colorScheme.primary,
),
),
- const SizedBox(width: 8),
- Text(
- isWaiting ? '-- 件' : '$total 件',
- style: TextStyle(
- fontSize: 12,
- fontWeight: FontWeight.w700,
- color: isWaiting
- ? Colors.grey.shade400
- : Colors.black87,
- ),
- ),
- ],
- ),
- const SizedBox(height: 5),
- ClipRRect(
- borderRadius: BorderRadius.circular(2),
- child: LinearProgressIndicator(
- value: progress,
- minHeight: 3,
- backgroundColor: Colors.grey.shade300,
- valueColor: AlwaysStoppedAnimation(
- finished ? Colors.green.shade700 : colorScheme.primary,
- ),
),
- ),
- const SizedBox(height: 5),
- Align(
- alignment: Alignment.centerLeft,
- child: Text(
- isWaiting
- ? '已有 -- 箱 · 最大箱号 --'
- : '已有 ${_existingBoxes.length} 箱 · 最大箱号 $_maxBoxNo · 已装 $packed/$total',
- style: TextStyle(
- fontSize: 11,
- color: isWaiting
- ? Colors.grey.shade400
- : Colors.grey.shade600,
- ),
- overflow: TextOverflow.ellipsis,
- ),
- ),
- ],
+ ],
+ ),
),
- ),
- const SizedBox(width: 10),
- _buildDetailButton(detailEnabled, colorScheme),
- ],
+ const SizedBox(width: 10),
+ _buildDetailButton(detailEnabled, colorScheme),
+ ],
+ ),
),
);
}
@@ -2064,44 +2041,45 @@ class _BoxingPageState extends State with WidgetsBindingObserver {
final isSingle = _mode == BoxingMode.singleCode;
final bgColor = isSingle ? Colors.blue.shade700 : Colors.orange.shade700;
- return GestureDetector(
- onTap: _isAutoProcessing ? null : _cycleMode,
- child: Container(
- padding: const EdgeInsets.symmetric(horizontal: 9, vertical: 3),
- decoration: BoxDecoration(
- color: bgColor,
- borderRadius: BorderRadius.circular(12),
- ),
- child: Row(
- mainAxisSize: MainAxisSize.min,
- children: [
- const Icon(Icons.swap_horiz, color: Colors.white, size: 14),
- const SizedBox(width: 4),
- Text(
- _modeLabel,
- style: const TextStyle(
- color: Colors.white,
- fontSize: 11,
- fontWeight: FontWeight.w700,
- ),
- ),
- const SizedBox(width: 4),
- Container(
- padding: const EdgeInsets.symmetric(horizontal: 4),
- decoration: BoxDecoration(
- color: Colors.white.withValues(alpha: 0.22),
- borderRadius: BorderRadius.circular(4),
- ),
- child: const Text(
- 'P2',
- style: TextStyle(
- color: Colors.white,
- fontSize: 10,
- fontWeight: FontWeight.w600,
+ return Material(
+ borderRadius: BorderRadius.circular(8),
+ color: bgColor,
+ child: InkWell(
+ borderRadius: BorderRadius.circular(8),
+ onTap: _isAutoProcessing ? null : _cycleMode,
+ child: Container(
+ height: 36,
+ padding: const EdgeInsets.symmetric(horizontal: 10),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ const Icon(Icons.swap_horiz, color: Colors.white, size: 18),
+ const SizedBox(width: 6),
+ Flexible(
+ child: FittedBox(
+ fit: BoxFit.scaleDown,
+ child: Text(
+ _modeLabel,
+ maxLines: 1,
+ style: const TextStyle(
+ color: Colors.white,
+ fontSize: 18,
+ fontWeight: FontWeight.w800,
+ ),
+ ),
),
),
- ),
- ],
+ const SizedBox(width: 8),
+ Text(
+ 'P2',
+ style: TextStyle(
+ color: Colors.white.withValues(alpha: 0.88),
+ fontSize: 12,
+ fontWeight: FontWeight.w700,
+ ),
+ ),
+ ],
+ ),
),
),
);