style: 淡薰紫 Lavender Breeze + UI修复
- 主色改淡薰紫 #8B9CF7 + 白底 清新风格 - 每个智能体卡不同淡色调 - 删除欢迎卡底部"或直接对我说" - 运动创建/打卡接入 API - 全项目薄荷绿→淡紫替换
This commit is contained in:
@@ -26,10 +26,10 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
width: 80,
|
||||
height: 80,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFE6FAF6),
|
||||
color: const Color(0xFFF0F2FF),
|
||||
borderRadius: BorderRadius.circular(40),
|
||||
),
|
||||
child: const Icon(Icons.health_and_safety, size: 40, color: Color(0xFF14B8A6)),
|
||||
child: const Icon(Icons.health_and_safety, size: 40, color: Color(0xFF8B9CF7)),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text('开始和 AI 健康管家对话吧', style: Theme.of(context).textTheme.bodyMedium),
|
||||
@@ -100,7 +100,7 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
color: const Color(0xFFFFFFFF),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
boxShadow: [
|
||||
BoxShadow(color: const Color(0xFF14B8A6).withAlpha(20), blurRadius: 16, offset: const Offset(0, 4)),
|
||||
BoxShadow(color: const Color(0xFF8B9CF7).withAlpha(20), blurRadius: 16, offset: const Offset(0, 4)),
|
||||
],
|
||||
),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
@@ -113,7 +113,7 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
padding: const EdgeInsets.fromLTRB(20, 24, 16, 20),
|
||||
decoration: const BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: [Color(0xFF2DC4B4), Color(0xFF14B8A6), Color(0xFF0E8071)],
|
||||
colors: [Color(0xFFA8B5FA), Color(0xFF8B9CF7), Color(0xFF5C70D6)],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
@@ -143,7 +143,7 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
color: Colors.white.withAlpha(25),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Text(info.$3, style: const TextStyle(fontSize: 12, color: Color(0xFFC6EBE6))),
|
||||
child: Text(info.$3, style: const TextStyle(fontSize: 12, color: Color(0xFFD8DCFD))),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -157,7 +157,7 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
color: Colors.white.withAlpha(20),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: const Icon(Icons.close, size: 16, color: Color(0xFFC6EBE6)),
|
||||
child: const Icon(Icons.close, size: 16, color: Color(0xFFD8DCFD)),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -176,21 +176,7 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
),
|
||||
),
|
||||
|
||||
// ── 底部提示 ──
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(0, 12, 0, 18),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(width: 24, height: 1, color: const Color(0xFFC6EBE6)),
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 10),
|
||||
child: Text('或直接对我说...', style: TextStyle(fontSize: 13, color: Color(0xFF9EDBD3))),
|
||||
),
|
||||
Container(width: 24, height: 1, color: const Color(0xFFC6EBE6)),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -200,14 +186,18 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
Widget _agentActionBtn(_AgentAction a, double screenWidth, BuildContext context, WidgetRef ref) {
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
if (a.route != null) {
|
||||
if (a.action == 'createPlan') {
|
||||
_createExercisePlan(ref, context);
|
||||
} else if (a.action == 'checkIn') {
|
||||
_exerciseCheckIn(ref, context);
|
||||
} else if (a.label == '服药打卡') {
|
||||
_medicationCheckIn(ref, context);
|
||||
} else if (a.route != null) {
|
||||
if (a.route == 'camera' || a.route == 'gallery') {
|
||||
ref.read(cameraActionProvider.notifier).trigger(a.route!);
|
||||
} else {
|
||||
pushRoute(ref, a.route!);
|
||||
}
|
||||
} else if (a.label == '服药打卡') {
|
||||
_medicationCheckIn(ref, context);
|
||||
}
|
||||
}, borderRadius: BorderRadius.circular(14),
|
||||
child: Container(
|
||||
@@ -216,7 +206,7 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF7F5FF),
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
border: Border.all(color: const Color(0xFFD4EDE8), width: 1),
|
||||
border: Border.all(color: const Color(0xFFD8DCFD), width: 1),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
@@ -228,7 +218,7 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
color: const Color(0xFFEDEAFF),
|
||||
borderRadius: BorderRadius.circular(11),
|
||||
),
|
||||
child: Icon(a.icon, size: 20, color: const Color(0xFF14B8A6)),
|
||||
child: Icon(a.icon, size: 20, color: const Color(0xFF8B9CF7)),
|
||||
),
|
||||
const SizedBox(height: 7),
|
||||
Text(a.label, style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500, color: Color(0xFF333333))),
|
||||
@@ -257,13 +247,13 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
border: Border.all(color: const Color(0xFFE6FAF6)),
|
||||
border: Border.all(color: const Color(0xFFF0F2FF)),
|
||||
),
|
||||
child: Column(children: [
|
||||
CircleAvatar(
|
||||
radius: 24,
|
||||
backgroundColor: const Color(0xFFE6FAF6),
|
||||
child: Text(doc['name']![0], style: const TextStyle(fontSize: 20, color: Color(0xFF14B8A6))),
|
||||
backgroundColor: const Color(0xFFF0F2FF),
|
||||
child: Text(doc['name']![0], style: const TextStyle(fontSize: 20, color: Color(0xFF8B9CF7))),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(doc['name']!, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w600)),
|
||||
@@ -272,10 +262,10 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF2FAF9),
|
||||
color: const Color(0xFFF0F2FF),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Text(doc['dept']!, style: const TextStyle(fontSize: 10, color: Color(0xFF14B8A6))),
|
||||
child: Text(doc['dept']!, style: const TextStyle(fontSize: 10, color: Color(0xFF8B9CF7))),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
Text(
|
||||
@@ -310,7 +300,7 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFFFFFFF),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
boxShadow: [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
|
||||
boxShadow: [BoxShadow(color: const Color(0xFF8B9CF7).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
|
||||
),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: Column(
|
||||
@@ -431,7 +421,7 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
width: 22,
|
||||
height: h,
|
||||
decoration: BoxDecoration(
|
||||
color: e.key == trend.length - 1 ? const Color(0xFF14B8A6) : const Color(0xFFD5D0FF),
|
||||
color: e.key == trend.length - 1 ? const Color(0xFF8B9CF7) : const Color(0xFFD5D0FF),
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
),
|
||||
@@ -482,7 +472,7 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFFFFFFF),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
boxShadow: [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
|
||||
boxShadow: [BoxShadow(color: const Color(0xFF8B9CF7).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
|
||||
),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: Column(
|
||||
@@ -493,7 +483,7 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.fromLTRB(18, 20, 18, 16),
|
||||
decoration: const BoxDecoration(
|
||||
gradient: LinearGradient(colors: [Color(0xFFE8F0FE), Color(0xFFF2FAF9)]),
|
||||
gradient: LinearGradient(colors: [Color(0xFFE8F0FE), Color(0xFFF0F2FF)]),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
@@ -537,7 +527,7 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
children: [
|
||||
const Text('剩余药量', style: TextStyle(fontSize: 13, color: Color(0xFF666666))),
|
||||
const Spacer(),
|
||||
Text('${(remaining * 100).toInt()}%', style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: Color(0xFF14B8A6))),
|
||||
Text('${(remaining * 100).toInt()}%', style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: Color(0xFF8B9CF7))),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
@@ -547,7 +537,7 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
value: remaining,
|
||||
minHeight: 8,
|
||||
backgroundColor: const Color(0xFFEFEDFF),
|
||||
valueColor: const AlwaysStoppedAnimation<Color>(Color(0xFF14B8A6)),
|
||||
valueColor: const AlwaysStoppedAnimation<Color>(Color(0xFF8B9CF7)),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -601,7 +591,7 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFFFFFFF),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
boxShadow: [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
|
||||
boxShadow: [BoxShadow(color: const Color(0xFF8B9CF7).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
|
||||
),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: Column(
|
||||
@@ -657,7 +647,7 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
] else ...[
|
||||
Container(
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(color: const Color(0xFFF2FAF9), borderRadius: BorderRadius.circular(12)),
|
||||
decoration: BoxDecoration(color: const Color(0xFFF0F2FF), borderRadius: BorderRadius.circular(12)),
|
||||
child: const Row(mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
Icon(Icons.hourglass_empty, size: 18, color: Color(0xFF999999)),
|
||||
SizedBox(width: 8),
|
||||
@@ -672,7 +662,7 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
const SizedBox(height: 6),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(color: const Color(0xFFF2FAF9), borderRadius: BorderRadius.circular(10)),
|
||||
decoration: BoxDecoration(color: const Color(0xFFF0F2FF), borderRadius: BorderRadius.circular(10)),
|
||||
child: Text(advice, style: const TextStyle(fontSize: 13, height: 1.6, color: Color(0xFF555555))),
|
||||
),
|
||||
]),
|
||||
@@ -702,7 +692,7 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFFFFFFF),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
boxShadow: [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
|
||||
boxShadow: [BoxShadow(color: const Color(0xFF8B9CF7).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
|
||||
),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: Column(
|
||||
@@ -839,9 +829,9 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
children: [
|
||||
const Row(
|
||||
children: [
|
||||
Icon(Icons.auto_awesome, size: 16, color: Color(0xFF14B8A6)),
|
||||
Icon(Icons.auto_awesome, size: 16, color: Color(0xFF8B9CF7)),
|
||||
SizedBox(width: 6),
|
||||
Text('AI 解读摘要', style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: Color(0xFF14B8A6))),
|
||||
Text('AI 解读摘要', style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: Color(0xFF8B9CF7))),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
@@ -883,7 +873,7 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFFFFFFF),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
boxShadow: [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
|
||||
boxShadow: [BoxShadow(color: const Color(0xFF8B9CF7).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(18, 16, 18, 14),
|
||||
@@ -897,8 +887,8 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
return ElevatedButton(
|
||||
onPressed: () {},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFFF2FAF9),
|
||||
foregroundColor: const Color(0xFF14B8A6),
|
||||
backgroundColor: const Color(0xFFF0F2FF),
|
||||
foregroundColor: const Color(0xFF8B9CF7),
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 11),
|
||||
@@ -926,8 +916,8 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFFEFEFF),
|
||||
borderRadius: const BorderRadius.only(topLeft: Radius.circular(4), topRight: Radius.circular(20), bottomLeft: Radius.circular(20), bottomRight: Radius.circular(20)),
|
||||
border: Border.all(color: const Color(0xFFD4EDE8), width: 1.5),
|
||||
boxShadow: [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(12), blurRadius: 10, offset: const Offset(0, 3))],
|
||||
border: Border.all(color: const Color(0xFFD8DCFD), width: 1.5),
|
||||
boxShadow: [BoxShadow(color: const Color(0xFF8B9CF7).withAlpha(12), blurRadius: 10, offset: const Offset(0, 3))],
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
@@ -937,10 +927,10 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
height: 26,
|
||||
padding: const EdgeInsets.all(5),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFE6FAF6),
|
||||
color: const Color(0xFFF0F2FF),
|
||||
borderRadius: BorderRadius.circular(13),
|
||||
),
|
||||
child: const CircularProgressIndicator(strokeWidth: 2.2, color: Color(0xFF14B8A6)),
|
||||
child: const CircularProgressIndicator(strokeWidth: 2.2, color: Color(0xFF8B9CF7)),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Text(thinkingText?.isNotEmpty == true ? thinkingText! : '正在分析...', style: const TextStyle(fontSize: 14, color: Color(0xFF999999))),
|
||||
@@ -963,15 +953,15 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.82),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
||||
decoration: BoxDecoration(
|
||||
color: isUser ? const Color(0xFF14B8A6) : const Color(0xFFFEFEFF),
|
||||
color: isUser ? const Color(0xFF8B9CF7) : const Color(0xFFFEFEFF),
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(isUser ? 20 : 4),
|
||||
topRight: Radius.circular(isUser ? 4 : 20),
|
||||
bottomLeft: const Radius.circular(20),
|
||||
bottomRight: const Radius.circular(20),
|
||||
),
|
||||
border: isUser ? null : Border.all(color: const Color(0xFFD4EDE8), width: 1.5),
|
||||
boxShadow: isUser ? [] : [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(12), blurRadius: 10, offset: const Offset(0, 3))],
|
||||
border: isUser ? null : Border.all(color: const Color(0xFFD8DCFD), width: 1.5),
|
||||
boxShadow: isUser ? [] : [BoxShadow(color: const Color(0xFF8B9CF7).withAlpha(12), blurRadius: 10, offset: const Offset(0, 3))],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -998,14 +988,14 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
p: const TextStyle(fontSize: 16, color: Color(0xFF1A1A1A), height: 1.5),
|
||||
h1: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A)),
|
||||
h2: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A)),
|
||||
code: const TextStyle(fontSize: 14, backgroundColor: Color(0xFFF2FAF9)),
|
||||
code: const TextStyle(fontSize: 14, backgroundColor: Color(0xFFF0F2FF)),
|
||||
),
|
||||
),
|
||||
if (!isUser && msg.content.isNotEmpty)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: Row(children: [
|
||||
const CircleAvatar(radius: 10, backgroundColor: Color(0xFFE6FAF6), child: Icon(Icons.chat_bubble_outline, size: 14, color: Color(0xFF14B8A6))),
|
||||
const CircleAvatar(radius: 10, backgroundColor: Color(0xFFF0F2FF), child: Icon(Icons.chat_bubble_outline, size: 14, color: Color(0xFF8B9CF7))),
|
||||
const SizedBox(width: 6),
|
||||
const Text('健康管家', style: TextStyle(fontSize: 12, color: Color(0xFF9E9E9E))),
|
||||
const SizedBox(width: 4),
|
||||
@@ -1038,7 +1028,7 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
return ElevatedButton(
|
||||
onPressed: () {},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF14B8A6),
|
||||
backgroundColor: const Color(0xFF8B9CF7),
|
||||
foregroundColor: Colors.white,
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
@@ -1056,8 +1046,8 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
return OutlinedButton(
|
||||
onPressed: () {},
|
||||
style: OutlinedButton.styleFrom(
|
||||
foregroundColor: const Color(0xFF14B8A6),
|
||||
side: const BorderSide(color: Color(0xFF14B8A6), width: 1.2),
|
||||
foregroundColor: const Color(0xFF8B9CF7),
|
||||
side: const BorderSide(color: Color(0xFF8B9CF7), width: 1.2),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
padding: const EdgeInsets.symmetric(vertical: 11),
|
||||
),
|
||||
@@ -1149,6 +1139,73 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
}
|
||||
}
|
||||
|
||||
static void _createExercisePlan(WidgetRef ref, BuildContext context) async {
|
||||
try {
|
||||
final service = ref.read(exerciseServiceProvider);
|
||||
final today = DateTime.now();
|
||||
final monday = today.subtract(Duration(days: today.weekday - 1));
|
||||
final items = List.generate(7, (i) => {
|
||||
'dayOfWeek': i,
|
||||
'exerciseType': i == 2 || i == 5 ? '休息' : '散步',
|
||||
'durationMinutes': i == 2 || i == 5 ? 0 : 30,
|
||||
'isRestDay': i == 2 || i == 5,
|
||||
});
|
||||
await service.createPlan({
|
||||
'weekStartDate': '${monday.year}-${monday.month.toString().padLeft(2, '0')}-${monday.day.toString().padLeft(2, '0')}',
|
||||
'items': items,
|
||||
});
|
||||
ref.invalidate(currentExercisePlanProvider);
|
||||
if (!context.mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('运动计划已创建'), backgroundColor: Color(0xFF43A047)),
|
||||
);
|
||||
pushRoute(ref, 'exercisePlan');
|
||||
} catch (e) {
|
||||
if (!context.mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('创建失败:$e'), backgroundColor: Colors.red),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static void _exerciseCheckIn(WidgetRef ref, BuildContext context) async {
|
||||
try {
|
||||
final plan = await ref.read(currentExercisePlanProvider.future);
|
||||
if (plan == null || plan.isEmpty) {
|
||||
if (!context.mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('请先创建运动计划'), backgroundColor: Color(0xFFFF9800)),
|
||||
);
|
||||
return;
|
||||
}
|
||||
final items = (plan['items'] as List?)?.cast<Map<String, dynamic>>() ?? [];
|
||||
final today = DateTime.now().weekday - 1;
|
||||
final todayItem = items.cast<Map<String, dynamic>?>().firstWhere(
|
||||
(i) => i?['dayOfWeek'] == today && i?['isRestDay'] != true,
|
||||
orElse: () => null,
|
||||
);
|
||||
if (todayItem == null) {
|
||||
if (!context.mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('今天休息日'), backgroundColor: Color(0xFFFF9800)),
|
||||
);
|
||||
return;
|
||||
}
|
||||
final service = ref.read(exerciseServiceProvider);
|
||||
await service.checkIn(todayItem['id']?.toString() ?? '');
|
||||
ref.invalidate(currentExercisePlanProvider);
|
||||
if (!context.mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('打卡成功'), backgroundColor: Color(0xFF43A047)),
|
||||
);
|
||||
} catch (e) {
|
||||
if (!context.mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('打卡失败:$e'), backgroundColor: Colors.red),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static (_AgentIcon, String, String) _agentInfo(ActiveAgent agent) {
|
||||
return switch (agent) {
|
||||
ActiveAgent.health => (Icons.favorite_border, '记数据', '录入血压、血糖、心率等日常指标'),
|
||||
@@ -1195,9 +1252,9 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(bottom: 12),
|
||||
padding: const EdgeInsets.all(14),
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(10), blurRadius: 8, offset: const Offset(0, 2))]),
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [BoxShadow(color: const Color(0xFF8B9CF7).withAlpha(10), blurRadius: 8, offset: const Offset(0, 2))]),
|
||||
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
Row(children: [Icon(Icons.today, size: 18, color: const Color(0xFF14B8A6)), const SizedBox(width: 8), const Text('今日任务', style: TextStyle(fontSize: 15, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A)))]),
|
||||
Row(children: [Icon(Icons.today, size: 18, color: const Color(0xFF8B9CF7)), const SizedBox(width: 8), const Text('今日任务', style: TextStyle(fontSize: 15, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A)))]),
|
||||
const SizedBox(height: 10),
|
||||
Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [
|
||||
_miniMetric('血压', bpText, Icons.favorite),
|
||||
@@ -1211,7 +1268,7 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
|
||||
Widget _miniMetric(String label, String value, IconData icon) {
|
||||
return Column(children: [
|
||||
Icon(icon, size: 20, color: const Color(0xFF14B8A6)),
|
||||
Icon(icon, size: 20, color: const Color(0xFF8B9CF7)),
|
||||
const SizedBox(height: 4),
|
||||
Text(value, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.bold, color: Color(0xFF1A1A1A))),
|
||||
Text(label, style: const TextStyle(fontSize: 10, color: Color(0xFF999999))),
|
||||
@@ -1230,8 +1287,9 @@ class _AgentAction {
|
||||
final IconData icon;
|
||||
final bool isWide;
|
||||
final String? route;
|
||||
final String? action;
|
||||
|
||||
const _AgentAction({required this.label, required this.icon, this.isWide = false, this.route});
|
||||
const _AgentAction({required this.label, required this.icon, this.isWide = false, this.route, this.action});
|
||||
}
|
||||
|
||||
final _agentActions = <ActiveAgent, List<_AgentAction>>{
|
||||
@@ -1256,9 +1314,9 @@ final _agentActions = <ActiveAgent, List<_AgentAction>>{
|
||||
_AgentAction(label: '查看历史', icon: Icons.history_outlined, isWide: true, route: 'reports'),
|
||||
],
|
||||
ActiveAgent.exercise: [
|
||||
_AgentAction(label: '本周计划', icon: Icons.calendar_month_outlined, isWide: true, route: 'exercisePlan'),
|
||||
_AgentAction(label: '新建计划', icon: Icons.add_task_outlined, isWide: true, route: 'exercisePlan'),
|
||||
_AgentAction(label: '今日打卡', icon: Icons.fact_check_outlined, isWide: true, route: 'exercisePlan'),
|
||||
_AgentAction(label: '查看计划', icon: Icons.calendar_month_outlined, isWide: true, route: 'exercisePlan'),
|
||||
_AgentAction(label: '新建计划', icon: Icons.add_task_outlined, isWide: true, action: 'createPlan'),
|
||||
_AgentAction(label: '今日打卡', icon: Icons.fact_check_outlined, isWide: true, action: 'checkIn'),
|
||||
],
|
||||
};
|
||||
|
||||
@@ -1298,9 +1356,9 @@ class _ExpandableAdviceState extends State<_ExpandableAdvice> {
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Icon(Icons.lightbulb_outline, size: 16, color: Color(0xFF14B8A6)),
|
||||
const Icon(Icons.lightbulb_outline, size: 16, color: Color(0xFF8B9CF7)),
|
||||
const SizedBox(width: 6),
|
||||
const Text('AI 建议', style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: Color(0xFF14B8A6))),
|
||||
const Text('AI 建议', style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: Color(0xFF8B9CF7))),
|
||||
const Spacer(),
|
||||
Icon(_expanded ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down, size: 18, color: const Color(0xFFAAAAAA)),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user