feat: 健康仪表盘配色调整 + 登录页品牌升级 + iOS 配置 + 隐私文案修订 + 文档清理

## UI 配色
- 健康仪表盘: 背景从蓝紫粉三色渐变改为 #4FACFE 纯色蓝, 白字清晰不抢眼
- app_colors / app_design_tokens / app_theme: 配色体系微调
- 多个 widget 和页面跟随配色更新(health_drawer/admin_drawer/doctor_drawer/enterprise_widgets 等)

## 登录页品牌升级
- 新增品牌素材: drawer_background_v2 / login_background_v2 / health_login_character_transparent
- login_page 重构, 接入新品牌视觉
- app.dart 启动流程调整

## iOS / Android 配置
- Info.plist: 权限描述调整
- AppIcon / LaunchImage: 资源更新
- AndroidManifest: 权限微调

## 隐私文案修订
- privacy.html: 蓝牙设备描述调整为"标准蓝牙血压服务", 移除未上线设备类型表述
- terms.html: 移除"在线医生咨询"相关条款, 服务范围收窄

## 通知中心
- notification_center_page: 重构通知项布局

## 其他
- 删除已完成的计划/spec 文档(ui-system-first-pass / apple-sign-in / secondary-page-color-refresh / notification-preferences-design / ui-design-system)
- 新增 native_navigation_test
- 新增 HANDOFF 交接文档
- home_message_order_test 更新
- .gitignore 调整
This commit is contained in:
MingNian
2026-07-16 22:30:23 +08:00
parent 528859686f
commit 6e5d3e64cd
44 changed files with 624 additions and 1234 deletions

View File

@@ -1,6 +1,5 @@
import 'dart:io';
import 'dart:async';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:image_picker/image_picker.dart';
@@ -31,6 +30,26 @@ class _HomePageState extends ConsumerState<HomePage>
final _scaffoldKey = GlobalKey<ScaffoldState>();
String? _pickedImagePath;
Timer? _notificationTimer;
double _conversationDragDistance = 0;
void _startConversationDrawerDrag(DragStartDetails details) {
_conversationDragDistance = 0;
}
void _updateConversationDrawerDrag(DragUpdateDetails details) {
_conversationDragDistance += details.delta.dx;
if (_conversationDragDistance < 0) {
_conversationDragDistance = 0;
}
if (_conversationDragDistance >= 42) {
_conversationDragDistance = 0;
_scaffoldKey.currentState?.openDrawer();
}
}
void _endConversationDrawerDrag(DragEndDetails details) {
_conversationDragDistance = 0;
}
@override
void initState() {
@@ -134,9 +153,7 @@ class _HomePageState extends ConsumerState<HomePage>
key: _scaffoldKey,
backgroundColor: const Color(0xFFFFFCFF),
drawer: const HealthDrawer(),
drawerEnableOpenDragGesture: true,
drawerDragStartBehavior: DragStartBehavior.down,
drawerEdgeDragWidth: MediaQuery.sizeOf(context).width * 0.8,
drawerEnableOpenDragGesture: false,
body: DecoratedBox(
decoration: const BoxDecoration(
gradient: LinearGradient(
@@ -150,8 +167,15 @@ class _HomePageState extends ConsumerState<HomePage>
children: [
_buildHeader(user),
Expanded(
child: RepaintBoundary(
child: _HomeMessages(scrollCtrl: _scrollCtrl),
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onHorizontalDragStart: _startConversationDrawerDrag,
onHorizontalDragUpdate: _updateConversationDrawerDrag,
onHorizontalDragEnd: _endConversationDrawerDrag,
onHorizontalDragCancel: () => _conversationDragDistance = 0,
child: RepaintBoundary(
child: _HomeMessages(scrollCtrl: _scrollCtrl),
),
),
),
_buildBottomBar(context),
@@ -197,7 +221,7 @@ class _HomePageState extends ConsumerState<HomePage>
'${_getGreeting()}$name',
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w800,
fontWeight: FontWeight.w600,
color: AppColors.textPrimary,
),
),
@@ -657,7 +681,7 @@ class _HeaderIconButton extends StatelessWidget {
style: const TextStyle(
color: Colors.white,
fontSize: 10,
fontWeight: FontWeight.w800,
fontWeight: FontWeight.w600,
),
),
),

View File

@@ -231,7 +231,7 @@ class ChatMessagesView extends ConsumerWidget {
info.$2,
style: AppTextStyles.chatTitle.copyWith(
fontSize: 22,
fontWeight: FontWeight.w900,
fontWeight: FontWeight.w700,
),
),
const SizedBox(height: 8),
@@ -692,7 +692,7 @@ class ChatMessagesView extends ConsumerWidget {
text: mainValue,
style: TextStyle(
fontSize: 36,
fontWeight: FontWeight.w800,
fontWeight: FontWeight.w600,
color: abnormal
? AppColors.error
: AppColors.textPrimary,
@@ -886,7 +886,7 @@ class ChatMessagesView extends ConsumerWidget {
'确认录入',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w800,
fontWeight: FontWeight.w600,
color: AppColors.textPrimary,
),
),
@@ -1416,7 +1416,7 @@ class ChatMessagesView extends ConsumerWidget {
'今日健康',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w800,
fontWeight: FontWeight.w600,
color: AppColors.textPrimary,
),
),
@@ -1570,8 +1570,7 @@ class ChatMessagesView extends ConsumerWidget {
'健康指标',
trailing: trailing,
status: 'warning',
iconColor: AppColors.warning,
iconBg: AppColors.warningLight,
iconGradient: AppModuleVisuals.health.gradient,
onTap: () => pushRoute(ref, 'trend'),
),
);
@@ -1586,6 +1585,7 @@ class ChatMessagesView extends ConsumerWidget {
status: 'done',
iconColor: healthIconColor,
iconBg: healthIconBg,
iconGradient: AppModuleVisuals.health.gradient,
onTap: () => pushRoute(ref, 'trend'),
),
);
@@ -1625,6 +1625,7 @@ class ChatMessagesView extends ConsumerWidget {
: (now.hour >= 18 ? 'overdue' : 'pending'),
iconColor: exIconColor,
iconBg: exIconBg,
iconGradient: AppModuleVisuals.exercise.gradient,
onTap: () => pushRoute(ref, 'exercisePlan'),
),
);
@@ -1642,6 +1643,7 @@ class ChatMessagesView extends ConsumerWidget {
status: 'pending',
iconColor: exIconColor,
iconBg: exIconBg,
iconGradient: AppModuleVisuals.exercise.gradient,
onTap: () => pushRoute(ref, 'exercisePlan'),
),
);
@@ -1657,6 +1659,7 @@ class ChatMessagesView extends ConsumerWidget {
status: 'overdue',
iconColor: exIconColor,
iconBg: exIconBg,
iconGradient: AppModuleVisuals.exercise.gradient,
onTap: () => pushRoute(ref, 'exercisePlan'),
),
);
@@ -1672,6 +1675,7 @@ class ChatMessagesView extends ConsumerWidget {
status: 'pending',
iconColor: exIconColor,
iconBg: exIconBg,
iconGradient: AppModuleVisuals.exercise.gradient,
onTap: () => pushRoute(ref, 'exercisePlan'),
),
);
@@ -1690,12 +1694,13 @@ class ChatMessagesView extends ConsumerWidget {
tasks.add(
_taskRow(
context,
LucideIcons.pill,
AppModuleVisuals.medication.icon,
'用药',
trailing: meds.isEmpty ? '暂无用药安排' : '暂时不用吃药',
status: 'done',
iconColor: medIconColor,
iconBg: medIconBg,
iconGradient: AppModuleVisuals.medication.gradient,
onTap: () => pushRoute(ref, 'medCheckIn'),
),
);
@@ -1748,12 +1753,13 @@ class ChatMessagesView extends ConsumerWidget {
tasks.add(
_taskRow(
context,
LucideIcons.pill,
AppModuleVisuals.medication.icon,
title,
trailing: trailing,
status: status,
iconColor: medIconColor,
iconBg: medIconBg,
iconGradient: AppModuleVisuals.medication.gradient,
onTap: () => pushRoute(ref, 'medCheckIn'),
),
);
@@ -1788,7 +1794,7 @@ class ChatMessagesView extends ConsumerWidget {
'今日健康',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w800,
fontWeight: FontWeight.w600,
color: AppColors.textPrimary,
height: 1.15,
),
@@ -1835,10 +1841,11 @@ class ChatMessagesView extends ConsumerWidget {
VoidCallback? onTap,
Color? iconColor,
Color? iconBg,
LinearGradient? iconGradient,
}) {
final colors = {
'done': AppTheme.success,
'warning': AppColors.warning,
'warning': const Color(0xFFE8562A),
'pending': AppColors.textHint,
'overdue': AppTheme.error,
};
@@ -1852,7 +1859,7 @@ class ChatMessagesView extends ConsumerWidget {
final ibg = iconBg ?? AppTheme.primaryLight;
final textColor = switch (status) {
'overdue' => AppColors.error,
'warning' => AppColors.warning,
'warning' => const Color(0xFFE8562A),
_ => AppColors.textPrimary,
};
return Padding(
@@ -1871,10 +1878,15 @@ class ChatMessagesView extends ConsumerWidget {
width: 32,
height: 32,
decoration: BoxDecoration(
color: ibg,
color: iconGradient == null ? ibg : null,
gradient: iconGradient,
borderRadius: AppRadius.smBorder,
),
child: Icon(icon, size: 18, color: ic),
child: Icon(
icon,
size: 18,
color: iconGradient == null ? ic : Colors.white,
),
),
const SizedBox(width: 10),
Expanded(