feat: UI清爽紫蓝风全面改造 + 对话卡片重构 + 配色体系升级
- 新增 AppColors 统一配色方案(清爽紫蓝,参考蚂蚁阿福风格) - 新增 common_widgets(GradientBorderButton / CardActionButton / IconBox) - AgentWelcomeCard 美化:渐变 header + AI标签 + 核心功能区 + 快捷操作区 - DataConfirmCard 统一:三合一(健康/药品/运动),可编辑字段列表 - 删除死代码:medicationConfirm/dietAnalysis/reportAnalysis/quickOptions 卡片 - 删除死路由:doctors/profileEdit/editProfile - AI 对话去除 Markdown 符号(_stripMd),统一行间距 1.5 - 逐字淡入动画修复:key 改用 stableId 避免重复触发 - 健康概览时间修复:前端发送 UTC 避免时区歧义 - PG 数据目录迁入项目 backend/pgdata/,加入 .gitignore - 新增欧姆龙血压计实施方案文档
This commit is contained in:
@@ -3,7 +3,7 @@ import 'package:dio/dio.dart';
|
||||
import 'local_database.dart';
|
||||
|
||||
/// API 基础地址
|
||||
const String baseUrl = 'http://192.168.1.45:5000';
|
||||
const String baseUrl = 'http://10.4.164.158:5000';
|
||||
|
||||
/// Dio HTTP 客户端封装——带 token 注入、401 自动刷新
|
||||
class ApiClient {
|
||||
|
||||
161
health_app/lib/core/app_colors.dart
Normal file
161
health_app/lib/core/app_colors.dart
Normal file
@@ -0,0 +1,161 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// 统一配色方案 - 清爽紫蓝风格(参考蚂蚁阿福)
|
||||
class AppColors {
|
||||
AppColors._();
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// 主色调
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/// 纯白背景
|
||||
static const Color background = Color(0xFFFFFFFF);
|
||||
|
||||
/// 次级背景色(非常淡的蓝紫色)
|
||||
static const Color backgroundSecondary = Color(0xFFF8FAFF);
|
||||
|
||||
/// 卡片背景
|
||||
static const Color cardBackground = Color(0xFFFFFFFF);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// 紫色系(清爽浅紫)
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/// 主紫色(浅紫,蚂蚁阿福风格)
|
||||
static const Color primaryPurple = Color(0xFFB8C4FF);
|
||||
|
||||
/// 深一点的紫色(用于强调)
|
||||
static const Color primaryPurpleDark = Color(0xFF8BA4E8);
|
||||
|
||||
/// 紫色渐变起点
|
||||
static const Color purpleGradientStart = Color(0xFFD4DFFF);
|
||||
|
||||
/// 紫色渐变终点
|
||||
static const Color purpleGradientEnd = Color(0xFFB8C4FF);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// 蓝色系
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/// 主蓝色(清爽蓝)
|
||||
static const Color primaryBlue = Color(0xFF5B9FFF);
|
||||
|
||||
/// 深一点的蓝色
|
||||
static const Color primaryBlueDark = Color(0xFF3A7FE8);
|
||||
|
||||
/// 蓝色渐变起点
|
||||
static const Color blueGradientStart = Color(0xFFB8D4FF);
|
||||
|
||||
/// 蓝色渐变终点
|
||||
static const Color blueGradientEnd = Color(0xFF7BB8FF);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// 渐变组合
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/// 紫蓝渐变(用于标题背景、图标背景)
|
||||
static const LinearGradient purpleBlueGradient = LinearGradient(
|
||||
colors: [purpleGradientStart, blueGradientEnd],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
);
|
||||
|
||||
/// 轻量级渐变(用于卡片内小元素)
|
||||
static const LinearGradient lightGradient = LinearGradient(
|
||||
colors: [Color(0xFFEEF2FF), Color(0xFFF0F5FF)],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// 文字颜色
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/// 主要文字(深色)
|
||||
static const Color textPrimary = Color(0xFF1A1A2E);
|
||||
|
||||
/// 次要文字(中等灰色)
|
||||
static const Color textSecondary = Color(0xFF666666);
|
||||
|
||||
/// 辅助文字(浅灰色)
|
||||
static const Color textHint = Color(0xFF999999);
|
||||
|
||||
/// 文字颜色(用于渐变背景上的白色文字)
|
||||
static const Color textOnGradient = Color(0xFFFFFFFF);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// 图标和元素颜色
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/// 图标背景色(非常淡的蓝紫色)
|
||||
static const Color iconBackground = Color(0xFFEEF2FF);
|
||||
|
||||
/// 图标主色(清爽蓝紫色)
|
||||
static const Color iconColor = Color(0xFF5B8DEF);
|
||||
|
||||
/// 次要图标色
|
||||
static const Color iconColorSecondary = Color(0xFF8BA4E8);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// 边框和分割线
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/// 默认边框色
|
||||
static const Color border = Color(0xFFE8EBF5);
|
||||
|
||||
/// 浅边框色
|
||||
static const Color borderLight = Color(0xFFF0F2F7);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// 功能色
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/// 成功色(绿色)
|
||||
static const Color success = Color(0xFF4CAF50);
|
||||
|
||||
/// 错误色(柔和红)
|
||||
static const Color error = Color(0xFFFF6B6B);
|
||||
|
||||
/// 警告色(橙色)
|
||||
static const Color warning = Color(0xFFFFB74D);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// 按钮渐变(白色底+渐变边框)
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/// 主按钮渐变边框色
|
||||
static const LinearGradient buttonGradient = LinearGradient(
|
||||
colors: [primaryPurple, primaryBlue],
|
||||
begin: Alignment.centerLeft,
|
||||
end: Alignment.centerRight,
|
||||
);
|
||||
|
||||
/// 成功按钮渐变
|
||||
static const LinearGradient successButtonGradient = LinearGradient(
|
||||
colors: [Color(0xFF81E6A0), success],
|
||||
begin: Alignment.centerLeft,
|
||||
end: Alignment.centerRight,
|
||||
);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// 阴影
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/// 卡片阴影
|
||||
static List<BoxShadow> cardShadow = [
|
||||
BoxShadow(
|
||||
color: primaryPurple.withAlpha(15),
|
||||
blurRadius: 20,
|
||||
offset: const Offset(0, 6),
|
||||
),
|
||||
];
|
||||
|
||||
/// 按钮阴影
|
||||
static List<BoxShadow> buttonShadow = [
|
||||
BoxShadow(
|
||||
color: primaryPurple.withAlpha(20),
|
||||
blurRadius: 12,
|
||||
offset: const Offset(0, 4),
|
||||
),
|
||||
];
|
||||
}
|
||||
@@ -12,7 +12,6 @@ import '../pages/consultation/consultation_pages.dart';
|
||||
import '../pages/settings/settings_pages.dart';
|
||||
import '../pages/settings/notification_prefs_page.dart';
|
||||
import '../pages/profile/profile_page.dart';
|
||||
import '../pages/profile/profile_detail_page.dart';
|
||||
import '../pages/profile/service_package_detail_page.dart';
|
||||
import '../pages/diet/diet_capture_page.dart';
|
||||
import '../pages/remaining_pages.dart';
|
||||
@@ -41,8 +40,6 @@ Widget buildPage(RouteInfo route) {
|
||||
return ReportDetailPage(id: params['id']!);
|
||||
case 'aiAnalysis':
|
||||
return AiAnalysisPage(id: params['id']!);
|
||||
case 'doctors':
|
||||
return const DoctorListPage();
|
||||
case 'consultation':
|
||||
return DoctorChatPage(id: params['id']!);
|
||||
case 'exercisePlan':
|
||||
@@ -55,10 +52,6 @@ Widget buildPage(RouteInfo route) {
|
||||
return const DietCapturePage();
|
||||
case 'profile':
|
||||
return const ProfilePage();
|
||||
case 'profileEdit':
|
||||
return const ProfileDetailPage();
|
||||
case 'editProfile':
|
||||
return const EditProfilePage();
|
||||
case 'devices':
|
||||
return const DeviceManagementPage();
|
||||
case 'healthArchive':
|
||||
|
||||
@@ -1,31 +1,32 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
import 'app_colors.dart';
|
||||
|
||||
/// 健康管家 — 淡紫清新风
|
||||
/// 健康管家 — 清爽紫蓝风
|
||||
class AppTheme {
|
||||
AppTheme._();
|
||||
|
||||
// ── 主色调:柔和紫 ──
|
||||
static const Color primary = Color(0xFF7C6FF7); // 柔紫
|
||||
static const Color primaryLight = Color(0xFFEDEAFF); // 浅薰衣草
|
||||
static const Color primaryDark = Color(0xFF4A3FBE); // 深紫
|
||||
static const Color primaryGlow = Color(0xFFD9D4FF); // 发光紫
|
||||
// ── 主色调 ──
|
||||
static const Color primary = AppColors.primaryPurple;
|
||||
static const Color primaryLight = AppColors.iconBackground;
|
||||
static const Color primaryDark = AppColors.iconColor;
|
||||
static const Color primaryGlow = AppColors.purpleGradientStart;
|
||||
|
||||
// ── 中性色 ──
|
||||
static const Color bg = Color(0xFFFAF9FF); // 淡紫白
|
||||
static const Color surface = Color(0xFFFFFFFF);
|
||||
static const Color text = Color(0xFF1E1B2E); // 紫黑
|
||||
static const Color textSub = Color(0xFF6E6B82); // 灰紫
|
||||
static const Color textHint = Color(0xFFB5B2C8); // 浅灰紫
|
||||
static const Color border = Color(0xFFE8E6F0);
|
||||
static const Color divider = Color(0xFFF4F2FA);
|
||||
static const Color bg = AppColors.backgroundSecondary;
|
||||
static const Color surface = AppColors.cardBackground;
|
||||
static const Color text = AppColors.textPrimary;
|
||||
static const Color textSub = AppColors.textSecondary;
|
||||
static const Color textHint = AppColors.textHint;
|
||||
static const Color border = AppColors.border;
|
||||
static const Color divider = AppColors.borderLight;
|
||||
|
||||
// ── 语义色 ──
|
||||
static const Color success = Color(0xFF52B788); // 翠绿
|
||||
static const Color error = Color(0xFFE85D75); // 柔红
|
||||
static const Color warning = Color(0xFFF5B041); // 暖琥珀
|
||||
static const Color accent = Color(0xFFA78BFA); // 中紫
|
||||
static const Color info = Color(0xFF7C6FF7); // 柔紫
|
||||
static const Color success = AppColors.success;
|
||||
static const Color error = AppColors.error;
|
||||
static const Color warning = AppColors.warning;
|
||||
static const Color accent = AppColors.primaryBlue;
|
||||
static const Color info = AppColors.primaryBlue;
|
||||
|
||||
// ── 圆角 ──
|
||||
static const double rXs = 6;
|
||||
@@ -53,13 +54,13 @@ class AppTheme {
|
||||
|
||||
// ── 智能体配色 ──
|
||||
static const Map<String, Color> agentColors = {
|
||||
'default': Color(0xFFEDEAFF), // 淡紫
|
||||
'consultation': Color(0xFFE0F0FF), // 淡天蓝
|
||||
'health': Color(0xFFE8FFE8), // 淡翠绿
|
||||
'diet': Color(0xFFFFF0E0), // 淡杏
|
||||
'medication': Color(0xFFFFE8EC), // 淡粉
|
||||
'report': Color(0xFFE8F0FF), // 淡水蓝
|
||||
'exercise': Color(0xFFF0E8FF), // 淡紫
|
||||
'default': AppColors.iconBackground,
|
||||
'consultation': Color(0xFFE0F0FF),
|
||||
'health': Color(0xFFE8FFE8),
|
||||
'diet': Color(0xFFFFF0E0),
|
||||
'medication': Color(0xFFFFE8EC),
|
||||
'report': Color(0xFFE8F0FF),
|
||||
'exercise': Color(0xFFF0E8FF),
|
||||
};
|
||||
|
||||
static Color agentLight(String? name) => agentColors[name] ?? primaryLight;
|
||||
@@ -141,9 +142,9 @@ class AppTheme {
|
||||
popoverForeground: text,
|
||||
primary: primary,
|
||||
primaryForeground: Colors.white,
|
||||
secondary: Color(0xFFF4F2FA),
|
||||
secondary: divider,
|
||||
secondaryForeground: text,
|
||||
muted: Color(0xFFF4F2FA),
|
||||
muted: divider,
|
||||
mutedForeground: textSub,
|
||||
accent: accent,
|
||||
accentForeground: Colors.white,
|
||||
@@ -152,7 +153,7 @@ class AppTheme {
|
||||
border: border,
|
||||
input: border,
|
||||
ring: primary,
|
||||
selection: Color(0xFFD9D4FF),
|
||||
selection: primaryGlow,
|
||||
),
|
||||
radius: BorderRadius.circular(rMd),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user