fix: 欢迎卡片UI优化 + 蓝牙录入按钮 + 多处修复
- 欢迎卡片:去掉白框圆角错位、图片满宽、按钮去箭头改圆角居中 - 渐变actionOutlineGradient改紫蓝双色循环 - 新增健康Agent"蓝牙录入"按钮→蓝牙设备页 - "查看健康情况"改名"健康概览" - 饮食编辑框删除bug修复(控制器缓存) - 启动脚本加adb reverse自动转发 - 登录闪屏修复
This commit is contained in:
@@ -133,7 +133,9 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
case MessageType.dataConfirm:
|
||||
return _buildDataConfirmCard(context, ref, msg);
|
||||
default:
|
||||
if (!msg.isUser && chatState.isStreaming && msg.content.length < 5) {
|
||||
if (!msg.isUser &&
|
||||
chatState.isStreaming &&
|
||||
msg.content.trim().isEmpty) {
|
||||
return _buildThinkingBubble(context, chatState.thinkingText);
|
||||
}
|
||||
return _buildTextBubble(context, msg, chatState);
|
||||
@@ -152,14 +154,9 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
) {
|
||||
final info = _agentInfo(agent);
|
||||
final actions = agent.actions;
|
||||
final features = _getAgentFeatures(agent);
|
||||
final screenWidth = MediaQuery.of(context).size.width;
|
||||
final agentColors = _agentColors(agent);
|
||||
final iconGradient = LinearGradient(
|
||||
colors: agentColors.gradient,
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
);
|
||||
final artworkPath = _agentArtworkPath(agent);
|
||||
|
||||
return _AnimatedCardEntry(
|
||||
child: Align(
|
||||
@@ -168,10 +165,20 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
margin: const EdgeInsets.only(bottom: 16),
|
||||
constraints: BoxConstraints(maxWidth: screenWidth * 0.95),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.cardBackground,
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(24),
|
||||
border: Border.all(color: AppColors.border),
|
||||
boxShadow: AppColors.cardShadow,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: const Color(0xFF6B5CE7).withValues(alpha: 0.12),
|
||||
blurRadius: 28,
|
||||
offset: const Offset(0, 14),
|
||||
),
|
||||
BoxShadow(
|
||||
color: const Color(0xFF101828).withValues(alpha: 0.06),
|
||||
blurRadius: 12,
|
||||
offset: const Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: Column(
|
||||
@@ -180,40 +187,31 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
// ── 标题区域 ──
|
||||
Stack(
|
||||
children: [
|
||||
Positioned.fill(
|
||||
child: Opacity(
|
||||
opacity: 0.72,
|
||||
child: Image.asset(
|
||||
'assets/branding/agent_welcome_abstract.png',
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned.fill(
|
||||
child: DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
Colors.white.withValues(alpha: 0.95),
|
||||
agentColors.bg.withValues(alpha: 0.70),
|
||||
Colors.white.withValues(alpha: 0.28),
|
||||
Colors.white,
|
||||
agentColors.bg.withValues(alpha: 0.86),
|
||||
agentColors.accent.withValues(alpha: 0.12),
|
||||
],
|
||||
stops: const [0.0, 0.46, 1.0],
|
||||
begin: Alignment.centerLeft,
|
||||
end: Alignment.centerRight,
|
||||
stops: const [0.0, 0.58, 1.0],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
right: -18,
|
||||
top: -22,
|
||||
child: _SignalHalo(colors: agentColors),
|
||||
right: 18,
|
||||
top: 18,
|
||||
child: _MiniSignalStrip(colors: agentColors),
|
||||
),
|
||||
Positioned(
|
||||
right: 18,
|
||||
bottom: 14,
|
||||
child: _MiniSignalStrip(colors: agentColors),
|
||||
bottom: 18,
|
||||
child: _LinearAccentMark(colors: agentColors),
|
||||
),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
@@ -288,119 +286,13 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
],
|
||||
),
|
||||
|
||||
// ── 功能特性区 ──
|
||||
if (features.isNotEmpty) ...[
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 14, 16, 0),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(14),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
border: Border.all(color: AppColors.border),
|
||||
boxShadow: AppColors.cardShadowLight,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 4,
|
||||
height: 16,
|
||||
decoration: BoxDecoration(
|
||||
gradient: iconGradient,
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
const Text(
|
||||
'核心功能',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.textSecondary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
children: features.map((feature) {
|
||||
return Expanded(
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(
|
||||
horizontal: 3,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 12,
|
||||
horizontal: 6,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(
|
||||
color: agentColors.accent.withValues(
|
||||
alpha: 0.16,
|
||||
),
|
||||
),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: agentColors.accent.withValues(
|
||||
alpha: 0.05,
|
||||
),
|
||||
blurRadius: 10,
|
||||
offset: const Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: agentColors.iconBg,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
border: Border.all(
|
||||
color: agentColors.accent.withValues(
|
||||
alpha: 0.12,
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Icon(
|
||||
feature.icon,
|
||||
size: 20,
|
||||
color: agentColors.accent,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
Text(
|
||||
feature.title,
|
||||
style: const TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.textPrimary,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
feature.desc,
|
||||
style: const TextStyle(
|
||||
fontSize: 11,
|
||||
color: AppColors.textHint,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
// ── 插画展示 ──
|
||||
Image.asset(
|
||||
artworkPath,
|
||||
width: double.infinity,
|
||||
height: 206,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
|
||||
// ── 医生选择区(问诊专用)──
|
||||
if (agent == ActiveAgent.consultation) ...[
|
||||
@@ -411,51 +303,24 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
),
|
||||
],
|
||||
|
||||
// ── 快捷操作按钮区 ──
|
||||
if (actions.isNotEmpty) ...[
|
||||
const SizedBox(height: 14),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 6,
|
||||
height: 18,
|
||||
decoration: BoxDecoration(
|
||||
gradient: iconGradient,
|
||||
borderRadius: BorderRadius.circular(3),
|
||||
),
|
||||
for (int i = 0; i < actions.length; i++) ...[
|
||||
if (i > 0) const SizedBox(width: 10),
|
||||
Flexible(
|
||||
child: _buildActionButton(
|
||||
actions[i],
|
||||
context,
|
||||
ref,
|
||||
agentColors,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
'快捷操作',
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.textPrimary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
children: [
|
||||
for (int i = 0; i < actions.length; i++) ...[
|
||||
if (i > 0) const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: _buildActionButton(
|
||||
actions[i],
|
||||
context,
|
||||
ref,
|
||||
agentColors,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -527,81 +392,44 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
}
|
||||
}
|
||||
},
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
borderRadius: BorderRadius.circular(28),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 12),
|
||||
padding: const EdgeInsets.all(1.4),
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: [Colors.white, colors.bg.withValues(alpha: 0.82)],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
border: Border.all(color: colors.accent.withValues(alpha: 0.18)),
|
||||
boxShadow: AppColors.cardShadowLight,
|
||||
gradient: AppColors.actionOutlineGradient,
|
||||
borderRadius: BorderRadius.circular(28),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: colors.iconBg,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(
|
||||
color: colors.accent.withValues(alpha: 0.14),
|
||||
),
|
||||
),
|
||||
child: Icon(a.icon, size: 22, color: colors.accent),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Text(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 14, horizontal: 18),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(26.5),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(a.icon, size: 24, color: AppColors.textPrimary),
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
a.label,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.textPrimary,
|
||||
),
|
||||
style: const TextStyle(fontSize: 17, fontWeight: FontWeight.w700, color: AppColors.textPrimary),
|
||||
),
|
||||
),
|
||||
Icon(Icons.chevron_right, size: 18, color: AppColors.border),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<_AgentFeature> _getAgentFeatures(ActiveAgent agent) {
|
||||
String _agentArtworkPath(ActiveAgent agent) {
|
||||
return switch (agent) {
|
||||
ActiveAgent.health => [
|
||||
_AgentFeature(Icons.trending_up, '趋势分析', '查看历史数据'),
|
||||
_AgentFeature(Icons.add, '快速录入', '血压心率血糖'),
|
||||
],
|
||||
ActiveAgent.diet => [
|
||||
_AgentFeature(Icons.camera_alt, '拍照识别', '自动识别食物'),
|
||||
_AgentFeature(Icons.bar_chart, '营养分析', '热量营养成分'),
|
||||
],
|
||||
ActiveAgent.medication => [
|
||||
_AgentFeature(Icons.list, '用药清单', '管理所有药品'),
|
||||
_AgentFeature(Icons.alarm, '智能提醒', '按时服药提醒'),
|
||||
],
|
||||
ActiveAgent.consultation => [
|
||||
_AgentFeature(Icons.message, '在线问诊', '专业医生解答'),
|
||||
_AgentFeature(Icons.local_hospital, '科室选择', '精准匹配'),
|
||||
],
|
||||
ActiveAgent.report => [
|
||||
_AgentFeature(Icons.upload, '上传报告', '支持多种格式'),
|
||||
_AgentFeature(Icons.search, 'AI解读', '智能分析报告'),
|
||||
],
|
||||
ActiveAgent.exercise => [
|
||||
_AgentFeature(Icons.calendar_month, '运动计划', '科学规划'),
|
||||
_AgentFeature(Icons.check_circle, '打卡记录', '坚持完成'),
|
||||
],
|
||||
_ => [
|
||||
_AgentFeature(Icons.health_and_safety, '健康管理', '全方位呵护'),
|
||||
_AgentFeature(Icons.chat, '智能咨询', '随时答疑'),
|
||||
],
|
||||
ActiveAgent.consultation => 'assets/branding/agent_consultation_card.png',
|
||||
ActiveAgent.health => 'assets/branding/agent_health_card.png',
|
||||
ActiveAgent.diet => 'assets/branding/agent_diet_card.png',
|
||||
ActiveAgent.medication => 'assets/branding/agent_medication_card.png',
|
||||
ActiveAgent.report => 'assets/branding/agent_report_card.png',
|
||||
ActiveAgent.exercise => 'assets/branding/agent_exercise_card.png',
|
||||
_ => 'assets/branding/agent_health_card.png',
|
||||
};
|
||||
}
|
||||
|
||||
@@ -855,10 +683,20 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
margin: const EdgeInsets.only(bottom: 16),
|
||||
constraints: BoxConstraints(maxWidth: screenWidth * 0.95),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.cardBackground,
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(28),
|
||||
border: Border.all(color: Color(0xFFE2E8F0), width: 2),
|
||||
boxShadow: AppColors.cardShadow,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: const Color(0xFF6366F1).withValues(alpha: 0.10),
|
||||
blurRadius: 28,
|
||||
offset: const Offset(0, 14),
|
||||
),
|
||||
BoxShadow(
|
||||
color: const Color(0xFF101828).withValues(alpha: 0.06),
|
||||
blurRadius: 12,
|
||||
offset: const Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: Column(
|
||||
@@ -868,7 +706,13 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.fromLTRB(20, 20, 20, 18),
|
||||
decoration: const BoxDecoration(color: Color(0xFFF8F6FF)),
|
||||
decoration: const BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
colors: [Color(0xFFFFFFFF), Color(0xFFF7F4FF)],
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@@ -876,11 +720,11 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
width: 56,
|
||||
height: 56,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.cardInner,
|
||||
gradient: AppColors.actionOutlineGradient,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColors.primaryPurple.withAlpha(35),
|
||||
color: AppColors.auraIndigo.withValues(alpha: 0.18),
|
||||
blurRadius: 10,
|
||||
offset: const Offset(0, 4),
|
||||
),
|
||||
@@ -930,85 +774,92 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(20, 14, 20, 0),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(20),
|
||||
padding: const EdgeInsets.all(1.4),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.backgroundSecondary,
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
border: Border.all(color: AppColors.border),
|
||||
gradient: AppColors.actionOutlineGradient,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: 68,
|
||||
height: 68,
|
||||
decoration: BoxDecoration(
|
||||
gradient: AppColors.lightGradient,
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: 68,
|
||||
height: 68,
|
||||
decoration: BoxDecoration(
|
||||
gradient: AppColors.lightGradient,
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
),
|
||||
child: Center(
|
||||
child: isHealth
|
||||
? Icon(
|
||||
_getMetricIconData(backendType),
|
||||
size: 34,
|
||||
color: AppColors.primaryDark,
|
||||
)
|
||||
: Icon(
|
||||
isMedication
|
||||
? Icons.medication_liquid_outlined
|
||||
: Icons.directions_run_outlined,
|
||||
size: 36,
|
||||
color: AppColors.iconColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: isHealth
|
||||
? Text(
|
||||
_getMetricIcon(backendType),
|
||||
style: const TextStyle(fontSize: 36),
|
||||
)
|
||||
: Icon(
|
||||
isMedication
|
||||
? Icons.medication_liquid_outlined
|
||||
: Icons.directions_run_outlined,
|
||||
size: 36,
|
||||
color: AppColors.iconColor,
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
mainLabel,
|
||||
style: const TextStyle(
|
||||
fontSize: 17,
|
||||
color: AppColors.textSecondary,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
mainLabel,
|
||||
style: const TextStyle(
|
||||
fontSize: 17,
|
||||
color: AppColors.textSecondary,
|
||||
),
|
||||
),
|
||||
if (mainValue.isNotEmpty) ...[
|
||||
const SizedBox(height: 8),
|
||||
RichText(
|
||||
text: TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: mainValue,
|
||||
style: TextStyle(
|
||||
fontSize: 36,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: abnormal
|
||||
? AppColors.error
|
||||
: AppColors.textPrimary,
|
||||
letterSpacing: -0.5,
|
||||
),
|
||||
),
|
||||
if (mainUnit.isNotEmpty)
|
||||
if (mainValue.isNotEmpty) ...[
|
||||
const SizedBox(height: 8),
|
||||
RichText(
|
||||
text: TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: ' $mainUnit',
|
||||
text: mainValue,
|
||||
style: TextStyle(
|
||||
fontSize: 19,
|
||||
fontSize: 36,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: abnormal
|
||||
? AppColors.error
|
||||
: AppColors.iconColor,
|
||||
fontWeight: FontWeight.w500,
|
||||
: AppColors.textPrimary,
|
||||
letterSpacing: -0.5,
|
||||
),
|
||||
),
|
||||
],
|
||||
if (mainUnit.isNotEmpty)
|
||||
TextSpan(
|
||||
text: ' $mainUnit',
|
||||
style: TextStyle(
|
||||
fontSize: 19,
|
||||
color: abnormal
|
||||
? AppColors.error
|
||||
: AppColors.iconColor,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -1098,36 +949,38 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: 56,
|
||||
padding: const EdgeInsets.all(1.4),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
gradient: AppColors.actionOutlineGradient,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
border: Border.all(
|
||||
color: AppColors.borderLight,
|
||||
width: 1.5,
|
||||
),
|
||||
boxShadow: AppColors.cardShadow,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColors.auraIndigo.withValues(alpha: 0.18),
|
||||
blurRadius: 18,
|
||||
offset: const Offset(0, 8),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: msg.confirmed
|
||||
? Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: AppColors.successButtonGradient,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
boxShadow: AppColors.buttonShadow,
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
),
|
||||
child: Row(
|
||||
child: const Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(
|
||||
Icon(
|
||||
Icons.check_circle_outline,
|
||||
size: 22,
|
||||
color: Colors.white,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
const Text(
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
'录入成功',
|
||||
style: TextStyle(
|
||||
fontSize: 19,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
@@ -1142,33 +995,39 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
.read(chatProvider.notifier)
|
||||
.confirmMessage(msg.id);
|
||||
},
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 32,
|
||||
height: 32,
|
||||
decoration: BoxDecoration(
|
||||
gradient: AppColors.purpleBlueGradient,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 32,
|
||||
height: 32,
|
||||
decoration: BoxDecoration(
|
||||
gradient: AppColors.actionOutlineGradient,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: const Icon(
|
||||
Icons.check_rounded,
|
||||
size: 19,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
child: const Icon(
|
||||
Icons.check,
|
||||
size: 18,
|
||||
color: Colors.white,
|
||||
const SizedBox(width: 10),
|
||||
const Text(
|
||||
'确认录入',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: AppColors.textPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
'确认录入',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.textPrimary,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -1249,7 +1108,9 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
key: ValueKey('editing_${msg.id}_${field.label}'),
|
||||
initialValue: field.value,
|
||||
onDone: (value) {
|
||||
ref.read(chatProvider.notifier).finishEditingField(msg.id, field.label, value);
|
||||
ref
|
||||
.read(chatProvider.notifier)
|
||||
.finishEditingField(msg.id, field.label, value);
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -1612,22 +1473,22 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
}
|
||||
}
|
||||
|
||||
String _getMetricIcon(String type) {
|
||||
IconData _getMetricIconData(String type) {
|
||||
switch (type.toLowerCase()) {
|
||||
case 'blood_pressure':
|
||||
return '🩺';
|
||||
return Icons.bloodtype_outlined;
|
||||
case 'heart_rate':
|
||||
return '💓';
|
||||
return Icons.monitor_heart_outlined;
|
||||
case 'glucose':
|
||||
return '💉';
|
||||
return Icons.water_drop_outlined;
|
||||
case 'spo2':
|
||||
return '🫁';
|
||||
return Icons.air_outlined;
|
||||
case 'weight':
|
||||
return '⚖️';
|
||||
return Icons.monitor_weight_outlined;
|
||||
case 'exercise':
|
||||
return '🏃';
|
||||
return Icons.directions_run_outlined;
|
||||
default:
|
||||
return '📊';
|
||||
return Icons.query_stats_outlined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1692,46 +1553,46 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
static _AgentColors _agentColors(ActiveAgent agent) {
|
||||
return switch (agent) {
|
||||
ActiveAgent.consultation => _AgentColors(
|
||||
gradient: [AppColors.primary, AppColors.blueMeasure],
|
||||
bg: const Color(0xFFF3F6FF),
|
||||
border: const Color(0xFFDCE5FF),
|
||||
iconBg: const Color(0xFFEFF4FF),
|
||||
accent: AppColors.blueMeasure,
|
||||
gradient: [AppColors.sageAccent, AppColors.primary],
|
||||
bg: const Color(0xFFF2FBF9),
|
||||
border: const Color(0xFFD9F0EA),
|
||||
iconBg: const Color(0xFFE8F8F4),
|
||||
accent: const Color(0xFF4F9E90),
|
||||
),
|
||||
ActiveAgent.health => _AgentColors(
|
||||
gradient: [AppColors.primary, const Color(0xFF26B99A)],
|
||||
bg: const Color(0xFFF1FBF8),
|
||||
border: const Color(0xFFD8F1EA),
|
||||
iconBg: const Color(0xFFE9F8F4),
|
||||
accent: const Color(0xFF26B99A),
|
||||
gradient: [AppColors.meadowAccent, AppColors.auraDeepIndigo],
|
||||
bg: const Color(0xFFF3FBF4),
|
||||
border: const Color(0xFFDFF2E4),
|
||||
iconBg: const Color(0xFFEFF9F0),
|
||||
accent: const Color(0xFF4EA65B),
|
||||
),
|
||||
ActiveAgent.diet => _AgentColors(
|
||||
gradient: [AppColors.primary, const Color(0xFFFFA14F)],
|
||||
gradient: [AppColors.peachAccent, AppColors.auraOrchid],
|
||||
bg: const Color(0xFFFFF7F0),
|
||||
border: const Color(0xFFFFE8D4),
|
||||
iconBg: const Color(0xFFFFF0E4),
|
||||
accent: const Color(0xFFFF8A3D),
|
||||
accent: const Color(0xFFE26A64),
|
||||
),
|
||||
ActiveAgent.medication => _AgentColors(
|
||||
gradient: [AppColors.primary, AppColors.blueMeasure],
|
||||
gradient: [AppColors.auraLavender, AppColors.blueMeasure],
|
||||
bg: const Color(0xFFF4F6FF),
|
||||
border: const Color(0xFFDDE6FF),
|
||||
iconBg: const Color(0xFFEFF3FF),
|
||||
accent: AppColors.primary,
|
||||
),
|
||||
ActiveAgent.report => _AgentColors(
|
||||
gradient: [AppColors.primary, const Color(0xFF9B7CFF)],
|
||||
gradient: [AppColors.primary, AppColors.roseAccent],
|
||||
bg: const Color(0xFFF8F5FF),
|
||||
border: const Color(0xFFE9E0FF),
|
||||
iconBg: const Color(0xFFF2EDFF),
|
||||
accent: AppColors.primary,
|
||||
),
|
||||
ActiveAgent.exercise => _AgentColors(
|
||||
gradient: [AppColors.primary, const Color(0xFF21A6B7)],
|
||||
gradient: [AppColors.sageAccent, AppColors.auraDeepIndigo],
|
||||
bg: const Color(0xFFF0FBFD),
|
||||
border: const Color(0xFFD6EEF2),
|
||||
iconBg: const Color(0xFFE8F7FA),
|
||||
accent: const Color(0xFF21A6B7),
|
||||
accent: const Color(0xFF2B8EA0),
|
||||
),
|
||||
_ => _AgentColors(
|
||||
gradient: [AppColors.primary, AppColors.blueMeasure],
|
||||
@@ -2022,7 +1883,10 @@ class ChatMessagesView extends ConsumerWidget {
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.fromLTRB(16, 12, 16, 10),
|
||||
decoration: const BoxDecoration(gradient: AppColors.drawerGradient),
|
||||
decoration: const BoxDecoration(
|
||||
gradient: AppColors.drawerGradient,
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(28)),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
@@ -2197,23 +2061,21 @@ class _AgentMark extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _SignalHalo extends StatelessWidget {
|
||||
class _LinearAccentMark extends StatelessWidget {
|
||||
final _AgentColors colors;
|
||||
const _SignalHalo({required this.colors});
|
||||
const _LinearAccentMark({required this.colors});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: 118,
|
||||
height: 118,
|
||||
width: 86,
|
||||
height: 8,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
gradient: RadialGradient(
|
||||
colors: [
|
||||
colors.accent.withValues(alpha: 0.18),
|
||||
colors.accent.withValues(alpha: 0.06),
|
||||
Colors.transparent,
|
||||
],
|
||||
borderRadius: BorderRadius.circular(999),
|
||||
gradient: LinearGradient(
|
||||
colors: colors.gradient
|
||||
.map((color) => color.withValues(alpha: 0.34))
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -2279,14 +2141,6 @@ class _AgentAction {
|
||||
});
|
||||
}
|
||||
|
||||
class _AgentFeature {
|
||||
final IconData icon;
|
||||
final String title;
|
||||
final String desc;
|
||||
|
||||
const _AgentFeature(this.icon, this.title, this.desc);
|
||||
}
|
||||
|
||||
class _ConfirmField {
|
||||
final String label;
|
||||
final String value;
|
||||
@@ -2303,11 +2157,17 @@ class _ConfirmField {
|
||||
final _agentActions = <ActiveAgent, List<_AgentAction>>{
|
||||
ActiveAgent.health: [
|
||||
_AgentAction(
|
||||
label: '查看健康情况',
|
||||
label: '健康概览',
|
||||
icon: Icons.trending_up,
|
||||
isWide: true,
|
||||
route: 'trend',
|
||||
),
|
||||
_AgentAction(
|
||||
label: '蓝牙录入',
|
||||
icon: Icons.bluetooth,
|
||||
isWide: true,
|
||||
route: 'devices',
|
||||
),
|
||||
],
|
||||
ActiveAgent.diet: [
|
||||
_AgentAction(
|
||||
@@ -2446,30 +2306,52 @@ class _ExpandableAdviceState extends State<_ExpandableAdvice> {
|
||||
class _EditFieldCell extends StatefulWidget {
|
||||
final String initialValue;
|
||||
final ValueChanged<String> onDone;
|
||||
const _EditFieldCell({super.key, required this.initialValue, required this.onDone});
|
||||
const _EditFieldCell({
|
||||
super.key,
|
||||
required this.initialValue,
|
||||
required this.onDone,
|
||||
});
|
||||
|
||||
@override State<_EditFieldCell> createState() => _EditFieldCellState();
|
||||
@override
|
||||
State<_EditFieldCell> createState() => _EditFieldCellState();
|
||||
}
|
||||
|
||||
class _EditFieldCellState extends State<_EditFieldCell> {
|
||||
late final TextEditingController _ctrl;
|
||||
|
||||
@override void initState() {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_ctrl = TextEditingController(text: widget.initialValue);
|
||||
}
|
||||
|
||||
@override void dispose() { _ctrl.dispose(); super.dispose(); }
|
||||
@override
|
||||
void dispose() {
|
||||
_ctrl.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override Widget build(BuildContext context) => TextField(
|
||||
@override
|
||||
Widget build(BuildContext context) => TextField(
|
||||
controller: _ctrl,
|
||||
autofocus: true,
|
||||
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600, color: Color(0xFF1E293B)),
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF1E293B),
|
||||
),
|
||||
decoration: InputDecoration(
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
filled: true, fillColor: Colors.white,
|
||||
enabledBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(8), borderSide: BorderSide(color: const Color(0xFF6366F1).withAlpha(80))),
|
||||
focusedBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(8), borderSide: const BorderSide(color: Color(0xFF6366F1), width: 1.5)),
|
||||
filled: true,
|
||||
fillColor: Colors.white,
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: BorderSide(color: const Color(0xFF6366F1).withAlpha(80)),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: Color(0xFF6366F1), width: 1.5),
|
||||
),
|
||||
),
|
||||
onSubmitted: widget.onDone,
|
||||
onTapOutside: (_) => widget.onDone(_ctrl.text),
|
||||
|
||||
Reference in New Issue
Block a user