feat(client): KPI 图标改用 lucide(与原型同源图形库)

原型图标源自 lucide-static(icons.js)。引入 lucide_icons_flutter 包,
库存屏 KPI 图标改 LucideIcons.box/database/box/triangleAlert,与原型一模一样
(不再用 Material 凑近似)。golden_harness 加载 Lucide package 字体(family 带
packages/ 前缀),golden 正确渲染。flutter test 242 通过。

后续:侧栏/顶栏/状态栏图标也逐步换 lucide(对照 shell.js)。

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 22:56:10 +08:00
parent 00d9410bd3
commit 0b19a99fda
10 changed files with 22 additions and 4 deletions
@@ -15,6 +15,7 @@ import '../../widgets/write_guard.dart';
import '../../providers/inventory_provider.dart';
import '../../widgets/data_table_card.dart';
import '../../widgets/kpi_card.dart' show StatusPill; // 旧 tab/移动卡片用,待统一 DsBadge
import 'package:lucide_icons_flutter/lucide_icons.dart';
import '../../widgets/ds/ds_atoms.dart';
import '../../widgets/ds/ds_kpi.dart';
import '../../widgets/ds/ds_table.dart';
@@ -646,7 +647,7 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
title: 'SKU 总数',
value: NumberFormat.decimalPattern()
.format(summary?.skuCount ?? result.total),
icon: Icons.inventory_2,
icon: LucideIcons.box,
tone: DsKpiTone.info,
delta: '点击清筛选',
onTap: () {
@@ -666,7 +667,7 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
DsKpi(
title: '库存货值',
value: summary != null ? yuanWan(summary.stockValue) : '',
icon: Icons.savings_outlined,
icon: LucideIcons.database,
tone: DsKpiTone.ok,
delta: '按进价',
),
@@ -674,14 +675,14 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
title: '在库数量',
value: NumberFormat.decimalPattern()
.format((summary?.inStockQty ?? 0).round()),
icon: Icons.warehouse_outlined,
icon: LucideIcons.box,
tone: DsKpiTone.blue,
delta: '',
),
DsKpi(
title: '缺货预警',
value: '${summary?.shortageCount ?? 0}',
icon: Icons.error_outline,
icon: LucideIcons.triangleAlert,
tone: DsKpiTone.alert,
delta: (summary?.warningCount ?? 0) > 0
? '需补货 ${summary!.warningCount}'
+8
View File
@@ -469,6 +469,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.3"
lucide_icons_flutter:
dependency: "direct main"
description:
name: lucide_icons_flutter
sha256: "7c5dc01a32a9905ae34e2d84224e92d6d0c42acf8926df9e01c35a1446bf1b69"
url: "https://pub.dev"
source: hosted
version: "3.1.14+2"
matcher:
dependency: transitive
description:
+1
View File
@@ -31,6 +31,7 @@ dependencies:
ffi: ^2.1.3
# GBK 编码(TSPL TEXT 内置中文字体需要),支持 macOS/Windows/Linux
charset_converter: ^2.1.0
lucide_icons_flutter: ^3.1.14+2
dev_dependencies:
flutter_test:
Binary file not shown.

Before

Width:  |  Height:  |  Size: 212 KiB

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 KiB

After

Width:  |  Height:  |  Size: 212 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 213 KiB

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 KiB

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 KiB

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 KiB

After

Width:  |  Height:  |  Size: 164 KiB

+8
View File
@@ -27,6 +27,14 @@ Future<void> ensureGoldenFonts() async {
break;
} catch (_) {/* 换下一个 asset key */}
}
// lucide 图标字体(与原型同款图形库)。
try {
// package 字体在运行时 family 带 packages/<pkg>/ 前缀,FontLoader 须用全名。
final lucide = FontLoader('packages/lucide_icons_flutter/Lucide')
..addFont(
rootBundle.load('packages/lucide_icons_flutter/assets/lucide.ttf'));
await lucide.load();
} catch (_) {/* 包未装时跳过 */}
_fontsLoaded = true;
}