refactor(client): Phase 0.1 统一中文字体地基(golden 消豆腐块,可与原型保真比对)

- 打包 Noto Sans SC(pubspec fonts:),ThemeData.fontFamily 全平台统一
- golden_harness 用 FontLoader 注入 ttf + withGoldenFont,golden 渲染真实中文
- 修复 data_table_card 根因:DefaultTextStyle → .merge(替换式会吞掉继承字体,
  导致所有表格屏表头/单元格渲染豆腐块);顺手 hover 硬编码色 → context.tokens.rowHover
- 全部 golden 用新字体重生成;test/golden/failures/ 加入 gitignore

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 17:39:23 +08:00
parent e0a3081d9f
commit 55c23e869e
75 changed files with 34 additions and 5 deletions
+20 -1
View File
@@ -1,8 +1,26 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle, FontLoader;
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:jiu_client/core/theme/themes.dart';
// 加载真实中文字体(消除 golden 豆腐块),使 golden 能与原型截图做保真 diff。
// 原型截图侧同样注入 Noto Sans SC(见 tools/fidelity.mjs),两边字体一致。
bool _fontsLoaded = false;
Future<void> ensureGoldenFonts() async {
if (_fontsLoaded) return;
final loader = FontLoader('NotoSansSC')
..addFont(rootBundle.load('assets/fonts/NotoSansSC.ttf'));
await loader.load();
_fontsLoaded = true;
}
/// 把 NotoSansSC 套到主题文字上(含 hardcoded TextStyle 经 DefaultTextStyle 继承)。
ThemeData withGoldenFont(ThemeData base) => base.copyWith(
textTheme: base.textTheme.apply(fontFamily: 'NotoSansSC'),
primaryTextTheme: base.primaryTextTheme.apply(fontFamily: 'NotoSansSC'),
);
/// design-distill 阶段4Flutter 端)可复用 golden 骨架。
/// 在指定主题 / viewport 下渲染 [child](含 provider 覆盖),比对/更新 golden。
///
@@ -23,6 +41,7 @@ Future<void> pumpGolden(
Size logical = const Size(1280, 900),
double dpr = 2.0,
}) async {
await ensureGoldenFonts();
tester.view.physicalSize = Size(logical.width * dpr, logical.height * dpr);
tester.view.devicePixelRatio = dpr;
addTearDown(tester.view.resetPhysicalSize);
@@ -32,7 +51,7 @@ Future<void> pumpGolden(
overrides: overrides,
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: buildTheme(theme),
theme: withGoldenFont(buildTheme(theme)),
home: child,
),
));