refactor(client): 设置/外壳颜色迁移到 context.tokens

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-06-25 00:10:15 +08:00
parent 7a92b0dfff
commit 9afe0dcf6e
2 changed files with 102 additions and 102 deletions
@@ -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<SettingsScreen> {
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<SettingsScreen> {
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<SettingsScreen> {
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<SettingsScreen> {
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<SettingsScreen> {
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<SettingsScreen> {
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<SettingsScreen> {
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<SettingsScreen> {
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<SettingsScreen> {
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<SettingsScreen> {
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<SettingsScreen> {
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<SettingsScreen> {
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<SettingsScreen> {
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<SettingsScreen> {
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<SettingsScreen> {
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<SettingsScreen> {
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<SettingsScreen> {
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<SettingsScreen> {
});
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<SettingsScreen> {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('更新失败:$e'),
backgroundColor: AppTheme.danger),
backgroundColor: context.tokens.danger),
);
}
}
@@ -731,8 +731,8 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
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<SettingsScreen> {
(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<SettingsScreen> {
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 {
+20 -20
View File
@@ -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<AppShell> {
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<AppShell> {
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<AppShell> {
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<AppShell> {
// 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<AppShell> {
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<AppShell> {
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<AppShell> {
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<AppShell> {
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)),
),
],