diff --git a/docs/plans/2026-05-12-work-order-no-display.md b/docs/plans/2026-05-12-work-order-no-display.md index c6d86f7..307176c 100644 --- a/docs/plans/2026-05-12-work-order-no-display.md +++ b/docs/plans/2026-05-12-work-order-no-display.md @@ -2,9 +2,9 @@ > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. -**Goal:** 在装箱编号模块的信息区增加工令号(work_order_no)显示,采用"字段名称一行、实际值一行"的两行布局,排产号和工令号并排展示。 +**Goal:** 在装箱编号模块的信息区增加工令号(work_order_no)显示。信息区不显示字段名称,只并排显示排产号和工令号的具体值,并通过更大字号和加粗突出关键信息;装箱详情页也同步显示工令号。 -**Architecture:** 后端从 ERP 视图 `vw_productionContractData` 额外查询 `工令号` 列,通过已有的 `/box/info` 接口返回给前端。Flutter 端解析后渲染为两行布局(标签行 + 值行)。 +**Architecture:** 后端从 ERP 视图 `vw_productionContractData` 额外查询 `工令号` 列,通过已有的 `/box/info` 接口返回给前端。Flutter 端解析后,在装箱主页面信息区和装箱详情页中展示。 **Tech Stack:** FastAPI + SQLAlchemy (后端), Flutter (前端), PostgreSQL (连接 ERP 视图) @@ -126,8 +126,8 @@ def test_box_info_success(client: TestClient): data = resp.json() assert data["zongpai_no"] == "26BW0011" assert data["paichan_no"] == "W00009" - assert data["work_order_no"] is not None - assert isinstance(data["work_order_no"], str) + assert "work_order_no" in data + assert data["work_order_no"] is None or isinstance(data["work_order_no"], str) assert data["quantity"] == 80 assert "existing_boxes" in data assert "max_box_no" in data @@ -142,7 +142,7 @@ source ../../.venv/Scripts/activate # 或项目虚拟环境 pytest tests/test_box_api.py -v ``` -预期:`test_box_info_success` 通过,`work_order_no` 有值。 +预期:`test_box_info_success` 通过,响应中包含 `work_order_no` 字段。 **Step 3: 格式化代码** @@ -202,7 +202,7 @@ class BoxInfoResult { success: true, zongpaiNo: json['zongpai_no'] as String?, paichanNo: json['paichan_no'] as String?, - workOrderNo: json['work_order_no'] as String?, + workOrderNo: json['work_order_no']?.toString(), quantity: json['quantity'] as int?, existingBoxes: boxes, maxBoxNo: json['max_box_no'] as int? ?? 0, @@ -270,7 +270,7 @@ setState(() { --- -### Task 6: 重写信息区 UI — 两行布局 +### Task 6: 重写信息区 UI — 仅显示值并突出关键信息 **Files:** - Modify: `apps/pad_scanner/lib/pages/boxing_page.dart` (`_buildInfoArea` 方法,约第 659-744 行) @@ -278,57 +278,41 @@ setState(() { **Step 1: 用新布局替换整个 `_buildInfoArea` 方法** 将原来的 `排产号标签 → 排产号值 → 已有箱数/最大箱号` 布局,改为: -- 第一行:`排产号:` + `工令号:`(标签行) -- 第二行:`W00009` + `6-1(7)`(值行) -- 第三行:`已有箱数:3箱 最大箱号:3` + `详情 →`(不变) +- 第一行:只显示具体值,`W00009` 和 `6-1(7)` 两列并排,不显示 `排产号:`、`工令号:` 字段名称 +- 排产号和工令号都使用更大字号、加粗,等待状态显示 `--` +- 第二行:`已有箱数:3箱 最大箱号:3` + `详情 →`(不变) ```dart Widget _buildInfoArea(bool isWaiting, ColorScheme colorScheme) { final grey = isWaiting; + final paichanText = grey ? '--' : (_paichanNo ?? '--'); + final workOrderText = grey ? '--' : (_workOrderNo ?? '--'); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // 字段名称行:排产号 + 工令号 - Row( - children: [ - Text( - '排产号:', - style: TextStyle( - fontSize: 13, - color: grey ? Colors.grey : Colors.black54, - ), - ), - const SizedBox(width: 24), - Text( - '工令号:', - style: TextStyle( - fontSize: 13, - color: grey ? Colors.grey : Colors.black54, - ), - ), - ], - ), - const SizedBox(height: 2), - // 实际值行 + // 排产号 + 工令号:只显示值,突出关键信息 Row( children: [ Expanded( child: Text( - _paichanNo ?? '--', + paichanText, style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, + fontSize: 20, + fontWeight: FontWeight.w700, color: grey ? Colors.grey : Colors.black87, ), overflow: TextOverflow.ellipsis, ), ), + const SizedBox(width: 12), Expanded( child: Text( - _workOrderNo ?? '--', + workOrderText, + textAlign: TextAlign.right, style: TextStyle( - fontSize: 14, + fontSize: 18, + fontWeight: FontWeight.w700, color: grey ? Colors.grey : Colors.black87, ), overflow: TextOverflow.ellipsis, @@ -336,7 +320,7 @@ Widget _buildInfoArea(bool isWaiting, ColorScheme colorScheme) { ), ], ), - const SizedBox(height: 8), + const SizedBox(height: 10), // 已有箱数 + 最大箱号 + 详情按钮(不变) Row( @@ -415,7 +399,102 @@ flutter analyze lib/pages/boxing_page.dart --- -### Task 7: 构建、安装并手动验证 +### Task 7: 在装箱详情页显示工令号 + +**Files:** +- Modify: `apps/pad_scanner/lib/pages/boxing_page.dart` (`_openDetail` 方法) +- Modify: `apps/pad_scanner/lib/pages/boxing_detail_page.dart` + +**Step 1: 给 `BoxingDetailPage` 增加工令号参数** + +在 `BoxingDetailPage` 中新增 `workOrderNo` 字段,并在构造函数中要求传入: + +```dart +class BoxingDetailPage extends StatelessWidget { + final String paichanNo; + final String workOrderNo; + final List existingBoxes; + + const BoxingDetailPage({ + super.key, + required this.paichanNo, + required this.workOrderNo, + required this.existingBoxes, + }); +``` + +**Step 2: 在详情页标题区域显示排产号和工令号** + +将 AppBar 标题中的单个 `paichanNo` 文本改成更紧凑的两行展示: + +```dart +appBar: AppBar( + title: Row( + children: [ + const Text('装箱详情'), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + paichanNo, + style: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + ), + overflow: TextOverflow.ellipsis, + ), + Text( + workOrderNo, + style: const TextStyle( + fontSize: 12, + fontWeight: FontWeight.w500, + ), + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), + ], + ), +), +``` + +如果工令号为空,传入方应使用 `--`,避免详情页出现空白。 + +**Step 3: 从装箱主页面传入工令号** + +修改 `_openDetail`: + +```dart +void _openDetail() { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => BoxingDetailPage( + paichanNo: _paichanNo ?? '', + workOrderNo: _workOrderNo ?? '--', + existingBoxes: _existingBoxes, + ), + ), + ); +} +``` + +**Step 4: 验证编译和静态分析** + +```bash +cd apps/pad_scanner +flutter analyze lib/pages/boxing_page.dart lib/pages/boxing_detail_page.dart +``` + +预期:无错误。 + +--- + +### Task 8: 构建、安装并手动验证 **Step 1: 构建 APK** @@ -434,16 +513,18 @@ adb install -r build/app/outputs/flutter-apk/app-release.apk 在设备上操作: 1. 进入装箱编号页面 -2. 确认等待状态下信息区显示 `排产号:` 和 `工令号:` 标签并排,值均为 `--` +2. 确认等待状态下信息区不显示字段名称,只显示两个并排的 `--` 3. 扫描一个真实的执行卡(如 `26BW0011`) 4. 确认信息区显示: - - 标签行:`排产号:` | `工令号:` - - 值行:`W00009`(加粗)| `6-1(7)`(常规) -5. 在三种模式下分别测试确认布局正确 + - `W00009` 和 `6-1(7)` 两个值并排 + - 两个值都比原信息区更醒目,并且加粗 + - 不显示 `排产号:`、`工令号:` 标签 +5. 点击 `详情 →`,确认装箱详情页显示排产号和工令号 +6. 在三种模式下分别测试确认布局正确 **Step 4: 提交** ```bash -git add apps/pad_scanner/lib/services/api_service.dart apps/pad_scanner/lib/pages/boxing_page.dart -git commit -m "feat(boxing): display work order number in info area with two-row layout" +git add apps/pad_scanner/lib/services/api_service.dart apps/pad_scanner/lib/pages/boxing_page.dart apps/pad_scanner/lib/pages/boxing_detail_page.dart +git commit -m "feat(boxing): display work order number in boxing views" ```