Compare commits
1 Commits
master
...
dev-module
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e50c242bb7 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -16,7 +16,4 @@ Thumbs.db
|
|||||||
|
|
||||||
# AI Agents
|
# AI Agents
|
||||||
.claude/
|
.claude/
|
||||||
.sisyphus/
|
|
||||||
.agents/
|
|
||||||
|
|
||||||
tmp/
|
|
||||||
7
.gitmodules
vendored
7
.gitmodules
vendored
@@ -1,9 +1,6 @@
|
|||||||
[submodule "apps/pad_scanner"]
|
[submodule "apps/pad_scanner"]
|
||||||
path = apps/pad_scanner
|
path = apps/pad_scanner
|
||||||
url = git@gitea.server10086.icu:CargoTrace/pad_scanner.git
|
url = git@gitea.server10086.icu:CargoTrace/pad_scanner.git
|
||||||
[submodule "services/fastapi"]
|
[submodule "apps/fastAPI"]
|
||||||
path = services/fastapi
|
path = apps/fastAPI
|
||||||
url = git@gitea.server10086.icu:CargoTrace/fastAPI.git
|
url = git@gitea.server10086.icu:CargoTrace/fastAPI.git
|
||||||
[submodule "WareShipManifest"]
|
|
||||||
path = WareShipManifest
|
|
||||||
url = git@gitea.server10086.icu:CargoTrace/WareShipManifest.git
|
|
||||||
|
|||||||
14
README.md
14
README.md
@@ -12,11 +12,9 @@
|
|||||||
- **技术栈**: Flutter
|
- **技术栈**: Flutter
|
||||||
- **说明**: 基于 Flutter 框架的安卓应用,用于货物扫描和追踪
|
- **说明**: 基于 Flutter 框架的安卓应用,用于货物扫描和追踪
|
||||||
|
|
||||||
### 后端服务 (FastAPI)
|
### 后端服务
|
||||||
- **路径**: `services/fastapi`
|
- **状态**: 待定
|
||||||
- **仓库**: `git@gitea.server10086.icu:CargoTrace/fastAPI.git`
|
- **技术栈**: 待定(可能使用 FastAPI 等)
|
||||||
- **技术栈**: FastAPI (Python)
|
|
||||||
- **说明**: 后端 API 服务
|
|
||||||
|
|
||||||
## 项目结构
|
## 项目结构
|
||||||
|
|
||||||
@@ -24,10 +22,8 @@
|
|||||||
CargoTrace/
|
CargoTrace/
|
||||||
├── apps/ # 应用层子模块
|
├── apps/ # 应用层子模块
|
||||||
│ └── pad_scanner/ # Flutter Android 应用
|
│ └── pad_scanner/ # Flutter Android 应用
|
||||||
├── services/ # 后端服务子模块
|
├── services/ # 后端服务子模块(待添加)
|
||||||
│ └── fastapi/ # FastAPI 后端服务
|
|
||||||
├── shared/ # 共享代码/库(待添加)
|
├── shared/ # 共享代码/库(待添加)
|
||||||
├── infra/ # 基础设施(待添加)
|
|
||||||
└── docs/ # 项目文档
|
└── docs/ # 项目文档
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -66,7 +62,7 @@ git pull origin main
|
|||||||
| 层级 | 技术栈 | 状态 |
|
| 层级 | 技术栈 | 状态 |
|
||||||
|------|--------|------|
|
|------|--------|------|
|
||||||
| Android 端 | Flutter | ✅ 确定 |
|
| Android 端 | Flutter | ✅ 确定 |
|
||||||
| 后端服务 | FastAPI (Python) | ✅ 确定 |
|
| 后端服务 | 待定 | ⏳ 待定 |
|
||||||
|
|
||||||
## 许可证
|
## 许可证
|
||||||
|
|
||||||
|
|||||||
Submodule WareShipManifest deleted from 4dc563cdd9
1
apps/fastAPI
Submodule
1
apps/fastAPI
Submodule
Submodule apps/fastAPI added at 2cc476b314
Submodule apps/pad_scanner updated: 99ed3bb9ec...b129ed9714
@@ -1,530 +0,0 @@
|
|||||||
# 工令号显示功能 Implementation Plan
|
|
||||||
|
|
||||||
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
|
||||||
|
|
||||||
**Goal:** 在装箱编号模块的信息区增加工令号(work_order_no)显示。信息区不显示字段名称,只并排显示排产号和工令号的具体值,并通过更大字号和加粗突出关键信息;装箱详情页也同步显示工令号。
|
|
||||||
|
|
||||||
**Architecture:** 后端从 ERP 视图 `vw_productionContractData` 额外查询 `工令号` 列,通过已有的 `/box/info` 接口返回给前端。Flutter 端解析后,在装箱主页面信息区和装箱详情页中展示。
|
|
||||||
|
|
||||||
**Tech Stack:** FastAPI + SQLAlchemy (后端), Flutter (前端), PostgreSQL (连接 ERP 视图)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 步骤一:FastAPI 后端
|
|
||||||
|
|
||||||
### Task 1: 扩展 ERP 查询 SQL,增加工令号字段
|
|
||||||
|
|
||||||
**Files:**
|
|
||||||
- Modify: `services/fastapi/app/services/box_service.py:46-59`
|
|
||||||
|
|
||||||
**Step 1: 修改 `_erp_info_sql` 函数**
|
|
||||||
|
|
||||||
将 SQL 查询从 3 列扩展为 4 列,增加 `工令号`。
|
|
||||||
|
|
||||||
```python
|
|
||||||
def _erp_info_sql(db: Session) -> str:
|
|
||||||
dialect_name = db.bind.dialect.name if db.bind is not None else ""
|
|
||||||
if dialect_name == "postgresql":
|
|
||||||
return (
|
|
||||||
'SELECT "总排号", "排产号", "数量", "工令号" '
|
|
||||||
'FROM "ERPAuto"."vw_productionContractData" '
|
|
||||||
'WHERE "总排号" = :zongpai_no '
|
|
||||||
"LIMIT 1"
|
|
||||||
)
|
|
||||||
return (
|
|
||||||
"SELECT TOP 1 [总排号], [排产号], [数量], [工令号] "
|
|
||||||
"FROM [ERPAuto].[vw_productionContractData] "
|
|
||||||
"WHERE [总排号] = :zongpai_no"
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
**Step 2: 修改 `query_erp_info` 函数**
|
|
||||||
|
|
||||||
在返回字典中增加 `work_order_no` 字段。
|
|
||||||
|
|
||||||
```python
|
|
||||||
def query_erp_info(db: Session, zongpai_no: str) -> dict:
|
|
||||||
"""从 ERP 视图查询总排号对应的排产号、工令号和数量。"""
|
|
||||||
sql = text(_erp_info_sql(db))
|
|
||||||
row = db.execute(sql, {"zongpai_no": zongpai_no}).fetchone()
|
|
||||||
if not row:
|
|
||||||
raise ZongpaiNotFoundError()
|
|
||||||
return {
|
|
||||||
"zongpai_no": row[0],
|
|
||||||
"paichan_no": row[1],
|
|
||||||
"quantity": int(row[2]),
|
|
||||||
"work_order_no": row[3],
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Step 3: 修改 `get_box_info` 函数的返回值**
|
|
||||||
|
|
||||||
在返回字典中增加 `work_order_no`。
|
|
||||||
|
|
||||||
```python
|
|
||||||
return {
|
|
||||||
"zongpai_no": zongpai_no,
|
|
||||||
"paichan_no": paichan_no,
|
|
||||||
"work_order_no": erp["work_order_no"],
|
|
||||||
"quantity": quantity,
|
|
||||||
"existing_boxes": existing_boxes,
|
|
||||||
"max_box_no": max_box_no,
|
|
||||||
"suggested_box_no": max_box_no + 1,
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Step 4: 验证**
|
|
||||||
|
|
||||||
启动服务,用 curl 或浏览器测试:
|
|
||||||
```bash
|
|
||||||
curl "http://localhost:8000/CargoTrace/box/info?zongpai_no=26BW0011"
|
|
||||||
```
|
|
||||||
|
|
||||||
预期响应中包含 `"work_order_no": "6-1(7)"`。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Task 2: 更新 Pydantic Schema
|
|
||||||
|
|
||||||
**Files:**
|
|
||||||
- Modify: `services/fastapi/app/schemas/box.py:20-27`
|
|
||||||
|
|
||||||
**Step 1: 在 `BoxInfoResponse` 中增加 `work_order_no` 字段**
|
|
||||||
|
|
||||||
```python
|
|
||||||
class BoxInfoResponse(BaseModel):
|
|
||||||
"""GET /box/info 响应"""
|
|
||||||
zongpai_no: str
|
|
||||||
paichan_no: str
|
|
||||||
work_order_no: str | None = None
|
|
||||||
quantity: int
|
|
||||||
existing_boxes: list[BoxDetail]
|
|
||||||
max_box_no: int
|
|
||||||
suggested_box_no: int
|
|
||||||
```
|
|
||||||
|
|
||||||
**Step 2: 验证 API 文档**
|
|
||||||
|
|
||||||
启动服务后访问 `http://localhost:8000/docs`,确认 `BoxInfoResponse` 包含 `work_order_no` 字段。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Task 3: 更新测试
|
|
||||||
|
|
||||||
**Files:**
|
|
||||||
- Modify: `services/fastapi/tests/test_box_api.py:7-19`
|
|
||||||
|
|
||||||
**Step 1: 在 `test_box_info_success` 中增加 `work_order_no` 断言**
|
|
||||||
|
|
||||||
```python
|
|
||||||
def test_box_info_success(client: TestClient):
|
|
||||||
"""查询真实存在的总排号 → 200"""
|
|
||||||
resp = client.get(
|
|
||||||
"/CargoTrace/box/info", params={"zongpai_no": "26BW0011"}
|
|
||||||
)
|
|
||||||
assert resp.status_code == 200
|
|
||||||
data = resp.json()
|
|
||||||
assert data["zongpai_no"] == "26BW0011"
|
|
||||||
assert data["paichan_no"] == "W00009"
|
|
||||||
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
|
|
||||||
assert data["suggested_box_no"] == data["max_box_no"] + 1
|
|
||||||
```
|
|
||||||
|
|
||||||
**Step 2: 运行测试验证**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd services/fastapi
|
|
||||||
source ../../.venv/Scripts/activate # 或项目虚拟环境
|
|
||||||
pytest tests/test_box_api.py -v
|
|
||||||
```
|
|
||||||
|
|
||||||
预期:`test_box_info_success` 通过,响应中包含 `work_order_no` 字段。
|
|
||||||
|
|
||||||
**Step 3: 格式化代码**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
black app/services/box_service.py app/schemas/box.py tests/test_box_api.py
|
|
||||||
```
|
|
||||||
|
|
||||||
**Step 4: 提交**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git add services/fastapi/app/services/box_service.py services/fastapi/app/schemas/box.py services/fastapi/tests/test_box_api.py
|
|
||||||
git commit -m "feat(box): add work_order_no to box info API response"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 步骤二:Flutter 应用
|
|
||||||
|
|
||||||
### Task 4: 扩展 API 数据模型
|
|
||||||
|
|
||||||
**Files:**
|
|
||||||
- Modify: `apps/pad_scanner/lib/services/api_service.dart:66-107`
|
|
||||||
|
|
||||||
**Step 1: 在 `BoxInfoResult` 中增加 `workOrderNo` 字段**
|
|
||||||
|
|
||||||
```dart
|
|
||||||
class BoxInfoResult {
|
|
||||||
final bool success;
|
|
||||||
final String? errorMessage;
|
|
||||||
final String? zongpaiNo;
|
|
||||||
final String? paichanNo;
|
|
||||||
final String? workOrderNo;
|
|
||||||
final int? quantity;
|
|
||||||
final List<BoxDetailData> existingBoxes;
|
|
||||||
final int maxBoxNo;
|
|
||||||
final int suggestedBoxNo;
|
|
||||||
|
|
||||||
BoxInfoResult({
|
|
||||||
required this.success,
|
|
||||||
this.errorMessage,
|
|
||||||
this.zongpaiNo,
|
|
||||||
this.paichanNo,
|
|
||||||
this.workOrderNo,
|
|
||||||
this.quantity,
|
|
||||||
this.existingBoxes = const [],
|
|
||||||
this.maxBoxNo = 0,
|
|
||||||
this.suggestedBoxNo = 1,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory BoxInfoResult.ok(Map<String, dynamic> json) {
|
|
||||||
final boxes =
|
|
||||||
(json['existing_boxes'] as List<dynamic>?)
|
|
||||||
?.map((b) => BoxDetailData.fromJson(b as Map<String, dynamic>))
|
|
||||||
.toList() ??
|
|
||||||
[];
|
|
||||||
return BoxInfoResult(
|
|
||||||
success: true,
|
|
||||||
zongpaiNo: json['zongpai_no'] as String?,
|
|
||||||
paichanNo: json['paichan_no'] as String?,
|
|
||||||
workOrderNo: json['work_order_no']?.toString(),
|
|
||||||
quantity: json['quantity'] as int?,
|
|
||||||
existingBoxes: boxes,
|
|
||||||
maxBoxNo: json['max_box_no'] as int? ?? 0,
|
|
||||||
suggestedBoxNo: json['suggested_box_no'] as int? ?? 1,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
factory BoxInfoResult.error(String message) {
|
|
||||||
return BoxInfoResult(success: false, errorMessage: message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Step 2: 验证编译通过**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd apps/pad_scanner
|
|
||||||
flutter analyze lib/services/api_service.dart
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Task 5: 更新 BoxingPage 状态管理
|
|
||||||
|
|
||||||
**Files:**
|
|
||||||
- Modify: `apps/pad_scanner/lib/pages/boxing_page.dart`
|
|
||||||
|
|
||||||
**Step 1: 增加状态变量**
|
|
||||||
|
|
||||||
在 `_BoxingPageState` 的状态变量区域(约第 51 行之后),增加:
|
|
||||||
|
|
||||||
```dart
|
|
||||||
// 工令号(来自后端查询)
|
|
||||||
String? _workOrderNo;
|
|
||||||
```
|
|
||||||
|
|
||||||
**Step 2: 更新 `_resetState` 方法**
|
|
||||||
|
|
||||||
在 `_resetState` 中增加清除 `work_order_no`:
|
|
||||||
|
|
||||||
```dart
|
|
||||||
void _resetState() {
|
|
||||||
_phase = _Phase.waiting;
|
|
||||||
_zongpaiNo = null;
|
|
||||||
_paichanNo = null;
|
|
||||||
_workOrderNo = null; // 新增
|
|
||||||
_erpQuantity = null;
|
|
||||||
// ... 其余不变
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Step 3: 更新 `_queryBoxInfo` 中的 setState**
|
|
||||||
|
|
||||||
在 `_queryBoxInfo` 方法的 `setState` 块中增加赋值:
|
|
||||||
|
|
||||||
```dart
|
|
||||||
setState(() {
|
|
||||||
_zongpaiNo = zongpai;
|
|
||||||
_paichanNo = result.paichanNo;
|
|
||||||
_workOrderNo = result.workOrderNo; // 新增
|
|
||||||
_erpQuantity = result.quantity;
|
|
||||||
// ... 其余不变
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Task 6: 重写信息区 UI — 仅显示值并突出关键信息
|
|
||||||
|
|
||||||
**Files:**
|
|
||||||
- Modify: `apps/pad_scanner/lib/pages/boxing_page.dart` (`_buildInfoArea` 方法,约第 659-744 行)
|
|
||||||
|
|
||||||
**Step 1: 用新布局替换整个 `_buildInfoArea` 方法**
|
|
||||||
|
|
||||||
将原来的 `排产号标签 → 排产号值 → 已有箱数/最大箱号` 布局,改为:
|
|
||||||
- 第一行:只显示具体值,`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: [
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
paichanText,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
color: grey ? Colors.grey : Colors.black87,
|
|
||||||
),
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 12),
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
workOrderText,
|
|
||||||
textAlign: TextAlign.right,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 18,
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
color: grey ? Colors.grey : Colors.black87,
|
|
||||||
),
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
|
|
||||||
// 已有箱数 + 最大箱号 + 详情按钮(不变)
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'已有箱数:',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 13,
|
|
||||||
color: grey ? Colors.grey : Colors.black54,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
grey ? '--' : '${_existingBoxes.length}箱',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 13,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: grey ? Colors.grey : Colors.black87,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 16),
|
|
||||||
Text(
|
|
||||||
'最大箱号:',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 13,
|
|
||||||
color: grey ? Colors.grey : Colors.black54,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
grey ? '--' : '$_maxBoxNo',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 13,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: _maxBoxNo > 0
|
|
||||||
? Colors.amber.shade800
|
|
||||||
: Colors.grey,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
TextButton(
|
|
||||||
onPressed: grey || _existingBoxes.isEmpty ? null : _openDetail,
|
|
||||||
style: TextButton.styleFrom(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
|
||||||
minimumSize: Size.zero,
|
|
||||||
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
'详情 →',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 13,
|
|
||||||
color: grey || _existingBoxes.isEmpty
|
|
||||||
? Colors.grey.shade400
|
|
||||||
: colorScheme.primary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Step 2: 验证编译和静态分析**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd apps/pad_scanner
|
|
||||||
flutter analyze lib/pages/boxing_page.dart
|
|
||||||
```
|
|
||||||
|
|
||||||
预期:无错误。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 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<BoxDetailData> 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**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd apps/pad_scanner
|
|
||||||
flutter build apk --release
|
|
||||||
```
|
|
||||||
|
|
||||||
**Step 2: 安装到设备**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
adb install -r build/app/outputs/flutter-apk/app-release.apk
|
|
||||||
```
|
|
||||||
|
|
||||||
**Step 3: 手动验证**
|
|
||||||
|
|
||||||
在设备上操作:
|
|
||||||
1. 进入装箱编号页面
|
|
||||||
2. 确认等待状态下信息区不显示字段名称,只显示两个并排的 `--`
|
|
||||||
3. 扫描一个真实的执行卡(如 `26BW0011`)
|
|
||||||
4. 确认信息区显示:
|
|
||||||
- `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 apps/pad_scanner/lib/pages/boxing_detail_page.dart
|
|
||||||
git commit -m "feat(boxing): display work order number in boxing views"
|
|
||||||
```
|
|
||||||
Submodule services/fastapi deleted from eec0fd3189
Reference in New Issue
Block a user