feat(mp): 首页设备状态卡片组件 — 血压计/血糖仪快捷入口

This commit is contained in:
iven
2026-04-28 19:42:24 +08:00
parent 00f615d8e5
commit 601b2d7f52
3 changed files with 109 additions and 5 deletions

View File

@@ -0,0 +1,51 @@
@import '../../styles/variables.scss';
.device-card {
display: flex;
align-items: center;
padding: 24rpx;
background: $card;
border-radius: $r;
margin-bottom: 16rpx;
box-shadow: $shadow-sm;
.device-icon {
font-size: 48rpx;
margin-right: 20rpx;
}
.device-info {
flex: 1;
.device-name {
font-size: 28rpx;
font-weight: 600;
color: $tx;
display: block;
}
.device-status {
font-size: 24rpx;
margin-top: 4rpx;
display: block;
&.connected { color: $pri; }
&.idle { color: $tx3; }
}
.last-sync {
font-size: 22rpx;
color: $tx3;
margin-top: 4rpx;
display: block;
}
}
.sync-btn {
padding: 12rpx 28rpx;
background: $pri;
color: #fff;
border-radius: $r-pill;
font-size: 24rpx;
}
}

View File

@@ -0,0 +1,39 @@
import { View, Text } from '@tarojs/components';
import Taro from '@tarojs/taro';
import './index.scss';
interface DeviceCardProps {
deviceName: string;
deviceType: string;
lastSyncAt?: string;
status: 'connected' | 'disconnected' | 'never';
}
const DEVICE_ICONS: Record<string, string> = {
blood_pressure: '\u{1FA7A}',
blood_glucose: '\u{1FA78}',
heart_rate: '\u{2764}',
blood_oxygen: '\u{1FAB1}',
};
export default function DeviceCard({ deviceName, deviceType, lastSyncAt, status }: DeviceCardProps) {
const icon = DEVICE_ICONS[deviceType] || '\u{1F4F1}';
const statusLabel = status === 'connected' ? '已连接' : status === 'disconnected' ? '未连接' : '未配对';
const statusClass = status === 'connected' ? 'connected' : 'idle';
const handleSync = () => {
Taro.navigateTo({ url: '/pages/device-sync/index' });
};
return (
<View className='device-card' onClick={handleSync}>
<View className='device-icon'>{icon}</View>
<View className='device-info'>
<Text className='device-name'>{deviceName}</Text>
<Text className={`device-status ${statusClass}`}>{statusLabel}</Text>
{lastSyncAt && <Text className='last-sync'>: {lastSyncAt}</Text>}
</View>
<View className='sync-btn'></View>
</View>
);
}

View File

@@ -3,7 +3,7 @@ import { useState } from 'react';
import Taro, { useDidShow } from '@tarojs/taro';
import { useAuthStore } from '../../stores/auth';
import { useHealthStore } from '../../stores/health';
import EmptyState from '../../components/EmptyState';
import DeviceCard from '../../components/DeviceCard';
import Loading from '../../components/Loading';
import { trackPageView } from '@/services/analytics';
import * as appointmentApi from '@/services/appointment';
@@ -13,8 +13,8 @@ import './index.scss';
const QUICK_SERVICES = [
{ label: '预约挂号', char: '约', path: '/pages/appointment/create/index' },
{ label: '健康录入', char: '录', path: '/pages/health/input/index' },
{ label: '健康趋势', char: '势', path: '/pages/health/trend/index' },
{ label: '健康录入', char: '录', path: '/pages/pkg-health/input/index' },
{ label: '健康趋势', char: '势', path: '/pages/pkg-health/trend/index' },
{ label: '资讯文章', char: '文', path: '/pages/article/index' },
{ label: 'AI 报告', char: 'AI', path: '/pages/ai-report/list/index' },
];
@@ -123,6 +123,20 @@ export default function Index() {
<Text className='greeting-date'>{new Date().toLocaleDateString('zh-CN', { month: 'long', day: 'numeric', weekday: 'short' })}</Text>
</View>
{/* 设备快捷入口 */}
<View className='device-section'>
<DeviceCard
deviceName='血压计'
deviceType='blood_pressure'
status='never'
/>
<DeviceCard
deviceName='血糖仪'
deviceType='blood_glucose'
status='never'
/>
</View>
{/* 今日健康 */}
<View className='health-section'>
<Text className='section-title'></Text>
@@ -132,7 +146,7 @@ export default function Index() {
<View className='health-empty'>
<Text className='health-empty-text'></Text>
<View className='health-empty-action'>
<View className='health-empty-btn' onClick={() => Taro.navigateTo({ url: '/pages/health/input/index' })}>
<View className='health-empty-btn' onClick={() => Taro.navigateTo({ url: '/pages/pkg-health/input/index' })}>
<Text className='health-empty-btn-text'></Text>
</View>
</View>
@@ -142,7 +156,7 @@ export default function Index() {
{healthItems.map((item) => {
const tag = getStatusTag(item.status);
return (
<View className='health-cell' key={item.label} onClick={() => Taro.navigateTo({ url: `/pages/health/trend/index?indicator=${item.label === '血压' ? 'blood_pressure_systolic' : item.label === '心率' ? 'heart_rate' : item.label === '血糖' ? 'blood_sugar_fasting' : 'weight'}` })}>
<View className='health-cell' key={item.label} onClick={() => Taro.navigateTo({ url: `/pages/pkg-health/trend/index?indicator=${item.label === '血压' ? 'blood_pressure_systolic' : item.label === '心率' ? 'heart_rate' : item.label === '血糖' ? 'blood_sugar_fasting' : 'weight'}` })}>
<Text className='health-cell-label'>{item.label}</Text>
<Text className='health-cell-value'>{item.value}</Text>
<View className='health-cell-bottom'>