From 102ace42acc518b3cfaa8a8639c6d2c147cca6be Mon Sep 17 00:00:00 2001 From: wangjia <809946525@qq.com> Date: Tue, 23 Jun 2026 23:57:28 +0800 Subject: [PATCH] =?UTF-8?q?feat(client):=20=E5=85=A5=E5=BA=93/=E5=87=BA?= =?UTF-8?q?=E5=BA=93=E6=90=9C=E7=B4=A2=E6=A1=86=E6=94=AF=E6=8C=81=E9=85=92?= =?UTF-8?q?=E5=90=8D=EF=BC=8C=E5=B9=B6=E5=AF=B9=E6=90=9C=E7=B4=A2=E9=99=90?= =?UTF-8?q?=E6=B5=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 搜索框 hint 改为「单号/往来单位/酒名」 - setKeyword 加去重+350ms 防抖:同词不重查、连发回车/狂点合并取最后一次, 避免酒名模糊查询(单次约 55ms 明细扫描)被刷 - Timer 在 provider dispose 时取消 Co-Authored-By: Claude Opus 4.8 --- client/lib/providers/stock_in_provider.dart | 17 ++++++++++++++--- client/lib/providers/stock_out_provider.dart | 17 ++++++++++++++--- .../screens/stock_in/stock_in_list_screen.dart | 2 +- .../stock_out/stock_out_list_screen.dart | 2 +- 4 files changed, 30 insertions(+), 8 deletions(-) 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(