feat(client): 往来单位屏设计语言重建(副标/状态徽章/两行名称/响应式 toolbar)

- 副标「共 N 个供应商/客户」(还原 .head .sub)
- 状态 → StatusPill(启用绿/停用灰,新 _PartnerStatusPill),桌面+移动一致
- 编码+名称合并两行(name 加粗 + code 等宽 muted)
- toolbar 响应式(窄屏搜索独占一行 + 操作行)+ token 间距,修预存窄屏溢出
- 整屏 golden ×三主题(桌面+移动)入回归闸
暂缓(数据缺口/有意偏差):应收/应付列(Partner 模型无该字段)、
类型 chips(现保留 供应商/客户 两 Tab)。

analyze 0 error · flutter test +181(往来桌面/移动各 3 golden)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TSKEiHsvauyxYUW2itzUXX
This commit is contained in:
wangjia
2026-06-25 13:05:12 +08:00
parent a661afe0d0
commit 07d3559d0a
8 changed files with 190 additions and 57 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

@@ -0,0 +1,96 @@
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/partner.dart';
import 'package:jiu_client/providers/partner_provider.dart';
import 'package:jiu_client/screens/partners/partners_screen.dart';
import '../support/golden_harness.dart';
/// design-distill 阶段4:往来单位整屏 golden × 三主题(桌面 + 移动,回归闸)。
/// 保真目检:shoot partners.html + montage 与 goldens/partners_*.png 并排。
/// 更新基准:flutter test --update-goldens test/golden/partners_golden_test.dart
const _suppliers = [
Partner(
id: 1, code: 'GYS-001', name: '茅台华东总代', type: 'supplier',
contact: '张伟', phone: '138-0011-2233', address: '上海市黄浦区中山东路 8 号',
status: 'enabled'),
Partner(
id: 2, code: 'GYS-002', name: '老窖酒水批发', type: 'supplier',
contact: '李建国', phone: '139-2200-7788', address: '江苏省南京市建邺区江东中路',
status: 'enabled'),
Partner(
id: 3, code: 'GYS-003', name: '五粮液川南运营中心', type: 'supplier',
contact: '刘海涛', phone: '135-8899-0011', address: '四川省宜宾市翠屏区岷江路',
status: 'disabled'),
];
const _customers = [
Partner(
id: 11, code: 'KH-001', name: '鼎丰超市', type: 'customer',
contact: '王芳', phone: '137-6655-4321', address: '浙江省杭州市西湖区文三路',
status: 'enabled'),
Partner(
id: 12, code: 'KH-002', name: '金樽酒楼', type: 'customer',
contact: '陈静', phone: '136-2211-9900', address: '江苏省苏州市姑苏区干将路',
status: 'enabled'),
];
class _FakeSupplierNotifier extends PartnerListNotifier {
@override
Future<PageResult<Partner>> build() async => const PageResult(
data: _suppliers, total: 3, page: 1, pageSize: 20);
@override
void setPage(int page) {}
@override
void setPageSize(int pageSize) {}
@override
void setKeyword(String keyword) {}
@override
void reload() {}
}
class _FakeCustomerNotifier extends PartnerListNotifier {
@override
Future<PageResult<Partner>> build() async => const PageResult(
data: _customers, total: 2, page: 1, pageSize: 20);
@override
void setPage(int page) {}
@override
void setPageSize(int pageSize) {}
@override
void setKeyword(String keyword) {}
@override
void reload() {}
}
List<Override> _overrides() => [
supplierListProvider.overrideWith(() => _FakeSupplierNotifier()),
customerListProvider.overrideWith(() => _FakeCustomerNotifier()),
isReadonlyProvider.overrideWithValue(false),
];
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
SharedPreferences.setMockInitialValues({});
goldenAcrossThemes(
'partners 整屏(桌面)',
goldenPrefix: 'partners',
child: () => const Scaffold(body: PartnersScreen()),
overrides: _overrides,
logical: const Size(1280, 900),
);
goldenAcrossThemes(
'partners 整屏(移动)',
goldenPrefix: 'partners_mobile',
child: () => const Scaffold(body: PartnersScreen()),
overrides: _overrides,
logical: const Size(390, 1200),
);
}