feat: Cupertino滚轮选择器 + 品牌更名 + UI全面优化

- 日期/时间/次数选择器统一改为底部弹出Cupertino滚轮,无单位标签,双横线选区
- App更名为"小脉健康",副标题"血管病患者的AI健康管理助手"
- 健康仪表盘及侧边栏移除体重指标,侧边栏背景改为蓝白渐变
- 健康档案按钮移入功能入口网格,与其他入口样式统一
- 记数据智能体配色改为绿色渐变(#A1FFCE→#69DB8F)
- 隐私协议/关于页从Text改为MarkdownBody正确渲染
- 运动计划/饮食记录卡片添加边框和阴影
- 服药次数从chip改为滚轮选择器
- 日期显示格式统一为空格分隔(1999 01 01)
- 健康档案页背景改为纯白
This commit is contained in:
MingNian
2026-06-22 13:59:37 +08:00
parent a479e5e95d
commit 431b72d49a
15 changed files with 466 additions and 165 deletions

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../core/app_colors.dart';
import '../core/app_theme.dart';
@@ -582,6 +583,8 @@ class DietRecordDetailPage extends ConsumerWidget {
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(AppTheme.rMd),
border: Border.all(color: const Color(0xFFE8ECF0)),
boxShadow: [AppTheme.shadowLight],
),
child: Row(
children: [
@@ -629,6 +632,8 @@ class DietRecordDetailPage extends ConsumerWidget {
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(AppTheme.rMd),
border: Border.all(color: const Color(0xFFE8ECF0)),
boxShadow: [AppTheme.shadowLight],
),
child: Row(
children: [
@@ -765,6 +770,8 @@ class _ExercisePlanPageState extends ConsumerState<ExercisePlanPage> {
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(AppTheme.rMd),
border: Border.all(color: const Color(0xFFE8ECF0)),
boxShadow: [AppTheme.shadowLight],
),
child: Row(
children: [
@@ -998,8 +1005,8 @@ class _ExercisePlanCreatePageState
const SizedBox(height: 6),
GestureDetector(
onTap: () async {
final d = await showDatePicker(
context: context,
final d = await showAppDatePicker(
context,
initialDate: val,
firstDate: DateTime(2024),
lastDate: DateTime(2030),
@@ -1014,7 +1021,7 @@ class _ExercisePlanCreatePageState
borderRadius: BorderRadius.circular(12),
),
child: Text(
'${val.year}-${val.month.toString().padLeft(2, '0')}-${val.day.toString().padLeft(2, '0')}',
'${val.year} ${val.month.toString().padLeft(2, '0')} ${val.day.toString().padLeft(2, '0')}',
style: const TextStyle(fontSize: 19),
),
),
@@ -1032,7 +1039,7 @@ class _ExercisePlanCreatePageState
const SizedBox(height: 6),
GestureDetector(
onTap: () async {
final picked = await showTimePicker(context: context, initialTime: _reminderTime);
final picked = await showAppTimePicker(context, initialTime: _reminderTime);
if (picked != null && mounted) setState(() => _reminderTime = picked);
},
child: Container(
@@ -1320,12 +1327,11 @@ class _HealthArchivePageState extends ConsumerState<HealthArchivePage> {
Future<void> _pickDate(void Function(String) onPicked) async {
final now = DateTime.now();
final d = await showDatePicker(
context: context,
final d = await showAppDatePicker(
context,
initialDate: DateTime(now.year - 30),
firstDate: DateTime(1900),
lastDate: now,
locale: const Locale('zh'),
);
if (d != null) {
onPicked(
@@ -1400,7 +1406,8 @@ class _HealthArchivePageState extends ConsumerState<HealthArchivePage> {
@override
Widget build(BuildContext context) {
if (_loading) {
return GradientScaffold(
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0,
@@ -1417,7 +1424,8 @@ class _HealthArchivePageState extends ConsumerState<HealthArchivePage> {
body: const Center(child: CircularProgressIndicator()),
);
}
return GradientScaffold(
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0,
@@ -1718,7 +1726,7 @@ class _DateF extends StatelessWidget {
child: Row(
children: [
Text(
value.isEmpty ? '点击选择日期' : value,
value.isEmpty ? '点击选择日期' : value.replaceAll('-', ' '),
style: TextStyle(
fontSize: 16,
color: value.isEmpty
@@ -1769,7 +1777,7 @@ class _DateF2 extends StatelessWidget {
child: Row(
children: [
Text(
value.isEmpty ? (hint ?? '点击选择') : value,
value.isEmpty ? (hint ?? '点击选择') : value.replaceAll('-', ' '),
style: TextStyle(
fontSize: 13,
color: value.isEmpty
@@ -1833,9 +1841,9 @@ class _HealthCalendarPageState extends ConsumerState<HealthCalendarPage> {
Map<String, List<Map<String, dynamic>>> _events = {};
Map<String, dynamic>? _selectedDayData;
static const _medBlue = Color(0xFF0000FF);
static const _exGreen = Color(0xFF00FF00);
static const _fupOrange = Color(0xFFFFA500);
static const _medBlue = Color(0xFF3B82F6);
static const _exGreen = Color(0xFF22C55E);
static const _fupOrange = Color(0xFFF59E0B);
@override
void initState() {
@@ -2308,7 +2316,7 @@ class StaticTextPage extends ConsumerWidget {
const StaticTextPage({super.key, required this.type});
@override
Widget build(BuildContext context, WidgetRef ref) {
final titles = {'privacy': '隐私协议', 'terms': '服务协议', 'about': '关于健康管家'};
final titles = {'privacy': '隐私协议', 'terms': '服务协议', 'about': '关于小脉健康'};
final contents = {
'privacy': '''## 隐私政策
@@ -2352,12 +2360,12 @@ class StaticTextPage extends ConsumerWidget {
如有任何关于隐私的问题,请联系:
邮箱privacy@healthbutler.com
电话400-xxx-xxxx''',
'about': '''## 关于健康管家
'about': '''## 关于小脉健康
版本v1.0.0 (Build 20260101)
### 产品介绍
健康管家是一款面向心脏术后康复患者的私人 AI 健康管理应用。以对话为核心交互方式,患者可以通过自然语言记录健康数据、获取饮食运动建议、管理用药、解读检查报告。
小脉健康是一款面向血管病患者的 AI 健康管理应用。以对话为核心交互方式,患者可以通过自然语言记录健康数据、获取饮食运动建议、管理用药、解读检查报告。
### 核心功能
- AI 智能问诊:基于大语言模型的健康咨询服务
@@ -2377,7 +2385,7 @@ class StaticTextPage extends ConsumerWidget {
- 客服热线400-xxx-xxxx工作日 9:00-18:00
### 版权声明
© 2025-2026 健康管家团队。保留所有权利。
© 2025-2026 小脉健康团队。保留所有权利。
本软件受中华人民共和国著作权法保护。''',
};
return GradientScaffold(
@@ -2399,12 +2407,15 @@ class StaticTextPage extends ConsumerWidget {
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(20),
child: Text(
contents[type] ?? '内容加载中...',
style: TextStyle(
fontSize: 17,
height: 1.8,
color: AppColors.textPrimary,
child: MarkdownBody(
data: contents[type] ?? '内容加载中...',
selectable: true,
styleSheet: MarkdownStyleSheet(
p: const TextStyle(fontSize: 17, height: 1.8, color: AppColors.textPrimary),
h1: const TextStyle(fontSize: 22, fontWeight: FontWeight.w700, color: AppColors.textPrimary, height: 1.5),
h2: const TextStyle(fontSize: 20, fontWeight: FontWeight.w700, color: AppColors.textPrimary, height: 1.5),
h3: const TextStyle(fontSize: 18, fontWeight: FontWeight.w700, color: AppColors.textPrimary, height: 1.5),
listBullet: const TextStyle(fontSize: 17, height: 1.8, color: AppColors.textPrimary),
),
),
),