fix: 数据确认面板修复 - 显示实际数值+确认关闭+侧边栏刷新+清理旧数据
- Handler返回value/unit/isAbnormal到metadata - DataConfirmCard显示实际数值和单位 - 确认按钮关闭卡片+刷新健康概览 - 健康Agent欢迎卡简化为'查看趋势' - 清空87条旧健康测试数据
This commit is contained in:
@@ -62,7 +62,7 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
case MessageType.taskCard:
|
||||
return _buildTaskCardInChat(context, ref);
|
||||
case MessageType.dataConfirm:
|
||||
return _buildDataConfirmCard(context, msg);
|
||||
return _buildDataConfirmCard(context, ref, msg);
|
||||
case MessageType.medicationConfirm:
|
||||
return _buildMedicationConfirmCard(context, msg);
|
||||
case MessageType.dietAnalysis:
|
||||
@@ -269,14 +269,14 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
// 2. DataConfirmCard — 增强版数据确认卡片
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
Widget _buildDataConfirmCard(BuildContext context, ChatMessage msg) {
|
||||
Widget _buildDataConfirmCard(BuildContext context, WidgetRef ref, ChatMessage msg) {
|
||||
if (msg.confirmed) return const SizedBox.shrink();
|
||||
final meta = msg.metadata;
|
||||
final metricType = meta?['type'] as String? ?? '';
|
||||
final value = meta?['value'] as String? ?? '';
|
||||
final abnormal = meta?['abnormal'] as bool? ?? false;
|
||||
final recordTime = meta?['recordTime'] as String? ?? '';
|
||||
final unit = meta?['unit'] as String? ?? _getMetricUnit(metricType);
|
||||
final trend = meta?['trend'] as List? ?? [0.6, 0.8, 0.5];
|
||||
|
||||
return Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
@@ -286,154 +286,55 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFFFFFFF),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
boxShadow: [BoxShadow(color: const Color(0xFF8B9CF7).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
|
||||
boxShadow: [BoxShadow(color: const Color(0xFF6C5CE7).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
|
||||
),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// ── 绿色勾选条 ──
|
||||
child: Column(mainAxisSize: MainAxisSize.min, children: [
|
||||
Container(
|
||||
width: double.infinity, padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
decoration: const BoxDecoration(gradient: LinearGradient(colors: [Color(0xFF4CAF50), Color(0xFF43A047)])),
|
||||
child: const Row(mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
Icon(Icons.check_circle, size: 18, color: Colors.white), SizedBox(width: 6),
|
||||
Text('数据已记录', style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Colors.white)),
|
||||
]),
|
||||
),
|
||||
Padding(padding: const EdgeInsets.all(18), child: Column(children: [
|
||||
Align(alignment: Alignment.centerLeft, child: Text(recordTime.isNotEmpty ? recordTime : _formatTime(msg.createdAt), style: const TextStyle(fontSize: 12, color: Color(0xFF9E9E9E)))),
|
||||
const SizedBox(height: 14),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
decoration: const BoxDecoration(
|
||||
gradient: LinearGradient(colors: [Color(0xFF4CAF50), Color(0xFF43A047)]),
|
||||
),
|
||||
child: const Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(Icons.check_circle, size: 18, color: Colors.white),
|
||||
SizedBox(width: 6),
|
||||
Text('✓ 数据已记录', style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Colors.white)),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(18),
|
||||
child: Column(
|
||||
children: [
|
||||
// 记录时间
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(recordTime.isNotEmpty ? recordTime : _formatTime(msg.createdAt), style: const TextStyle(fontSize: 12, color: Color(0xFF9E9E9E))),
|
||||
),
|
||||
const SizedBox(height: 14),
|
||||
|
||||
// 主要指标区域
|
||||
Container(
|
||||
padding: const EdgeInsets.all(18),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF9F8FF),
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 52,
|
||||
height: 52,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFEDEAFF),
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
),
|
||||
child: Center(child: Text(_getMetricIcon(metricType), style: const TextStyle(fontSize: 26))),
|
||||
),
|
||||
const SizedBox(width: 14),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(_getMetricName(metricType), style: const TextStyle(fontSize: 13, color: Color(0xFF888888))),
|
||||
const SizedBox(height: 4),
|
||||
RichText(
|
||||
text: TextSpan(
|
||||
children: [
|
||||
TextSpan(text: value, style: TextStyle(fontSize: 28, fontWeight: FontWeight.w800, color: abnormal ? const Color(0xFFE53935) : const Color(0xFF1A1A2E))),
|
||||
TextSpan(text: ' $unit', style: TextStyle(fontSize: 14, color: abnormal ? const Color(0xFFE53970) : const Color(0xFF999999))),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
// 异常警告条
|
||||
if (abnormal) ...[
|
||||
const SizedBox(height: 12),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFFFF3F0),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
border: Border.all(color: const Color(0xFFFFDAD4), width: 1),
|
||||
),
|
||||
child: const Row(
|
||||
children: [
|
||||
Icon(Icons.warning_amber_rounded, size: 18, color: Color(0xFFE53935)),
|
||||
SizedBox(width: 8),
|
||||
Expanded(child: Text('⚠️ 数值偏高,建议关注', style: TextStyle(fontSize: 13, color: Color(0xFFE53935), fontWeight: FontWeight.w500))),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
// 迷你趋势图(最近3次)
|
||||
const SizedBox(height: 16),
|
||||
Row(
|
||||
children: [
|
||||
const Text('近期趋势', style: TextStyle(fontSize: 12, color: Color(0xFFAAAAAA))),
|
||||
const Spacer(),
|
||||
const Text('最近3次', style: TextStyle(fontSize: 11, color: Color(0xFFCCCCCC))),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
SizedBox(
|
||||
height: 36,
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: trend.asMap().entries.map((e) {
|
||||
final h = (e.value * 32).clamp(6.0, 32.0);
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(right: e.key < trend.length - 1 ? 10 : 0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
width: 22,
|
||||
height: h,
|
||||
decoration: BoxDecoration(
|
||||
color: e.key == trend.length - 1 ? const Color(0xFF8B9CF7) : const Color(0xFFD5D0FF),
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text('${e.key + 1}', style: const TextStyle(fontSize: 9, color: Color(0xFFBBBBBB))),
|
||||
],
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
|
||||
// 底部操作按钮
|
||||
const SizedBox(height: 18),
|
||||
Row(children: [
|
||||
Expanded(child: _cardOutlineBtn('编辑', Icons.edit_outlined)),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: _cardFilledBtn('确认', Icons.check)),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: _cardOutlineBtn('查看详情', Icons.trending_up_outlined)),
|
||||
]),
|
||||
],
|
||||
),
|
||||
decoration: BoxDecoration(color: const Color(0xFFF9F8FF), borderRadius: BorderRadius.circular(16)),
|
||||
child: Row(children: [
|
||||
Container(width: 52, height: 52, decoration: BoxDecoration(color: const Color(0xFFEDEAFF), borderRadius: BorderRadius.circular(14)), child: Center(child: Text(_getMetricIcon(metricType), style: const TextStyle(fontSize: 26)))),
|
||||
const SizedBox(width: 14),
|
||||
Expanded(child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
Text(_getMetricName(metricType), style: const TextStyle(fontSize: 13, color: Color(0xFF888888))),
|
||||
const SizedBox(height: 4),
|
||||
RichText(text: TextSpan(children: [
|
||||
TextSpan(text: value, style: TextStyle(fontSize: 28, fontWeight: FontWeight.w800, color: abnormal ? const Color(0xFFE53935) : const Color(0xFF1A1A2E))),
|
||||
TextSpan(text: ' $unit', style: TextStyle(fontSize: 14, color: abnormal ? const Color(0xFFE53970) : const Color(0xFF999999))),
|
||||
])),
|
||||
])),
|
||||
]),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (abnormal) ...[
|
||||
const SizedBox(height: 12),
|
||||
Container(width: double.infinity, padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10), decoration: BoxDecoration(color: const Color(0xFFFFF3F0), borderRadius: BorderRadius.circular(10), border: Border.all(color: const Color(0xFFFFDAD4))),
|
||||
child: const Row(children: [Icon(Icons.warning_amber_rounded, size: 18, color: Color(0xFFE53935)), SizedBox(width: 8), Expanded(child: Text('数值偏高,建议关注', style: TextStyle(fontSize: 13, color: Color(0xFFE53935), fontWeight: FontWeight.w500)))])),
|
||||
],
|
||||
const SizedBox(height: 18),
|
||||
Row(children: [
|
||||
Expanded(child: _cardFilledBtn('确认', Icons.check, onTap: () {
|
||||
msg.confirmed = true;
|
||||
ref.invalidate(latestHealthProvider);
|
||||
final notifier = ref.read(chatProvider.notifier);
|
||||
notifier.markNeedsRebuild();
|
||||
})),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: _cardOutlineBtn('查看详情', Icons.trending_up_outlined, onTap: () => pushRoute(ref, 'trend', params: {'type': metricType}))),
|
||||
]),
|
||||
])),
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -1061,11 +962,11 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
// 公共组件:通用按钮
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
Widget _cardFilledBtn(String label, IconData icon) {
|
||||
Widget _cardFilledBtn(String label, IconData icon, {VoidCallback? onTap}) {
|
||||
return ElevatedButton(
|
||||
onPressed: () {},
|
||||
onPressed: onTap ?? () {},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF8B9CF7),
|
||||
backgroundColor: const Color(0xFF6C5CE7),
|
||||
foregroundColor: Colors.white,
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
@@ -1079,12 +980,12 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _cardOutlineBtn(String label, IconData icon) {
|
||||
Widget _cardOutlineBtn(String label, IconData icon, {VoidCallback? onTap}) {
|
||||
return OutlinedButton(
|
||||
onPressed: () {},
|
||||
onPressed: onTap ?? () {},
|
||||
style: OutlinedButton.styleFrom(
|
||||
foregroundColor: const Color(0xFF8B9CF7),
|
||||
side: const BorderSide(color: Color(0xFF8B9CF7), width: 1.2),
|
||||
foregroundColor: const Color(0xFF6C5CE7),
|
||||
side: const BorderSide(color: Color(0xFF6C5CE7), width: 1.2),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
padding: const EdgeInsets.symmetric(vertical: 11),
|
||||
),
|
||||
@@ -1451,11 +1352,7 @@ class _AgentAction {
|
||||
|
||||
final _agentActions = <ActiveAgent, List<_AgentAction>>{
|
||||
ActiveAgent.health: [
|
||||
_AgentAction(label: '录入血压', icon: Icons.monitor_heart_outlined, route: 'trend'),
|
||||
_AgentAction(label: '录入血糖', icon: Icons.bloodtype_outlined, route: 'trend'),
|
||||
_AgentAction(label: '录入心率', icon: Icons.favorite_border, route: 'trend'),
|
||||
_AgentAction(label: '录入血氧', icon: Icons.air_outlined, route: 'trend'),
|
||||
_AgentAction(label: '录入体重', icon: Icons.monitor_weight_outlined, route: 'trend'),
|
||||
_AgentAction(label: '查看趋势', icon: Icons.trending_up, isWide: true, route: 'trend'),
|
||||
],
|
||||
ActiveAgent.diet: [
|
||||
_AgentAction(label: '拍照识别', icon: Icons.camera_alt_outlined, isWide: true, route: 'dietCapture'),
|
||||
|
||||
Reference in New Issue
Block a user