feat(client): 库存筛选全部上移工具栏(参照出库管理),列头漏斗退役

- 工具栏:搜索 + 规格/系列/仓库 多选 chip(值/N 项 摘要 + × 单清)+ 状态
  单选 chip + 重置;列头只留 5 列排序箭头
- 原型 inventory.html 同步:toolbar 三 chip + openDimFilter、COLS 状态去
  filter、clearFilters/chip 值渲染跟进
- 桌面库存 golden 重录 ×3

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JJ1g8XV1YhhmHRzhwWEW7o
This commit is contained in:
wangjia
2026-07-07 17:01:54 +08:00
parent c7f36b2d72
commit e0d9b8ab09
5 changed files with 62 additions and 45 deletions
@@ -206,7 +206,25 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
if (v != null && mounted) _applyStatusFilter(v);
}
// ── 多选漏斗(规格/系列/仓库 ──
// ── 工具栏多选 chip(规格/系列/仓库,2026-07-07 从列头漏斗上移 ──
Widget _multiChip(String label, List<String> options, Set<String> selected,
ValueChanged<Set<String>> onChanged) {
return Builder(
builder: (chipCtx) => DsChip(
label: label,
value: selected.isEmpty
? null
: selected.length == 1
? selected.first
: '${selected.length}',
onTap: () => _openMultiFilter(chipCtx,
options: options, selected: selected, onChanged: onChanged),
onClear: () => onChanged({}),
),
);
}
// ── 多选菜单(规格/系列/仓库,chip 锚定) ──
void _openMultiFilter(
BuildContext anchorContext, {
required List<String> options,
@@ -908,11 +926,40 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
);
}
// 桌面 toolbar合一搜索框 + 重置
// 状态筛选 chip 已按用户口径删除,状态列漏斗保留)
// 桌面 toolbar搜索 + 筛选 chips + 重置
// 2026-07-07 用户口径反转:筛选全部上移工具栏,形式
// 参照出库管理;列头只留排序,漏斗退役)
return Row(
children: [
SizedBox(width: 260, child: searchField),
const SizedBox(width: AppDims.sp2),
_multiChip('规格', specOptions, _filterSpec, (v) {
setState(() => _filterSpec = v);
ref
.read(inventoryListProvider.notifier)
.setSpec(v.toList());
}),
const SizedBox(width: AppDims.sp2),
_multiChip('系列', seriesOptions, _filterSeries, (v) {
setState(() => _filterSeries = v);
ref
.read(inventoryListProvider.notifier)
.setSeries(v.toList());
}),
const SizedBox(width: AppDims.sp2),
_multiChip('仓库', warehouseOptions, _filterWarehouse,
(v) => setState(() => _filterWarehouse = v)),
const SizedBox(width: AppDims.sp2),
Builder(
builder: (chipCtx) => DsChip(
label: '状态',
value: _statusFilter == '全部'
? null
: _statusFilter,
onTap: () => _openStatusMenu(chipCtx),
onClear: () => _applyStatusFilter('全部'),
),
),
const Spacer(),
DsButton('重置', small: true, onPressed: _clearFilters),
],
@@ -927,46 +974,8 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
},
emptyText: '没有匹配的商品 · 试试调整筛选或搜索',
columns: visibleCols.map((c) {
// 筛选已全部上移工具栏 chips(2026-07-07),列头只留排序。
final Widget? header = switch (c.key) {
'spec' => DsFilterHeader(
label: c.label,
filtered: _filterSpec.isNotEmpty,
onOpen: (bctx) => _openMultiFilter(bctx,
options: specOptions,
selected: _filterSpec, onChanged: (v) {
setState(() => _filterSpec = v);
ref
.read(inventoryListProvider.notifier)
.setSpec(v.toList());
}),
),
'series' => DsFilterHeader(
label: c.label,
filtered: _filterSeries.isNotEmpty,
onOpen: (bctx) => _openMultiFilter(bctx,
options: seriesOptions,
selected: _filterSeries, onChanged: (v) {
setState(() => _filterSeries = v);
ref
.read(inventoryListProvider.notifier)
.setSeries(v.toList());
}),
),
'warehouse' => DsFilterHeader(
label: c.label,
filtered: _filterWarehouse.isNotEmpty,
onOpen: (bctx) => _openMultiFilter(bctx,
options: warehouseOptions,
selected: _filterWarehouse,
onChanged: (v) =>
setState(() => _filterWarehouse = v)),
),
// 原型 COLS 里带 filter 的列只有状态(单选)。
'status' => DsFilterHeader(
label: c.label,
filtered: _statusFilter != '全部',
onOpen: _openStatusMenu,
),
// 可排序列(原型 COLS sort:true,服务端全局排序)
'qty' ||
'cost' ||
Binary file not shown.

Before

Width:  |  Height:  |  Size: 414 KiB

After

Width:  |  Height:  |  Size: 420 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 409 KiB

After

Width:  |  Height:  |  Size: 414 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 415 KiB

After

Width:  |  Height:  |  Size: 422 KiB