refactor(mp): 统一空状态为 EmptyState 组件 + 清理旧 Tab CSS

- 4 个页面的内联空状态替换为共享 EmptyState 组件
  (messages / action-inbox / pkg-health/alerts / mall)
- 清理 10 个页面的旧 Tab CSS(迁移到 SegmentTabs 后不再需要)
- 清理 elder-mode 中已删除的 mall-empty-state 引用
This commit is contained in:
iven
2026-05-15 23:11:34 +08:00
parent c06e986090
commit 3fb5a77ac0
17 changed files with 16 additions and 446 deletions

View File

@@ -20,51 +20,6 @@
color: $tx;
}
/* ─── 类型 Tab ─── */
.vital-tabs {
display: flex;
padding: 0 0 16px;
gap: 8px;
}
.vital-tab {
flex: 1;
height: 48px;
border-radius: $r-sm;
background: $surface-alt;
@include flex-center;
position: relative;
&:active {
opacity: 0.85;
}
&.vital-tab-active {
background: $pri;
box-shadow: 0 2px 8px rgba(196, 98, 58, 0.25);
.vital-tab-text {
color: $white;
}
}
}
.vital-tab-text {
font-size: var(--tk-font-cap);
font-weight: 600;
color: $tx2;
}
.vital-tab-dot {
position: absolute;
top: 8px;
right: 8px;
width: 6px;
height: 6px;
border-radius: 50%;
background: $wrn;
}
/* ─── 录入区 ─── */
.input-section {
margin-bottom: 20px;

View File

@@ -207,58 +207,3 @@
}
}
/* ─── 空状态 ─── */
.mall-empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100px 40px;
}
.empty-icon {
width: 120px;
height: 120px;
border-radius: 50%;
background: $pri-l;
@include flex-center;
margin-bottom: 32px;
}
.empty-char {
font-family: 'Georgia', 'Times New Roman', serif;
font-size: var(--tk-font-hero);
font-weight: bold;
color: $pri;
line-height: 1;
}
.empty-title {
font-size: var(--tk-font-body-lg);
font-weight: 600;
color: $tx;
margin-bottom: 12px;
}
.empty-hint {
font-size: var(--tk-font-h1);
color: var(--tk-text-secondary);
text-align: center;
margin-bottom: 24px;
}
.empty-action {
background: $pri;
border-radius: $r;
padding: 16px 48px;
&:active {
opacity: 0.85;
}
}
.empty-action-text {
font-size: var(--tk-font-body-lg);
color: $white;
font-weight: 600;
}

View File

@@ -8,6 +8,7 @@ import { useAuthStore } from '../../stores/auth';
import { usePointsStore } from '../../stores/points';
import Loading from '../../components/Loading';
import ErrorState from '../../components/ErrorState';
import EmptyState from '../../components/EmptyState';
import { useElderClass } from '../../hooks/useElderClass';
import './index.scss';
@@ -137,16 +138,13 @@ export default function Mall() {
if (noProfile) {
return (
<View className={`mall-page ${modeClass}`}>
<View className='mall-empty-state'>
<View className='empty-icon'>
<Text className='empty-char'></Text>
</View>
<Text className='empty-title'></Text>
<Text className='empty-hint'>使</Text>
<View className='empty-action' onClick={() => Taro.navigateTo({ url: '/pages/pkg-profile/family-add/index' })}>
<Text className='empty-action-text'></Text>
</View>
</View>
<EmptyState
icon='档'
text='请先完善个人档案'
hint='建档后即可使用积分商城、签到等功能'
actionText='去建档'
onAction={() => Taro.navigateTo({ url: '/pages/pkg-profile/family-add/index' })}
/>
</View>
);
}
@@ -195,13 +193,7 @@ export default function Mall() {
{error ? (
<ErrorState onRetry={() => loadAll()} />
) : products.length === 0 && !loading ? (
<View className='mall-empty-state'>
<View className='empty-icon'>
<Text className='empty-char'></Text>
</View>
<Text className='empty-title'></Text>
<Text className='empty-hint'></Text>
</View>
<EmptyState icon='礼' text='暂无商品' hint='更多好物即将上架' />
) : (
<View className='product-grid'>
{products.map((item) => (

View File

@@ -86,19 +86,6 @@
gap: 8px;
}
.msg-empty {
background: $card;
border-radius: $r;
padding: 48px 24px;
text-align: center;
box-shadow: $shadow-sm;
}
.msg-empty-text {
font-size: var(--tk-font-cap);
color: $tx2;
}
/* ─── 咨询卡片 ─── */
.consult-card {
display: flex;

View File

@@ -5,6 +5,7 @@ import { listConsultations, ConsultationSession } from '../../services/consultat
import { notificationService } from '../../services/notification';
import Loading from '../../components/Loading';
import ErrorState from '../../components/ErrorState';
import EmptyState from '../../components/EmptyState';
import GuestGuard from '../../components/GuestGuard';
import { useAuthStore } from '../../stores/auth';
import { useElderClass } from '../../hooks/useElderClass';
@@ -152,9 +153,7 @@ export default function Messages() {
loading ? (
<Loading />
) : sessions.length === 0 ? (
<View className='msg-empty'>
<Text className='msg-empty-text'></Text>
</View>
<EmptyState text='暂无咨询消息' />
) : (
<View className='msg-list'>
{sessions.map((session) => {
@@ -201,9 +200,7 @@ export default function Messages() {
loading ? (
<Loading />
) : notifications.length === 0 ? (
<View className='msg-empty'>
<Text className='msg-empty-text'></Text>
</View>
<EmptyState text='暂无新通知' />
) : (
<View className='msg-list'>
{notifications.map((n) => {

View File

@@ -26,26 +26,6 @@
color: $tx2;
}
.alert-tabs {
display: flex;
gap: 12px;
margin-bottom: 24px;
}
.alert-tab {
padding: 10px 24px;
border-radius: $r-pill;
background: $bd-l;
font-size: var(--tk-font-h2);
color: $tx2;
transition: all 0.2s;
&--active {
background: $pri;
color: $card;
}
}
.alert-cards {
display: flex;
flex-direction: column;

View File

@@ -20,43 +20,6 @@
color: $tx;
}
.tabs {
display: flex;
padding: 0 24px;
background: $card;
border-bottom: 1px solid $bd-l;
}
.tab {
flex: 1;
text-align: center;
padding: 20px 0;
position: relative;
&--active {
.tab-text {
color: $pri;
font-weight: bold;
}
&::after {
content: '';
position: absolute;
bottom: 0;
left: 25%;
right: 25%;
height: 4px;
background: $pri;
border-radius: $r-xs;
}
}
}
.tab-text {
font-size: var(--tk-font-h1);
color: $tx2;
}
.record-list {
padding: 16px 24px;
}

View File

@@ -20,43 +20,6 @@
color: $tx;
}
.tabs {
display: flex;
padding: 0 24px;
background: $card;
border-bottom: 1px solid $bd-l;
}
.tab {
flex: 1;
text-align: center;
padding: 20px 0;
position: relative;
&--active {
.tab-text {
color: $pri;
font-weight: bold;
}
&::after {
content: '';
position: absolute;
bottom: 0;
left: 25%;
right: 25%;
height: 4px;
background: $pri;
border-radius: $r-xs;
}
}
}
.tab-text {
font-size: var(--tk-font-h1);
color: $tx2;
}
.prescription-list {
padding: 16px 24px;
}

View File

@@ -6,44 +6,6 @@
background: $bg;
}
.inbox-tabs {
display: flex;
background: $card;
padding: 0 16px;
border-bottom: 1px solid $bd;
.inbox-tab {
flex: 1;
text-align: center;
padding: 12px 0;
min-height: 48px;
&.active {
.inbox-tab-text {
color: $pri;
font-weight: 600;
position: relative;
&::after {
content: '';
position: absolute;
bottom: -12px;
left: 30%;
right: 30%;
height: 3px;
background: $pri;
border-radius: $r-xs;
}
}
}
}
.inbox-tab-text {
font-size: var(--tk-font-cap);
color: $tx2;
}
}
.inbox-list {
height: calc(100vh - 50px);
padding: 12px;
@@ -103,16 +65,6 @@
}
}
.inbox-empty {
text-align: center;
padding: 80px 0;
.inbox-empty-text {
font-size: var(--tk-font-cap);
color: $tx3;
}
}
.half-screen-dialog {
position: fixed;
bottom: 0;

View File

@@ -11,6 +11,7 @@ import {
} from '@/services/action-inbox';
import Loading from '@/components/Loading';
import ErrorState from '@/components/ErrorState';
import EmptyState from '@/components/EmptyState';
import SegmentTabs from '@/components/SegmentTabs';
import { useElderClass } from '../../../hooks/useElderClass';
import './index.scss';
@@ -124,9 +125,7 @@ export default function ActionInboxPage() {
{error ? (
<ErrorState onRetry={() => fetchItems(1, activeTab, true)} />
) : items.length === 0 && !loading ? (
<View className="inbox-empty">
<Text className="inbox-empty-text"></Text>
</View>
<EmptyState text='暂无待办事项' />
) : (
<ScrollView scrollY className="inbox-list">
{items.map((item) => (

View File

@@ -6,38 +6,6 @@
background: $bg;
}
.tabs {
display: flex;
background: $card;
padding: 0 16px;
border-bottom: 1px solid $bd;
}
.tab {
flex: 1;
text-align: center;
padding: 24px 0;
font-size: var(--tk-font-body-lg);
color: $tx2;
position: relative;
&--active {
color: $pri;
font-weight: 600;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 30%;
right: 30%;
height: 4px;
background: $pri;
border-radius: $r-xs;
}
}
}
.session-list {
padding: 20px 24px;
display: flex;

View File

@@ -6,40 +6,6 @@
background: $bg;
}
.tabs {
display: flex;
background: $card;
padding: 0 12px;
border-bottom: 1px solid $bd;
overflow-x: auto;
white-space: nowrap;
}
.tab {
display: inline-block;
padding: 24px 16px;
font-size: var(--tk-font-h1);
color: $tx2;
position: relative;
flex-shrink: 0;
&--active {
color: $pri;
font-weight: 600;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 20%;
right: 20%;
height: 4px;
background: $pri;
border-radius: $r-xs;
}
}
}
.task-count {
padding: 20px 28px;

View File

@@ -105,34 +105,3 @@
color: $tx;
line-height: 1.5;
}
.alerts-empty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 120px 0;
}
.alerts-empty-text {
font-size: var(--tk-font-num);
color: var(--tk-text-secondary);
margin-bottom: 16px;
}
.alerts-empty-hint {
font-size: var(--tk-font-h1);
color: var(--tk-text-secondary);
}
.alerts-empty-action {
margin-top: 24px;
padding: 16px 48px;
background: $pri;
border-radius: $r-pill;
}
.alerts-empty-action-text {
color: $card;
font-size: var(--tk-font-body-lg);
}

View File

@@ -6,6 +6,7 @@ import { listPatientAlerts, type Alert } from '@/services/alert';
import { useAuthStore } from '@/stores/auth';
import Loading from '@/components/Loading';
import ErrorState from '@/components/ErrorState';
import EmptyState from '@/components/EmptyState';
import SegmentTabs from '@/components/SegmentTabs';
import { useElderClass } from '../../../hooks/useElderClass';
import './index.scss';
@@ -98,7 +99,7 @@ export default function PatientAlerts() {
<SegmentTabs tabs={STATUS_TABS} activeKey={status} onChange={handleTabChange} variant="pill" />
{alerts.length === 0 && !loading ? (
<ErrorState text='暂无告警记录' hint='您的各项指标正常' />
<EmptyState text='暂无告警记录' hint='您的各项指标正常' />
) : (
<View className='alerts-list'>
{alerts.map((item) => {

View File

@@ -45,29 +45,6 @@
padding: 0 32px 28px;
}
.trange-tab {
padding: 12px 32px;
border-radius: $r-pill;
background: $card;
box-shadow: $shadow-sm;
transition: all 0.2s;
}
.trange-tab-active {
background: $pri;
box-shadow: $shadow-md;
}
.trange-tab-text {
font-size: var(--tk-font-h2);
color: $tx2;
font-weight: 500;
}
.trange-tab-text-active {
color: $white;
}
/* ── chart card ── */
.trend-chart-card {
margin: 0 24px 20px;

View File

@@ -7,45 +7,6 @@
padding-bottom: 40px;
}
/* ===== 状态筛选标签 ===== */
.status-tabs {
display: flex;
gap: 0;
padding: 20px 24px 0;
background: $card;
margin-bottom: 16px;
border-radius: 0 0 $r-lg $r-lg;
}
.status-tab {
flex: 1;
@include flex-center;
padding: 16px 0;
position: relative;
&.active::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 40px;
height: 4px;
background: $pri;
border-radius: $r-xs;
}
}
.status-tab-text {
font-size: var(--tk-font-body-lg);
color: $tx3;
.status-tab.active & {
color: $pri;
font-weight: bold;
}
}
/* ===== 订单列表 ===== */
.order-list {
padding: 0 24px;