Files
jiu/docs/review/flutter-layout-bugs.md
wangjia 66e54af8c6 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>
2026-04-10 22:26:42 +08:00

69 lines
2.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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` 中改用非横向滚动的固定宽度容器。