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
@@ -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} 项'
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
Before Width: | Height: | Size: 212 KiB After Width: | Height: | Size: 214 KiB |
|
Before Width: | Height: | Size: 210 KiB After Width: | Height: | Size: 212 KiB |
|
Before Width: | Height: | Size: 213 KiB After Width: | Height: | Size: 214 KiB |
|
Before Width: | Height: | Size: 162 KiB After Width: | Height: | Size: 163 KiB |
|
Before Width: | Height: | Size: 162 KiB After Width: | Height: | Size: 163 KiB |
|
Before Width: | Height: | Size: 162 KiB After Width: | Height: | Size: 164 KiB |
@@ -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;
|
||||
}
|
||||
|
||||
|
||||