diff --git a/client/lib/screens/inventory/inventory_list_screen.dart b/client/lib/screens/inventory/inventory_list_screen.dart index 7332a07..952e6af 100644 --- a/client/lib/screens/inventory/inventory_list_screen.dart +++ b/client/lib/screens/inventory/inventory_list_screen.dart @@ -4,6 +4,7 @@ import 'package:file_picker/file_picker.dart'; 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 '../../core/config/app_config.dart'; import '../../core/config/app_constants.dart'; import '../../core/responsive/responsive.dart'; @@ -528,6 +529,18 @@ class _InventoryListScreenState extends ConsumerState { return Column( children: [ + // 副标(还原原型 .head .sub):商品总数 + 实时提示 + Container( + width: double.infinity, + color: context.tokens.bg, + padding: const EdgeInsets.fromLTRB( + AppDims.sp3, AppDims.sp3, AppDims.sp3, 0), + child: Text( + '共 ${NumberFormat.decimalPattern().format(result.total)} 个商品 · 数据实时', + style: + TextStyle(fontSize: AppDims.fsSm, color: context.tokens.muted), + ), + ), // KPI 卡(还原原型 .kpi):宽屏 4 等分,窄屏横向滚动 Builder(builder: (context) { final inStockQty = @@ -659,7 +672,7 @@ class _InventoryListScreenState extends ConsumerState { mainAxisSize: MainAxisSize.min, children: [ searchField, - const SizedBox(height: 8), + const SizedBox(height: AppDims.sp2), Row( children: [ if (canCheck) @@ -716,11 +729,11 @@ class _InventoryListScreenState extends ConsumerState { ); } - // 桌面:搜索置于最前,按钮成组靠左 + // 桌面:搜索置于最前(原型 searchbox 240),按钮成组靠左 return Row( children: [ - SizedBox(width: 220, child: searchField), - const SizedBox(width: 12), + SizedBox(width: 240, child: searchField), + const SizedBox(width: AppDims.sp3), if (canCheck) ...[ WriteGuard( child: OutlinedButton.icon( @@ -729,14 +742,14 @@ class _InventoryListScreenState extends ConsumerState { label: const Text('发起盘点'), ), ), - const SizedBox(width: 8), + const SizedBox(width: AppDims.sp2), ], OutlinedButton.icon( onPressed: doExport, icon: const Icon(Icons.download, size: 16), label: const Text('导出'), ), - const SizedBox(width: 8), + const SizedBox(width: AppDims.sp2), ColumnToggleButton( columns: _colDefs, hidden: hidden, @@ -745,7 +758,7 @@ class _InventoryListScreenState extends ConsumerState { ColumnPrefs.save(_screenId, v); }, ), - const SizedBox(width: 8), + const SizedBox(width: AppDims.sp2), OutlinedButton.icon( onPressed: () => ref.read(inventoryListProvider.notifier).reload(), diff --git a/client/lib/widgets/data_table_card.dart b/client/lib/widgets/data_table_card.dart index 31f93b5..828c077 100644 --- a/client/lib/widgets/data_table_card.dart +++ b/client/lib/widgets/data_table_card.dart @@ -83,6 +83,8 @@ class _DataTableCardState extends State { pageSize: widget.pageSize, onPageChanged: widget.onPageChanged, onPageSizeChanged: widget.onPageSizeChanged, + // 窄屏隐藏「每页 N 条」选择器,给翻页让位,避免横向溢出 + compact: context.isMobile, ), ], ), @@ -207,6 +209,7 @@ class _PaginationBar extends StatelessWidget { final int pageSize; final ValueChanged? onPageChanged; final ValueChanged? onPageSizeChanged; + final bool compact; static const _pageSizeOptions = [10, 20, 50, 100]; @@ -216,6 +219,7 @@ class _PaginationBar extends StatelessWidget { required this.pageSize, this.onPageChanged, this.onPageSizeChanged, + this.compact = false, }); @override @@ -225,8 +229,8 @@ class _PaginationBar extends StatelessWidget { final effectiveSize = _pageSizeOptions.contains(pageSize) ? pageSize : _pageSizeOptions.first; return Row( children: [ - // 每页条数选择器 - if (onPageSizeChanged != null) ...[ + // 每页条数选择器(窄屏隐藏,避免溢出) + if (onPageSizeChanged != null && !compact) ...[ Text('每页', style: TextStyle(fontSize: 13, color: context.tokens.muted)), const SizedBox(width: 4), DropdownButtonHideUnderline( diff --git a/client/test/golden/goldens/inventory_list_a.png b/client/test/golden/goldens/inventory_list_a.png index f1c0ec1..14fbc34 100644 Binary files a/client/test/golden/goldens/inventory_list_a.png and b/client/test/golden/goldens/inventory_list_a.png differ diff --git a/client/test/golden/goldens/inventory_list_b.png b/client/test/golden/goldens/inventory_list_b.png index 841a781..0ad4a33 100644 Binary files a/client/test/golden/goldens/inventory_list_b.png and b/client/test/golden/goldens/inventory_list_b.png differ diff --git a/client/test/golden/goldens/inventory_list_c.png b/client/test/golden/goldens/inventory_list_c.png index 71fd5ed..5eebb11 100644 Binary files a/client/test/golden/goldens/inventory_list_c.png and b/client/test/golden/goldens/inventory_list_c.png differ diff --git a/client/test/golden/goldens/inventory_list_mobile_a.png b/client/test/golden/goldens/inventory_list_mobile_a.png new file mode 100644 index 0000000..51a7b44 Binary files /dev/null and b/client/test/golden/goldens/inventory_list_mobile_a.png differ diff --git a/client/test/golden/goldens/inventory_list_mobile_b.png b/client/test/golden/goldens/inventory_list_mobile_b.png new file mode 100644 index 0000000..f3af24f Binary files /dev/null and b/client/test/golden/goldens/inventory_list_mobile_b.png differ diff --git a/client/test/golden/goldens/inventory_list_mobile_c.png b/client/test/golden/goldens/inventory_list_mobile_c.png new file mode 100644 index 0000000..8922ff3 Binary files /dev/null and b/client/test/golden/goldens/inventory_list_mobile_c.png differ diff --git a/client/test/golden/inventory_list_golden_test.dart b/client/test/golden/inventory_list_golden_test.dart index 29d5f49..907e8d5 100644 --- a/client/test/golden/inventory_list_golden_test.dart +++ b/client/test/golden/inventory_list_golden_test.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:jiu_client/core/models/page_result.dart'; @@ -70,20 +71,32 @@ class _FakeSpecNotifier extends ProductSpecListNotifier { Future> build() async => const []; } -void main() { - TestWidgetsFlutterBinding.ensureInitialized(); - SharedPreferences.setMockInitialValues({}); - - goldenAcrossThemes( - 'inventory list 整屏', - goldenPrefix: 'inventory_list', - child: () => const Scaffold(body: InventoryListScreen()), - overrides: () => [ +List _overrides() => [ inventoryListProvider.overrideWith(() => _FakeInvNotifier()), productSeriesListProvider.overrideWith(() => _FakeSeriesNotifier()), productSpecListProvider.overrideWith(() => _FakeSpecNotifier()), isReadonlyProvider.overrideWithValue(false), - ], + ]; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + SharedPreferences.setMockInitialValues({}); + + // 桌面:宽屏表格路径 + goldenAcrossThemes( + 'inventory list 整屏(桌面)', + goldenPrefix: 'inventory_list', + child: () => const Scaffold(body: InventoryListScreen()), + overrides: _overrides, logical: const Size(1280, 900), ); + + // 移动:窄屏(<600)→ context.isMobile → MobileListCard 卡片流路径 + goldenAcrossThemes( + 'inventory list 整屏(移动)', + goldenPrefix: 'inventory_list_mobile', + child: () => const Scaffold(body: InventoryListScreen()), + overrides: _overrides, + logical: const Size(390, 1400), + ); }