feat: 完善我的设备入口页
This commit is contained in:
49
src/pages/devices/device-data.ts
Normal file
49
src/pages/devices/device-data.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
export type DeviceCardTone = "muted" | "online" | "warning";
|
||||
|
||||
export type DeviceCardKey = "vitals" | "smart-bed" | "ai-camera";
|
||||
|
||||
export type DeviceCardIcon = "vitals" | "bed" | "camera";
|
||||
|
||||
export type DeviceCard = {
|
||||
key: DeviceCardKey;
|
||||
title: string;
|
||||
summary: string;
|
||||
statusText: string;
|
||||
statusTone: DeviceCardTone;
|
||||
actionText: string;
|
||||
icon: DeviceCardIcon;
|
||||
};
|
||||
|
||||
const deviceCards: DeviceCard[] = [
|
||||
{
|
||||
key: "vitals",
|
||||
title: "体征监测设备",
|
||||
summary: "支持心率、血氧、血压与呼吸等关键体征监测。",
|
||||
statusText: "未绑定设备",
|
||||
statusTone: "muted",
|
||||
actionText: "点击查看设备专区",
|
||||
icon: "vitals"
|
||||
},
|
||||
{
|
||||
key: "smart-bed",
|
||||
title: "智能床 / 床垫",
|
||||
summary: "覆盖睡眠监测、翻身检测、离床提醒与睡眠质量分析。",
|
||||
statusText: "1 台设备在线",
|
||||
statusTone: "online",
|
||||
actionText: "点击查看设备专区",
|
||||
icon: "bed"
|
||||
},
|
||||
{
|
||||
key: "ai-camera",
|
||||
title: "AI 摄像头",
|
||||
summary: "可用于跌倒识别、异常行为预警与实时监护联动。",
|
||||
statusText: "权限待确认",
|
||||
statusTone: "warning",
|
||||
actionText: "点击查看设备专区",
|
||||
icon: "camera"
|
||||
}
|
||||
];
|
||||
|
||||
export function getDeviceCards() {
|
||||
return deviceCards;
|
||||
}
|
||||
@@ -1,3 +1,233 @@
|
||||
.devices-page {
|
||||
display: block;
|
||||
position: relative;
|
||||
min-height: 100vh;
|
||||
padding: 26rpx 24rpx 44rpx;
|
||||
box-sizing: border-box;
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
var(--color-bg-page-gradient-start) 0%,
|
||||
var(--color-bg-page) 42%,
|
||||
var(--color-bg-page-gradient-end) 100%
|
||||
);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.devices-page__halo {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.devices-page__halo--large {
|
||||
top: -100rpx;
|
||||
right: -20rpx;
|
||||
width: 360rpx;
|
||||
height: 360rpx;
|
||||
background:
|
||||
radial-gradient(circle, rgba(54, 228, 170, 0.06) 0 24%, transparent 25% 42%, rgba(104, 116, 146, 0.18) 43% 62%, transparent 63%),
|
||||
radial-gradient(circle at center, rgba(255, 255, 255, 0.05), transparent 72%);
|
||||
}
|
||||
|
||||
.devices-page__halo--small {
|
||||
top: 140rpx;
|
||||
right: 110rpx;
|
||||
width: 170rpx;
|
||||
height: 120rpx;
|
||||
background: radial-gradient(circle at center, rgba(255, 255, 255, 0.04), transparent 70%);
|
||||
}
|
||||
|
||||
.devices-page__content {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.devices-page__card {
|
||||
position: relative;
|
||||
min-height: 280rpx;
|
||||
padding: 28rpx 32rpx;
|
||||
border-radius: 48rpx;
|
||||
background:
|
||||
linear-gradient(180deg, rgba(43, 50, 68, 0.98) 0%, rgba(39, 45, 62, 0.98) 100%),
|
||||
var(--color-bg-surface);
|
||||
box-shadow:
|
||||
inset 0 0 0 2rpx var(--color-border-light),
|
||||
var(--shadow-surface);
|
||||
overflow: hidden;
|
||||
transform: scale(1);
|
||||
transition: transform 180ms ease, box-shadow 180ms ease, filter 180ms ease;
|
||||
}
|
||||
|
||||
.devices-page__card::before {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
content: "";
|
||||
background: linear-gradient(90deg, rgba(255, 255, 255, 0.04), transparent 30%);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.devices-page__card--hover {
|
||||
transform: scale(0.985);
|
||||
filter: brightness(1.05);
|
||||
box-shadow:
|
||||
inset 0 0 0 2rpx rgba(255, 255, 255, 0.06),
|
||||
0 18rpx 36rpx rgba(4, 10, 24, 0.26);
|
||||
}
|
||||
|
||||
.devices-page__copy {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
max-width: 430rpx;
|
||||
min-height: 224rpx;
|
||||
}
|
||||
|
||||
.devices-page__title {
|
||||
color: var(--color-text-white);
|
||||
font-size: 38rpx;
|
||||
font-weight: 600;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.devices-page__summary {
|
||||
margin-top: 20rpx;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 24rpx;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.devices-page__status {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
margin-top: 22rpx;
|
||||
padding: 10rpx 18rpx;
|
||||
border-radius: 999rpx;
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
.devices-page__status--online {
|
||||
background: rgba(54, 228, 170, 0.12);
|
||||
}
|
||||
|
||||
.devices-page__status--warning {
|
||||
background: rgba(255, 157, 87, 0.14);
|
||||
}
|
||||
|
||||
.devices-page__status-dot {
|
||||
width: 12rpx;
|
||||
height: 12rpx;
|
||||
margin-right: 12rpx;
|
||||
border-radius: 50%;
|
||||
background: var(--color-text-muted);
|
||||
box-shadow: 0 0 0 6rpx rgba(255, 255, 255, 0.02);
|
||||
}
|
||||
|
||||
.devices-page__status--online .devices-page__status-dot {
|
||||
background: var(--color-text-accent);
|
||||
box-shadow: 0 0 0 6rpx rgba(54, 228, 170, 0.08);
|
||||
}
|
||||
|
||||
.devices-page__status--warning .devices-page__status-dot {
|
||||
background: var(--color-warning-main);
|
||||
box-shadow: 0 0 0 6rpx rgba(255, 157, 87, 0.08);
|
||||
}
|
||||
|
||||
.devices-page__status-text {
|
||||
color: var(--color-text-white);
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
.devices-page__action {
|
||||
margin-top: auto;
|
||||
color: var(--color-text-muted);
|
||||
font-size: 22rpx;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.devices-page__icon {
|
||||
position: absolute;
|
||||
right: 18rpx;
|
||||
bottom: 4rpx;
|
||||
width: 260rpx;
|
||||
height: 200rpx;
|
||||
opacity: 0.14;
|
||||
}
|
||||
|
||||
.devices-page__icon::before,
|
||||
.devices-page__icon::after {
|
||||
position: absolute;
|
||||
content: "";
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.devices-page__icon--vitals::before {
|
||||
left: 26rpx;
|
||||
top: 26rpx;
|
||||
width: 126rpx;
|
||||
height: 126rpx;
|
||||
border: 18rpx solid rgba(255, 255, 255, 0.72);
|
||||
border-right-color: transparent;
|
||||
border-bottom-color: transparent;
|
||||
border-radius: 70rpx 70rpx 0 0;
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
|
||||
.devices-page__icon--vitals::after {
|
||||
left: 58rpx;
|
||||
top: 98rpx;
|
||||
width: 148rpx;
|
||||
height: 20rpx;
|
||||
border-radius: 999rpx;
|
||||
background: rgba(18, 26, 39, 0.78);
|
||||
box-shadow:
|
||||
-48rpx -28rpx 0 -4rpx rgba(18, 26, 39, 0.78),
|
||||
-22rpx -2rpx 0 -4rpx rgba(18, 26, 39, 0.78),
|
||||
38rpx 0 0 -4rpx rgba(18, 26, 39, 0.78);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
.devices-page__icon--bed::before {
|
||||
left: 36rpx;
|
||||
right: 22rpx;
|
||||
bottom: 42rpx;
|
||||
height: 72rpx;
|
||||
border-radius: 34rpx 34rpx 30rpx 30rpx;
|
||||
background: rgba(255, 255, 255, 0.68);
|
||||
transform: skewX(-18deg);
|
||||
}
|
||||
|
||||
.devices-page__icon--bed::after {
|
||||
left: 62rpx;
|
||||
right: 44rpx;
|
||||
top: 28rpx;
|
||||
height: 88rpx;
|
||||
border-radius: 48rpx 48rpx 38rpx 38rpx;
|
||||
border: 14rpx solid rgba(18, 26, 39, 0.75);
|
||||
border-left-width: 0;
|
||||
border-bottom-width: 18rpx;
|
||||
transform: rotate(12deg);
|
||||
}
|
||||
|
||||
.devices-page__icon--camera::before {
|
||||
left: 70rpx;
|
||||
top: 18rpx;
|
||||
width: 128rpx;
|
||||
height: 128rpx;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
box-shadow: inset 0 0 0 26rpx rgba(18, 26, 39, 0.72);
|
||||
}
|
||||
|
||||
.devices-page__icon--camera::after {
|
||||
left: 74rpx;
|
||||
bottom: 28rpx;
|
||||
width: 122rpx;
|
||||
height: 68rpx;
|
||||
border-radius: 18rpx 18rpx 30rpx 30rpx;
|
||||
background: rgba(255, 255, 255, 0.62);
|
||||
clip-path: polygon(18% 0, 82% 0, 100% 100%, 0 100%);
|
||||
}
|
||||
|
||||
@@ -1,29 +1,49 @@
|
||||
import SecondaryPage, { type SecondaryPageSection } from "../../components/secondary-page";
|
||||
import { Text, View } from "@tarojs/components";
|
||||
import Taro from "@tarojs/taro";
|
||||
import { getDeviceCards, type DeviceCard } from "./device-data";
|
||||
import "./index.scss";
|
||||
|
||||
const sections: SecondaryPageSection[] = [
|
||||
{
|
||||
title: "设备概览",
|
||||
items: [
|
||||
{ label: "已绑定设备", value: "0 台" },
|
||||
{ label: "设备共享管理", value: "待接入" },
|
||||
{ label: "添加设备", value: "可复用首页绑定能力" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "当前状态",
|
||||
items: [{ label: "设备列表", value: "暂无已绑定设备" }]
|
||||
}
|
||||
];
|
||||
const deviceCards = getDeviceCards();
|
||||
|
||||
export default function DevicesPage() {
|
||||
const handleCardClick = (card: DeviceCard) => {
|
||||
Taro.showToast({
|
||||
title: `${card.title}页面待完善`,
|
||||
icon: "none"
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<SecondaryPage
|
||||
eyebrow="DEVICES"
|
||||
title="我的设备"
|
||||
description="这里先保留设备管理骨架,后续可以接真实设备列表、设备状态和共享管理。"
|
||||
sections={sections}
|
||||
footerTip="如果后面要对接设备绑定,可以优先复用首页已经实现的扫码和蓝牙入口。"
|
||||
/>
|
||||
<View className="devices-page">
|
||||
<View className="devices-page__halo devices-page__halo--large" />
|
||||
<View className="devices-page__halo devices-page__halo--small" />
|
||||
|
||||
<View className="devices-page__content">
|
||||
{deviceCards.map((card) => (
|
||||
<View
|
||||
className="devices-page__card"
|
||||
key={card.key}
|
||||
hoverClass="devices-page__card--hover"
|
||||
hoverStartTime={20}
|
||||
hoverStayTime={120}
|
||||
onClick={() => handleCardClick(card)}
|
||||
>
|
||||
<View className="devices-page__copy">
|
||||
<Text className="devices-page__title">{card.title}</Text>
|
||||
<Text className="devices-page__summary">{card.summary}</Text>
|
||||
|
||||
<View className={`devices-page__status devices-page__status--${card.statusTone}`}>
|
||||
<View className="devices-page__status-dot" />
|
||||
<Text className="devices-page__status-text">{card.statusText}</Text>
|
||||
</View>
|
||||
|
||||
<Text className="devices-page__action">{card.actionText}</Text>
|
||||
</View>
|
||||
|
||||
<View className={`devices-page__icon devices-page__icon--${card.icon}`} />
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user