refactor(client): 库存域颜色迁移到 context.tokens

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-06-24 23:25:34 +08:00
parent fb8c5b6926
commit 2c1e9b3fe8
2 changed files with 129 additions and 130 deletions
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import '../../core/theme/app_theme.dart'; import '../../core/theme/context_tokens.dart';
import '../../models/inventory.dart'; import '../../models/inventory.dart';
import '../../models/warehouse.dart'; import '../../models/warehouse.dart';
import '../../core/config/app_constants.dart'; import '../../core/config/app_constants.dart';
@@ -70,7 +70,7 @@ class _InventoryCheckScreenState extends ConsumerState<InventoryCheckScreen> {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text('加载库存失败:$e'), content: Text('加载库存失败:$e'),
backgroundColor: AppTheme.danger), backgroundColor: context.tokens.danger),
); );
} }
} }
@@ -107,9 +107,9 @@ class _InventoryCheckScreenState extends ConsumerState<InventoryCheckScreen> {
if (mounted) { if (mounted) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( SnackBar(
content: Text('盘点单已提交'), content: Text('盘点单已提交'),
backgroundColor: AppTheme.success, backgroundColor: context.tokens.success,
), ),
); );
context.go('/inventory'); context.go('/inventory');
@@ -119,7 +119,7 @@ class _InventoryCheckScreenState extends ConsumerState<InventoryCheckScreen> {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text('提交失败:$e'), content: Text('提交失败:$e'),
backgroundColor: AppTheme.danger), backgroundColor: context.tokens.danger),
); );
} }
} finally { } finally {
@@ -138,13 +138,13 @@ class _InventoryCheckScreenState extends ConsumerState<InventoryCheckScreen> {
final asyncWarehouses = ref.watch(warehouseListProvider); final asyncWarehouses = ref.watch(warehouseListProvider);
return Scaffold( return Scaffold(
backgroundColor: AppTheme.background, backgroundColor: context.tokens.bg,
body: Column( body: Column(
children: [ children: [
// Header // Header
Container( Container(
height: 52, height: 52,
color: AppTheme.surface, color: context.tokens.surface,
padding: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16),
child: Row( child: Row(
children: [ children: [
@@ -191,11 +191,11 @@ class _InventoryCheckScreenState extends ConsumerState<InventoryCheckScreen> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const Text('盘点基本信息', Text('盘点基本信息',
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: AppTheme.primaryDark)), color: context.tokens.primaryDark)),
const SizedBox(height: 16), const SizedBox(height: 16),
Wrap( Wrap(
spacing: 16, spacing: 16,
@@ -219,8 +219,8 @@ class _InventoryCheckScreenState extends ConsumerState<InventoryCheckScreen> {
loading: () => loading: () =>
const LinearProgressIndicator(), const LinearProgressIndicator(),
error: (e, _) => Text('$e', error: (e, _) => Text('$e',
style: const TextStyle( style: TextStyle(
color: AppTheme.danger, color: context.tokens.danger,
fontSize: 12)), fontSize: 12)),
data: (warehouses) => data: (warehouses) =>
DropdownButtonFormField<Warehouse>( DropdownButtonFormField<Warehouse>(
@@ -288,11 +288,11 @@ class _InventoryCheckScreenState extends ConsumerState<InventoryCheckScreen> {
children: [ children: [
Row( Row(
children: [ children: [
const Text('盘点明细', Text('盘点明细',
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: AppTheme.primaryDark)), color: context.tokens.primaryDark)),
const SizedBox(width: 12), const SizedBox(width: 12),
if (_checkItems.isNotEmpty) if (_checkItems.isNotEmpty)
Container( Container(
@@ -300,27 +300,27 @@ class _InventoryCheckScreenState extends ConsumerState<InventoryCheckScreen> {
horizontal: 8, vertical: 2), horizontal: 8, vertical: 2),
decoration: BoxDecoration( decoration: BoxDecoration(
color: color:
AppTheme.accent.withOpacity(0.1), context.tokens.accent.withOpacity(0.1),
borderRadius: borderRadius:
BorderRadius.circular(3), BorderRadius.circular(3),
), ),
child: Text( child: Text(
'差异 ${_checkItems.where((i) => _getDiff(i) != 0).length}', '差异 ${_checkItems.where((i) => _getDiff(i) != 0).length}',
style: const TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
color: AppTheme.accent), color: context.tokens.accent),
), ),
), ),
], ],
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
if (_selectedWarehouse == null) if (_selectedWarehouse == null)
const Center( Center(
child: Padding( child: Padding(
padding: EdgeInsets.all(32), padding: const EdgeInsets.all(32),
child: Text('请先选择盘点仓库', child: Text('请先选择盘点仓库',
style: TextStyle( style: TextStyle(
color: AppTheme.textSecondary)), color: context.tokens.muted)),
), ),
) )
else if (_loadingItems) else if (_loadingItems)
@@ -331,12 +331,12 @@ class _InventoryCheckScreenState extends ConsumerState<InventoryCheckScreen> {
), ),
) )
else if (_checkItems.isEmpty) else if (_checkItems.isEmpty)
const Center( Center(
child: Padding( child: Padding(
padding: EdgeInsets.all(32), padding: const EdgeInsets.all(32),
child: Text('该仓库暂无库存记录', child: Text('该仓库暂无库存记录',
style: TextStyle( style: TextStyle(
color: AppTheme.textSecondary)), color: context.tokens.muted)),
), ),
) )
else else
@@ -371,12 +371,11 @@ class _InventoryCheckScreenState extends ConsumerState<InventoryCheckScreen> {
horizontal: 8, horizontal: 8,
vertical: 10), vertical: 10),
child: Text(h, child: Text(h,
style: const TextStyle( style: TextStyle(
fontSize: 13, fontSize: 13,
fontWeight: fontWeight:
FontWeight.w600, FontWeight.w600,
color: AppTheme color: context.tokens.primaryDark)),
.primaryDark)),
)) ))
.toList(), .toList(),
), ),
@@ -394,28 +393,28 @@ class _InventoryCheckScreenState extends ConsumerState<InventoryCheckScreen> {
_SummaryItem( _SummaryItem(
label: '盘点商品', label: '盘点商品',
value: '${_checkItems.length}', value: '${_checkItems.length}',
color: AppTheme.primary, color: context.tokens.primary,
), ),
const SizedBox(width: 24), const SizedBox(width: 24),
_SummaryItem( _SummaryItem(
label: '盘盈', label: '盘盈',
value: value:
'${_checkItems.where((i) => _getDiff(i) > 0).length}', '${_checkItems.where((i) => _getDiff(i) > 0).length}',
color: AppTheme.success, color: context.tokens.success,
), ),
const SizedBox(width: 24), const SizedBox(width: 24),
_SummaryItem( _SummaryItem(
label: '盘亏', label: '盘亏',
value: value:
'${_checkItems.where((i) => _getDiff(i) < 0).length}', '${_checkItems.where((i) => _getDiff(i) < 0).length}',
color: AppTheme.danger, color: context.tokens.danger,
), ),
const SizedBox(width: 24), const SizedBox(width: 24),
_SummaryItem( _SummaryItem(
label: '相符', label: '相符',
value: value:
'${_checkItems.where((i) => _getDiff(i) == 0).length}', '${_checkItems.where((i) => _getDiff(i) == 0).length}',
color: AppTheme.textSecondary, color: context.tokens.muted,
), ),
], ],
), ),
@@ -443,8 +442,8 @@ class _InventoryCheckScreenState extends ConsumerState<InventoryCheckScreen> {
decoration: BoxDecoration( decoration: BoxDecoration(
color: diff != 0 color: diff != 0
? (diff > 0 ? (diff > 0
? AppTheme.success.withOpacity(0.04) ? context.tokens.success.withOpacity(0.04)
: AppTheme.danger.withOpacity(0.04)) : context.tokens.danger.withOpacity(0.04))
: (index.isEven ? Colors.white : const Color(0xFFFAFAFA)), : (index.isEven ? Colors.white : const Color(0xFFFAFAFA)),
), ),
children: [ children: [
@@ -452,17 +451,17 @@ class _InventoryCheckScreenState extends ConsumerState<InventoryCheckScreen> {
padding: padding:
const EdgeInsets.symmetric(horizontal: 8, vertical: 10), const EdgeInsets.symmetric(horizontal: 8, vertical: 10),
child: Text('${index + 1}', child: Text('${index + 1}',
style: const TextStyle( style: TextStyle(
fontSize: 13, color: AppTheme.textSecondary)), fontSize: 13, color: context.tokens.muted)),
), ),
Padding( Padding(
padding: padding:
const EdgeInsets.symmetric(horizontal: 8, vertical: 10), const EdgeInsets.symmetric(horizontal: 8, vertical: 10),
child: Text(inv.productCode.isEmpty ? '-' : inv.productCode, child: Text(inv.productCode.isEmpty ? '-' : inv.productCode,
style: const TextStyle( style: TextStyle(
fontFamily: 'monospace', fontFamily: 'monospace',
fontSize: 12, fontSize: 12,
color: AppTheme.textSecondary)), color: context.tokens.muted)),
), ),
Padding( Padding(
padding: padding:
@@ -503,8 +502,8 @@ class _InventoryCheckScreenState extends ConsumerState<InventoryCheckScreen> {
fontSize: 13, fontSize: 13,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: diff == 0 color: diff == 0
? AppTheme.textSecondary ? context.tokens.muted
: (diff > 0 ? AppTheme.success : AppTheme.danger), : (diff > 0 ? context.tokens.success : context.tokens.danger),
), ),
), ),
), ),
@@ -551,8 +550,8 @@ class _InfoField extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text(label, Text(label,
style: const TextStyle( style: TextStyle(
fontSize: 13, color: AppTheme.textSecondary)), fontSize: 13, color: context.tokens.muted)),
const SizedBox(height: 6), const SizedBox(height: 6),
child, child,
], ],
@@ -574,8 +573,8 @@ class _SummaryItem extends StatelessWidget {
return Row( return Row(
children: [ children: [
Text(label, Text(label,
style: const TextStyle( style: TextStyle(
fontSize: 13, color: AppTheme.textSecondary)), fontSize: 13, color: context.tokens.muted)),
const SizedBox(width: 4), const SizedBox(width: 4),
Text(value, Text(value,
style: TextStyle( style: TextStyle(
@@ -7,7 +7,7 @@ import 'package:go_router/go_router.dart';
import '../../core/config/app_config.dart'; import '../../core/config/app_config.dart';
import '../../core/config/app_constants.dart'; import '../../core/config/app_constants.dart';
import '../../core/responsive/responsive.dart'; import '../../core/responsive/responsive.dart';
import '../../core/theme/app_theme.dart'; import '../../core/theme/context_tokens.dart';
import '../../models/inventory.dart'; import '../../models/inventory.dart';
import '../../core/auth/auth_state.dart'; import '../../core/auth/auth_state.dart';
import '../../widgets/write_guard.dart'; import '../../widgets/write_guard.dart';
@@ -94,14 +94,14 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
: item.remark, : item.remark,
style: TextStyle( style: TextStyle(
color: item.remark.isEmpty color: item.remark.isEmpty
? AppTheme.textSecondary ? context.tokens.muted
: AppTheme.textPrimary, : context.tokens.text,
), ),
), ),
if (editable) ...[ if (editable) ...[
const SizedBox(width: 4), const SizedBox(width: 4),
const Icon(Icons.edit_outlined, Icon(Icons.edit_outlined,
size: 12, color: AppTheme.textSecondary), size: 12, color: context.tokens.muted),
], ],
], ],
); );
@@ -145,7 +145,7 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
} catch (e) { } catch (e) {
if (context.mounted) { if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('保存失败:$e'), backgroundColor: AppTheme.danger), SnackBar(content: Text('保存失败:$e'), backgroundColor: context.tokens.danger),
); );
} }
} }
@@ -286,8 +286,8 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
return switch (key) { return switch (key) {
'code' => DataCell(Text( 'code' => DataCell(Text(
item.productCode.isEmpty ? '-' : item.productCode, item.productCode.isEmpty ? '-' : item.productCode,
style: const TextStyle( style: TextStyle(
fontFamily: 'monospace', fontSize: 12, color: AppTheme.textSecondary))), fontFamily: 'monospace', fontSize: 12, color: context.tokens.muted))),
'name' => DataCell(item.productId != null 'name' => DataCell(item.productId != null
? GestureDetector( ? GestureDetector(
onTap: () => context.push('/products/${item.productId}'), onTap: () => context.push('/products/${item.productId}'),
@@ -296,10 +296,10 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
child: Text( child: Text(
item.productName.isEmpty ? '-' : item.productName, item.productName.isEmpty ? '-' : item.productName,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: const TextStyle( style: TextStyle(
color: AppTheme.primary, color: context.tokens.primary,
decoration: TextDecoration.underline, decoration: TextDecoration.underline,
decorationColor: AppTheme.primary, decorationColor: context.tokens.primary,
), ),
), ),
), ),
@@ -314,14 +314,14 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
'price' => DataCell(Text( 'price' => DataCell(Text(
item.unitPrice != null ? '¥${item.unitPrice!.toStringAsFixed(2)}' : '待定价', item.unitPrice != null ? '¥${item.unitPrice!.toStringAsFixed(2)}' : '待定价',
style: item.unitPrice == null style: item.unitPrice == null
? const TextStyle(color: AppTheme.warning) ? TextStyle(color: context.tokens.warn)
: null)), : null)),
'prodDate' => DataCell(Text(item.productionDate ?? '-')), 'prodDate' => DataCell(Text(item.productionDate ?? '-')),
'inTime' => DataCell(Text( 'inTime' => DataCell(Text(
item.createdAt != null && item.createdAt!.length >= 10 item.createdAt != null && item.createdAt!.length >= 10
? item.createdAt!.substring(0, 10) ? item.createdAt!.substring(0, 10)
: '-', : '-',
style: const TextStyle(fontSize: 12, color: AppTheme.textSecondary))), style: TextStyle(fontSize: 12, color: context.tokens.muted))),
'supplier' => DataCell(Text(item.supplierName.isEmpty ? '-' : item.supplierName)), 'supplier' => DataCell(Text(item.supplierName.isEmpty ? '-' : item.supplierName)),
'remark' => DataCell(Tooltip( 'remark' => DataCell(Tooltip(
message: item.remark.isEmpty ? '' : item.remark, message: item.remark.isEmpty ? '' : item.remark,
@@ -339,8 +339,8 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
'actions' => DataCell(item.productId != null 'actions' => DataCell(item.productId != null
? TextButton( ? TextButton(
onPressed: () => _printLabel(context, item), onPressed: () => _printLabel(context, item),
child: const Text('打标签', child: Text('打标签',
style: TextStyle(fontSize: 12, color: AppTheme.primary)), style: TextStyle(fontSize: 12, color: context.tokens.primary)),
) )
: const SizedBox()), : const SizedBox()),
_ => const DataCell(SizedBox()), _ => const DataCell(SizedBox()),
@@ -400,15 +400,15 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
style: TextStyle( style: TextStyle(
fontSize: 13, fontSize: 13,
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
color: item.quantity == 0 ? AppTheme.danger : AppTheme.accent), color: item.quantity == 0 ? context.tokens.danger : context.tokens.accent),
)), )),
MobileCardField('安全库存', '${item.minStock}'), MobileCardField('安全库存', '${item.minStock}'),
MobileCardField('缺口', null, MobileCardField('缺口', null,
valueWidget: Text( valueWidget: Text(
'${item.minStock! - item.quantity.toInt()}', '${item.minStock! - item.quantity.toInt()}',
style: const TextStyle( style: TextStyle(
fontSize: 13, fontSize: 13,
color: AppTheme.danger, color: context.tokens.danger,
fontWeight: FontWeight.w600), fontWeight: FontWeight.w600),
)), )),
], ],
@@ -430,8 +430,8 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
fontSize: 13, fontSize: 13,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: log.direction == 'in' color: log.direction == 'in'
? AppTheme.success ? context.tokens.success
: AppTheme.danger), : context.tokens.danger),
)), )),
MobileCardField('变前', log.qtyBefore?.toStringAsFixed(0) ?? '-'), MobileCardField('变前', log.qtyBefore?.toStringAsFixed(0) ?? '-'),
MobileCardField('变后', log.qtyAfter?.toStringAsFixed(0) ?? '-'), MobileCardField('变后', log.qtyAfter?.toStringAsFixed(0) ?? '-'),
@@ -468,10 +468,10 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
const Icon(Icons.error_outline, size: 40, color: AppTheme.textSecondary), Icon(Icons.error_outline, size: 40, color: context.tokens.muted),
const SizedBox(height: 12), const SizedBox(height: 12),
Text('加载失败:$e', Text('加载失败:$e',
style: const TextStyle(color: AppTheme.textSecondary), style: TextStyle(color: context.tokens.muted),
textAlign: TextAlign.center), textAlign: TextAlign.center),
const SizedBox(height: 12), const SizedBox(height: 12),
ElevatedButton( ElevatedButton(
@@ -522,7 +522,7 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
value: '${result.total}', value: '${result.total}',
unit: '', unit: '',
icon: Icons.inventory_2, icon: Icons.inventory_2,
color: AppTheme.primary, color: context.tokens.primary,
width: w), width: w),
const SizedBox(width: 12), const SizedBox(width: 12),
_SummaryCard( _SummaryCard(
@@ -530,7 +530,7 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
value: '$warningCount', value: '$warningCount',
unit: '', unit: '',
icon: Icons.warning_amber, icon: Icons.warning_amber,
color: AppTheme.accent, color: context.tokens.accent,
width: w), width: w),
const SizedBox(width: 12), const SizedBox(width: 12),
_SummaryCard( _SummaryCard(
@@ -538,11 +538,11 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
value: '$emptyCount', value: '$emptyCount',
unit: '', unit: '',
icon: Icons.remove_shopping_cart, icon: Icons.remove_shopping_cart,
color: AppTheme.danger, color: context.tokens.danger,
width: w), width: w),
]; ];
return Container( return Container(
color: AppTheme.background, color: context.tokens.bg,
padding: const EdgeInsets.all(12), padding: const EdgeInsets.all(12),
child: context.isMobile child: context.isMobile
? SingleChildScrollView( ? SingleChildScrollView(
@@ -751,9 +751,9 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
? [ ? [
DataRow(cells: [ DataRow(cells: [
const DataCell(SizedBox()), const DataCell(SizedBox()),
const DataCell(Text('暂无库存数据', DataCell(Text('暂无库存数据',
style: TextStyle( style: TextStyle(
color: AppTheme.textSecondary))), color: context.tokens.muted))),
for (int i = 2; i < visibleCols.length; i++) for (int i = 2; i < visibleCols.length; i++)
const DataCell(SizedBox()), const DataCell(SizedBox()),
]) ])
@@ -763,11 +763,11 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
color: WidgetStateProperty.resolveWith( color: WidgetStateProperty.resolveWith(
(states) { (states) {
if (item.quantity == 0) { if (item.quantity == 0) {
return AppTheme.danger.withValues(alpha: 0.04); return context.tokens.danger.withValues(alpha: 0.04);
} }
if (item.minStock != null && if (item.minStock != null &&
item.quantity < item.minStock!) { item.quantity < item.minStock!) {
return AppTheme.accent.withValues(alpha: 0.04); return context.tokens.accent.withValues(alpha: 0.04);
} }
return null; return null;
}), }),
@@ -792,10 +792,10 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
const Icon(Icons.error_outline, size: 40, color: AppTheme.textSecondary), Icon(Icons.error_outline, size: 40, color: context.tokens.muted),
const SizedBox(height: 12), const SizedBox(height: 12),
Text('加载失败:$e', Text('加载失败:$e',
style: const TextStyle(color: AppTheme.textSecondary), style: TextStyle(color: context.tokens.muted),
textAlign: TextAlign.center), textAlign: TextAlign.center),
const SizedBox(height: 12), const SizedBox(height: 12),
ElevatedButton( ElevatedButton(
@@ -816,13 +816,13 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
page: 1, page: 1,
toolbar: Row( toolbar: Row(
children: [ children: [
const Icon(Icons.warning_amber, Icon(Icons.warning_amber,
color: AppTheme.accent, size: 18), color: context.tokens.accent, size: 18),
const SizedBox(width: 8), const SizedBox(width: 8),
Text( Text(
'${warnings.length} 个商品库存低于安全库存', '${warnings.length} 个商品库存低于安全库存',
style: const TextStyle( style: TextStyle(
fontSize: 13, color: AppTheme.accent), fontSize: 13, color: context.tokens.accent),
), ),
const Spacer(), const Spacer(),
OutlinedButton.icon( OutlinedButton.icon(
@@ -856,24 +856,24 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
], ],
rows: warnings.isEmpty rows: warnings.isEmpty
? [ ? [
const DataRow(cells: [ DataRow(cells: [
DataCell(SizedBox()), const DataCell(SizedBox()),
DataCell(Text('暂无预警商品', DataCell(Text('暂无预警商品',
style: TextStyle( style: TextStyle(
color: AppTheme.textSecondary))), color: context.tokens.muted))),
DataCell(SizedBox()), const DataCell(SizedBox()),
DataCell(SizedBox()), const DataCell(SizedBox()),
DataCell(SizedBox()), const DataCell(SizedBox()),
DataCell(SizedBox()), const DataCell(SizedBox()),
DataCell(SizedBox()), const DataCell(SizedBox()),
]) ])
] ]
: warnings : warnings
.map((item) => DataRow( .map((item) => DataRow(
color: WidgetStateProperty.all( color: WidgetStateProperty.all(
item.quantity == 0 item.quantity == 0
? AppTheme.danger.withOpacity(0.05) ? context.tokens.danger.withOpacity(0.05)
: AppTheme.accent.withOpacity(0.04)), : context.tokens.accent.withOpacity(0.04)),
cells: [ cells: [
DataCell(Text( DataCell(Text(
item.productCode.isEmpty ? '-' : item.productCode, item.productCode.isEmpty ? '-' : item.productCode,
@@ -888,10 +888,10 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
child: Text( child: Text(
item.productName.isEmpty ? '-' : item.productName, item.productName.isEmpty ? '-' : item.productName,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: const TextStyle( style: TextStyle(
color: AppTheme.primary, color: context.tokens.primary,
decoration: TextDecoration.underline, decoration: TextDecoration.underline,
decorationColor: AppTheme.primary, decorationColor: context.tokens.primary,
)), )),
), ),
) )
@@ -903,14 +903,14 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
color: item.quantity == 0 color: item.quantity == 0
? AppTheme.danger ? context.tokens.danger
: AppTheme.accent), : context.tokens.accent),
)), )),
DataCell(Text('${item.minStock}')), DataCell(Text('${item.minStock}')),
DataCell(Text( DataCell(Text(
'${item.minStock! - item.quantity.toInt()}', '${item.minStock! - item.quantity.toInt()}',
style: const TextStyle( style: TextStyle(
color: AppTheme.danger, color: context.tokens.danger,
fontWeight: FontWeight.w600), fontWeight: FontWeight.w600),
)), )),
DataCell(_InventoryStatusBadge(item)), DataCell(_InventoryStatusBadge(item)),
@@ -930,10 +930,10 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
const Icon(Icons.error_outline, size: 40, color: AppTheme.textSecondary), Icon(Icons.error_outline, size: 40, color: context.tokens.muted),
const SizedBox(height: 12), const SizedBox(height: 12),
Text('加载失败:$e', Text('加载失败:$e',
style: const TextStyle(color: AppTheme.textSecondary), style: TextStyle(color: context.tokens.muted),
textAlign: TextAlign.center), textAlign: TextAlign.center),
const SizedBox(height: 12), const SizedBox(height: 12),
ElevatedButton( ElevatedButton(
@@ -956,7 +956,7 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
ref.read(inventoryLogProvider.notifier).setPageSize(s), ref.read(inventoryLogProvider.notifier).setPageSize(s),
toolbar: Row( toolbar: Row(
children: [ children: [
const Icon(Icons.history, color: AppTheme.primary, size: 18), Icon(Icons.history, color: context.tokens.primary, size: 18),
const SizedBox(width: 8), const SizedBox(width: 8),
const Text('库存流水记录', const Text('库存流水记录',
style: TextStyle( style: TextStyle(
@@ -995,17 +995,17 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
], ],
rows: logs.isEmpty rows: logs.isEmpty
? [ ? [
const DataRow(cells: [ DataRow(cells: [
DataCell(SizedBox()), const DataCell(SizedBox()),
DataCell(Text('暂无流水记录', DataCell(Text('暂无流水记录',
style: TextStyle( style: TextStyle(
color: AppTheme.textSecondary))), color: context.tokens.muted))),
DataCell(SizedBox()), const DataCell(SizedBox()),
DataCell(SizedBox()), const DataCell(SizedBox()),
DataCell(SizedBox()), const DataCell(SizedBox()),
DataCell(SizedBox()), const DataCell(SizedBox()),
DataCell(SizedBox()), const DataCell(SizedBox()),
DataCell(SizedBox()), const DataCell(SizedBox()),
]) ])
] ]
: logs : logs
@@ -1022,22 +1022,22 @@ class _InventoryListScreenState extends ConsumerState<InventoryListScreen> {
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: log.direction == 'in' color: log.direction == 'in'
? AppTheme.success ? context.tokens.success
: AppTheme.danger), : context.tokens.danger),
)), )),
DataCell(Text( DataCell(Text(
log.qtyBefore?.toStringAsFixed(0) ?? '-')), log.qtyBefore?.toStringAsFixed(0) ?? '-')),
DataCell(Text( DataCell(Text(
log.qtyAfter?.toStringAsFixed(0) ?? '-')), log.qtyAfter?.toStringAsFixed(0) ?? '-')),
DataCell(Text(log.refType ?? '-', DataCell(Text(log.refType ?? '-',
style: const TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
color: AppTheme.textSecondary))), color: context.tokens.muted))),
DataCell(Text( DataCell(Text(
log.createdAt?.substring(0, 19) ?? '-', log.createdAt?.substring(0, 19) ?? '-',
style: const TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
color: AppTheme.textSecondary), color: context.tokens.muted),
)), )),
])) ]))
.toList(), .toList(),
@@ -1072,9 +1072,9 @@ class _SummaryCard extends StatelessWidget {
height: 72, height: 72,
padding: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration( decoration: BoxDecoration(
color: AppTheme.surface, color: context.tokens.surface,
borderRadius: BorderRadius.circular(4), borderRadius: BorderRadius.circular(4),
border: Border.all(color: AppTheme.border, width: 0.5), border: Border.all(color: context.tokens.border, width: 0.5),
), ),
child: Row( child: Row(
children: [ children: [
@@ -1093,8 +1093,8 @@ class _SummaryCard extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Text(title, Text(title,
style: const TextStyle( style: TextStyle(
fontSize: 12, color: AppTheme.textSecondary)), fontSize: 12, color: context.tokens.muted)),
const SizedBox(height: 4), const SizedBox(height: 4),
Row( Row(
crossAxisAlignment: CrossAxisAlignment.baseline, crossAxisAlignment: CrossAxisAlignment.baseline,
@@ -1108,9 +1108,9 @@ class _SummaryCard extends StatelessWidget {
if (unit.isNotEmpty) ...[ if (unit.isNotEmpty) ...[
const SizedBox(width: 2), const SizedBox(width: 2),
Text(unit, Text(unit,
style: const TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
color: AppTheme.textSecondary)), color: context.tokens.muted)),
], ],
], ],
), ),
@@ -1137,15 +1137,15 @@ class _InventoryStatusBadge extends StatelessWidget {
if (item.quantity == 0) { if (item.quantity == 0) {
status = '缺货'; status = '缺货';
bg = const Color(0xFFFFEBEE); bg = const Color(0xFFFFEBEE);
fg = AppTheme.danger; fg = context.tokens.danger;
} else if (item.minStock != null && item.quantity < item.minStock!) { } else if (item.minStock != null && item.quantity < item.minStock!) {
status = '库存不足'; status = '库存不足';
bg = const Color(0xFFFFF3E0); bg = const Color(0xFFFFF3E0);
fg = AppTheme.accent; fg = context.tokens.accent;
} else { } else {
status = '正常'; status = '正常';
bg = const Color(0xFFE8F5E9); bg = const Color(0xFFE8F5E9);
fg = AppTheme.success; fg = context.tokens.success;
} }
return Container( return Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
@@ -1176,7 +1176,7 @@ class _DirectionBadge extends StatelessWidget {
child: Text( child: Text(
isIn ? '入库' : '出库', isIn ? '入库' : '出库',
style: TextStyle( style: TextStyle(
color: isIn ? AppTheme.success : AppTheme.danger, color: isIn ? context.tokens.success : context.tokens.danger,
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.w500), fontWeight: FontWeight.w500),
), ),
@@ -1254,7 +1254,7 @@ class _ImportProgressDialog extends StatelessWidget {
LinearProgressIndicator( LinearProgressIndicator(
value: state.uploadPercent / 100, value: state.uploadPercent / 100,
backgroundColor: Colors.grey[200], backgroundColor: Colors.grey[200],
valueColor: AlwaysStoppedAnimation<Color>(AppTheme.primary), valueColor: AlwaysStoppedAnimation<Color>(context.tokens.primary),
), ),
const SizedBox(height: 6), const SizedBox(height: 6),
Text('${state.uploadPercent}%', Text('${state.uploadPercent}%',
@@ -1272,7 +1272,7 @@ class _ImportProgressDialog extends StatelessWidget {
width: 16, height: 16, width: 16, height: 16,
child: CircularProgressIndicator( child: CircularProgressIndicator(
strokeWidth: 2, strokeWidth: 2,
valueColor: AlwaysStoppedAnimation<Color>(AppTheme.primary), valueColor: AlwaysStoppedAnimation<Color>(context.tokens.primary),
), ),
), ),
const SizedBox(width: 10), const SizedBox(width: 10),
@@ -1284,7 +1284,7 @@ class _ImportProgressDialog extends StatelessWidget {
const SizedBox(height: 8), const SizedBox(height: 8),
LinearProgressIndicator( LinearProgressIndicator(
backgroundColor: Colors.grey[200], backgroundColor: Colors.grey[200],
valueColor: AlwaysStoppedAnimation<Color>(AppTheme.primary), valueColor: AlwaysStoppedAnimation<Color>(context.tokens.primary),
), ),
], ],
); );
@@ -1298,7 +1298,7 @@ class _ImportProgressDialog extends StatelessWidget {
Row(children: [ Row(children: [
Icon( Icon(
allFailed ? Icons.warning_amber_rounded : Icons.check_circle, allFailed ? Icons.warning_amber_rounded : Icons.check_circle,
color: allFailed ? AppTheme.danger : AppTheme.success, color: allFailed ? context.tokens.danger : context.tokens.success,
size: 20, size: 20,
), ),
const SizedBox(width: 8), const SizedBox(width: 8),
@@ -1314,13 +1314,13 @@ class _ImportProgressDialog extends StatelessWidget {
style: TextStyle(fontSize: 13, color: Colors.grey[600])), style: TextStyle(fontSize: 13, color: Colors.grey[600])),
if (state.errors.isNotEmpty) if (state.errors.isNotEmpty)
Text('失败:${state.errors.length}', Text('失败:${state.errors.length}',
style: TextStyle(fontSize: 13, color: AppTheme.danger)), style: TextStyle(fontSize: 13, color: context.tokens.danger)),
if (state.errors.isNotEmpty) ...[ if (state.errors.isNotEmpty) ...[
const SizedBox(height: 6), const SizedBox(height: 6),
...state.errors.map((e) => Padding( ...state.errors.map((e) => Padding(
padding: const EdgeInsets.only(top: 4), padding: const EdgeInsets.only(top: 4),
child: Text(e, child: Text(e,
style: TextStyle(fontSize: 12, color: AppTheme.danger)), style: TextStyle(fontSize: 12, color: context.tokens.danger)),
)), )),
], ],
], ],
@@ -1330,12 +1330,12 @@ class _ImportProgressDialog extends StatelessWidget {
return Row( return Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Icon(Icons.error_outline, color: AppTheme.danger, size: 20), Icon(Icons.error_outline, color: context.tokens.danger, size: 20),
const SizedBox(width: 8), const SizedBox(width: 8),
Expanded( Expanded(
child: Text( child: Text(
'导入失败:${state.errorMsg}', '导入失败:${state.errorMsg}',
style: TextStyle(fontSize: 13, color: AppTheme.danger), style: TextStyle(fontSize: 13, color: context.tokens.danger),
), ),
), ),
], ],