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

@@ -19,7 +19,7 @@ class LoginPage extends ConsumerStatefulWidget {
}
class _LoginPageState extends ConsumerState<LoginPage> {
static const _loginBg = 'assets/branding/login_background_v1.png';
static const _loginBg = 'assets/branding/login_background_v2.png';
static const _loginActionGradient = AppColors.primaryGradient;
void _openStaticText(String type) {
@@ -220,7 +220,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 21,
fontWeight: FontWeight.w900,
fontWeight: FontWeight.w700,
color: AppColors.textPrimary,
letterSpacing: 0,
),
@@ -303,7 +303,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w900,
fontWeight: FontWeight.w700,
),
),
),
@@ -350,7 +350,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
'选择健康服务医生',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w800,
fontWeight: FontWeight.w600,
color: AppColors.textPrimary,
),
),
@@ -438,10 +438,12 @@ class _LoginPageState extends ConsumerState<LoginPage> {
body: Stack(
children: [
Positioned.fill(
child: Image.asset(
_loginBg,
fit: BoxFit.cover,
alignment: Alignment.topCenter,
child: RepaintBoundary(
child: Image.asset(
_loginBg,
fit: BoxFit.cover,
alignment: Alignment.topCenter,
),
),
),
Positioned.fill(
@@ -460,16 +462,13 @@ class _LoginPageState extends ConsumerState<LoginPage> {
),
),
),
AnimatedPadding(
duration: const Duration(milliseconds: 180),
curve: Curves.easeOutCubic,
padding: EdgeInsets.only(
bottom: MediaQuery.viewInsetsOf(context).bottom,
),
_LoginKeyboardLift(
child: SafeArea(
child: LayoutBuilder(
builder: (context, constraints) {
return SingleChildScrollView(
keyboardDismissBehavior:
ScrollViewKeyboardDismissBehavior.onDrag,
padding: const EdgeInsets.fromLTRB(20, 22, 20, 24),
child: ConstrainedBox(
constraints: BoxConstraints(
@@ -589,7 +588,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
_isLogin ? '没有账号?去注册' : '已有账号?去登录',
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w800,
fontWeight: FontWeight.w600,
),
),
),
@@ -613,6 +612,23 @@ class _LoginPageState extends ConsumerState<LoginPage> {
}
}
class _LoginKeyboardLift extends StatelessWidget {
final Widget child;
const _LoginKeyboardLift({required this.child});
@override
Widget build(BuildContext context) {
final keyboardHeight = MediaQuery.viewInsetsOf(context).bottom;
final lift = (keyboardHeight * 0.42).clamp(0.0, 150.0);
return Transform.translate(
offset: Offset(0, -lift),
transformHitTests: true,
child: RepaintBoundary(child: child),
);
}
}
class _LoginHero extends StatelessWidget {
const _LoginHero();
@@ -626,7 +642,7 @@ class _LoginHero extends StatelessWidget {
'小脉健康',
style: TextStyle(
fontSize: 28,
fontWeight: FontWeight.w900,
fontWeight: FontWeight.w700,
color: AppColors.textPrimary,
letterSpacing: 0,
),
@@ -676,26 +692,11 @@ class _BrandMark extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SizedBox(
width: 108,
height: 108,
child: Container(
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
color: Colors.white.withValues(alpha: 0.72),
shape: BoxShape.circle,
border: Border.all(color: Colors.white.withValues(alpha: 0.86)),
boxShadow: [
BoxShadow(
color: AppColors.primary.withValues(alpha: 0.10),
blurRadius: 20,
offset: const Offset(0, 8),
),
],
),
child: Image.asset(
'assets/branding/health_icon_master.png',
fit: BoxFit.cover,
),
width: 116,
height: 116,
child: Image.asset(
'assets/branding/health_login_character_transparent.png',
fit: BoxFit.contain,
),
);
}
@@ -981,7 +982,7 @@ class _PrimaryButton extends StatelessWidget {
style: const TextStyle(
fontSize: 17,
color: Colors.white,
fontWeight: FontWeight.w800,
fontWeight: FontWeight.w600,
),
),
),