refactor(client): 商品/财务域颜色迁移到 context.tokens

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-06-24 23:57:49 +08:00
parent 7612495bbc
commit 7a92b0dfff
3 changed files with 142 additions and 137 deletions
+42 -40
View File
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../core/responsive/responsive.dart'; import '../../core/responsive/responsive.dart';
import '../../core/config/app_constants.dart'; import '../../core/config/app_constants.dart';
import '../../core/theme/app_theme.dart'; import '../../core/theme/context_tokens.dart';
import '../../models/finance.dart'; import '../../models/finance.dart';
import '../../providers/finance_provider.dart'; import '../../providers/finance_provider.dart';
import '../../widgets/data_table_card.dart'; import '../../widgets/data_table_card.dart';
@@ -125,7 +125,7 @@ class _FinanceTabState extends ConsumerState<_FinanceTab> {
} catch (e) { } catch (e) {
if (mounted) { if (mounted) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('操作失败:$e'), backgroundColor: AppTheme.danger), SnackBar(content: Text('操作失败:$e'), backgroundColor: context.tokens.danger),
); );
} }
} }
@@ -159,7 +159,7 @@ class _FinanceTabState extends ConsumerState<_FinanceTab> {
'¥${r.balance.toStringAsFixed(2)}', '¥${r.balance.toStringAsFixed(2)}',
style: TextStyle( style: TextStyle(
fontSize: 13, fontSize: 13,
color: r.balance > 0 ? AppTheme.danger : AppTheme.textSecondary, color: r.balance > 0 ? context.tokens.danger : context.tokens.muted,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
), ),
)), )),
@@ -175,8 +175,8 @@ class _FinanceTabState extends ConsumerState<_FinanceTab> {
WriteGuard( WriteGuard(
child: TextButton( child: TextButton(
onPressed: () => _closeRecord(r), onPressed: () => _closeRecord(r),
child: const Text('结清', child: Text('结清',
style: TextStyle(fontSize: 13, color: AppTheme.success)), style: TextStyle(fontSize: 13, color: context.tokens.success)),
), ),
), ),
] ]
@@ -207,11 +207,11 @@ class _FinanceTabState extends ConsumerState<_FinanceTab> {
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
const Icon(Icons.cloud_off, Icon(Icons.cloud_off,
size: 40, color: AppTheme.textSecondary), size: 40, color: context.tokens.muted),
const SizedBox(height: 12), const SizedBox(height: 12),
const Text('暂无数据,网络不可用', Text('暂无数据,网络不可用',
style: TextStyle(color: AppTheme.textSecondary)), style: TextStyle(color: context.tokens.muted)),
const SizedBox(height: 12), const SizedBox(height: 12),
ElevatedButton(onPressed: _refetch, child: const Text('重试')), ElevatedButton(onPressed: _refetch, child: const Text('重试')),
], ],
@@ -296,8 +296,8 @@ class _FinanceTabState extends ConsumerState<_FinanceTab> {
r.refType != null && r.refId != null r.refType != null && r.refId != null
? '${r.refType!.replaceAll('_', '-')}#${r.refId}' ? '${r.refType!.replaceAll('_', '-')}#${r.refId}'
: '-', : '-',
style: const TextStyle( style: TextStyle(
fontSize: 11, fontFamily: 'monospace', color: AppTheme.primary), fontSize: 11, fontFamily: 'monospace', color: context.tokens.primary),
)); ));
case 'amount': case 'amount':
return DataCell(Text( return DataCell(Text(
@@ -308,7 +308,7 @@ class _FinanceTabState extends ConsumerState<_FinanceTab> {
return DataCell(Text( return DataCell(Text(
'¥${r.balance.toStringAsFixed(2)}', '¥${r.balance.toStringAsFixed(2)}',
style: TextStyle( style: TextStyle(
color: r.balance > 0 ? AppTheme.danger : AppTheme.textSecondary, color: r.balance > 0 ? context.tokens.danger : context.tokens.muted,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
), ),
)); ));
@@ -322,8 +322,8 @@ class _FinanceTabState extends ConsumerState<_FinanceTab> {
width: 160, width: 160,
child: Text(r.remark ?? '-', child: Text(r.remark ?? '-',
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: const TextStyle( style: TextStyle(
fontSize: 12, color: AppTheme.textSecondary)), fontSize: 12, color: context.tokens.muted)),
)); ));
case 'actions': case 'actions':
if ((r.type == 'payable' || r.type == 'receivable') && if ((r.type == 'payable' || r.type == 'receivable') &&
@@ -332,8 +332,8 @@ class _FinanceTabState extends ConsumerState<_FinanceTab> {
return DataCell(WriteGuard( return DataCell(WriteGuard(
child: TextButton( child: TextButton(
onPressed: () => _closeRecord(r), onPressed: () => _closeRecord(r),
child: const Text('结清', child: Text('结清',
style: TextStyle(fontSize: 12, color: AppTheme.success)), style: TextStyle(fontSize: 12, color: context.tokens.success)),
), ),
)); ));
} }
@@ -349,8 +349,8 @@ class _FinanceTabState extends ConsumerState<_FinanceTab> {
cells: List.generate( cells: List.generate(
visibleCols.length, visibleCols.length,
(i) => i == 0 (i) => i == 0
? const DataCell(Text('暂无记录', ? DataCell(Text('暂无记录',
style: TextStyle(color: AppTheme.textSecondary))) style: TextStyle(color: context.tokens.muted)))
: const DataCell(SizedBox()), : const DataCell(SizedBox()),
), ),
), ),
@@ -380,7 +380,7 @@ class _FinanceTabState extends ConsumerState<_FinanceTab> {
title: '合计金额', title: '合计金额',
value: '¥${(totalAmount / 10000).toStringAsFixed(2)}', value: '¥${(totalAmount / 10000).toStringAsFixed(2)}',
icon: Icons.account_balance_wallet, icon: Icons.account_balance_wallet,
color: AppTheme.primary, color: context.tokens.primary,
width: w, width: w,
), ),
const SizedBox(width: 12), const SizedBox(width: 12),
@@ -388,7 +388,7 @@ class _FinanceTabState extends ConsumerState<_FinanceTab> {
title: '未结清', title: '未结清',
value: '¥${(openAmount / 10000).toStringAsFixed(2)}', value: '¥${(openAmount / 10000).toStringAsFixed(2)}',
icon: Icons.pending_actions, icon: Icons.pending_actions,
color: AppTheme.danger, color: context.tokens.danger,
width: w, width: w,
), ),
const SizedBox(width: 12), const SizedBox(width: 12),
@@ -396,12 +396,12 @@ class _FinanceTabState extends ConsumerState<_FinanceTab> {
title: '已结清', title: '已结清',
value: '¥${(closedAmount / 10000).toStringAsFixed(2)}', value: '¥${(closedAmount / 10000).toStringAsFixed(2)}',
icon: Icons.check_circle, icon: Icons.check_circle,
color: AppTheme.success, color: context.tokens.success,
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(
@@ -550,8 +550,9 @@ class _AddPaymentDialogState extends State<_AddPaymentDialog> {
final amount = double.tryParse(_amountCtrl.text.trim()); final amount = double.tryParse(_amountCtrl.text.trim());
if (amount == null || amount <= 0) { if (amount == null || amount <= 0) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( SnackBar(
content: Text('请输入有效金额'), backgroundColor: AppTheme.danger), content: const Text('请输入有效金额'),
backgroundColor: context.tokens.danger),
); );
return; return;
} }
@@ -569,14 +570,15 @@ class _AddPaymentDialogState extends State<_AddPaymentDialog> {
Navigator.of(context).pop(); Navigator.of(context).pop();
widget.onSaved(); widget.onSaved();
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( SnackBar(
content: Text('添加成功'), backgroundColor: AppTheme.success), content: const Text('添加成功'),
backgroundColor: context.tokens.success),
); );
} }
} catch (e) { } catch (e) {
if (mounted) { if (mounted) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('添加失败:$e'), backgroundColor: AppTheme.danger), SnackBar(content: Text('添加失败:$e'), backgroundColor: context.tokens.danger),
); );
} }
} finally { } finally {
@@ -655,7 +657,7 @@ class _StatusBadge extends StatelessWidget {
child: Text( child: Text(
isOpen ? '未结清' : '已结清', isOpen ? '未结清' : '已结清',
style: TextStyle( style: TextStyle(
color: isOpen ? AppTheme.accent : AppTheme.textSecondary, color: isOpen ? context.tokens.accent : context.tokens.muted,
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
), ),
@@ -674,23 +676,23 @@ class _TypeBadge extends StatelessWidget {
switch (label) { switch (label) {
case '应收账款': case '应收账款':
bg = const Color(0xFFE3F2FD); bg = const Color(0xFFE3F2FD);
fg = AppTheme.primary; fg = context.tokens.primary;
break; break;
case '应付账款': case '应付账款':
bg = const Color(0xFFFFEBEE); bg = const Color(0xFFFFEBEE);
fg = AppTheme.danger; fg = context.tokens.danger;
break; break;
case '收款': case '收款':
bg = const Color(0xFFE8F5E9); bg = const Color(0xFFE8F5E9);
fg = AppTheme.success; fg = context.tokens.success;
break; break;
case '付款': case '付款':
bg = const Color(0xFFFFF3E0); bg = const Color(0xFFFFF3E0);
fg = AppTheme.accent; fg = context.tokens.accent;
break; break;
default: default:
bg = const Color(0xFFF5F5F5); bg = const Color(0xFFF5F5F5);
fg = AppTheme.textSecondary; fg = context.tokens.muted;
} }
return Container( return Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
@@ -724,9 +726,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: [
@@ -745,8 +747,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),
Text(value, Text(value,
style: TextStyle( style: TextStyle(
@@ -781,9 +783,9 @@ class _MonthSelector extends StatelessWidget {
height: 36, height: 36,
padding: const EdgeInsets.symmetric(horizontal: 8), padding: const EdgeInsets.symmetric(horizontal: 8),
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all(color: AppTheme.border), border: Border.all(color: context.tokens.border),
borderRadius: BorderRadius.circular(4), borderRadius: BorderRadius.circular(4),
color: AppTheme.surface, color: context.tokens.surface,
), ),
child: DropdownButtonHideUnderline( child: DropdownButtonHideUnderline(
child: DropdownButton<String>( child: DropdownButton<String>(
@@ -794,7 +796,7 @@ class _MonthSelector extends StatelessWidget {
child: Text(m, style: const TextStyle(fontSize: 13)))) child: Text(m, style: const TextStyle(fontSize: 13))))
.toList(), .toList(),
onChanged: (v) => onChanged(v!), onChanged: (v) => onChanged(v!),
style: const TextStyle(fontSize: 13, color: AppTheme.textPrimary), style: TextStyle(fontSize: 13, color: context.tokens.text),
), ),
), ),
); );
@@ -11,7 +11,7 @@ import '../../core/utils/print_util.dart';
import '../../widgets/label_preview_dialog.dart'; import '../../widgets/label_preview_dialog.dart';
import '../../widgets/fullscreen_image_viewer.dart'; import '../../widgets/fullscreen_image_viewer.dart';
import '../../widgets/write_guard.dart'; import '../../widgets/write_guard.dart';
import '../../core/theme/app_theme.dart'; import '../../core/theme/context_tokens.dart';
import '../../models/product.dart'; import '../../models/product.dart';
import '../../models/product_image.dart'; import '../../models/product_image.dart';
import '../../providers/product_provider.dart'; import '../../providers/product_provider.dart';
@@ -87,7 +87,7 @@ class _ProductDetailScreenState extends ConsumerState<ProductDetailScreen> {
} catch (e) { } catch (e) {
if (mounted) { if (mounted) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('保存失败:$e'), backgroundColor: AppTheme.danger), SnackBar(content: Text('保存失败:$e'), backgroundColor: context.tokens.danger),
); );
} }
} finally { } finally {
@@ -175,7 +175,7 @@ class _ProductDetailScreenState extends ConsumerState<ProductDetailScreen> {
} catch (e) { } catch (e) {
if (mounted) { if (mounted) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('上传失败:$e'), backgroundColor: AppTheme.danger), SnackBar(content: Text('上传失败:$e'), backgroundColor: context.tokens.danger),
); );
} }
} finally { } finally {
@@ -190,7 +190,7 @@ class _ProductDetailScreenState extends ConsumerState<ProductDetailScreen> {
} catch (e) { } catch (e) {
if (mounted) { if (mounted) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('删除失败:$e'), backgroundColor: AppTheme.danger), SnackBar(content: Text('删除失败:$e'), backgroundColor: context.tokens.danger),
); );
} }
} }
@@ -234,7 +234,7 @@ class _ProductDetailScreenState extends ConsumerState<ProductDetailScreen> {
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
const Icon(Icons.error_outline, size: 40, color: AppTheme.danger), Icon(Icons.error_outline, size: 40, color: context.tokens.danger),
const SizedBox(height: 12), const SizedBox(height: 12),
Text('加载失败:${snap.error}'), Text('加载失败:${snap.error}'),
const SizedBox(height: 12), const SizedBox(height: 12),
@@ -300,11 +300,11 @@ class _ProductDetailScreenState extends ConsumerState<ProductDetailScreen> {
return Column( return 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.textSecondary)), color: context.tokens.muted)),
const SizedBox(height: 8), const SizedBox(height: 8),
SizedBox( SizedBox(
height: 120, height: 120,
@@ -330,10 +330,10 @@ class _ProductDetailScreenState extends ConsumerState<ProductDetailScreen> {
), ),
), ),
if (p.images.isEmpty && !_uploading) if (p.images.isEmpty && !_uploading)
const Padding( Padding(
padding: EdgeInsets.only(top: 4), padding: const EdgeInsets.only(top: 4),
child: Text('暂无图片,点击 + 上传', child: Text('暂无图片,点击 + 上传',
style: TextStyle(fontSize: 12, color: AppTheme.textSecondary)), style: TextStyle(fontSize: 12, color: context.tokens.muted)),
), ),
], ],
); );
@@ -348,8 +348,8 @@ class _ProductDetailScreenState extends ConsumerState<ProductDetailScreen> {
SizedBox( SizedBox(
width: 56, width: 56,
child: Text(label, child: Text(label,
style: const TextStyle( style: TextStyle(
fontSize: 13, color: AppTheme.textSecondary))), fontSize: 13, color: context.tokens.muted))),
const SizedBox(width: 8), const SizedBox(width: 8),
Expanded( Expanded(
child: Text(value, style: const TextStyle(fontSize: 13))), child: Text(value, style: const TextStyle(fontSize: 13))),
@@ -361,7 +361,7 @@ class _ProductDetailScreenState extends ConsumerState<ProductDetailScreen> {
elevation: 0, elevation: 0,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6), borderRadius: BorderRadius.circular(6),
side: BorderSide(color: AppTheme.border, width: 0.5), side: BorderSide(color: context.tokens.border, width: 0.5),
), ),
child: Padding( child: Padding(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
@@ -412,7 +412,7 @@ class _ProductDetailScreenState extends ConsumerState<ProductDetailScreen> {
elevation: 0, elevation: 0,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6), borderRadius: BorderRadius.circular(6),
side: BorderSide(color: AppTheme.border, width: 0.5), side: BorderSide(color: context.tokens.border, width: 0.5),
), ),
child: Padding( child: Padding(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
@@ -425,8 +425,8 @@ class _ProductDetailScreenState extends ConsumerState<ProductDetailScreen> {
if (p.descriptionDocContent?.isNotEmpty ?? false) ...[ if (p.descriptionDocContent?.isNotEmpty ?? false) ...[
const SizedBox(height: 10), const SizedBox(height: 10),
Text(p.descriptionDocContent!, Text(p.descriptionDocContent!,
style: const TextStyle( style: TextStyle(
fontSize: 13, color: AppTheme.textSecondary, height: 1.6)), fontSize: 13, color: context.tokens.muted, height: 1.6)),
], ],
], ],
), ),
@@ -443,20 +443,20 @@ class _ProductDetailScreenState extends ConsumerState<ProductDetailScreen> {
elevation: 0, elevation: 0,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6), borderRadius: BorderRadius.circular(6),
side: BorderSide(color: AppTheme.border, width: 0.5), side: BorderSide(color: context.tokens.border, width: 0.5),
), ),
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
child: Row( child: Row(
children: [ children: [
const Text('建议零售价', Text('建议零售价',
style: TextStyle(fontSize: 13, color: AppTheme.textSecondary)), style: TextStyle(fontSize: 13, color: context.tokens.muted)),
const Spacer(), const Spacer(),
Text('¥$priceStr', Text('¥$priceStr',
style: const TextStyle( style: TextStyle(
fontSize: 22, fontSize: 22,
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
color: AppTheme.danger)), color: context.tokens.danger)),
], ],
), ),
), ),
@@ -468,7 +468,7 @@ class _ProductDetailScreenState extends ConsumerState<ProductDetailScreen> {
elevation: 0, elevation: 0,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6), borderRadius: BorderRadius.circular(6),
side: BorderSide(color: AppTheme.border, width: 0.5), side: BorderSide(color: context.tokens.border, width: 0.5),
), ),
child: Padding( child: Padding(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
@@ -509,14 +509,14 @@ class _ProductDetailScreenState extends ConsumerState<ProductDetailScreen> {
minLines: 3, minLines: 3,
decoration: InputDecoration( decoration: InputDecoration(
hintText: '输入商品描述,例如酒的产地、工艺、口感等...', hintText: '输入商品描述,例如酒的产地、工艺、口感等...',
hintStyle: const TextStyle( hintStyle: TextStyle(
fontSize: 13, color: AppTheme.textSecondary), fontSize: 13, color: context.tokens.muted),
border: OutlineInputBorder( border: OutlineInputBorder(
borderRadius: BorderRadius.circular(4), borderRadius: BorderRadius.circular(4),
borderSide: BorderSide(color: AppTheme.border)), borderSide: BorderSide(color: context.tokens.border)),
enabledBorder: OutlineInputBorder( enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(4), borderRadius: BorderRadius.circular(4),
borderSide: BorderSide(color: AppTheme.border)), borderSide: BorderSide(color: context.tokens.border)),
contentPadding: const EdgeInsets.all(12), contentPadding: const EdgeInsets.all(12),
), ),
), ),
@@ -532,7 +532,7 @@ class _ProductDetailScreenState extends ConsumerState<ProductDetailScreen> {
elevation: 0, elevation: 0,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6), borderRadius: BorderRadius.circular(6),
side: BorderSide(color: AppTheme.border, width: 0.5), side: BorderSide(color: context.tokens.border, width: 0.5),
), ),
child: Padding( child: Padding(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
@@ -547,9 +547,9 @@ class _ProductDetailScreenState extends ConsumerState<ProductDetailScreen> {
children: [ children: [
Expanded( Expanded(
child: Text(publicUrl, child: Text(publicUrl,
style: const TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
color: AppTheme.primary, color: context.tokens.primary,
fontFamily: 'monospace')), fontFamily: 'monospace')),
), ),
const SizedBox(width: 8), const SizedBox(width: 8),
@@ -597,9 +597,9 @@ class _ImageThumbnail extends StatelessWidget {
errorBuilder: (_, __, ___) => Container( errorBuilder: (_, __, ___) => Container(
width: 110, width: 110,
height: 110, height: 110,
color: AppTheme.border, color: context.tokens.border,
child: const Icon(Icons.broken_image, child: Icon(Icons.broken_image,
color: AppTheme.textSecondary), color: context.tokens.muted),
), ),
), ),
), ),
@@ -642,9 +642,9 @@ class _UploadButton extends StatelessWidget {
width: 110, width: 110,
height: 110, height: 110,
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all(color: AppTheme.border, width: 1.5), border: Border.all(color: context.tokens.border, width: 1.5),
borderRadius: BorderRadius.circular(4), borderRadius: BorderRadius.circular(4),
color: AppTheme.background, color: context.tokens.bg,
), ),
child: uploading child: uploading
? const Center( ? const Center(
@@ -652,15 +652,15 @@ class _UploadButton extends StatelessWidget {
width: 24, width: 24,
height: 24, height: 24,
child: CircularProgressIndicator(strokeWidth: 2))) child: CircularProgressIndicator(strokeWidth: 2)))
: const Column( : Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Icon(Icons.add_photo_alternate_outlined, Icon(Icons.add_photo_alternate_outlined,
size: 28, color: AppTheme.textSecondary), size: 28, color: context.tokens.muted),
SizedBox(height: 4), const SizedBox(height: 4),
Text('上传图片', Text('上传图片',
style: TextStyle( style: TextStyle(
fontSize: 11, color: AppTheme.textSecondary)), fontSize: 11, color: context.tokens.muted)),
], ],
), ),
), ),
@@ -2,7 +2,7 @@ import '../../core/utils/dialog_util.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.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/warehouse.dart'; import '../../models/warehouse.dart';
import '../../providers/product_option_provider.dart'; import '../../providers/product_option_provider.dart';
import '../../providers/warehouse_provider.dart'; import '../../providers/warehouse_provider.dart';
@@ -174,8 +174,8 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
? [ ? [
DataRow(cells: [ DataRow(cells: [
const DataCell(SizedBox()), const DataCell(SizedBox()),
const DataCell(Text('暂无数据', DataCell(Text('暂无数据',
style: TextStyle(color: AppTheme.textSecondary))), style: TextStyle(color: context.tokens.muted))),
const DataCell(SizedBox()), const DataCell(SizedBox()),
const DataCell(SizedBox()), const DataCell(SizedBox()),
]) ])
@@ -183,10 +183,10 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
: paged : paged
.map((it) => DataRow(cells: [ .map((it) => DataRow(cells: [
DataCell(Text(it.code ?? '-', DataCell(Text(it.code ?? '-',
style: const TextStyle( style: TextStyle(
fontFamily: 'monospace', fontFamily: 'monospace',
fontSize: 12, fontSize: 12,
color: AppTheme.textSecondary))), color: context.tokens.muted))),
DataCell(Text(it.name, DataCell(Text(it.name,
style: style:
const TextStyle(fontWeight: FontWeight.w500))), const TextStyle(fontWeight: FontWeight.w500))),
@@ -309,8 +309,8 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
? [ ? [
DataRow(cells: [ DataRow(cells: [
const DataCell(SizedBox()), const DataCell(SizedBox()),
const DataCell(Text('暂无数据', DataCell(Text('暂无数据',
style: TextStyle(color: AppTheme.textSecondary))), style: TextStyle(color: context.tokens.muted))),
const DataCell(SizedBox()), const DataCell(SizedBox()),
const DataCell(SizedBox()), const DataCell(SizedBox()),
]) ])
@@ -318,10 +318,10 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
: paged : paged
.map((it) => DataRow(cells: [ .map((it) => DataRow(cells: [
DataCell(Text(it.code ?? '-', DataCell(Text(it.code ?? '-',
style: const TextStyle( style: TextStyle(
fontFamily: 'monospace', fontFamily: 'monospace',
fontSize: 12, fontSize: 12,
color: AppTheme.textSecondary))), color: context.tokens.muted))),
DataCell(Text(it.name, DataCell(Text(it.name,
style: style:
const TextStyle(fontWeight: FontWeight.w500))), const TextStyle(fontWeight: FontWeight.w500))),
@@ -448,8 +448,8 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
? [ ? [
DataRow(cells: [ DataRow(cells: [
const DataCell(SizedBox()), const DataCell(SizedBox()),
const DataCell(Text('暂无数据', DataCell(Text('暂无数据',
style: TextStyle(color: AppTheme.textSecondary))), style: TextStyle(color: context.tokens.muted))),
const DataCell(SizedBox()), const DataCell(SizedBox()),
const DataCell(SizedBox()), const DataCell(SizedBox()),
const DataCell(SizedBox()), const DataCell(SizedBox()),
@@ -458,10 +458,10 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
: paged : paged
.map((it) => DataRow(cells: [ .map((it) => DataRow(cells: [
DataCell(Text(it.code ?? '-', DataCell(Text(it.code ?? '-',
style: const TextStyle( style: TextStyle(
fontFamily: 'monospace', fontFamily: 'monospace',
fontSize: 12, fontSize: 12,
color: AppTheme.textSecondary))), color: context.tokens.muted))),
DataCell(Text(it.name, DataCell(Text(it.name,
style: style:
const TextStyle(fontWeight: FontWeight.w500))), const TextStyle(fontWeight: FontWeight.w500))),
@@ -547,10 +547,10 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
const Icon(Icons.cloud_off, size: 40, color: AppTheme.textSecondary), Icon(Icons.cloud_off, size: 40, color: context.tokens.muted),
const SizedBox(height: 12), const SizedBox(height: 12),
const Text('暂无数据,网络不可用', Text('暂无数据,网络不可用',
style: TextStyle(color: AppTheme.textSecondary)), style: TextStyle(color: context.tokens.muted)),
const SizedBox(height: 12), const SizedBox(height: 12),
ElevatedButton(onPressed: onRetry, child: const Text('重试')), ElevatedButton(onPressed: onRetry, child: const Text('重试')),
], ],
@@ -608,8 +608,8 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
WriteGuard( WriteGuard(
child: TextButton( child: TextButton(
onPressed: onDelete, onPressed: onDelete,
child: const Text('删除', child: Text('删除',
style: TextStyle(fontSize: 13, color: AppTheme.danger)), style: TextStyle(fontSize: 13, color: context.tokens.danger)),
), ),
), ),
], ],
@@ -635,7 +635,7 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
size: 20, size: 20,
color: isDefault color: isDefault
? const Color(0xFFFFB300) // 明亮金色,醒目区分默认项 ? const Color(0xFFFFB300) // 明亮金色,醒目区分默认项
: AppTheme.textSecondary), : context.tokens.muted),
onPressed: isDefault ? null : onSetDefault, onPressed: isDefault ? null : onSetDefault,
), ),
TextButton( TextButton(
@@ -644,8 +644,8 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
), ),
TextButton( TextButton(
onPressed: onDelete, onPressed: onDelete,
child: const Text('删除', child: Text('删除',
style: TextStyle(fontSize: 12, color: AppTheme.danger)), style: TextStyle(fontSize: 12, color: context.tokens.danger)),
), ),
], ],
), ),
@@ -707,7 +707,7 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
ElevatedButton( ElevatedButton(
onPressed: () => Navigator.of(ctx).pop(true), onPressed: () => Navigator.of(ctx).pop(true),
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: AppTheme.danger, backgroundColor: context.tokens.danger,
foregroundColor: Colors.white), foregroundColor: Colors.white),
child: const Text('删除'), child: const Text('删除'),
), ),
@@ -721,7 +721,7 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
if (mounted) { if (mounted) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text('删除失败:$e'), backgroundColor: AppTheme.danger), content: Text('删除失败:$e'), backgroundColor: context.tokens.danger),
); );
} }
} }
@@ -810,8 +810,8 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
? [ ? [
DataRow(cells: [ DataRow(cells: [
const DataCell(SizedBox()), const DataCell(SizedBox()),
const DataCell(Text('暂无数据', DataCell(Text('暂无数据',
style: TextStyle(color: AppTheme.textSecondary))), style: TextStyle(color: context.tokens.muted))),
const DataCell(SizedBox()), const DataCell(SizedBox()),
const DataCell(SizedBox()) const DataCell(SizedBox())
]) ])
@@ -819,10 +819,10 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
: paged : paged
.map((it) => DataRow(cells: [ .map((it) => DataRow(cells: [
DataCell(Text(it.code ?? '-', DataCell(Text(it.code ?? '-',
style: const TextStyle( style: TextStyle(
fontFamily: 'monospace', fontFamily: 'monospace',
fontSize: 12, fontSize: 12,
color: AppTheme.textSecondary))), color: context.tokens.muted))),
DataCell(Text(it.name, DataCell(Text(it.name,
style: style:
const TextStyle(fontWeight: FontWeight.w500))), const TextStyle(fontWeight: FontWeight.w500))),
@@ -935,8 +935,8 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
? [ ? [
DataRow(cells: [ DataRow(cells: [
const DataCell(SizedBox()), const DataCell(SizedBox()),
const DataCell(Text('暂无数据', DataCell(Text('暂无数据',
style: TextStyle(color: AppTheme.textSecondary))), style: TextStyle(color: context.tokens.muted))),
const DataCell(SizedBox()), const DataCell(SizedBox()),
const DataCell(SizedBox()) const DataCell(SizedBox())
]) ])
@@ -944,10 +944,10 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
: paged : paged
.map((it) => DataRow(cells: [ .map((it) => DataRow(cells: [
DataCell(Text(it.code ?? '-', DataCell(Text(it.code ?? '-',
style: const TextStyle( style: TextStyle(
fontFamily: 'monospace', fontFamily: 'monospace',
fontSize: 12, fontSize: 12,
color: AppTheme.textSecondary))), color: context.tokens.muted))),
DataCell(Text(it.name, DataCell(Text(it.name,
style: style:
const TextStyle(fontWeight: FontWeight.w500))), const TextStyle(fontWeight: FontWeight.w500))),
@@ -1060,8 +1060,8 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
? [ ? [
DataRow(cells: [ DataRow(cells: [
const DataCell(SizedBox()), const DataCell(SizedBox()),
const DataCell(Text('暂无数据', DataCell(Text('暂无数据',
style: TextStyle(color: AppTheme.textSecondary))), style: TextStyle(color: context.tokens.muted))),
const DataCell(SizedBox()), const DataCell(SizedBox()),
const DataCell(SizedBox()) const DataCell(SizedBox())
]) ])
@@ -1069,10 +1069,10 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
: paged : paged
.map((it) => DataRow(cells: [ .map((it) => DataRow(cells: [
DataCell(Text(it.code ?? '-', DataCell(Text(it.code ?? '-',
style: const TextStyle( style: TextStyle(
fontFamily: 'monospace', fontFamily: 'monospace',
fontSize: 12, fontSize: 12,
color: AppTheme.textSecondary))), color: context.tokens.muted))),
DataCell(Text(it.name, DataCell(Text(it.name,
style: style:
const TextStyle(fontWeight: FontWeight.w500))), const TextStyle(fontWeight: FontWeight.w500))),
@@ -1180,9 +1180,9 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
.read( .read(
productDescriptionDocListProvider.notifier) productDescriptionDocListProvider.notifier)
.delete(it.id)), .delete(it.id)),
child: const Text('删除', child: Text('删除',
style: TextStyle( style: TextStyle(
fontSize: 13, color: AppTheme.danger)), fontSize: 13, color: context.tokens.danger)),
), ),
], ],
)) ))
@@ -1197,8 +1197,8 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
? [ ? [
DataRow(cells: [ DataRow(cells: [
const DataCell(SizedBox()), const DataCell(SizedBox()),
const DataCell(Text('暂无数据', DataCell(Text('暂无数据',
style: TextStyle(color: AppTheme.textSecondary))), style: TextStyle(color: context.tokens.muted))),
const DataCell(SizedBox()), const DataCell(SizedBox()),
const DataCell(SizedBox()) const DataCell(SizedBox())
]) ])
@@ -1211,8 +1211,8 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
DataCell(Text(it.title, DataCell(Text(it.title,
style: const TextStyle(fontWeight: FontWeight.w500))), style: const TextStyle(fontWeight: FontWeight.w500))),
DataCell(Text(preview, DataCell(Text(preview,
style: const TextStyle( style: TextStyle(
fontSize: 12, color: AppTheme.textSecondary))), fontSize: 12, color: context.tokens.muted))),
DataCell(Text(it.remark ?? '-')), DataCell(Text(it.remark ?? '-')),
DataCell(_actionButtons( DataCell(_actionButtons(
onEdit: () => _showDescDocDialog( onEdit: () => _showDescDocDialog(
@@ -1308,7 +1308,7 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text('保存失败:$e'), content: Text('保存失败:$e'),
backgroundColor: AppTheme.danger), backgroundColor: context.tokens.danger),
); );
} }
} }
@@ -1358,9 +1358,9 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
), ),
TextButton( TextButton(
onPressed: () => _confirmDeleteWarehouse(w), onPressed: () => _confirmDeleteWarehouse(w),
child: const Text('删除', child: Text('删除',
style: style: TextStyle(
TextStyle(fontSize: 13, color: AppTheme.danger)), fontSize: 13, color: context.tokens.danger)),
), ),
], ],
)) ))
@@ -1373,12 +1373,12 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
], ],
rows: warehouses.isEmpty rows: warehouses.isEmpty
? [ ? [
const DataRow(cells: [ DataRow(cells: [
DataCell(SizedBox()), const DataCell(SizedBox()),
DataCell(Text('暂无仓库', DataCell(Text('暂无仓库',
style: TextStyle(color: AppTheme.textSecondary))), style: TextStyle(color: context.tokens.muted))),
DataCell(SizedBox()), const DataCell(SizedBox()),
DataCell(SizedBox()), const DataCell(SizedBox()),
]) ])
] ]
: warehouses : warehouses
@@ -1387,8 +1387,8 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
style: const TextStyle(fontWeight: FontWeight.w500))), style: const TextStyle(fontWeight: FontWeight.w500))),
DataCell(Text(w.location ?? '-')), DataCell(Text(w.location ?? '-')),
DataCell(w.isDefault DataCell(w.isDefault
? const Icon(Icons.check_circle, ? Icon(Icons.check_circle,
color: AppTheme.success, size: 18) color: context.tokens.success, size: 18)
: const SizedBox()), : const SizedBox()),
DataCell(_actionButtons( DataCell(_actionButtons(
onEdit: () => _showWarehouseDialog(warehouse: w), onEdit: () => _showWarehouseDialog(warehouse: w),
@@ -1423,7 +1423,7 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
ElevatedButton( ElevatedButton(
onPressed: () => Navigator.of(ctx).pop(true), onPressed: () => Navigator.of(ctx).pop(true),
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: AppTheme.danger, backgroundColor: context.tokens.danger,
foregroundColor: Colors.white), foregroundColor: Colors.white),
child: const Text('删除'), child: const Text('删除'),
), ),
@@ -1434,13 +1434,15 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
try { try {
await ref.read(warehouseListProvider.notifier).deleteWarehouse(w.id); await ref.read(warehouseListProvider.notifier).deleteWarehouse(w.id);
if (mounted) { if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar( ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('删除成功'), backgroundColor: AppTheme.success)); content: const Text('删除成功'),
backgroundColor: context.tokens.success));
} }
} catch (e) { } catch (e) {
if (mounted) { if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar( ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('删除失败:$e'), backgroundColor: AppTheme.danger)); content: Text('删除失败:$e'),
backgroundColor: context.tokens.danger));
} }
} }
} }
@@ -1527,7 +1529,7 @@ class _ProductsScreenState extends ConsumerState<ProductsScreen> {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text('创建失败:$e'), content: Text('创建失败:$e'),
backgroundColor: AppTheme.danger), backgroundColor: context.tokens.danger),
); );
} }
} }
@@ -1595,13 +1597,14 @@ class _WarehouseFormDialogState extends ConsumerState<_WarehouseFormDialog> {
widget.onSaved(); widget.onSaved();
ScaffoldMessenger.of(context).showSnackBar(SnackBar( ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(widget.warehouse != null ? '仓库更新成功' : '仓库创建成功'), content: Text(widget.warehouse != null ? '仓库更新成功' : '仓库创建成功'),
backgroundColor: AppTheme.success, backgroundColor: context.tokens.success,
)); ));
} }
} catch (e) { } catch (e) {
if (mounted) { if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar( ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('保存失败:$e'), backgroundColor: AppTheme.danger)); content: Text('保存失败:$e'),
backgroundColor: context.tokens.danger));
} }
} finally { } finally {
if (mounted) setState(() => _saving = false); if (mounted) setState(() => _saving = false);