feat(client): 出入库列表窄屏对齐移动原型(KPI 筛选/搜索行/状态与详搜 sheet/图标徽章)
- 窄屏隐藏页内大标题头与新增/导出/打印入口(移动端无建单与打印——拍板) - KPI 改 MKpiGrid 2×2:待审核/草稿卡可点切换状态筛选(再点取消,selected 联动) - 工具栏改 MSearchRow:搜索(provider 内置防抖)+ 纯文字状态钮 + 图标详搜钮 - 状态筛选/详细搜索改 showMSheet 底部 sheet(详搜字段与桌面完全同集,重置/应用在 actions) - 卡片流徽章换图标变体(含派生态待定价/部分退单/已退单)+ › 箭头,行内操作收进详情 sheet - 确认进价/确认售价窄屏走 showMSheet;窄屏详情操作组不出打印 - 新增 390×844 三主题 golden(m_stock_in_list/m_stock_out_list);重生成既有 390×1300 移动 golden 基准(桌面 golden 零漂移) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
After Width: | Height: | Size: 149 KiB |
|
After Width: | Height: | Size: 148 KiB |
|
After Width: | Height: | Size: 150 KiB |
|
After Width: | Height: | Size: 139 KiB |
|
After Width: | Height: | Size: 138 KiB |
|
After Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 177 KiB After Width: | Height: | Size: 194 KiB |
|
Before Width: | Height: | Size: 178 KiB After Width: | Height: | Size: 195 KiB |
|
Before Width: | Height: | Size: 180 KiB After Width: | Height: | Size: 196 KiB |
|
Before Width: | Height: | Size: 170 KiB After Width: | Height: | Size: 157 KiB |
|
Before Width: | Height: | Size: 170 KiB After Width: | Height: | Size: 158 KiB |
|
Before Width: | Height: | Size: 172 KiB After Width: | Height: | Size: 159 KiB |
@@ -0,0 +1,115 @@
|
||||
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';
|
||||
import 'package:jiu_client/core/auth/auth_state.dart';
|
||||
import 'package:jiu_client/models/stock_in.dart';
|
||||
import 'package:jiu_client/models/stock_summary.dart';
|
||||
import 'package:jiu_client/providers/stock_in_provider.dart';
|
||||
import 'package:jiu_client/screens/stock_in/stock_in_list_screen.dart';
|
||||
|
||||
import '../support/golden_harness.dart';
|
||||
|
||||
/// P1 单据域:入库列表窄屏 golden × 三主题(390×844 @2x)——对齐移动原型
|
||||
/// m-stock-in-list.html:KPI 2×2(待审核/草稿可点筛选)+ MSearchRow(搜索 +
|
||||
/// 状态钮 + 详搜钮)+ .m-section + 卡片流(图标徽章含派生态 + › 箭头)。
|
||||
/// 更新基准:flutter test --update-goldens test/golden/stock_in_list_mobile_golden_test.dart
|
||||
|
||||
const _orders = [
|
||||
// 已审核 + 部分退单 + 待定价(三徽章派生态齐全)
|
||||
StockInOrder(
|
||||
id: 1,
|
||||
orderNo: 'RK-20260620-014',
|
||||
warehouseId: 1,
|
||||
warehouseName: '主仓',
|
||||
partnerName: '贵州茅台经销',
|
||||
operatorName: '王经理',
|
||||
reviewerName: '张管理',
|
||||
status: 'approved',
|
||||
returnState: 'partial',
|
||||
orderDate: '2026-06-20',
|
||||
costTotal: 34320,
|
||||
items: [
|
||||
StockInItem(productId: 1, quantity: 6, costPrice: 0, costAmount: 0),
|
||||
StockInItem(
|
||||
productId: 2, quantity: 6, costPrice: 2680, costAmount: 16080),
|
||||
]),
|
||||
StockInOrder(
|
||||
id: 2,
|
||||
orderNo: 'RK-20260618-009',
|
||||
warehouseId: 1,
|
||||
warehouseName: '主仓',
|
||||
partnerName: '宜宾五粮液',
|
||||
operatorName: '李销售',
|
||||
status: 'pending',
|
||||
orderDate: '2026-06-18',
|
||||
costTotal: 6700),
|
||||
StockInOrder(
|
||||
id: 3,
|
||||
orderNo: 'RK-20260615-003',
|
||||
warehouseId: 1,
|
||||
warehouseName: '二号仓',
|
||||
partnerName: '泸州老窖',
|
||||
operatorName: '王经理',
|
||||
status: 'draft',
|
||||
orderDate: '2026-06-15',
|
||||
costTotal: 5000),
|
||||
StockInOrder(
|
||||
id: 4,
|
||||
orderNo: 'RK-20260612-001',
|
||||
warehouseId: 1,
|
||||
warehouseName: '主仓',
|
||||
partnerName: '绵竹剑南春',
|
||||
operatorName: '李销售',
|
||||
reviewerName: '张管理',
|
||||
status: 'rejected',
|
||||
orderDate: '2026-06-12',
|
||||
costTotal: 3500),
|
||||
];
|
||||
|
||||
class _FakeStockInNotifier extends StockInListNotifier {
|
||||
@override
|
||||
Future<PageResult<StockInOrder>> build() async =>
|
||||
const PageResult(data: _orders, total: 4, page: 1, pageSize: 20);
|
||||
@override
|
||||
void setPage(int page) {}
|
||||
@override
|
||||
void setPageSize(int pageSize) {}
|
||||
@override
|
||||
void setStatus(String status) {}
|
||||
@override
|
||||
void setDateRange(String? startDate, String? endDate) {}
|
||||
@override
|
||||
void setKeyword(String keyword) {}
|
||||
@override
|
||||
void reload() {}
|
||||
}
|
||||
|
||||
List<Override> _overrides() => [
|
||||
stockInListProvider.overrideWith(() => _FakeStockInNotifier()),
|
||||
isReadonlyProvider.overrideWithValue(false),
|
||||
// KPI 2×2(近30天笔数/金额/待审核/草稿):对齐原型示例数值。
|
||||
stockInSummary30Provider.overrideWith((ref) => const StockSummary(
|
||||
monthCount: 28,
|
||||
monthAmount: 1860000,
|
||||
pendingCount: 4,
|
||||
draftCount: 2,
|
||||
lastMonthCount: 25,
|
||||
lastMonthAmount: 1715000,
|
||||
)),
|
||||
];
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
SharedPreferences.setMockInitialValues({});
|
||||
|
||||
goldenAcrossThemes(
|
||||
'stock-in list 窄屏(移动原型)',
|
||||
goldenPrefix: 'm_stock_in_list',
|
||||
child: () => const Scaffold(body: StockInListScreen()),
|
||||
overrides: _overrides,
|
||||
logical: const Size(390, 844),
|
||||
dpr: 2,
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
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';
|
||||
import 'package:jiu_client/core/auth/auth_state.dart';
|
||||
import 'package:jiu_client/models/stock_out.dart';
|
||||
import 'package:jiu_client/models/stock_summary.dart';
|
||||
import 'package:jiu_client/providers/stock_out_provider.dart';
|
||||
import 'package:jiu_client/screens/stock_out/stock_out_list_screen.dart';
|
||||
|
||||
import '../support/golden_harness.dart';
|
||||
|
||||
/// P1 单据域:出库列表窄屏 golden × 三主题(390×844 @2x)——对齐移动原型
|
||||
/// m-stock-out-list.html:KPI 2×2(待审核/草稿可点筛选)+ MSearchRow(搜索 +
|
||||
/// 状态钮 + 详搜钮)+ .m-section + 卡片流(图标徽章含派生态 + › 箭头)。
|
||||
/// 更新基准:flutter test --update-goldens test/golden/stock_out_list_mobile_golden_test.dart
|
||||
|
||||
const _orders = [
|
||||
// 已审核 + 部分退单(图标徽章派生态)
|
||||
StockOutOrder(
|
||||
id: 1,
|
||||
orderNo: 'CK-20260620-031',
|
||||
warehouseId: 1,
|
||||
warehouseName: '主仓',
|
||||
partnerName: '鼎丰超市',
|
||||
operatorName: '李销售',
|
||||
reviewerName: '张管理',
|
||||
status: 'approved',
|
||||
returnState: 'partial',
|
||||
orderDate: '2026-06-20',
|
||||
saleTotal: 12800,
|
||||
items: [
|
||||
StockOutItem(
|
||||
productId: 1,
|
||||
quantity: 4,
|
||||
salePrice: 3200,
|
||||
saleAmount: 12800,
|
||||
costPrice: 2680,
|
||||
costAmount: 10720),
|
||||
]),
|
||||
// 已审核 + 待定价(先卖后定价)
|
||||
StockOutOrder(
|
||||
id: 2,
|
||||
orderNo: 'CK-20260619-026',
|
||||
warehouseId: 1,
|
||||
warehouseName: '名酒仓',
|
||||
partnerName: '金樽会所',
|
||||
operatorName: '王经理',
|
||||
reviewerName: '张管理',
|
||||
status: 'approved',
|
||||
orderDate: '2026-06-19',
|
||||
saleTotal: 28000,
|
||||
items: [
|
||||
StockOutItem(productId: 2, quantity: 13, salePrice: 0, saleAmount: 0),
|
||||
]),
|
||||
StockOutOrder(
|
||||
id: 3,
|
||||
orderNo: 'CK-20260618-022',
|
||||
warehouseId: 1,
|
||||
warehouseName: '主仓',
|
||||
partnerName: '金樽酒楼',
|
||||
operatorName: '张前台',
|
||||
status: 'pending',
|
||||
orderDate: '2026-06-18',
|
||||
saleTotal: 5400),
|
||||
StockOutOrder(
|
||||
id: 4,
|
||||
orderNo: 'CK-20260615-017',
|
||||
warehouseId: 1,
|
||||
warehouseName: '二号仓',
|
||||
partnerName: '恒昌名酒行',
|
||||
operatorName: '李销售',
|
||||
status: 'draft',
|
||||
orderDate: '2026-06-15',
|
||||
saleTotal: 3200),
|
||||
];
|
||||
|
||||
class _FakeStockOutNotifier extends StockOutListNotifier {
|
||||
@override
|
||||
Future<PageResult<StockOutOrder>> build() async =>
|
||||
const PageResult(data: _orders, total: 4, page: 1, pageSize: 20);
|
||||
@override
|
||||
void setPage(int page) {}
|
||||
@override
|
||||
void setPageSize(int pageSize) {}
|
||||
@override
|
||||
void setStatus(String status) {}
|
||||
@override
|
||||
void setDateRange(String? startDate, String? endDate) {}
|
||||
@override
|
||||
void setKeyword(String keyword) {}
|
||||
@override
|
||||
void setProductCode(String code) {}
|
||||
@override
|
||||
void reload() {}
|
||||
}
|
||||
|
||||
List<Override> _overrides() => [
|
||||
stockOutListProvider.overrideWith(() => _FakeStockOutNotifier()),
|
||||
isReadonlyProvider.overrideWithValue(false),
|
||||
// KPI 2×2(近30天笔数/金额/待审核/草稿):对齐原型示例数值。
|
||||
stockOutSummary30Provider.overrideWith((ref) => const StockSummary(
|
||||
monthCount: 35,
|
||||
monthAmount: 2160000,
|
||||
pendingCount: 3,
|
||||
draftCount: 1,
|
||||
lastMonthCount: 32,
|
||||
lastMonthAmount: 2022000,
|
||||
)),
|
||||
];
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
SharedPreferences.setMockInitialValues({});
|
||||
|
||||
goldenAcrossThemes(
|
||||
'stock-out list 窄屏(移动原型)',
|
||||
goldenPrefix: 'm_stock_out_list',
|
||||
child: () => const Scaffold(body: StockOutListScreen()),
|
||||
overrides: _overrides,
|
||||
logical: const Size(390, 844),
|
||||
dpr: 2,
|
||||
);
|
||||
}
|
||||