fix: 任务卡片移入对话流 + 综合信息卡片分组修复

- 新增 taskCard 消息类型,作为对话第一条消息
- 今日任务卡片从独立区域移至聊天流内
- AgentWelcomeCard 从 metadata 读 agent 不再全局共享
- 切换胶囊不会影响已发过的卡片
This commit is contained in:
MingNian
2026-06-03 20:19:15 +08:00
parent 15f9a122ca
commit ea7226c805
3 changed files with 87 additions and 7 deletions

View File

@@ -63,7 +63,10 @@ class ChatMessagesView extends ConsumerWidget {
switch (msg.type) {
case MessageType.agentWelcome:
return _buildAgentWelcomeCard(context, ref, msg, chatState.activeAgent);
final storedAgent = _parseAgentFromName(msg.metadata?['agent'] as String?);
return _buildAgentWelcomeCard(context, ref, msg, storedAgent);
case MessageType.taskCard:
return _buildTaskCardInChat(context, ref);
case MessageType.dataConfirm:
return _buildDataConfirmCard(context, msg);
case MessageType.medicationConfirm:
@@ -1254,4 +1257,69 @@ class _ExpandableAdviceState extends State<_ExpandableAdvice> {
),
);
}
static ActiveAgent _parseAgentFromName(String? name) {
switch (name) {
case 'consultation': return ActiveAgent.consultation;
case 'health': return ActiveAgent.health;
case 'diet': return ActiveAgent.diet;
case 'medication': return ActiveAgent.medication;
case 'report': return ActiveAgent.report;
case 'exercise': return ActiveAgent.exercise;
default: return ActiveAgent.default_;
}
}
Widget _buildTaskCardInChat(BuildContext context, WidgetRef ref) {
final health = ref.watch(latestHealthProvider);
return health.when(
data: (data) => _taskCardBubble(context, ref, data),
loading: () => _taskCardBubble(context, ref, {}),
error: (_, __) => _taskCardBubble(context, ref, {}),
);
}
Widget _taskCardBubble(BuildContext context, WidgetRef ref, Map<String, dynamic> data) {
final bp = data['BloodPressure'];
final bpText = bp is Map ? '${bp['systolic'] ?? '--'}/${bp['diastolic'] ?? '--'}' : '--';
final hr = data['HeartRate'];
final hrText = hr is Map && hr['value'] != null ? '${hr['value']}' : '--';
final gl = data['Glucose'];
final glText = gl is Map && gl['value'] != null ? '${gl['value']}' : '--';
final sp = data['SpO2'];
final spText = sp is Map && sp['value'] != null ? '${sp['value']}' : '--';
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(0xFF635BFF).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(0xFF635BFF)),
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, ref),
_miniMetric('心率', hrText, Icons.monitor_heart, ref),
_miniMetric('血糖', glText, Icons.bloodtype, ref),
_miniMetric('血氧', spText, Icons.air, ref),
]),
]),
);
}
Widget _miniMetric(String label, String value, IconData icon, WidgetRef ref) {
return Column(children: [
Icon(icon, size: 20, color: const Color(0xFF635BFF)),
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))),
]);
}
}