From 9afe0dcf6ee9b5434d4aa04f303847be5ba77b94 Mon Sep 17 00:00:00 2001 From: wangjia <809946525@qq.com> Date: Thu, 25 Jun 2026 00:10:15 +0800 Subject: [PATCH] =?UTF-8?q?refactor(client):=20=E8=AE=BE=E7=BD=AE/?= =?UTF-8?q?=E5=A4=96=E5=A3=B3=E9=A2=9C=E8=89=B2=E8=BF=81=E7=A7=BB=E5=88=B0?= =?UTF-8?q?=20context.tokens?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- .../lib/screens/settings/settings_screen.dart | 164 +++++++++--------- client/lib/screens/shell/app_shell.dart | 40 ++--- 2 files changed, 102 insertions(+), 102 deletions(-) diff --git a/client/lib/screens/settings/settings_screen.dart b/client/lib/screens/settings/settings_screen.dart index 948becc..9f490dd 100644 --- a/client/lib/screens/settings/settings_screen.dart +++ b/client/lib/screens/settings/settings_screen.dart @@ -12,7 +12,7 @@ import '../../core/config/app_config.dart'; import '../../core/config/app_info.dart'; import '../../core/config/license_copy.dart'; import '../../core/responsive/responsive.dart'; -import '../../core/theme/app_theme.dart'; +import '../../core/theme/context_tokens.dart'; import '../../models/number_rule.dart'; import '../../models/user.dart'; import '../../providers/license_provider.dart'; @@ -48,16 +48,16 @@ class _SettingsScreenState extends ConsumerState { child: Column( children: [ Container( - color: AppTheme.surface, - child: const TabBar( + color: context.tokens.surface, + child: TabBar( isScrollable: true, - labelColor: AppTheme.primary, - unselectedLabelColor: AppTheme.textSecondary, - indicatorColor: AppTheme.primary, + labelColor: context.tokens.primary, + unselectedLabelColor: context.tokens.muted, + indicatorColor: context.tokens.primary, indicatorWeight: 2, labelStyle: - TextStyle(fontSize: 14, fontWeight: FontWeight.w500), - tabs: [ + const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), + tabs: const [ Tab(text: '酒行信息'), Tab(text: '用户管理'), Tab(text: '编号规则'), @@ -95,10 +95,10 @@ class _SettingsScreenState extends ConsumerState { child: Column( mainAxisAlignment: MainAxisAlignment.center, 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 Text('暂无数据,网络不可用', - style: TextStyle(color: AppTheme.textSecondary)), + Text('暂无数据,网络不可用', + style: TextStyle(color: context.tokens.muted)), const SizedBox(height: 12), ElevatedButton( onPressed: () => ref.invalidate(shopInfoProvider), @@ -115,8 +115,8 @@ class _SettingsScreenState extends ConsumerState { const Text('酒行信息', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600)), const SizedBox(height: 4), - const Text('门店的基本信息,仅管理员可编辑', - style: TextStyle(fontSize: 13, color: AppTheme.textSecondary)), + Text('门店的基本信息,仅管理员可编辑', + style: TextStyle(fontSize: 13, color: context.tokens.muted)), const SizedBox(height: 16), Card( child: Padding( @@ -136,7 +136,7 @@ class _SettingsScreenState extends ConsumerState { style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600)), const SizedBox(height: 4), Text(shop.code.isNotEmpty ? shop.code : '—', - style: const TextStyle(fontSize: 13, color: AppTheme.textSecondary)), + style: TextStyle(fontSize: 13, color: context.tokens.muted)), ], ), ], @@ -192,7 +192,7 @@ class _SettingsScreenState extends ConsumerState { children: [ Container( height: 52, - color: AppTheme.surface, + color: context.tokens.surface, padding: const EdgeInsets.symmetric(horizontal: 12), child: Row( children: [ @@ -214,10 +214,10 @@ class _SettingsScreenState extends ConsumerState { child: Column( mainAxisAlignment: MainAxisAlignment.center, 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 Text('暂无数据,网络不可用', - style: const TextStyle(color: AppTheme.textSecondary)), + Text('暂无数据,网络不可用', + style: TextStyle(color: context.tokens.muted)), const SizedBox(height: 12), ElevatedButton( onPressed: () => ref.read(userListProvider.notifier).reload(), @@ -244,13 +244,13 @@ class _SettingsScreenState extends ConsumerState { CircleAvatar( radius: 14, backgroundColor: - AppTheme.primary.withOpacity(0.15), + context.tokens.primary.withOpacity(0.15), child: Text( (u.realName ?? u.username) .substring(0, 1), - style: const TextStyle( + style: TextStyle( fontSize: 12, - color: AppTheme.primary, + color: context.tokens.primary, fontWeight: FontWeight.w600), ), ), @@ -314,8 +314,8 @@ class _SettingsScreenState extends ConsumerState { const Text('授权信息', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600)), const SizedBox(height: 4), - const Text('当前门店的授权状态与设备绑定', - style: TextStyle(fontSize: 13, color: AppTheme.textSecondary)), + Text('当前门店的授权状态与设备绑定', + style: TextStyle(fontSize: 13, color: context.tokens.muted)), const SizedBox(height: 16), Card( child: Padding( @@ -366,11 +366,11 @@ class _SettingsScreenState extends ConsumerState { padding: const EdgeInsets.symmetric(vertical: 8), child: Row( children: [ - const SizedBox( + SizedBox( width: 180, child: Text('授权状态', style: TextStyle( - fontSize: 14, color: AppTheme.textSecondary)), + fontSize: 14, color: context.tokens.muted)), ), Text(phaseText, style: TextStyle( @@ -405,19 +405,19 @@ class _SettingsScreenState extends ConsumerState { crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( - children: const [ + children: [ Icon(Icons.info_outline, - size: 16, color: AppTheme.textSecondary), - SizedBox(width: 6), - Text('过期说明', + size: 16, color: context.tokens.muted), + const SizedBox(width: 6), + const Text('过期说明', style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600)), ], ), const SizedBox(height: 4), - const Text('授权到期后会分阶段降级,请在到期前及时续费', + Text('授权到期后会分阶段降级,请在到期前及时续费', style: - TextStyle(fontSize: 13, color: AppTheme.textSecondary)), + TextStyle(fontSize: 13, color: context.tokens.muted)), const SizedBox(height: 12), for (final note in LicenseCopy.degradationNotes()) Padding( @@ -425,10 +425,10 @@ class _SettingsScreenState extends ConsumerState { child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Padding( - padding: EdgeInsets.only(top: 6, right: 8), + Padding( + padding: const EdgeInsets.only(top: 6, right: 8), child: Icon(Icons.circle, - size: 5, color: AppTheme.textSecondary), + size: 5, color: context.tokens.muted), ), Expanded( child: Text(note, @@ -455,9 +455,9 @@ class _SettingsScreenState extends ConsumerState { style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600)), const SizedBox(height: 8), - const Text('输入购买或活动获得的激活码,时长将叠加到当前授权之后', + Text('输入购买或活动获得的激活码,时长将叠加到当前授权之后', style: TextStyle( - fontSize: 13, color: AppTheme.textSecondary)), + fontSize: 13, color: context.tokens.muted)), const SizedBox(height: 12), Row( children: [ @@ -509,8 +509,8 @@ class _SettingsScreenState extends ConsumerState { await ref.read(licenseProvider.notifier).reload(); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text('兑换成功,授权已更新'), backgroundColor: AppTheme.success), + SnackBar( + content: const Text('兑换成功,授权已更新'), backgroundColor: context.tokens.success), ); } } catch (e) { @@ -518,7 +518,7 @@ class _SettingsScreenState extends ConsumerState { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(e.toString()), - backgroundColor: AppTheme.danger), + backgroundColor: context.tokens.danger), ); } } finally { @@ -571,10 +571,10 @@ class _SettingsScreenState extends ConsumerState { child: Column( mainAxisAlignment: MainAxisAlignment.center, 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 Text('暂无数据,网络不可用', - style: const TextStyle(color: AppTheme.textSecondary)), + Text('暂无数据,网络不可用', + style: TextStyle(color: context.tokens.muted)), const SizedBox(height: 12), ElevatedButton( onPressed: () => @@ -593,9 +593,9 @@ class _SettingsScreenState extends ConsumerState { style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600)), const SizedBox(height: 4), - const Text('配置各类单据的自动编号规则,修改后对新建单据生效', + Text('配置各类单据的自动编号规则,修改后对新建单据生效', style: TextStyle( - fontSize: 13, color: AppTheme.textSecondary)), + fontSize: 13, color: context.tokens.muted)), const SizedBox(height: 16), Card( child: DataTable( @@ -618,20 +618,20 @@ class _SettingsScreenState extends ConsumerState { padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 2), decoration: BoxDecoration( - color: AppTheme.primary.withOpacity(0.1), + color: context.tokens.primary.withOpacity(0.1), borderRadius: BorderRadius.circular(3), ), child: Text(r.prefix, - style: const TextStyle( - color: AppTheme.primary, + style: TextStyle( + color: context.tokens.primary, fontFamily: 'monospace', fontSize: 13, fontWeight: FontWeight.w600)), )), DataCell(Text(r.dateFormat, - style: const TextStyle( + style: TextStyle( fontSize: 12, - color: AppTheme.textSecondary))), + color: context.tokens.muted))), DataCell(Text(r.exampleNo, style: const TextStyle( fontFamily: 'monospace', fontSize: 12))), @@ -694,9 +694,9 @@ class _SettingsScreenState extends ConsumerState { }); if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text('编号规则已更新'), - backgroundColor: AppTheme.success), + SnackBar( + content: const Text('编号规则已更新'), + backgroundColor: context.tokens.success), ); } } catch (e) { @@ -704,7 +704,7 @@ class _SettingsScreenState extends ConsumerState { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('更新失败:$e'), - backgroundColor: AppTheme.danger), + backgroundColor: context.tokens.danger), ); } } @@ -731,8 +731,8 @@ class _SettingsScreenState extends ConsumerState { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text('基本设置', - style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: AppTheme.primaryDark)), + Text('基本设置', + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: context.tokens.primaryDark)), const Divider(height: 24), _ParamRow( label: '系统名称', @@ -759,8 +759,8 @@ class _SettingsScreenState extends ConsumerState { (v) => setState(() => _sysTimezone = v)), ), const SizedBox(height: 16), - const Text('审核设置', - style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: AppTheme.primaryDark)), + Text('审核设置', + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: context.tokens.primaryDark)), const Divider(height: 24), _ParamRow( label: '入库单需要审核', @@ -792,9 +792,9 @@ class _SettingsScreenState extends ConsumerState { children: [ ElevatedButton( onPressed: () { - ScaffoldMessenger.of(context).showSnackBar(const SnackBar( - content: Text('设置已保存'), - backgroundColor: AppTheme.success)); + ScaffoldMessenger.of(context).showSnackBar(SnackBar( + content: const Text('设置已保存'), + backgroundColor: context.tokens.success)); }, child: const Text('保存设置'), ), @@ -943,14 +943,14 @@ class _UserFormDialogState extends ConsumerState<_UserFormDialog> { widget.onSaved(); ScaffoldMessenger.of(context).showSnackBar(SnackBar( content: Text(_isEdit ? '用户更新成功' : '用户创建成功'), - backgroundColor: AppTheme.success, + backgroundColor: context.tokens.success, )); } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar(SnackBar( content: Text('保存失败:$e'), - backgroundColor: AppTheme.danger, + backgroundColor: context.tokens.danger, )); } } finally { @@ -1054,16 +1054,16 @@ class _ResetPasswordDialogState extends ConsumerState<_ResetPasswordDialog> { await ref.read(userListProvider.notifier).resetPassword(widget.user.id, _ctrl.text); if (mounted) { Navigator.of(context).pop(); - ScaffoldMessenger.of(context).showSnackBar(const SnackBar( - content: Text('密码已重置'), - backgroundColor: AppTheme.success, + ScaffoldMessenger.of(context).showSnackBar(SnackBar( + content: const Text('密码已重置'), + backgroundColor: context.tokens.success, )); } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar(SnackBar( content: Text('重置失败:$e'), - backgroundColor: AppTheme.danger, + backgroundColor: context.tokens.danger, )); } } finally { @@ -1112,19 +1112,19 @@ class _RoleBadge extends StatelessWidget { switch (role) { case '超级管理员': bg = const Color(0xFFFCE4EC); - fg = AppTheme.danger; + fg = context.tokens.danger; break; case '管理员': bg = const Color(0xFFE3F2FD); - fg = AppTheme.primary; + fg = context.tokens.primary; break; case '操作员': bg = const Color(0xFFE8F5E9); - fg = AppTheme.success; + fg = context.tokens.success; break; default: bg = const Color(0xFFF5F5F5); - fg = AppTheme.textSecondary; + fg = context.tokens.muted; } return Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), @@ -1158,8 +1158,8 @@ class _ParamRow extends StatelessWidget { SizedBox( width: 180, child: Text(label, - style: const TextStyle( - fontSize: 14, color: AppTheme.textSecondary)), + style: TextStyle( + fontSize: 14, color: context.tokens.muted)), ), if (switchValue != null) Switch( @@ -1247,8 +1247,8 @@ class _ShopInfoRow extends StatelessWidget { SizedBox( width: 88, child: Text(label, - style: const TextStyle( - fontSize: 14, color: AppTheme.textSecondary)), + style: TextStyle( + fontSize: 14, color: context.tokens.muted)), ), Expanded( child: Text(value, @@ -1314,16 +1314,16 @@ class _ShopEditDialogState extends ConsumerState<_ShopEditDialog> { await ref.read(shopRepositoryProvider).uploadLogo(file.bytes!, file.name); ref.invalidate(shopInfoProvider); if (mounted) { - ScaffoldMessenger.of(context).showSnackBar(const SnackBar( - content: Text('Logo 已更新'), - backgroundColor: AppTheme.success, + ScaffoldMessenger.of(context).showSnackBar(SnackBar( + content: const Text('Logo 已更新'), + backgroundColor: context.tokens.success, )); } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar(SnackBar( content: Text('上传失败:$e'), - backgroundColor: AppTheme.danger, + backgroundColor: context.tokens.danger, )); } } finally { @@ -1344,16 +1344,16 @@ class _ShopEditDialogState extends ConsumerState<_ShopEditDialog> { if (mounted) { Navigator.of(context).pop(); widget.onSaved(); - ScaffoldMessenger.of(context).showSnackBar(const SnackBar( - content: Text('信息已更新'), - backgroundColor: AppTheme.success, + ScaffoldMessenger.of(context).showSnackBar(SnackBar( + content: const Text('信息已更新'), + backgroundColor: context.tokens.success, )); } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar(SnackBar( content: Text('保存失败:$e'), - backgroundColor: AppTheme.danger, + backgroundColor: context.tokens.danger, )); } } finally { diff --git a/client/lib/screens/shell/app_shell.dart b/client/lib/screens/shell/app_shell.dart index 3bbcf6f..3d46288 100644 --- a/client/lib/screens/shell/app_shell.dart +++ b/client/lib/screens/shell/app_shell.dart @@ -10,7 +10,7 @@ import '../../widgets/write_guard.dart'; import '../../core/config/app_config.dart'; import '../../core/config/license_copy.dart'; import '../../core/responsive/responsive.dart'; -import '../../core/theme/app_theme.dart'; +import '../../core/theme/context_tokens.dart'; import '../../providers/connectivity_provider.dart'; import '../../providers/session_heartbeat.dart'; import '../../providers/shop_provider.dart'; @@ -54,11 +54,11 @@ class _AppShellState extends ConsumerState { builder: (ctx) => PopScope( canPop: false, child: AlertDialog( - title: const Row( + title: Row( children: [ - Icon(Icons.system_update, color: AppTheme.primary), - SizedBox(width: 8), - Text('发现新版本'), + Icon(Icons.system_update, color: context.tokens.primary), + const SizedBox(width: 8), + const Text('发现新版本'), ], ), content: Text('发现新版本 v${info.latestVersion},需更新后才能继续使用,' @@ -94,7 +94,7 @@ class _AppShellState extends ConsumerState { final logoUrl = shopAsync.valueOrNull?.logoUrl ?? ''; return Drawer( child: Container( - color: AppTheme.primaryDark, + color: context.tokens.primaryDark, child: SafeArea( child: Column( children: [ @@ -102,7 +102,7 @@ class _AppShellState extends ConsumerState { Container( width: double.infinity, padding: const EdgeInsets.fromLTRB(16, 20, 16, 16), - color: AppTheme.primary, + color: context.tokens.primary, child: Row( children: [ _ShopLogo(logoUrl: logoUrl, shopName: shopName, size: 40), @@ -206,7 +206,7 @@ class _AppShellState extends ConsumerState { // Top Bar(高度含状态栏内边距,蓝色铺满到屏幕顶,内容下移避开状态栏) Container( height: 56 + topInset, - color: AppTheme.primary, + color: context.tokens.primary, padding: EdgeInsets.only(top: topInset, left: 8, right: 8), child: Row( children: [ @@ -296,7 +296,7 @@ class _AppShellState extends ConsumerState { duration: const Duration(milliseconds: 200), curve: Curves.easeInOut, width: sidebarWidth, - color: AppTheme.primaryDark, + color: context.tokens.primaryDark, child: Column( children: [ Expanded( @@ -457,7 +457,7 @@ class _AppShellState extends ConsumerState { if (!isOnline) Container( width: double.infinity, - color: AppTheme.danger, + color: context.tokens.danger, padding: const EdgeInsets.symmetric( horizontal: 16, vertical: 6), child: const Row( @@ -493,7 +493,7 @@ class _AppShellState extends ConsumerState { height: 28, color: isOnline ? const Color(0xFF37474F) - : AppTheme.danger, + : context.tokens.danger, padding: const EdgeInsets.symmetric(horizontal: 12), child: Row( @@ -596,7 +596,7 @@ class _AppShellState extends ConsumerState { void _showLicenseExpiryDialog(BuildContext ctx, LicenseInfo lic) { final (title, body) = LicenseCopy.dialog(lic); final Color titleColor = - lic.phase == 'grace' ? Colors.orange[800]! : AppTheme.danger; + lic.phase == 'grace' ? Colors.orange[800]! : ctx.tokens.danger; showDialog( context: ctx, barrierDismissible: true, @@ -651,7 +651,7 @@ class _SidebarItem extends StatelessWidget { return SizedBox( height: 48, child: Material( - color: isActive ? AppTheme.primary.withAlpha(76) : Colors.transparent, + color: isActive ? context.tokens.primary.withAlpha(76) : Colors.transparent, child: InkWell( onTap: onTap, hoverColor: Colors.white.withAlpha(13), @@ -824,9 +824,9 @@ void _showShopPanel(BuildContext context, AuthUser u, // Header Container( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16), - decoration: const BoxDecoration( - color: AppTheme.primary, - borderRadius: BorderRadius.vertical(top: Radius.circular(10)), + decoration: BoxDecoration( + color: context.tokens.primary, + borderRadius: const BorderRadius.vertical(top: Radius.circular(10)), ), child: Row( children: [ @@ -974,19 +974,19 @@ class _InfoRow extends StatelessWidget { Widget build(BuildContext context) { return Row( children: [ - Icon(icon, size: 16, color: AppTheme.textSecondary), + Icon(icon, size: 16, color: context.tokens.muted), const SizedBox(width: 10), SizedBox( width: 72, child: Text(label, style: - const TextStyle(fontSize: 13, color: AppTheme.textSecondary)), + TextStyle(fontSize: 13, color: context.tokens.muted)), ), Expanded( child: Text(value, - style: const TextStyle( + style: TextStyle( fontSize: 13, - color: AppTheme.textPrimary, + color: context.tokens.text, fontWeight: FontWeight.w500)), ), ],