feat(client): 全列表下拉刷新 + 库存移动工具行移除

- DsTable 窄屏卡片流支持 onRefresh(RefreshIndicator,空态也可下拉)——
  等价桌面工具栏「刷新」;库存/入库/出库/往来/财务流水/用户/基础数据
  全 tab 接线(基础数据下拉一并重拉五个 tab 数据源)
- 库存移动端「盘点/表格视图/导出/列设置/刷新」工具行移除(2026-07-04
  拍板:刷新改下拉手势、盘点入口在「我的」、其余桌面专属),
  库存移动 golden 随更新

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-07-04 23:52:06 +08:00
parent 99ceaa87bb
commit c9217601a1
14 changed files with 71 additions and 72 deletions
@@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:intl/intl.dart';
import 'package:lucide_icons_flutter/lucide_icons.dart';
import '../../core/responsive/responsive.dart';
@@ -41,7 +40,6 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
// 库存状态前端筛选(派生自 qty vs 安全库存):全部/在售/预警/缺货
String _statusFilter = '全部';
Set<String>? _hiddenCols; // null = 尚未载入本地存档
bool _mobileTableView = false; // 移动端:false=卡片列表,true=表格(横向滚动)
static const _screenId = 'inventory_list';
static const _statusOptions = ['全部', '在售', '预警', '缺货'];
@@ -812,7 +810,6 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
ref.read(inventoryListProvider.notifier).setPageSize(s),
toolbar: Builder(builder: (ctx) {
final isMobile = ctx.isMobile;
void doExport() => _exportInventory(filteredItems);
// 搜索合一(用户口径):名称/拼音/编码同框,回车触发
// (后端 keyword 本就 LIKE name/code/拼音/首字母)。
@@ -824,11 +821,10 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
.setKeyword(v.trim()),
);
final canCheck = !WriteGuard.isReadonly(ref);
if (isMobile) {
// 移动端:MSearchRow(原型 .m-search + 详搜钮)独占一行
// + 紧凑图标操作行(含 表格/列表 切换)
//(盘点/导出/列设置/刷新工具行 2026-07-04 拍板移除,
// 刷新改下拉手势,盘点入口在「我的」)
return Column(
mainAxisSize: MainAxisSize.min,
children: [
@@ -842,62 +838,6 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
onFilterTap: () => _openMobileFilterSheet(
specOptions, seriesOptions),
),
const SizedBox(height: AppDims.sp2),
Row(
children: [
if (canCheck)
WriteGuard(
child: OutlinedButton.icon(
onPressed: () =>
context.go('/inventory/check'),
icon: const Icon(
LucideIcons.clipboardCheck,
size: 16),
label: const Text('盘点'),
style: OutlinedButton.styleFrom(
padding: const EdgeInsets.symmetric(
horizontal: 10, vertical: 6),
minimumSize: Size.zero,
tapTargetSize:
MaterialTapTargetSize.shrinkWrap,
),
),
),
const Spacer(),
IconButton(
tooltip: _mobileTableView ? '卡片视图' : '表格视图',
icon: Icon(
_mobileTableView
? LucideIcons.layoutList
: LucideIcons.rows3,
size: 20),
onPressed: () => setState(() =>
_mobileTableView = !_mobileTableView),
),
IconButton(
tooltip: '导出',
icon: const Icon(LucideIcons.download,
size: 20),
onPressed: doExport,
),
Builder(
builder: (bctx) => IconButton(
tooltip: '列设置',
icon: const Icon(LucideIcons.alignLeft,
size: 20),
onPressed: () => _openColMenu(bctx),
),
),
IconButton(
tooltip: '刷新',
icon: const Icon(LucideIcons.refreshCw,
size: 20),
onPressed: () => ref
.read(inventoryListProvider.notifier)
.reload(),
),
],
),
],
);
}
@@ -912,9 +852,13 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
],
);
}),
mobileCards: _mobileTableView
? null
: filteredItems.map(_inventoryCard).toList(),
mobileCards: filteredItems.map(_inventoryCard).toList(),
// 下拉刷新 = 桌面「刷新」(reload 保留旧内容叠进度)
onRefresh: () async {
ref.read(inventoryListProvider.notifier).reload();
await Future<void>.delayed(
const Duration(milliseconds: 600));
},
emptyText: '没有匹配的商品 · 试试调整筛选或搜索',
columns: visibleCols.map((c) {
final Widget? header = switch (c.key) {