refactor: 重构前端 UI 组件与后端 AgentScope schemas

This commit is contained in:
qzl
2026-03-12 18:26:10 +08:00
parent 78c2488144
commit f201babb48
16 changed files with 1341 additions and 617 deletions
@@ -4,6 +4,7 @@ import 'package:go_router/go_router.dart';
import '../../../../core/di/injection.dart';
import '../../../../core/notifications/local_notification_service.dart';
import '../../../../core/theme/design_tokens.dart';
import '../../../../shared/widgets/page_header.dart' as widgets;
import '../../data/services/calendar_service.dart';
import '../../data/models/schedule_item_model.dart';
import '../widgets/create_event_sheet.dart';
@@ -62,20 +63,22 @@ class _CalendarEventDetailScreenState extends State<CalendarEventDetailScreen> {
style: TextStyle(color: AppColors.slate600),
),
const SizedBox(height: 16),
GestureDetector(
onTap: () => context.pop(),
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 8,
),
decoration: BoxDecoration(
color: AppColors.blue600,
borderRadius: BorderRadius.circular(20),
SizedBox(
height: AppSpacing.xxl * 2,
child: TextButton(
onPressed: () => context.pop(),
style: TextButton.styleFrom(
padding: const EdgeInsets.symmetric(
horizontal: AppSpacing.lg,
),
backgroundColor: AppColors.blue600,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppRadius.full),
),
),
child: const Text(
'返回',
style: TextStyle(color: Colors.white),
style: TextStyle(color: AppColors.white),
),
),
),
@@ -108,23 +111,7 @@ class _CalendarEventDetailScreenState extends State<CalendarEventDetailScreen> {
padding: const EdgeInsets.only(left: 16, right: 16, top: 12, bottom: 8),
child: Row(
children: [
GestureDetector(
onTap: () => Navigator.of(context).pop(),
child: Container(
width: 36,
height: 36,
decoration: BoxDecoration(
color: const Color(0xFFF8FAFF),
borderRadius: BorderRadius.circular(18),
border: Border.all(color: const Color(0xFFDEE7F6)),
),
child: const Icon(
LucideIcons.chevronLeft,
size: 16,
color: AppColors.slate700,
),
),
),
widgets.BackButton(onPressed: () => Navigator.of(context).pop()),
],
),
),
@@ -241,7 +228,7 @@ class _CalendarEventDetailScreenState extends State<CalendarEventDetailScreen> {
Row(
children: [
if (event.canEdit)
GestureDetector(
_buildHeaderActionButton(
onTap: () => CreateEventSheet.edit(
context,
event,
@@ -251,43 +238,23 @@ class _CalendarEventDetailScreenState extends State<CalendarEventDetailScreen> {
});
},
),
child: Container(
width: 36,
height: 36,
decoration: BoxDecoration(
color: const Color(0xFFF8FAFF),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: const Color(0xFFDCE5F4)),
),
child: const Icon(
LucideIcons.pencil,
size: 18,
color: AppColors.slate600,
),
),
icon: LucideIcons.pencil,
iconColor: AppColors.slate600,
backgroundColor: AppColors.surfaceTertiary,
borderColor: AppColors.borderTertiary,
),
if (event.canEdit) const SizedBox(width: 8),
if (event.canDelete)
GestureDetector(
_buildHeaderActionButton(
onTap: _showDeleteConfirmation,
child: Container(
width: 36,
height: 36,
decoration: BoxDecoration(
color: const Color(0xFFFFF1F2),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: const Color(0xFFFECACA)),
),
child: const Icon(
LucideIcons.trash2,
size: 18,
color: AppColors.red500,
),
),
icon: LucideIcons.trash2,
iconColor: AppColors.red500,
backgroundColor: AppColors.warningBackground,
borderColor: AppColors.messageRejectBorder,
),
if (event.canInvite) ...[
const SizedBox(width: 8),
GestureDetector(
_buildHeaderActionButton(
onTap: () => CalendarShareDialog.show(
context,
event.id,
@@ -295,20 +262,10 @@ class _CalendarEventDetailScreenState extends State<CalendarEventDetailScreen> {
canInvite: event.canInvite,
canEdit: event.canEdit,
),
child: Container(
width: 36,
height: 36,
decoration: BoxDecoration(
color: const Color(0xFFF0FDF4),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: const Color(0xFFBBF7D0)),
),
child: const Icon(
LucideIcons.share2,
size: 18,
color: AppColors.slate600,
),
),
icon: LucideIcons.share2,
iconColor: AppColors.slate600,
backgroundColor: AppColors.blue50,
borderColor: AppColors.blue100,
),
],
],
@@ -317,6 +274,35 @@ class _CalendarEventDetailScreenState extends State<CalendarEventDetailScreen> {
);
}
Widget _buildHeaderActionButton({
required VoidCallback onTap,
required IconData icon,
required Color iconColor,
required Color backgroundColor,
required Color borderColor,
}) {
return SizedBox(
width: AppSpacing.xxl * 2,
height: AppSpacing.xxl * 2,
child: TextButton(
onPressed: onTap,
style: TextButton.styleFrom(
padding: const EdgeInsets.all(AppSpacing.none),
backgroundColor: backgroundColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppRadius.md),
side: BorderSide(color: borderColor),
),
),
child: Icon(
icon,
size: AppSpacing.lg + AppSpacing.xs,
color: iconColor,
),
),
);
}
void _showDeleteConfirmation() {
showDialog(
context: context,
@@ -145,12 +145,22 @@ class _CreateEventSheetState extends State<CreateEventSheet>
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
onTap: () => Navigator.pop(context),
child: const Icon(
LucideIcons.x,
size: 24,
color: AppColors.slate700,
SizedBox(
width: AppSpacing.xxl * 2,
height: AppSpacing.xxl * 2,
child: TextButton(
onPressed: () => Navigator.pop(context),
style: TextButton.styleFrom(
padding: const EdgeInsets.all(AppSpacing.none),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppRadius.full),
),
),
child: const Icon(
LucideIcons.x,
size: AppSpacing.xxl,
color: AppColors.slate700,
),
),
),
Text(
@@ -164,16 +174,25 @@ class _CreateEventSheetState extends State<CreateEventSheet>
ValueListenableBuilder<TextEditingValue>(
valueListenable: _titleController,
builder: (context, value, child) {
return GestureDetector(
onTap: _saveEvent,
child: Text(
'保存',
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.w600,
color: value.text.trim().isNotEmpty
? AppColors.blue600
: AppColors.slate400,
final enabled = value.text.trim().isNotEmpty;
return SizedBox(
height: AppSpacing.xxl * 2,
child: TextButton(
onPressed: enabled ? _saveEvent : null,
style: TextButton.styleFrom(
padding: const EdgeInsets.symmetric(
horizontal: AppSpacing.md,
),
minimumSize: const Size(AppSpacing.none, AppSpacing.none),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
child: Text(
'保存',
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.w600,
color: enabled ? AppColors.blue600 : AppColors.slate400,
),
),
),
);
@@ -3,6 +3,9 @@ import 'package:go_router/go_router.dart';
import '../../../../core/theme/design_tokens.dart';
import '../../../../shared/widgets/page_header.dart' as widgets;
import '../../../../shared/widgets/app_input.dart';
import '../../../../shared/widgets/link_button.dart';
import '../../../../shared/widgets/toast/toast.dart';
import '../../../../shared/widgets/toast/toast_type.dart';
class AddContactScreen extends StatefulWidget {
final String? contactId;
@@ -62,17 +65,24 @@ class _AddContactScreenState extends State<AddContactScreen> {
}
Widget _buildConfirmButton() {
return GestureDetector(
onTap: _handleConfirm,
child: Container(
width: 36,
height: 36,
decoration: BoxDecoration(
color: AppColors.surfaceInfo,
borderRadius: BorderRadius.circular(18),
border: Border.all(color: AppColors.borderQuaternary),
return SizedBox(
width: AppSpacing.xxl * 2,
height: AppSpacing.xxl * 2,
child: TextButton(
onPressed: _handleConfirm,
style: TextButton.styleFrom(
padding: const EdgeInsets.all(AppSpacing.none),
backgroundColor: AppColors.surfaceInfo,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppRadius.full),
side: const BorderSide(color: AppColors.borderQuaternary),
),
),
child: const Icon(
Icons.check,
size: AppSpacing.lg,
color: AppColors.blue600,
),
child: const Icon(Icons.check, size: 16, color: AppColors.blue600),
),
);
}
@@ -83,7 +93,7 @@ class _AddContactScreenState extends State<AddContactScreen> {
width: 72,
height: 72,
decoration: BoxDecoration(
color: const Color(0xFFF3F6FC),
color: AppColors.surfaceInfoLight,
borderRadius: BorderRadius.circular(36),
border: Border.all(color: Colors.transparent),
),
@@ -102,7 +112,7 @@ class _AddContactScreenState extends State<AddContactScreen> {
decoration: BoxDecoration(
color: AppColors.white,
borderRadius: BorderRadius.circular(16),
border: Border.all(color: const Color(0xFFE3EAF6)),
border: Border.all(color: AppColors.messageCardBorder),
),
child: Column(
children: [
@@ -127,19 +137,12 @@ class _AddContactScreenState extends State<AddContactScreen> {
}
Widget _buildDeleteRow() {
return GestureDetector(
onTap: _handleDelete,
child: Container(
padding: const EdgeInsets.only(bottom: 8),
alignment: Alignment.center,
child: const Text(
'删除联系人',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
color: AppColors.red600,
),
),
return Padding(
padding: const EdgeInsets.only(bottom: AppSpacing.sm),
child: LinkButton(
text: '删除联系人',
onTap: _handleDelete,
foregroundColor: AppColors.red600,
),
);
}
@@ -149,9 +152,7 @@ class _AddContactScreenState extends State<AddContactScreen> {
final email = _emailController.text.trim();
if (name.isEmpty || email.isEmpty) {
ScaffoldMessenger.of(
context,
).showSnackBar(const SnackBar(content: Text('请填写昵称和邮箱')));
Toast.show(context, '请填写昵称和邮箱', type: ToastType.warning);
return;
}
@@ -3,6 +3,7 @@ import 'package:go_router/go_router.dart';
import '../../../../core/theme/design_tokens.dart';
import '../../../../core/di/injection.dart';
import '../../../../shared/widgets/app_button.dart';
import '../../../../shared/widgets/page_header.dart' as widgets;
import '../../../../shared/widgets/toast/toast.dart';
import '../../../../shared/widgets/toast/toast_type.dart';
import '../../../users/data/models/user_response.dart';
@@ -161,23 +162,7 @@ class _EditProfileScreenState extends State<EditProfileScreen> {
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Row(
children: [
GestureDetector(
onTap: () => context.pop(),
child: Container(
width: 36,
height: 36,
decoration: BoxDecoration(
color: const Color(0xFFF8FAFF),
borderRadius: BorderRadius.circular(18),
border: Border.all(color: const Color(0xFFDEE7F6)),
),
child: const Icon(
Icons.chevron_left,
size: 18,
color: Color(0xFF334155),
),
),
),
widgets.BackButton(onPressed: () => context.pop()),
const SizedBox(width: 12),
const Text(
'编辑资料',
@@ -3,6 +3,7 @@ import 'package:go_router/go_router.dart';
import 'package:lucide_icons/lucide_icons.dart';
import '../../../../core/di/injection.dart';
import '../../../../core/theme/design_tokens.dart';
import '../../../../shared/widgets/page_header.dart' as widgets;
import '../../../../shared/widgets/app_button.dart';
import '../../../../shared/widgets/toast/toast.dart';
import '../../../../shared/widgets/toast/toast_type.dart';
@@ -101,26 +102,7 @@ class _TodoDetailScreenState extends State<TodoDetailScreen> {
padding: const EdgeInsets.only(left: 16, right: 16, top: 12, bottom: 8),
child: Row(
children: [
GestureDetector(
onTap: () => Navigator.of(context).pop(),
child: Container(
width: 36,
height: 36,
decoration: BoxDecoration(
color: AppColors.messageBtnWrap,
borderRadius: BorderRadius.circular(18),
border: Border.all(
color: AppColors.messageBtnBorder,
width: 1,
),
),
child: const Icon(
LucideIcons.chevronLeft,
size: 16,
color: AppColors.slate700,
),
),
),
widgets.BackButton(onPressed: () => Navigator.of(context).pop()),
const Spacer(),
if (_todo != null) ...[
IconButton(