feat: 添加视觉设计语言系统并重构认证页面UI

- 新增 visual_design_language.md 设计规范文档
- 新增 auth 设计 tokens (authBackground, authCard, authInput, feedback 系列等)
- 重构登录/注册/验证码/重置密码页面为新设计系统
- 新增 AuthHeroHeader, AuthSurfaceCard, AuthSection, AuthField, PasswordField 组件
- 重构 AppBanner 和 Toast 支持多类型配置 (info/success/warning/error)
- 后端 AgentScope: 重整 schemas/prompts/tools 作用域, 新增协议文档
- 更新 AGENTS.md 集成视觉设计语言约束
This commit is contained in:
qzl
2026-03-13 14:10:13 +08:00
parent fb3c649db7
commit a10a2db27a
100 changed files with 6333 additions and 4800 deletions
+104 -38
View File
@@ -1,74 +1,140 @@
import 'package:flutter/material.dart';
import '../../core/theme/design_tokens.dart';
class AppButton extends StatelessWidget {
const AppButton({
super.key,
required this.text,
this.onPressed,
this.isOutlined = false,
this.height = 52,
this.isLoading = false,
});
final String text;
final VoidCallback? onPressed;
final bool isOutlined;
final double height;
final bool isLoading;
const AppButton({
super.key,
required this.text,
this.onPressed,
this.isOutlined = false,
this.height = 44,
this.isLoading = false,
});
@override
Widget build(BuildContext context) {
final isDisabled = onPressed == null || isLoading;
if (isOutlined) {
return SizedBox(
height: height,
child: OutlinedButton(
onPressed: isLoading ? null : onPressed,
style: OutlinedButton.styleFrom(
backgroundColor: AppColors.background,
foregroundColor: AppColors.slate500,
side: const BorderSide(color: AppColors.input),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppRadius.sm),
backgroundColor: isDisabled
? AppColors.authSecondaryButtonBackground.withValues(
alpha: 0.55,
)
: AppColors.authSecondaryButtonBackground,
foregroundColor: isDisabled
? AppColors.authLinkMuted
: AppColors.authSecondaryButtonText,
side: BorderSide(
color: isDisabled
? AppColors.authSecondaryButtonBorder.withValues(alpha: 0.7)
: AppColors.authSecondaryButtonBorder,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppRadius.full),
),
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.xl),
),
child: isLoading
? const SizedBox(
width: 16,
height: 16,
child: CircularProgressIndicator(strokeWidth: 2),
? SizedBox(
width: 18,
height: 18,
child: CircularProgressIndicator(
strokeWidth: 2.2,
color: AppColors.authSecondaryButtonText,
),
)
: Text(
text,
style: const TextStyle(
fontSize: 13,
fontWeight: FontWeight.w500,
fontSize: 15,
fontWeight: FontWeight.w700,
letterSpacing: 0.2,
),
),
),
);
}
return SizedBox(
height: height,
child: ElevatedButton(
onPressed: isLoading ? null : onPressed,
child: isLoading
? const SizedBox(
width: 16,
height: 16,
child: CircularProgressIndicator(
strokeWidth: 2,
color: AppColors.primaryForeground,
),
)
: Text(
text,
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
return DecoratedBox(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(AppRadius.full),
boxShadow: isDisabled
? const []
: [
BoxShadow(
color: AppColors.blue300.withValues(alpha: 0.24),
blurRadius: 18,
offset: const Offset(0, 10),
),
],
),
child: SizedBox(
height: height,
width: double.infinity,
child: ElevatedButton(
onPressed: isLoading ? null : onPressed,
style: ButtonStyle(
elevation: const WidgetStatePropertyAll(0),
backgroundColor: WidgetStateProperty.resolveWith((states) {
if (states.contains(WidgetState.disabled)) {
return AppColors.authPrimaryButtonDisabled;
}
if (states.contains(WidgetState.pressed)) {
return AppColors.authPrimaryButtonPressed;
}
return AppColors.authPrimaryButton;
}),
foregroundColor: const WidgetStatePropertyAll(
AppColors.authPrimaryButtonText,
),
overlayColor: WidgetStateProperty.resolveWith((states) {
if (states.contains(WidgetState.pressed)) {
return AppColors.white.withValues(alpha: 0.08);
}
return null;
}),
shape: WidgetStatePropertyAll(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppRadius.full),
),
),
padding: const WidgetStatePropertyAll(
EdgeInsets.symmetric(horizontal: AppSpacing.xl),
),
),
child: isLoading
? const SizedBox(
width: 18,
height: 18,
child: CircularProgressIndicator(
strokeWidth: 2.2,
color: AppColors.authPrimaryButtonText,
),
)
: Text(
text,
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w700,
letterSpacing: 0.2,
color: isDisabled
? AppColors.authLinkMuted
: AppColors.authPrimaryButtonText,
),
),
),
),
);
}