feat(client): 出入库列表按原型重建(KPI/详情抽屉/详细搜索/工具栏/选中复制/窗口尺寸)

- 列表重建:KPI 卡、状态+时间列、操作改眼睛开右侧详情抽屉、重置右置
- 详情抽屉(order_detail_drawer) 100% 还原原型 + SelectionArea 可选中复制
- 详细搜索弹窗:ComboSearchField/滚轮日期、字段重构、白底盒子按钮
- 工具栏:搜索框×清除+占位精简、供应商/客户下拉取全部、状态菜单收窄
- 加载不白屏(半透明遮罩)、输入框与下拉等高、windows/macOS 默认窗口尺寸调大

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-07-02 08:48:01 +08:00
parent 998bbab546
commit a3a722689e
42 changed files with 3689 additions and 1961 deletions
+28 -1
View File
@@ -6,6 +6,7 @@ import '../core/auth/auth_state.dart';
import '../core/config/app_constants.dart';
import '../core/models/page_result.dart';
import '../models/stock_out.dart';
import '../models/stock_summary.dart';
import '../repositories/stock_out_repository.dart';
import 'connectivity_provider.dart';
import 'inventory_provider.dart';
@@ -19,6 +20,13 @@ final stockOutListProvider =
StockOutListNotifier.new,
);
/// 出库 KPI 汇总(换店/网络恢复自动刷新)。
final stockOutSummaryProvider = FutureProvider.autoDispose<StockSummary>((ref) {
ref.watch(authStateProvider.select((s) => s.user?.shopId));
ref.watch(networkRecoveryCountProvider);
return ref.read(stockOutRepositoryProvider).summary();
});
class StockOutListNotifier extends AsyncNotifier<PageResult<StockOutOrder>> {
int _page = 1;
int _pageSize = AppConstants.defaultPageSize;
@@ -27,6 +35,7 @@ class StockOutListNotifier extends AsyncNotifier<PageResult<StockOutOrder>> {
String? _endDate;
String _keyword = '';
String _productCode = '';
Map<String, String> _detail = const {};
PageResult<StockOutOrder>? _cache;
Timer? _searchDebounce;
@@ -52,6 +61,7 @@ class StockOutListNotifier extends AsyncNotifier<PageResult<StockOutOrder>> {
endDate: _endDate,
keyword: _keyword.isEmpty ? null : _keyword,
productCode: _productCode.isEmpty ? null : _productCode,
detail: _detail.isEmpty ? null : _detail,
page: _page,
pageSize: _pageSize,
);
@@ -106,8 +116,19 @@ class StockOutListNotifier extends AsyncNotifier<PageResult<StockOutOrder>> {
reload();
}
Map<String, String> get currentDetail => _detail;
/// 详细搜索多字段(order_no/partner_id/series/spec/category_id/... → 后端组合 AND)。
void setDetail(Map<String, String> detail) {
_detail = detail;
_page = 1;
reload();
}
void reload() {
state = const AsyncValue.loading();
// 保留上一次数据(isReloading)→ 屏幕可继续渲染旧内容 + 叠加半透明进度,不白屏。
state = const AsyncValue<PageResult<StockOutOrder>>.loading()
.copyWithPrevious(state);
_fetch().then((result) {
_cache = result;
state = AsyncValue.data(result);
@@ -156,4 +177,10 @@ class StockOutListNotifier extends AsyncNotifier<PageResult<StockOutOrder>> {
reload();
ref.invalidate(inventoryListProvider);
}
/// 确认售价(先出后定价):items 为 [{item_id, sale_price}]。
Future<void> confirmSale(int id, List<Map<String, dynamic>> items) async {
await ref.read(stockOutRepositoryProvider).confirmSale(id, items);
reload();
}
}