chore: 补提测试修复、新增测试工具和设计文档
- fix(test): 同步 listInventory 签名(补 series/spec 参数) - test(backend): 新增 import_parse_test.go - chore(backend): 新增 cmd/test_xls 调试工具 - docs: UI 筛选组件设计规范、Gemini 项目配置 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
# 库存查询「规格」「系列」列头筛选 — UI 变更规范
|
||||
|
||||
**变更类型**:简单变更,flutter-coder 可直接实现
|
||||
**对应文件**:`client/lib/screens/inventory/inventory_list_screen.dart`
|
||||
|
||||
---
|
||||
|
||||
## 复杂度判断
|
||||
|
||||
复用现有 `FilterableColumnHeader` 组件,实现方式与已有「仓库」列筛选完全一致,无新组件、无新页面、无复杂交互,属于简单变更。
|
||||
|
||||
---
|
||||
|
||||
## 变更详情
|
||||
|
||||
### [UI-001] 新增 State 变量
|
||||
|
||||
**位置**:`_InventoryListScreenState` 类顶部,紧跟 `_filterWarehouse` 声明之后
|
||||
|
||||
```dart
|
||||
Set<String> _filterWarehouse = {};
|
||||
Set<String> _filterSpec = {}; // 新增:规格筛选
|
||||
Set<String> _filterSeries = {}; // 新增:系列筛选
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### [UI-002] 派生筛选选项
|
||||
|
||||
**位置**:`_buildInventoryTab()` 方法内,`data:` 回调中,紧跟 `warehouseOptions` 和 `filteredItems` 的现有代码之后替换
|
||||
|
||||
**现有代码段(第 368-379 行):**
|
||||
|
||||
```dart
|
||||
final warehouseOptions = items
|
||||
.map((i) => i.warehouseName)
|
||||
.where((s) => s.isNotEmpty)
|
||||
.toSet()
|
||||
.toList()
|
||||
..sort();
|
||||
final filteredItems = _filterWarehouse.isEmpty
|
||||
? items
|
||||
: items
|
||||
.where((i) => _filterWarehouse.contains(i.warehouseName))
|
||||
.toList();
|
||||
```
|
||||
|
||||
**替换为:**
|
||||
|
||||
```dart
|
||||
final warehouseOptions = items
|
||||
.map((i) => i.warehouseName)
|
||||
.where((s) => s.isNotEmpty)
|
||||
.toSet()
|
||||
.toList()
|
||||
..sort();
|
||||
|
||||
final specOptions = items // 新增:规格选项
|
||||
.map((i) => i.spec)
|
||||
.where((s) => s.isNotEmpty)
|
||||
.toSet()
|
||||
.toList()
|
||||
..sort();
|
||||
|
||||
final seriesOptions = items // 新增:系列选项
|
||||
.map((i) => i.series)
|
||||
.where((s) => s.isNotEmpty)
|
||||
.toSet()
|
||||
.toList()
|
||||
..sort();
|
||||
|
||||
// 三个筛选叠加(AND 逻辑)
|
||||
final filteredItems = items.where((i) {
|
||||
if (_filterWarehouse.isNotEmpty && !_filterWarehouse.contains(i.warehouseName)) {
|
||||
return false;
|
||||
}
|
||||
if (_filterSpec.isNotEmpty && !_filterSpec.contains(i.spec)) {
|
||||
return false;
|
||||
}
|
||||
if (_filterSeries.isNotEmpty && !_filterSeries.contains(i.series)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}).toList();
|
||||
```
|
||||
|
||||
**说明:**
|
||||
- 选项数据从当前页已加载的 `items` 派生,客户端筛选,与「仓库」逻辑一致
|
||||
- 三个筛选条件为 AND 叠加(同时满足才显示)
|
||||
- 空集合(`isEmpty`)视为「不筛选该维度」,等同于全选
|
||||
|
||||
---
|
||||
|
||||
### [UI-003] 替换「规格」和「系列」列头
|
||||
|
||||
**位置**:`columns:` 列表中第 491-494 行(当前为 `const DataColumn`)
|
||||
|
||||
**现有代码:**
|
||||
|
||||
```dart
|
||||
const DataColumn(label: Text('规格')),
|
||||
const DataColumn(label: Text('系列')),
|
||||
```
|
||||
|
||||
**替换为:**
|
||||
|
||||
```dart
|
||||
DataColumn(
|
||||
label: FilterableColumnHeader(
|
||||
text: '规格',
|
||||
options: specOptions,
|
||||
selected: _filterSpec,
|
||||
onChanged: (v) => setState(() => _filterSpec = v),
|
||||
),
|
||||
),
|
||||
DataColumn(
|
||||
label: FilterableColumnHeader(
|
||||
text: '系列',
|
||||
options: seriesOptions,
|
||||
selected: _filterSeries,
|
||||
onChanged: (v) => setState(() => _filterSeries = v),
|
||||
),
|
||||
),
|
||||
```
|
||||
|
||||
**注意**:移除原来的 `const` 关键字,因为构造函数参数不再是编译期常量。
|
||||
|
||||
---
|
||||
|
||||
## 视觉规范(无需改动)
|
||||
|
||||
`FilterableColumnHeader` 的所有视觉行为保持原样:
|
||||
|
||||
| 状态 | 表现 |
|
||||
|------|------|
|
||||
| 默认(无筛选) | 纯文字列头,无图标 |
|
||||
| Hover | 显示半透明 `filter_alt_outlined` 图标(灰色)|
|
||||
| 已激活筛选 | 图标变为实心 `filter_alt`(主色 #1565C0)+ 右侧出现 X 清除按钮 |
|
||||
| X 按钮点击 | 清空该维度筛选(`onChanged({})` ),无需打开弹窗 |
|
||||
| 列头点击图标 | 弹出 `_MultiSelectDialog`(全选/清空 + checkbox 列表 + 取消/应用) |
|
||||
|
||||
---
|
||||
|
||||
## 受影响范围
|
||||
|
||||
- 仅修改 `_InventoryListScreenState` 内部,不涉及 provider、model、API
|
||||
- `_buildWarningTab()` 和 `_buildLogTab()` 不受影响
|
||||
- 导出 Excel 的 `filteredItems` 自动受益于新筛选逻辑,无需额外改动
|
||||
- 窄屏卡片流(`mobileCards`)同样使用 `filteredItems`,筛选效果自动生效
|
||||
Reference in New Issue
Block a user