feat: 商品追踪页面 + 出库提交库存校验
后端: - feat(backend): 重命名 Batches→Products 接口,新增库存状态(在售/已卖出)和买家信息 - feat(backend): 出库单创建/提交时校验仓库库存,不足则返回明确错误信息 - fix(backend): 出库创建 status 判断逻辑修复(空值默认 draft) 前端: - feat(client): 批次追踪改为商品追踪,新增状态列(在售/已卖出)和买家/时间列 - fix(client): 无批次号时显示"无批次"而非空 - refactor(client): BatchRecord → ProductTrackingRecord,repository 接口更新 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
# Flutter 布局 Bug 报告
|
||||
|
||||
## BUG-001
|
||||
|
||||
**严重程度**:高
|
||||
|
||||
**问题描述**:
|
||||
`DataTableCard` 将 toolbar 包裹在 `SingleChildScrollView(scrollDirection: Axis.horizontal)` 中,
|
||||
而 toolbar 内使用了 `Spacer`(`Flexible` 组件)。`Spacer` 在无界宽度约束下无法布局,导致运行时
|
||||
抛出 Flutter assertion:
|
||||
|
||||
```
|
||||
RenderFlex children have non-zero flex but incoming width constraints are unbounded.
|
||||
```
|
||||
|
||||
受影响页面:
|
||||
- `ProductsScreen`(`products_screen.dart:139`)
|
||||
- `PartnersScreen`(`partners_screen.dart`)
|
||||
- `StockInListScreen`(`stock_in_list_screen.dart`)
|
||||
|
||||
**复现步骤**:
|
||||
1. 打开包含 `DataTableCard` 的任意页面(商品、往来单位、入库单等)
|
||||
2. 由于 `SingleChildScrollView` 提供无界宽度,toolbar 中的 `Spacer` 无法展开
|
||||
3. Flutter 抛出断言错误,页面渲染失败(测试中表现为所有 Widget 测试失败)
|
||||
|
||||
**失败的测试用例**:
|
||||
所有 `products_screen_test.dart`、`partners_screen_test.dart`、`stock_in_screen_test.dart` 中的
|
||||
测试均失败,错误来自 `data_table_card.dart:35` 的布局计算。
|
||||
|
||||
**根因分析**:
|
||||
`client/lib/widgets/data_table_card.dart` 第 33-46 行:
|
||||
```dart
|
||||
SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
child: Row(
|
||||
children: [
|
||||
ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
minWidth: (MediaQuery.of(context).size.width - 212 - 24).clamp(0.0, double.infinity),
|
||||
),
|
||||
child: toolbar!, // toolbar 中含有 Spacer,而父容器宽度无界
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
```
|
||||
|
||||
`ConstrainedBox` 设置了 `minWidth`,但 `SingleChildScrollView` 为子组件提供的是
|
||||
`BoxConstraints(minWidth, Infinity)` — 最大宽度无界。`Spacer` 尝试填充剩余空间
|
||||
(即无限空间),触发 Flutter 的约束断言。
|
||||
|
||||
**修复建议**:
|
||||
方案 A:将 `ConstrainedBox` 改为固定宽度的 `SizedBox`,让 toolbar 占满 `minWidth`,
|
||||
并把 toolbar 的 `Spacer` 替换为 `MainAxisAlignment.spaceBetween` 或
|
||||
`SizedBox(width: X)` 固定间距:
|
||||
|
||||
```dart
|
||||
// data_table_card.dart - 去掉 SingleChildScrollView 横向滚动,
|
||||
// 改用固定宽度容器,或让 toolbar Row 使用 mainAxisSize: MainAxisSize.min
|
||||
SizedBox(
|
||||
width: (MediaQuery.of(context).size.width - 212 - 24).clamp(0.0, double.infinity),
|
||||
child: toolbar!,
|
||||
)
|
||||
```
|
||||
|
||||
方案 B:在各 Screen 的 toolbar Row 中将 `Spacer()` 替换为 `SizedBox(width: 8)`,
|
||||
并在 `DataTableCard` 中改用非横向滚动的固定宽度容器。
|
||||
Reference in New Issue
Block a user