diff --git a/client/lib/providers/stock_in_provider.dart b/client/lib/providers/stock_in_provider.dart index 27378d5..31a3992 100644 --- a/client/lib/providers/stock_in_provider.dart +++ b/client/lib/providers/stock_in_provider.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../core/api/api_client.dart'; import '../core/auth/auth_state.dart'; @@ -25,9 +27,11 @@ class StockInListNotifier extends AsyncNotifier> { String? _endDate; String _keyword = ''; PageResult? _cache; + Timer? _searchDebounce; @override Future> build() async { + ref.onDispose(() => _searchDebounce?.cancel()); ref.watch(authStateProvider.select((s) => s.user?.shopId)); ref.watch(networkRecoveryCountProvider); try { @@ -78,10 +82,17 @@ class StockInListNotifier extends AsyncNotifier> { reload(); } + /// 关键词搜索(含酒名模糊反查,单次约 55ms 的明细扫描)。 + /// 去重 + 防抖限流:同词不重查;连发回车/狂点合并取最后一次,避免昂贵查询被刷。 void setKeyword(String keyword) { - _keyword = keyword; - _page = 1; - reload(); + final kw = keyword.trim(); + if (kw == _keyword) return; + _searchDebounce?.cancel(); + _searchDebounce = Timer(const Duration(milliseconds: 350), () { + _keyword = kw; + _page = 1; + reload(); + }); } void reload() { diff --git a/client/lib/providers/stock_out_provider.dart b/client/lib/providers/stock_out_provider.dart index 8379beb..1c21a2b 100644 --- a/client/lib/providers/stock_out_provider.dart +++ b/client/lib/providers/stock_out_provider.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../core/api/api_client.dart'; import '../core/auth/auth_state.dart'; @@ -26,9 +28,11 @@ class StockOutListNotifier extends AsyncNotifier> { String _keyword = ''; String _productCode = ''; PageResult? _cache; + Timer? _searchDebounce; @override Future> build() async { + ref.onDispose(() => _searchDebounce?.cancel()); ref.watch(authStateProvider.select((s) => s.user?.shopId)); ref.watch(networkRecoveryCountProvider); try { @@ -80,10 +84,17 @@ class StockOutListNotifier extends AsyncNotifier> { reload(); } + /// 关键词搜索(含酒名模糊反查,单次约 55ms 的明细扫描)。 + /// 去重 + 防抖限流:同词不重查;连发回车/狂点合并取最后一次,避免昂贵查询被刷。 void setKeyword(String keyword) { - _keyword = keyword; - _page = 1; - reload(); + final kw = keyword.trim(); + if (kw == _keyword) return; + _searchDebounce?.cancel(); + _searchDebounce = Timer(const Duration(milliseconds: 350), () { + _keyword = kw; + _page = 1; + reload(); + }); } /// 按商品编码精确反查(独立于 keyword) diff --git a/client/lib/screens/stock_in/stock_in_list_screen.dart b/client/lib/screens/stock_in/stock_in_list_screen.dart index 2b27f1e..103f68b 100644 --- a/client/lib/screens/stock_in/stock_in_list_screen.dart +++ b/client/lib/screens/stock_in/stock_in_list_screen.dart @@ -366,7 +366,7 @@ class _StockInListScreenState extends ConsumerState { final searchField = TextField( controller: _searchCtrl, decoration: InputDecoration( - hintText: '单号/往来单位,回车搜索', + hintText: '单号/往来单位/酒名,回车搜索', prefixIcon: const Icon(Icons.search, size: 16), hintStyle: const TextStyle(fontSize: 12), suffixIcon: IconButton( diff --git a/client/lib/screens/stock_out/stock_out_list_screen.dart b/client/lib/screens/stock_out/stock_out_list_screen.dart index 38ae326..7f619b9 100644 --- a/client/lib/screens/stock_out/stock_out_list_screen.dart +++ b/client/lib/screens/stock_out/stock_out_list_screen.dart @@ -378,7 +378,7 @@ class _StockOutListScreenState extends ConsumerState { final searchField = TextField( controller: _searchCtrl, decoration: InputDecoration( - hintText: '单号/往来单位,回车搜索', + hintText: '单号/往来单位/酒名,回车搜索', prefixIcon: const Icon(Icons.search, size: 16), hintStyle: const TextStyle(fontSize: 12), suffixIcon: IconButton(