refactor(miniprogram): 全面接入 Design Token — 68 SCSS 文件 px→var(--tk-*)
- 重写 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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user