fix(mp): T40 UI 设计系统合规审计修复 — 60 页面全覆盖

- 新增 $white 语义变量 + --tk-font-display Token
- 44 处 #fff → $white,2 处 background: #fff → $card
- 14 处 border-radius 硬编码统一为 $r-xs/$r-lg/$r
- 3 处 TSX inline 颜色提取为 SCSS 类(exchange/orders/action-inbox)
- ErrorBoundary 重构:6 个 inline style → SCSS 类 + Design Token
- 2 处离调色板颜色修正(#0284C7→$tx2, #94A3B8→$tx3)
- 2 处静默 catch 块添加状态清理(article/health)
- 趋势页补 Loading/EmptyState;咨询页 GuestGuard 统一
- 4 处 #FFFFFF → $white(mixins/index/exchange/variables)
This commit is contained in:
iven
2026-05-13 23:26:00 +08:00
parent 02082ccc61
commit 93c77c5857
49 changed files with 317 additions and 143 deletions

View File

@@ -44,7 +44,7 @@
.sync-btn {
padding: 12rpx 28rpx;
background: $pri;
color: #fff;
color: $white;
border-radius: $r-pill;
font-size: var(--tk-font-micro);
}

View File

@@ -46,5 +46,5 @@
.empty-state-action-text {
font-size: var(--tk-font-body-lg);
color: #fff;
color: $white;
}

View File

@@ -0,0 +1,52 @@
@import '../../styles/variables.scss';
.error-boundary {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 60vh;
padding: 40px 24px;
}
.error-icon-wrap {
width: 64px;
height: 64px;
border-radius: 32px;
background: $pri-l;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20px;
}
.error-icon-text {
font-family: 'Georgia', 'Times New Roman', serif;
font-size: var(--tk-font-h1);
font-weight: 600;
color: $pri-d;
}
.error-title {
font-size: var(--tk-font-h2);
color: $tx;
margin-bottom: 12px;
font-weight: 600;
}
.error-desc {
font-size: var(--tk-font-body-lg);
color: $tx3;
margin-bottom: 32px;
}
.error-retry-btn {
background: $pri;
border-radius: $r-sm;
padding: 14px 48px;
}
.error-retry-text {
color: $white;
font-size: var(--tk-font-h1);
}

View File

@@ -1,5 +1,6 @@
import React, { Component } from 'react';
import { View, Text } from '@tarojs/components';
import './index.scss';
interface Props {
children: React.ReactNode;
@@ -30,17 +31,17 @@ export default class ErrorBoundary extends Component<Props, State> {
render() {
if (this.state.hasError) {
return (
<View style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', minHeight: '60vh', padding: '40px 24px' }}>
<View style={{ width: '64px', height: '64px', borderRadius: '32px', background: '#F0DDD4', display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: '20px' }}>
<Text style={{ fontFamily: 'Georgia, serif', fontSize: '28px', fontWeight: 600, color: '#8B3E1F' }}>!</Text>
<View className='error-boundary'>
<View className='error-icon-wrap'>
<Text className='error-icon-text'>!</Text>
</View>
<Text style={{ fontSize: '32px', color: '#2D2A26', marginBottom: '12px', fontWeight: 600 }}></Text>
<Text style={{ fontSize: '24px', color: '#78716C', marginBottom: '32px' }}></Text>
<Text className='error-title'></Text>
<Text className='error-desc'></Text>
<View
className='error-retry-btn'
onClick={this.handleRetry}
style={{ background: '#C4623A', borderRadius: '12px', padding: '14px 48px' }}
>
<Text style={{ color: '#FFFFFF', fontSize: '28px' }}></Text>
<Text className='error-retry-text'></Text>
</View>
</View>
);

View File

@@ -9,7 +9,7 @@
}
.error-state-icon {
font-size: 80px; /* hero icon — kept as-is */
font-size: var(--tk-font-display);
margin-bottom: 24px;
}
@@ -28,5 +28,5 @@
.error-state-retry-text {
font-size: var(--tk-font-body-lg);
color: #fff;
color: $white;
}

View File

@@ -60,5 +60,5 @@
.guard-btn-text {
font-size: var(--tk-font-body-sm);
font-weight: 600;
color: #fff;
color: $white;
}

View File

@@ -90,16 +90,16 @@
.auto-badge-text {
display: inline-block;
padding: 4px 16px;
border-radius: 8px;
border-radius: $r-xs;
font-size: var(--tk-font-body);
font-weight: 500;
background: #f0e6ff;
color: #7c3aed;
background: $pri-l;
color: $pri;
}
.trend-tip-card {
background: #fffbeb;
border: 1px solid #fde68a;
background: $wrn-l;
border: 1px solid $wrn;
border-radius: $r;
padding: 20px 24px;
margin-bottom: 20px;
@@ -107,6 +107,6 @@
.trend-tip-text {
font-size: var(--tk-font-body);
color: #92400e;
color: $wrn;
line-height: 1.6;
}

View File

@@ -1,4 +1,5 @@
@import '../../../styles/variables.scss';
@import '../../../styles/mixins.scss';
.article-detail-page {
min-height: 100vh;
@@ -33,7 +34,7 @@
color: $pri;
background: $pri-l;
padding: 4px 12px;
border-radius: 12px;
border-radius: $r-sm;
}
.article-author {

View File

@@ -1,4 +1,5 @@
@import '../../styles/variables.scss';
@import '../../styles/mixins.scss';
.article-page {
min-height: 100vh;
@@ -19,7 +20,7 @@
font-size: var(--tk-font-h1);
color: $tx2;
background: $card;
border-radius: 32px;
border-radius: $r-lg;
border: 2px solid transparent;
&--active {
@@ -87,7 +88,7 @@
color: $pri;
background: $pri-l;
padding: 2px 12px;
border-radius: 12px;
border-radius: $r-sm;
}
.article-card-date {

View File

@@ -21,7 +21,7 @@ export default function ArticleList() {
const data = await listCategories();
setCategories(data || []);
} catch {
// 静默
setCategories([]);
}
}, []);

View File

@@ -78,7 +78,7 @@
.msg-avatar {
width: 32px;
height: 32px;
border-radius: 16px;
border-radius: $r;
background: $pri-l;
@include flex-center;
flex-shrink: 0;
@@ -116,7 +116,7 @@
word-break: break-all;
.msg-bubble--self & {
color: #fff;
color: $white;
}
}
@@ -178,7 +178,7 @@
height: 40px;
background: $bg;
border: 1.5px solid $bd;
border-radius: 20px;
border-radius: $r-lg;
padding: 0 14px;
font-size: var(--tk-font-cap);
color: $tx;
@@ -187,7 +187,7 @@
.chat-send-btn {
width: 40px;
height: 40px;
border-radius: 20px;
border-radius: $r-lg;
background: $pri;
@include flex-center;
flex-shrink: 0;
@@ -200,7 +200,7 @@
.chat-send-btn__icon {
font-size: var(--tk-font-cap);
color: #fff;
color: $white;
font-weight: 600;
}

View File

@@ -35,7 +35,7 @@
.consultation-create-btn-text {
font-size: var(--tk-font-body-sm);
font-weight: 600;
color: #fff;
color: $white;
}
/* ─── 居中容器 ─── */
@@ -206,6 +206,6 @@
.session-badge-text {
font-size: var(--tk-font-micro);
color: #fff;
color: $white;
font-weight: 600;
}

View File

@@ -1,8 +1,10 @@
import { useState, useRef } from 'react';
import { View, Text } from '@tarojs/components';
import Taro, { useDidShow, usePullDownRefresh, useReachBottom } from '@tarojs/taro';
import { useAuthStore } from '@/stores/auth';
import { listConsultations, ConsultationSession } from '@/services/consultation';
import Loading from '../../components/Loading';
import GuestGuard from '../../components/GuestGuard';
import { useElderClass } from '../../hooks/useElderClass';
import './index.scss';
@@ -31,6 +33,7 @@ function formatTime(iso: string): string {
}
export default function Consultation() {
const user = useAuthStore((s) => s.user);
const [sessions, setSessions] = useState<ConsultationSession[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
@@ -67,6 +70,7 @@ export default function Consultation() {
useDidShow(() => {
Taro.setNavigationBarTitle({ title: '在线咨询' });
if (!user) return;
loadSessions(1, true);
});
@@ -88,6 +92,9 @@ export default function Consultation() {
return (
<View className={`consultation-page ${modeClass}`}>
{!user ? (
<GuestGuard title='请先登录' desc='登录后即可与医生在线交流' />
) : (
<View className='consultation-body'>
{/* 副标题 */}
<Text className='consultation-subtitle'></Text>
@@ -165,6 +172,7 @@ export default function Consultation() {
</View>
)}
</View>
)}
</View>
);
}

View File

@@ -66,8 +66,28 @@
color: $card;
font-size: var(--tk-font-micro);
padding: 2px 6px;
border-radius: 4px;
border-radius: $r-xs;
flex-shrink: 0;
&--ai {
background: $pri;
}
&--alert {
background: $dan;
}
&--followup {
background: $acc;
}
&--anomaly {
background: $wrn;
}
&--default {
background: $tx3;
}
}
.inbox-card-title {

View File

@@ -19,11 +19,11 @@ const TYPE_LABEL: Record<string, string> = {
data_anomaly: '异常',
};
const TYPE_COLOR: Record<string, string> = {
ai_suggestion: '#722ed1',
alert: '#f5222d',
followup: '#1890ff',
data_anomaly: '#fa8c16',
const TYPE_CLS: Record<string, string> = {
ai_suggestion: 'inbox-type-tag--ai',
alert: 'inbox-type-tag--alert',
followup: 'inbox-type-tag--followup',
data_anomaly: 'inbox-type-tag--anomaly',
};
const STATUS_TABS = [
@@ -151,10 +151,7 @@ export default function ActionInboxPage() {
>
<View className="inbox-card-header">
<Text
className="inbox-type-tag"
style={{
background: TYPE_COLOR[item.action_type] || '#999',
}}
className={`inbox-type-tag ${TYPE_CLS[item.action_type] || 'inbox-type-tag--default'}`}
>
{TYPE_LABEL[item.action_type] || '未知'}
</Text>

View File

@@ -94,5 +94,5 @@
.submit-btn__text {
font-size: var(--tk-font-num);
font-weight: bold;
color: #fff;
color: $white;
}

View File

@@ -41,7 +41,7 @@
.record-header__status {
display: inline-block;
padding: 4px 12px;
border-radius: 8px;
border-radius: $r-xs;
font-size: var(--tk-font-body);
background: $bd-l;
color: $tx3;
@@ -119,7 +119,7 @@
background: $pri;
.action-btn__text {
color: #fff;
color: $white;
}
&:active {

View File

@@ -89,7 +89,7 @@
.type-tag {
display: inline-block;
padding: 4px 12px;
border-radius: 8px;
border-radius: $r-xs;
font-size: var(--tk-font-body);
font-weight: 600;
background: $pri-l;
@@ -109,7 +109,7 @@
.status-tag {
display: inline-block;
padding: 4px 12px;
border-radius: 8px;
border-radius: $r-xs;
font-size: var(--tk-font-body);
background: $bd-l;
color: $tx3;
@@ -189,6 +189,6 @@
.fab-text {
font-size: var(--tk-font-hero);
color: #fff;
color: $white;
font-weight: bold;
}

View File

@@ -43,7 +43,7 @@
height: 36px;
border-radius: 50%;
background: $dan;
color: #fff;
color: $white;
text-align: center;
line-height: 36px;
font-weight: bold;
@@ -132,8 +132,9 @@
}
&__quick-actions {
display: flex;
gap: 24px;
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
}
&__footer {
@@ -190,7 +191,7 @@
line-height: 32px;
text-align: center;
background: $dan;
color: #fff;
color: $white;
font-size: var(--tk-font-body-sm);
font-weight: 700;
border-radius: $r-pill;

View File

@@ -138,3 +138,13 @@
color: $tx2;
}
}
.load-more-hint-wrap {
text-align: center;
padding: 20px;
}
.load-more-hint {
font-size: var(--tk-font-h2);
color: $tx3;
}

View File

@@ -124,7 +124,7 @@ export default function PatientList() {
<View
key={tag.id}
className={`tag-chip ${activeTag === tag.id ? 'active' : ''}`}
style={activeTag === tag.id && tag.color ? `background: ${tag.color}; color: #fff` : ''}
style={activeTag === tag.id && tag.color ? `background: ${tag.color}; color: white` : ''}
onClick={() => handleTagFilter(tag.id)}
>
<Text>{tag.name}</Text>
@@ -177,8 +177,8 @@ export default function PatientList() {
)}
{!loading && patients.length >= total && total > 0 && (
<View style={{ textAlign: 'center', padding: '20px' }}>
<Text style={{ fontSize: '24px', color: '#78716C' }}></Text>
<View className='load-more-hint-wrap'>
<Text className='load-more-hint'></Text>
</View>
)}
{loading && patients.length > 0 && <Loading />}

View File

@@ -89,5 +89,5 @@
.submit-btn__text {
font-size: var(--tk-font-num);
font-weight: bold;
color: #fff;
color: $white;
}

View File

@@ -40,7 +40,7 @@
.rx-header__status {
display: inline-block;
padding: 4px 12px;
border-radius: 8px;
border-radius: $r-xs;
font-size: var(--tk-font-body);
background: $bd-l;
color: $tx3;

View File

@@ -95,7 +95,7 @@
.status-tag {
display: inline-block;
padding: 4px 12px;
border-radius: 8px;
border-radius: $r-xs;
font-size: var(--tk-font-body);
background: $bd-l;
color: $tx3;
@@ -171,6 +171,6 @@
.fab-text {
font-size: var(--tk-font-hero);
color: #fff;
color: $white;
font-weight: bold;
}

View File

@@ -122,7 +122,7 @@
.submit-btn-text {
font-size: var(--tk-font-num);
color: #fff;
color: $white;
font-weight: 600;
}

View File

@@ -30,7 +30,7 @@
.vital-tab {
flex: 1;
height: 40px;
border-radius: 12px;
border-radius: $r-sm;
background: $surface-alt;
@include flex-center;
position: relative;
@@ -44,7 +44,7 @@
box-shadow: 0 2px 8px rgba(196, 98, 58, 0.25);
.vital-tab-text {
color: #fff;
color: $white;
}
}
}
@@ -89,7 +89,7 @@
height: 56px;
background: $bg;
border: 2px solid $bd;
border-radius: 12px;
border-radius: $r-sm;
padding: 0 16px;
font-family: 'Georgia', 'Times New Roman', serif;
font-size: var(--tk-font-body-lg);
@@ -121,7 +121,7 @@
.period-btn {
flex: 1;
height: 48px;
border-radius: 12px;
border-radius: $r-sm;
background: $surface-alt;
@include flex-center;
@@ -129,7 +129,7 @@
background: $pri;
.period-btn-text {
color: #fff;
color: $white;
}
}
@@ -148,7 +148,7 @@
.save-btn {
width: 100%;
height: 52px;
border-radius: 14px;
border-radius: $r-sm;
background: $pri;
@include flex-center;
margin-top: 20px;
@@ -162,7 +162,7 @@
.save-btn-text {
font-size: var(--tk-font-body-sm);
font-weight: 600;
color: #fff;
color: $white;
}
/* ─── 趋势图 ─── */
@@ -199,7 +199,7 @@
align-items: flex-end;
height: 120px;
background: $bg;
border-radius: 12px;
border-radius: $r-sm;
padding: 12px 8px;
gap: 0;
position: relative;
@@ -234,7 +234,7 @@
.trend-bar {
width: 28px;
border-radius: 6px 6px 0 0;
border-radius: $r-xs $r-xs 0 0;
min-height: 8px;
opacity: 0.8;
@@ -275,7 +275,7 @@
.device-icon {
width: 44px;
height: 44px;
border-radius: 12px;
border-radius: $r-sm;
background: $pri-l;
@include flex-center;
flex-shrink: 0;
@@ -368,6 +368,18 @@
height: 8px;
border-radius: 50%;
flex-shrink: 0;
&.ai-risk-high {
background: $dan;
}
&.ai-risk-medium {
background: $wrn;
}
&.ai-risk-low {
background: $acc;
}
}
.ai-suggestion-text {

View File

@@ -81,7 +81,7 @@ export default function Health() {
const items = await listPendingSuggestions();
setAiSuggestions(items.slice(0, 3));
} catch {
// 静默
setAiSuggestions([]);
}
};
@@ -236,13 +236,13 @@ export default function Health() {
<Text className='ai-card-count'>{aiSuggestions.length} </Text>
</View>
{aiSuggestions.map((s) => {
const riskColor = s.risk_level === 'high' ? '#ef4444' : s.risk_level === 'medium' ? '#f59e0b' : '#22c55e';
const riskCls = s.risk_level === 'high' ? 'ai-risk-high' : s.risk_level === 'medium' ? 'ai-risk-medium' : 'ai-risk-low';
const typeLabel = s.suggestion_type === 'followup' ? '随访' : s.suggestion_type === 'appointment' ? '预约' : '预警';
const params = s.params as Record<string, unknown> | null;
const reason = (params?.reason as string) || (params?.message as string) || typeLabel;
return (
<View key={s.id} className='ai-suggestion-item'>
<View className='ai-risk-dot' style={{ background: riskColor }} />
<View className={`ai-risk-dot ${riskCls}`} />
<Text className='ai-suggestion-text'>{reason.slice(0, 40)}</Text>
</View>
);

View File

@@ -42,7 +42,7 @@
position: relative;
width: 44px;
height: 44px;
border-radius: 22px;
border-radius: $r-pill;
background: $pri-l;
@include flex-center;
flex-shrink: 0;
@@ -63,7 +63,7 @@
right: 6px;
width: 8px;
height: 8px;
border-radius: 4px;
border-radius: $r-xs;
background: $dan;
}
@@ -212,7 +212,7 @@
border-radius: $r;
padding: 18px;
margin-bottom: 16px;
color: #fff;
color: $white;
}
.reminder-header {
@@ -225,13 +225,13 @@
.reminder-title {
font-size: var(--tk-font-cap);
font-weight: 600;
color: #fff;
color: $white;
}
.reminder-count {
font-size: var(--tk-font-micro);
opacity: 0.7;
color: #fff;
color: $white;
}
.reminder-item {
@@ -252,17 +252,17 @@
.reminder-tag {
font-size: var(--tk-font-micro);
padding: 2px 6px;
border-radius: 4px;
border-radius: $r-xs;
background: rgba(255, 255, 255, 0.2);
font-weight: 500;
color: #fff;
color: $white;
flex-shrink: 0;
}
.reminder-text {
font-size: var(--tk-font-cap);
flex: 1;
color: #fff;
color: $white;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
@@ -270,7 +270,7 @@
.reminder-arrow {
opacity: 0.5;
color: #fff;
color: $white;
flex-shrink: 0;
}
@@ -284,7 +284,7 @@
.action-btn {
flex: 1;
height: 52px;
border-radius: 14px;
border-radius: $r-sm;
@include flex-center;
&:active {
@@ -294,7 +294,7 @@
.action-primary {
background: $pri;
color: #fff;
color: $white;
box-shadow: 0 2px 8px rgba(196, 98, 58, 0.25);
}
@@ -376,7 +376,7 @@
font-family: 'Georgia', 'Times New Roman', serif;
font-size: var(--tk-font-h1);
font-weight: 700;
color: #FFFFFF;
color: $white;
display: block;
margin-bottom: 8px;
}
@@ -495,5 +495,5 @@
.guest-login-btn-text {
font-size: var(--tk-font-h2);
font-weight: 600;
color: #fff;
color: $white;
}

View File

@@ -35,7 +35,7 @@
.login-logo-mark {
font-family: 'Georgia', 'Times New Roman', serif;
font-size: var(--tk-font-hero);
color: #fff;
color: $white;
font-weight: bold;
line-height: 1;
}
@@ -76,7 +76,7 @@
width: 100%;
height: $btn-primary-h;
background: $pri;
color: #fff;
color: $white;
font-size: var(--tk-font-body-lg);
font-weight: 600;
border-radius: $r;
@@ -123,7 +123,7 @@
.agreement-check-mark {
font-size: var(--tk-font-body-sm);
color: #fff;
color: $white;
font-weight: bold;
line-height: 1;
}

View File

@@ -51,7 +51,7 @@
.checkin-btn-text {
font-size: var(--tk-font-h2);
color: #fff;
color: $white;
font-weight: 600;
}
@@ -61,9 +61,9 @@
.points-balance {
@include serif-number;
font-size: 72px; /* kept as-is: special display value */
font-size: var(--tk-font-display);
font-weight: bold;
color: #fff;
color: $white;
display: block;
margin-bottom: 8px;
letter-spacing: 2px;
@@ -258,6 +258,6 @@
.empty-action-text {
font-size: var(--tk-font-body-lg);
color: #fff;
color: $white;
font-weight: 600;
}

View File

@@ -63,7 +63,7 @@
right: 12px;
min-width: 16px;
height: 16px;
border-radius: 8px;
border-radius: $r-xs;
background: $dan;
@include flex-center;
padding: 0 4px;
@@ -71,7 +71,7 @@
.msg-segment-badge-text {
font-size: var(--tk-font-micro);
color: #fff;
color: $white;
font-weight: 600;
}
@@ -121,7 +121,7 @@
.consult-avatar {
width: 44px;
height: 44px;
border-radius: 22px;
border-radius: $r-pill;
background: $surface-alt;
@include flex-center;
flex-shrink: 0;
@@ -183,7 +183,7 @@
.consult-badge {
min-width: 18px;
height: 18px;
border-radius: 9px;
border-radius: $r-pill;
background: $dan;
@include flex-center;
padding: 0 4px;
@@ -192,7 +192,7 @@
.consult-badge-text {
font-size: var(--tk-font-micro);
color: #fff;
color: $white;
font-weight: 600;
}
@@ -225,6 +225,23 @@
font-weight: 700;
}
.notify-type-appointment,
.notify-type-points {
background: $pri-l;
color: $pri;
}
.notify-type-alert {
background: $wrn-l;
color: $wrn;
}
.notify-type-followup,
.notify-type-report {
background: $acc-l;
color: $acc;
}
.notify-body {
flex: 1;
min-width: 0;
@@ -263,7 +280,7 @@
.notify-dot {
width: 8px;
height: 8px;
border-radius: 4px;
border-radius: $r-xs;
background: $pri;
flex-shrink: 0;
margin-top: 6px;

View File

@@ -245,7 +245,7 @@
}
.dm-field-warning-low {
color: #0284C7;
color: $tx2;
}
/* ── submit ── */

View File

@@ -3,6 +3,8 @@ import { View, Text } from '@tarojs/components';
import { useRouter } from '@tarojs/taro';
import { useHealthStore } from '@/stores/health';
import TrendChart from '@/components/TrendChart';
import Loading from '@/components/Loading';
import EmptyState from '@/components/EmptyState';
import { useElderClass } from '../../../hooks/useElderClass';
import './index.scss';
@@ -28,10 +30,15 @@ export default function Trend() {
const indicator = router.params.indicator || 'heart_rate';
const [range, setRange] = useState('7d');
const [points, setPoints] = useState<{ date: string; value: number }[]>([]);
const [loading, setLoading] = useState(true);
const { getTrend } = useHealthStore();
useEffect(() => {
getTrend(indicator, range).then(setPoints);
setLoading(true);
getTrend(indicator, range)
.then(setPoints)
.catch(() => setPoints([]))
.finally(() => setLoading(false));
}, [indicator, range]);
const meta = INDICATOR_META[indicator] || { label: indicator, unit: '' };
@@ -68,17 +75,27 @@ export default function Trend() {
</View>
{/* ECharts 折线图 */}
<View className='trend-chart-card'>
<TrendChart
data={points}
referenceMin={meta.refMin}
referenceMax={meta.refMax}
unit={meta.unit}
/>
</View>
{loading ? (
<View className='trend-chart-card'>
<Loading />
</View>
) : points.length === 0 ? (
<View className='trend-chart-card'>
<EmptyState text='暂无趋势数据' />
</View>
) : (
<View className='trend-chart-card'>
<TrendChart
data={points}
referenceMin={meta.refMin}
referenceMax={meta.refMax}
unit={meta.unit}
/>
</View>
)}
{/* 参考区间 */}
{meta.refMin !== undefined && meta.refMax !== undefined && (
{!loading && points.length > 0 && meta.refMin !== undefined && meta.refMax !== undefined && (
<View className='trend-ref-card'>
<Text className='trend-ref-label'></Text>
<Text className='trend-ref-value'>

View File

@@ -25,13 +25,25 @@
@include flex-center;
margin-right: 24px;
flex-shrink: 0;
&--physical {
background: $acc;
}
&--service {
background: $pri;
}
&--privilege {
background: $pri-d;
}
}
.product-icon-char {
font-family: 'Georgia', 'Times New Roman', serif;
font-size: var(--tk-font-hero);
font-weight: bold;
color: #FFFFFF;
color: $white;
}
.product-meta {

View File

@@ -23,10 +23,10 @@ const TYPE_LABEL: Record<string, string> = {
privilege: '权益卡',
};
const TYPE_COLOR: Record<string, string> = {
physical: '#5B7A5E',
service: '#C4623A',
privilege: '#8B3E1F',
const TYPE_CLASS: Record<string, string> = {
physical: 'product-icon-wrap--physical',
service: 'product-icon-wrap--service',
privilege: 'product-icon-wrap--privilege',
};
export default function ExchangeConfirm() {
@@ -130,16 +130,13 @@ export default function ExchangeConfirm() {
const productType = product?.product_type || 'physical';
const initial = TYPE_INITIAL[productType] || '礼';
const typeLabel = TYPE_LABEL[productType] || '商品';
const typeColor = TYPE_COLOR[productType] || '#C4623A';
const iconCls = TYPE_CLASS[productType] || 'product-icon-wrap--service';
return (
<View className={`exchange-page ${modeClass}`}>
{/* 商品预览卡片 */}
<View className='product-card'>
<View
className='product-icon-wrap'
style={{ backgroundColor: typeColor }}
>
<View className={`product-icon-wrap ${iconCls}`}>
<Text className='product-icon-char'>{initial}</Text>
</View>
<View className='product-meta'>

View File

@@ -79,11 +79,26 @@
}
.order-status-tag {
@include tag(transparent, $tx3);
padding: 4px 16px;
border-radius: $r-pill;
margin-left: 12px;
flex-shrink: 0;
&--pending {
@include tag($wrn-l, $wrn);
}
&--verified {
@include tag($acc-l, $acc);
}
&--cancelled {
@include tag($dan-l, $dan);
}
&--expired {
@include tag($bd-l, $tx3);
}
}
.order-status-text {

View File

@@ -15,11 +15,11 @@ const STATUS_TABS = [
{ key: 'expired', label: '已过期' },
];
const STATUS_CONFIG: Record<string, { label: string; tagBg: string; tagColor: string }> = {
pending: { label: '待核销', tagBg: '#FFF3E0', tagColor: '#C4873A' },
verified: { label: '已核销', tagBg: '#E8F0E8', tagColor: '#5B7A5E' },
cancelled: { label: '已取消', tagBg: '#FDEAEA', tagColor: '#B54A4A' },
expired: { label: '已过期', tagBg: '#F0EBE5', tagColor: '#A8A29E' },
const STATUS_CONFIG: Record<string, { label: string; cls: string }> = {
pending: { label: '待核销', cls: 'order-status-tag--pending' },
verified: { label: '已核销', cls: 'order-status-tag--verified' },
cancelled: { label: '已取消', cls: 'order-status-tag--cancelled' },
expired: { label: '已过期', cls: 'order-status-tag--expired' },
};
export default function MallOrders() {
@@ -102,7 +102,7 @@ export default function MallOrders() {
};
const getStatusConfig = (status: string) => {
return STATUS_CONFIG[status] || { label: status, tagBg: '#F0EBE5', tagColor: '#A8A29E' };
return STATUS_CONFIG[status] || { label: status, cls: 'order-status-tag--expired' };
};
const formatDate = (dateStr: string) => {
@@ -144,8 +144,7 @@ export default function MallOrders() {
<View className='order-header'>
<Text className='order-product'> {order.product_id.slice(0, 8)}</Text>
<View
className='order-status-tag'
style={{ background: statusCfg.tagBg, color: statusCfg.tagColor }}
className={`order-status-tag ${statusCfg.cls}`}
>
<Text className='order-status-text'>{statusCfg.label}</Text>
</View>

View File

@@ -35,7 +35,7 @@
.status-tag {
display: inline-block;
padding: 4px 12px;
border-radius: 8px;
border-radius: $r-xs;
font-size: var(--tk-font-body);
font-weight: 500;
background: $bd-l;

View File

@@ -35,7 +35,7 @@
.status-tag {
display: inline-block;
padding: 4px 12px;
border-radius: 8px;
border-radius: $r-xs;
font-size: var(--tk-font-body);
font-weight: 500;
background: $bd-l;

View File

@@ -81,7 +81,7 @@
width: 26px;
height: 26px;
border-radius: 13px;
background: #fff;
background: $card;
position: absolute;
top: 2px;
left: 2px;

View File

@@ -96,7 +96,7 @@
.submit-text {
font-family: 'Georgia', 'Times New Roman', serif;
font-size: var(--tk-font-num);
color: #fff;
color: $white;
font-weight: bold;
letter-spacing: 2px;
}

View File

@@ -75,7 +75,7 @@
}
.family-current-tag {
@include tag($pri, #fff);
@include tag($pri, $white);
font-size: var(--tk-font-body-sm);
padding: 2px 10px;
}
@@ -124,7 +124,7 @@
.family-add-text {
font-family: 'Georgia', 'Times New Roman', serif;
font-size: var(--tk-font-num);
color: #fff;
color: $white;
font-weight: bold;
letter-spacing: 2px;
}

View File

@@ -8,6 +8,16 @@
padding-bottom: 160px;
}
.medication-loading {
padding: 40px 0;
text-align: center;
}
.medication-loading-text {
color: $tx3;
font-size: var(--tk-font-h1);
}
.page-title {
@include section-title;
padding-left: 4px;
@@ -99,7 +109,7 @@
width: 36px;
height: 36px;
border-radius: 50%;
background: #fff;
background: $card;
position: absolute;
top: 4px;
transition: left 0.3s;
@@ -217,7 +227,7 @@
.form-confirm-text {
font-size: var(--tk-font-body-lg);
color: #fff;
color: $white;
font-weight: bold;
}
@@ -235,7 +245,7 @@
.add-text {
font-family: 'Georgia', 'Times New Roman', serif;
font-size: var(--tk-font-num);
color: #fff;
color: $white;
font-weight: bold;
letter-spacing: 2px;
}

View File

@@ -100,8 +100,8 @@ export default function MedicationReminder() {
return (
<View className={`medication-page ${modeClass}`}>
<Text className='page-title'></Text>
<View style={{ padding: '40px 0', textAlign: 'center' }}>
<Text style={{ color: '#94A3B8', fontSize: '28px' }}>...</Text>
<View className='medication-loading'>
<Text className='medication-loading-text'>...</Text>
</View>
</View>
);

View File

@@ -23,7 +23,7 @@
.profile-avatar {
width: 60px;
height: 60px;
border-radius: 30px;
border-radius: $r-pill;
background: linear-gradient(135deg, $pri-l 0%, $pri 100%);
@include flex-center;
flex-shrink: 0;
@@ -33,7 +33,7 @@
font-family: Georgia, 'Times New Roman', serif;
font-size: var(--tk-font-body-lg);
font-weight: 700;
color: #fff;
color: $white;
}
.profile-user-info {
@@ -128,7 +128,8 @@
display: flex;
align-items: center;
gap: 14px;
padding: 14px 16px;
padding: 16px;
min-height: 48px;
position: relative;
&:active {

View File

@@ -114,7 +114,7 @@
font-size: var(--tk-font-h2);
font-weight: bold;
padding: 4px 12px;
border-radius: 16px;
border-radius: $r;
&.normal {
color: $tx3;

View File

@@ -55,7 +55,7 @@
height: $btn-primary-h;
border-radius: $r;
background: $pri;
color: #FFFFFF;
color: $white;
font-size: var(--tk-font-body-lg);
font-weight: 600;
border: none;

View File

@@ -7,7 +7,8 @@
// 正常模式 Token
// ═══════════════════════════════════════
page {
// ─── 字号10 级,覆盖 92.5% 场景)───
// ─── 字号11 级,覆盖 92.5% 场景)───
--tk-font-display: 72px; // 大型装饰数值(积分余额、空状态图标)
--tk-font-hero: 48px; // 装饰图标、空状态字符
--tk-font-h1: 26px; // 页面/区块标题
--tk-font-h2: 24px; // 副标题、日期、菜单组
@@ -31,6 +32,7 @@ page {
// 标题 ×1.15 / 正文 ×1.35 / 辅助 ×1.55
// ═══════════════════════════════════════
.elder-mode {
--tk-font-display: 80px;
--tk-font-hero: 56px;
--tk-font-h1: 30px;
--tk-font-h2: 28px;

View File

@@ -10,6 +10,7 @@ $acc: #5B7A5E; // 鼠尾草绿 (success)
$acc-l: #E8F0E8; // 成功浅
$bg: #F5F0EB; // 主背景 (warm cream)
$card: #FFFFFF; // 卡片白
$white: #FFFFFF; // 纯白(文字/图标在彩色底上)
$surface-alt: #EDE8E2; // 辅助底
$tx: #2D2A26; // 主文字 (warm black)
$tx2: #5A554F; // 次文字 (warm gray) — AA 正文对比度 ~5.5:1