refactor(miniprogram): 全面接入 Design Token — 68 SCSS 文件 px→var(--tk-*)
Some checks failed
CI / security-audit (push) Has been cancelled
CI / rust-check (push) Has been cancelled
CI / rust-test (push) Has been cancelled
CI / frontend-build (push) Has been cancelled

- 重写 tokens.scss:校准 10 级字号 + 4 结构 token 匹配实际设计值
- 更新 mixins.scss:4 个 mixin 引用 token 替代硬编码
- 68 SCSS 文件全面迁移:font-size px → var(--tk-font-*),辅助文字色 → var(--tk-text-secondary)
- 清理 12 个页面的本地 mixin 重复定义
- elder-mode.scss 从 530 行缩减至 ~120 行:删除所有字号/颜色覆写,仅保留结构布局
- Token 覆盖率:634 引用 / 仅 3 个特殊硬编码值(72px/80px/21px)

关怀模式通过 CSS 变量级联自动生效,消除"打地鼠"问题。
This commit is contained in:
iven
2026-05-09 23:53:07 +08:00
parent 257ca94a25
commit 890c132890
74 changed files with 1127 additions and 1688 deletions

View File

@@ -26,7 +26,7 @@
.greeting-text {
@include serif-number;
font-size: 26px;
font-size: var(--tk-font-h1);
font-weight: 700;
color: $tx;
display: block;
@@ -34,8 +34,8 @@
}
.greeting-date {
font-size: 14px;
color: $tx3;
font-size: var(--tk-font-cap);
color: var(--tk-text-secondary);
}
.greeting-bell {
@@ -53,7 +53,7 @@
}
.greeting-bell-icon {
font-size: 18px;
font-size: var(--tk-font-body-sm);
color: $pri-d;
}
@@ -94,7 +94,7 @@
}
.checkin-title {
font-size: 16px;
font-size: var(--tk-font-body-sm);
font-weight: 600;
color: $tx;
display: block;
@@ -108,7 +108,7 @@
}
.capsule {
font-size: 11px;
font-size: var(--tk-font-micro);
padding: 3px 8px;
border-radius: $r-pill;
font-weight: 500;
@@ -151,7 +151,7 @@
}
.vital-label {
font-size: 13px;
font-size: var(--tk-font-cap);
color: $tx2;
display: block;
margin-bottom: 6px;
@@ -165,15 +165,15 @@
.vital-value {
@include serif-number;
font-size: 30px;
font-size: var(--tk-font-num);
font-weight: 700;
color: $tx;
line-height: 1;
}
.vital-unit {
font-size: 12px;
color: $tx3;
font-size: var(--tk-font-micro);
color: var(--tk-text-secondary);
margin-left: 3px;
}
@@ -183,7 +183,7 @@
}
.vital-tag {
font-size: 11px;
font-size: var(--tk-font-micro);
font-weight: 500;
padding: 2px 8px;
border-radius: $r-pill;
@@ -223,13 +223,13 @@
}
.reminder-title {
font-size: 15px;
font-size: var(--tk-font-cap);
font-weight: 600;
color: #fff;
}
.reminder-count {
font-size: 12px;
font-size: var(--tk-font-micro);
opacity: 0.7;
color: #fff;
}
@@ -250,7 +250,7 @@
}
.reminder-tag {
font-size: 10px;
font-size: var(--tk-font-micro);
padding: 2px 6px;
border-radius: 4px;
background: rgba(255, 255, 255, 0.2);
@@ -260,7 +260,7 @@
}
.reminder-text {
font-size: 13px;
font-size: var(--tk-font-cap);
flex: 1;
color: #fff;
overflow: hidden;
@@ -305,7 +305,7 @@
}
.action-btn-text {
font-size: 17px;
font-size: var(--tk-font-body-sm);
font-weight: 600;
}
@@ -361,7 +361,7 @@
.guest-slide-title {
font-family: 'Georgia', 'Times New Roman', serif;
font-size: 26px;
font-size: var(--tk-font-h1);
font-weight: 700;
color: #FFFFFF;
display: block;
@@ -369,7 +369,7 @@
}
.guest-slide-desc {
font-size: 16px;
font-size: var(--tk-font-body-sm);
color: rgba(255, 255, 255, 0.85);
display: block;
}
@@ -381,7 +381,7 @@
.guest-section-title {
font-family: 'Georgia', 'Times New Roman', serif;
font-size: 22px;
font-size: var(--tk-font-body);
font-weight: bold;
color: $tx;
display: block;
@@ -406,7 +406,7 @@
}
.guest-article-title {
font-size: 16px;
font-size: var(--tk-font-body-sm);
font-weight: 600;
color: $tx;
display: block;
@@ -417,8 +417,8 @@
}
.guest-article-summary {
font-size: 13px;
color: $tx3;
font-size: var(--tk-font-cap);
color: var(--tk-text-secondary);
display: block;
overflow: hidden;
text-overflow: ellipsis;
@@ -431,8 +431,8 @@
}
.guest-empty-text {
font-size: 14px;
color: $tx3;
font-size: var(--tk-font-cap);
color: var(--tk-text-secondary);
}
/* ─── 底部登录引导 ─── */
@@ -449,7 +449,7 @@
.guest-login-text {
flex: 1;
font-size: 13px;
font-size: var(--tk-font-cap);
color: $tx2;
}
@@ -467,7 +467,7 @@
}
.guest-login-btn-text {
font-size: 20px;
font-size: var(--tk-font-h2);
font-weight: 600;
color: #fff;
}

View File

@@ -3,6 +3,7 @@ import { useState, useCallback } from 'react';
import Taro, { useDidShow, usePullDownRefresh } from '@tarojs/taro';
import { useAuthStore } from '../../stores/auth';
import { useUIStore } from '../../stores/ui';
import { navigateToLogin } from '../../utils/navigate';
import { useHealthStore } from '../../stores/health';
import ProgressRing from '../../components/ProgressRing';
import Loading from '../../components/Loading';
@@ -11,7 +12,6 @@ import * as appointmentApi from '@/services/appointment';
import * as followupApi from '@/services/followup';
import { listPendingSuggestions, type AiSuggestionItem } from '@/services/ai-analysis';
import { notificationService } from '@/services/notification';
import * as articleApi from '@/services/article';
import './index.scss';
interface ReminderItem {
@@ -30,26 +30,6 @@ const CAROUSEL_SLIDES = [
];
function GuestHome({ modeClass }: { modeClass: string }) {
const [articles, setArticles] = useState<articleApi.Article[]>([]);
const [loading, setLoading] = useState(false);
useDidShow(() => {
loadArticles();
trackPageView('guest-home');
});
const loadArticles = async () => {
setLoading(true);
try {
const res = await articleApi.listArticles({ page: 1, page_size: 4 });
setArticles(res.data || []);
} catch {
// 文章加载失败不阻塞
} finally {
setLoading(false);
}
};
return (
<View className={`guest-page ${modeClass}`}>
{/* 轮播图 */}
@@ -76,29 +56,23 @@ function GuestHome({ modeClass }: { modeClass: string }) {
))}
</Swiper>
{/* 健康资讯 */}
{/* 功能亮点 */}
<View className='guest-section'>
<Text className='guest-section-title'></Text>
{loading ? (
<Loading />
) : articles.length > 0 ? (
<View className='guest-articles'>
{articles.map((a) => (
<View
key={a.id}
className='guest-article-card'
onClick={() => Taro.navigateTo({ url: `/pages/article/detail/index?id=${a.id}` })}
>
<Text className='guest-article-title'>{a.title}</Text>
{a.summary && <Text className='guest-article-summary'>{a.summary}</Text>}
</View>
))}
<Text className='guest-section-title'></Text>
<View className='guest-articles'>
<View className='guest-article-card'>
<Text className='guest-article-title'></Text>
<Text className='guest-article-summary'></Text>
</View>
) : (
<View className='guest-empty'>
<Text className='guest-empty-text'></Text>
<View className='guest-article-card'>
<Text className='guest-article-title'></Text>
<Text className='guest-article-summary'>线</Text>
</View>
)}
<View className='guest-article-card'>
<Text className='guest-article-title'>AI </Text>
<Text className='guest-article-summary'></Text>
</View>
</View>
</View>
{/* 底部登录引导 */}
@@ -106,7 +80,7 @@ function GuestHome({ modeClass }: { modeClass: string }) {
<Text className='guest-login-text'>使</Text>
<View
className='guest-login-btn'
onClick={() => Taro.navigateTo({ url: '/pages/login/index' })}
onClick={navigateToLogin}
>
<Text className='guest-login-btn-text'></Text>
</View>