feat: add message page
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
export default defineAppConfig({
|
export default defineAppConfig({
|
||||||
pages: ["pages/index/index"],
|
pages: ["pages/index/index", "pages/message/index"],
|
||||||
window: {
|
window: {
|
||||||
navigationBarTitleText: "新手小程序",
|
navigationBarTitleText: "新手小程序",
|
||||||
navigationBarBackgroundColor: "#1AAD19",
|
navigationBarBackgroundColor: "#1AAD19",
|
||||||
|
|||||||
164
src/components/tab-bar/index.scss
Normal file
164
src/components/tab-bar/index.scss
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
.app-tabbar {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 10;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-around;
|
||||||
|
padding: 16rpx 24rpx calc(20rpx + env(safe-area-inset-bottom));
|
||||||
|
background: rgba(24, 30, 43, 0.98);
|
||||||
|
box-shadow: 0 -8rpx 24rpx rgba(4, 8, 20, 0.34);
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-tabbar__item {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
min-width: 88rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-tabbar__icon {
|
||||||
|
position: relative;
|
||||||
|
width: 34rpx;
|
||||||
|
height: 34rpx;
|
||||||
|
margin-bottom: 8rpx;
|
||||||
|
color: #8f97a9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-tabbar__icon::before,
|
||||||
|
.app-tabbar__icon::after {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-tabbar__icon--home {
|
||||||
|
border: 2rpx solid currentColor;
|
||||||
|
border-top: none;
|
||||||
|
border-radius: 0 0 8rpx 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-tabbar__icon--home::before {
|
||||||
|
left: 4rpx;
|
||||||
|
top: -2rpx;
|
||||||
|
width: 22rpx;
|
||||||
|
height: 22rpx;
|
||||||
|
border-top: 2rpx solid currentColor;
|
||||||
|
border-left: 2rpx solid currentColor;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-tabbar__icon--report::before,
|
||||||
|
.app-tabbar__icon--report::after {
|
||||||
|
bottom: 4rpx;
|
||||||
|
width: 6rpx;
|
||||||
|
border-radius: 999rpx;
|
||||||
|
background: currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-tabbar__icon--report::before {
|
||||||
|
left: 7rpx;
|
||||||
|
height: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-tabbar__icon--report::after {
|
||||||
|
left: 19rpx;
|
||||||
|
height: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-tabbar__icon--assistant {
|
||||||
|
border: 2rpx solid currentColor;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-tabbar__icon--assistant::before {
|
||||||
|
left: 6rpx;
|
||||||
|
top: 8rpx;
|
||||||
|
width: 18rpx;
|
||||||
|
height: 10rpx;
|
||||||
|
border-bottom: 2rpx solid currentColor;
|
||||||
|
border-radius: 0 0 12rpx 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-tabbar__icon--assistant::after {
|
||||||
|
left: 12rpx;
|
||||||
|
top: 6rpx;
|
||||||
|
width: 4rpx;
|
||||||
|
height: 4rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: currentColor;
|
||||||
|
box-shadow: 8rpx 0 0 currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-tabbar__icon--message {
|
||||||
|
border: 2rpx solid currentColor;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-tabbar__icon--message::before,
|
||||||
|
.app-tabbar__icon--message::after {
|
||||||
|
left: 8rpx;
|
||||||
|
right: 8rpx;
|
||||||
|
height: 2rpx;
|
||||||
|
background: currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-tabbar__icon--message::before {
|
||||||
|
top: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-tabbar__icon--message::after {
|
||||||
|
bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-tabbar__icon--mine {
|
||||||
|
border: 2rpx solid currentColor;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-tabbar__icon--mine::before {
|
||||||
|
left: 9rpx;
|
||||||
|
top: 5rpx;
|
||||||
|
width: 12rpx;
|
||||||
|
height: 12rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-tabbar__icon--mine::after {
|
||||||
|
left: 5rpx;
|
||||||
|
bottom: 5rpx;
|
||||||
|
width: 20rpx;
|
||||||
|
height: 10rpx;
|
||||||
|
border-radius: 10rpx 10rpx 6rpx 6rpx;
|
||||||
|
border: 2rpx solid currentColor;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-tabbar__icon--active {
|
||||||
|
color: #36e4aa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-tabbar__badge {
|
||||||
|
position: absolute;
|
||||||
|
top: -4rpx;
|
||||||
|
right: -4rpx;
|
||||||
|
width: 10rpx;
|
||||||
|
height: 10rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #ff4d4f;
|
||||||
|
box-shadow: 0 0 0 4rpx rgba(24, 30, 43, 0.98);
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-tabbar__label {
|
||||||
|
color: #b0b6c4;
|
||||||
|
font-size: 20rpx;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-tabbar__label--active {
|
||||||
|
color: #36e4aa;
|
||||||
|
}
|
||||||
63
src/components/tab-bar/index.tsx
Normal file
63
src/components/tab-bar/index.tsx
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import { Text, View } from "@tarojs/components";
|
||||||
|
import Taro from "@tarojs/taro";
|
||||||
|
import "./index.scss";
|
||||||
|
|
||||||
|
export type TabBarKey = "home" | "report" | "assistant" | "message" | "mine";
|
||||||
|
|
||||||
|
type TabBarProps = {
|
||||||
|
activeKey: TabBarKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
type TabItem = {
|
||||||
|
key: TabBarKey;
|
||||||
|
label: string;
|
||||||
|
hasBadge?: boolean;
|
||||||
|
pagePath?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const tabItems: TabItem[] = [
|
||||||
|
{ key: "home", label: "首页", pagePath: "/pages/index/index" },
|
||||||
|
{ key: "report", label: "报告" },
|
||||||
|
{ key: "assistant", label: "小e" },
|
||||||
|
{ key: "message", label: "消息", hasBadge: true, pagePath: "/pages/message/index" },
|
||||||
|
{ key: "mine", label: "我的" }
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function TabBar({ activeKey }: TabBarProps) {
|
||||||
|
const showToast = (title: string) => {
|
||||||
|
Taro.showToast({
|
||||||
|
title,
|
||||||
|
icon: "none"
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleTabClick = (item: TabItem) => {
|
||||||
|
if (item.key === activeKey) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.pagePath) {
|
||||||
|
Taro.redirectTo({ url: item.pagePath });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
showToast(`${item.label}功能待接入`);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View className="app-tabbar">
|
||||||
|
{tabItems.map((item) => {
|
||||||
|
const isActive = item.key === activeKey;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View className="app-tabbar__item" key={item.key} onClick={() => handleTabClick(item)}>
|
||||||
|
<View className={`app-tabbar__icon app-tabbar__icon--${item.key} ${isActive ? "app-tabbar__icon--active" : ""}`}>
|
||||||
|
{item.hasBadge ? <View className="app-tabbar__badge" /> : null}
|
||||||
|
</View>
|
||||||
|
<Text className={`app-tabbar__label ${isActive ? "app-tabbar__label--active" : ""}`}>{item.label}</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -363,89 +363,3 @@
|
|||||||
line-height: 1.7;
|
line-height: 1.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
.device-tabbar {
|
|
||||||
position: fixed;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
z-index: 5;
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
justify-content: space-around;
|
|
||||||
padding: 16rpx 24rpx calc(20rpx + env(safe-area-inset-bottom));
|
|
||||||
background: rgba(30, 35, 48, 0.98);
|
|
||||||
box-shadow: 0 -8rpx 24rpx rgba(4, 8, 20, 0.34);
|
|
||||||
}
|
|
||||||
|
|
||||||
.device-tabbar__item {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
min-width: 88rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.device-tabbar__icon {
|
|
||||||
position: relative;
|
|
||||||
width: 34rpx;
|
|
||||||
height: 34rpx;
|
|
||||||
margin-bottom: 8rpx;
|
|
||||||
border-radius: 10rpx;
|
|
||||||
border: 2rpx solid #8f97a9;
|
|
||||||
opacity: 0.86;
|
|
||||||
}
|
|
||||||
|
|
||||||
.device-tabbar__icon::before,
|
|
||||||
.device-tabbar__icon::after {
|
|
||||||
position: absolute;
|
|
||||||
content: "";
|
|
||||||
}
|
|
||||||
|
|
||||||
.device-tabbar__icon::before {
|
|
||||||
left: 8rpx;
|
|
||||||
right: 8rpx;
|
|
||||||
top: 10rpx;
|
|
||||||
height: 2rpx;
|
|
||||||
background: currentColor;
|
|
||||||
color: #8f97a9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.device-tabbar__icon::after {
|
|
||||||
left: 8rpx;
|
|
||||||
right: 8rpx;
|
|
||||||
bottom: 10rpx;
|
|
||||||
height: 2rpx;
|
|
||||||
background: currentColor;
|
|
||||||
color: #8f97a9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.device-tabbar__icon--active {
|
|
||||||
border-color: #36e4aa;
|
|
||||||
background: rgba(54, 228, 170, 0.12);
|
|
||||||
}
|
|
||||||
|
|
||||||
.device-tabbar__icon--active::before,
|
|
||||||
.device-tabbar__icon--active::after {
|
|
||||||
color: #36e4aa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.device-tabbar__badge {
|
|
||||||
position: absolute;
|
|
||||||
top: -4rpx;
|
|
||||||
right: -4rpx;
|
|
||||||
width: 10rpx;
|
|
||||||
height: 10rpx;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: #ff4d4f;
|
|
||||||
box-shadow: 0 0 0 4rpx rgba(30, 35, 48, 0.98);
|
|
||||||
}
|
|
||||||
|
|
||||||
.device-tabbar__label {
|
|
||||||
color: #b0b6c4;
|
|
||||||
font-size: 20rpx;
|
|
||||||
line-height: 1.2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.device-tabbar__label--active {
|
|
||||||
color: #36e4aa;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Text, View } from "@tarojs/components";
|
import { Text, View } from "@tarojs/components";
|
||||||
import Taro from "@tarojs/taro";
|
import Taro from "@tarojs/taro";
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
|
import TabBar from "../../components/tab-bar";
|
||||||
import "./index.scss";
|
import "./index.scss";
|
||||||
|
|
||||||
type BluetoothStatus = "idle" | "searching" | "empty" | "success";
|
type BluetoothStatus = "idle" | "searching" | "empty" | "success";
|
||||||
@@ -17,14 +18,6 @@ const notices = [
|
|||||||
"3. 扫码功能需开启相机权限"
|
"3. 扫码功能需开启相机权限"
|
||||||
];
|
];
|
||||||
|
|
||||||
const navItems = [
|
|
||||||
{ key: "home", label: "首页", active: true },
|
|
||||||
{ key: "report", label: "报告", active: false },
|
|
||||||
{ key: "assistant", label: "小e", active: false },
|
|
||||||
{ key: "message", label: "消息", active: false, badge: true },
|
|
||||||
{ key: "mine", label: "我的", active: false }
|
|
||||||
];
|
|
||||||
|
|
||||||
const mockBluetoothDevices: DeviceCandidate[] = [
|
const mockBluetoothDevices: DeviceCandidate[] = [
|
||||||
{ id: "mock-thermo-01", name: "体征监测设备 A1", source: "mock" },
|
{ id: "mock-thermo-01", name: "体征监测设备 A1", source: "mock" },
|
||||||
{ id: "mock-thermo-02", name: "体征监测设备 B2", source: "mock" }
|
{ id: "mock-thermo-02", name: "体征监测设备 B2", source: "mock" }
|
||||||
@@ -109,10 +102,6 @@ export default function Index() {
|
|||||||
showToast("后续可从这里进入设备管理页");
|
showToast("后续可从这里进入设备管理页");
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleTabClick = (label: string) => {
|
|
||||||
showToast(`${label}功能待接入`);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleScanBind = async () => {
|
const handleScanBind = async () => {
|
||||||
try {
|
try {
|
||||||
setStatusHint("等待扫码识别设备编码。");
|
setStatusHint("等待扫码识别设备编码。");
|
||||||
@@ -334,16 +323,7 @@ export default function Index() {
|
|||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View className="device-tabbar">
|
<TabBar activeKey="home" />
|
||||||
{navItems.map((item) => (
|
|
||||||
<View className="device-tabbar__item" key={item.key} onClick={() => handleTabClick(item.label)}>
|
|
||||||
<View className={`device-tabbar__icon ${item.active ? "device-tabbar__icon--active" : ""}`}>
|
|
||||||
{item.badge ? <View className="device-tabbar__badge" /> : null}
|
|
||||||
</View>
|
|
||||||
<Text className={`device-tabbar__label ${item.active ? "device-tabbar__label--active" : ""}`}>{item.label}</Text>
|
|
||||||
</View>
|
|
||||||
))}
|
|
||||||
</View>
|
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
4
src/pages/message/index.config.ts
Normal file
4
src/pages/message/index.config.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export default definePageConfig({
|
||||||
|
navigationStyle: "custom",
|
||||||
|
navigationBarTitleText: "消息"
|
||||||
|
});
|
||||||
129
src/pages/message/index.scss
Normal file
129
src/pages/message/index.scss
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
.message-page {
|
||||||
|
position: relative;
|
||||||
|
min-height: 100vh;
|
||||||
|
padding: 24rpx 24rpx 156rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: linear-gradient(180deg, #1d2331 0%, #171d29 100%);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-page__glow {
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 50%;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-page__glow--top {
|
||||||
|
top: -80rpx;
|
||||||
|
left: -40rpx;
|
||||||
|
width: 280rpx;
|
||||||
|
height: 280rpx;
|
||||||
|
background: radial-gradient(circle, rgba(55, 228, 171, 0.1), transparent 70%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-page__glow--side {
|
||||||
|
top: 160rpx;
|
||||||
|
right: -90rpx;
|
||||||
|
width: 240rpx;
|
||||||
|
height: 320rpx;
|
||||||
|
background: radial-gradient(circle, rgba(86, 116, 184, 0.12), transparent 72%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-tabs {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 110rpx;
|
||||||
|
padding: 20rpx 0 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-tabs__item {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-width: 120rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-tabs__label {
|
||||||
|
color: #8f97ac;
|
||||||
|
font-size: 24rpx;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-tabs__label--active {
|
||||||
|
color: #36e4aa;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-tabs__dot {
|
||||||
|
position: absolute;
|
||||||
|
top: 6rpx;
|
||||||
|
right: -10rpx;
|
||||||
|
width: 10rpx;
|
||||||
|
height: 10rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #ff4d4f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-tabs__line {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
bottom: -10rpx;
|
||||||
|
width: 52rpx;
|
||||||
|
height: 4rpx;
|
||||||
|
border-radius: 999rpx;
|
||||||
|
background: linear-gradient(90deg, #35e5b3 0%, #20c9bf 100%);
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-list {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-card {
|
||||||
|
padding: 24rpx 26rpx;
|
||||||
|
border-radius: 26rpx;
|
||||||
|
background: rgba(42, 48, 66, 0.96);
|
||||||
|
box-shadow: inset 0 0 0 2rpx rgba(255, 255, 255, 0.03);
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-card + .message-card {
|
||||||
|
margin-top: 22rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-card__title {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 18rpx;
|
||||||
|
color: #f3f7ff;
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-card__row {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
line-height: 1.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-card__row + .message-card__row {
|
||||||
|
margin-top: 6rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-card__label {
|
||||||
|
width: 104rpx;
|
||||||
|
flex-shrink: 0;
|
||||||
|
color: #7f889d;
|
||||||
|
font-size: 22rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-card__value {
|
||||||
|
flex: 1;
|
||||||
|
color: #d9dfeb;
|
||||||
|
font-size: 22rpx;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
145
src/pages/message/index.tsx
Normal file
145
src/pages/message/index.tsx
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
import { Text, View } from "@tarojs/components";
|
||||||
|
import { useState } from "react";
|
||||||
|
import TabBar from "../../components/tab-bar";
|
||||||
|
import "./index.scss";
|
||||||
|
|
||||||
|
type MessageTabKey = "vital" | "system";
|
||||||
|
|
||||||
|
type MessageItem = {
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
deviceId: string;
|
||||||
|
userName: string;
|
||||||
|
messageType: string;
|
||||||
|
valueText: string;
|
||||||
|
occurredAt: string;
|
||||||
|
category: MessageTabKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
const tabs: Array<{ key: MessageTabKey; label: string; hasDot?: boolean }> = [
|
||||||
|
{ key: "vital", label: "体征消息" },
|
||||||
|
{ key: "system", label: "系统消息", hasDot: true }
|
||||||
|
];
|
||||||
|
|
||||||
|
const messageList: MessageItem[] = [
|
||||||
|
{
|
||||||
|
id: "vital-1",
|
||||||
|
title: "实时监测结果通知",
|
||||||
|
deviceId: "A54984651",
|
||||||
|
userName: "1201/李小北",
|
||||||
|
messageType: "心率异常",
|
||||||
|
valueText: "106",
|
||||||
|
occurredAt: "2024-07-30 01:15",
|
||||||
|
category: "vital"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "vital-2",
|
||||||
|
title: "睡眠报告分析通知",
|
||||||
|
deviceId: "A54984651",
|
||||||
|
userName: "1201/李小北",
|
||||||
|
messageType: "HRV异常",
|
||||||
|
valueText: "89",
|
||||||
|
occurredAt: "2024-07-30 01:15",
|
||||||
|
category: "vital"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "vital-3",
|
||||||
|
title: "睡眠月报分析通知",
|
||||||
|
deviceId: "A54984651",
|
||||||
|
userName: "1201/李小北",
|
||||||
|
messageType: "睡眠得分",
|
||||||
|
valueText: "有20天低于60分",
|
||||||
|
occurredAt: "2024-07-30 01:15",
|
||||||
|
category: "vital"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "system-1",
|
||||||
|
title: "系统升级提醒",
|
||||||
|
deviceId: "平台消息",
|
||||||
|
userName: "全部用户",
|
||||||
|
messageType: "版本更新",
|
||||||
|
valueText: "建议升级到最新版本",
|
||||||
|
occurredAt: "2024-07-30 09:30",
|
||||||
|
category: "system"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "system-2",
|
||||||
|
title: "服务时间调整通知",
|
||||||
|
deviceId: "平台消息",
|
||||||
|
userName: "全部用户",
|
||||||
|
messageType: "运营公告",
|
||||||
|
valueText: "周日 02:00-04:00 系统维护",
|
||||||
|
occurredAt: "2024-07-29 18:00",
|
||||||
|
category: "system"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const fieldLabels = {
|
||||||
|
deviceId: "设备ID",
|
||||||
|
userName: "使用人员",
|
||||||
|
messageType: "消息类型",
|
||||||
|
valueText: "检测数值",
|
||||||
|
occurredAt: "发生时间"
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function MessagePage() {
|
||||||
|
const [activeTab, setActiveTab] = useState<MessageTabKey>("vital");
|
||||||
|
|
||||||
|
const currentMessages = messageList.filter((item) => item.category === activeTab);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View className="message-page">
|
||||||
|
<View className="message-page__glow message-page__glow--top" />
|
||||||
|
<View className="message-page__glow message-page__glow--side" />
|
||||||
|
|
||||||
|
<View className="message-tabs">
|
||||||
|
{tabs.map((item) => {
|
||||||
|
const isActive = item.key === activeTab;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View className="message-tabs__item" key={item.key} onClick={() => setActiveTab(item.key)}>
|
||||||
|
<Text className={`message-tabs__label ${isActive ? "message-tabs__label--active" : ""}`}>{item.label}</Text>
|
||||||
|
{item.hasDot ? <View className="message-tabs__dot" /> : null}
|
||||||
|
{isActive ? <View className="message-tabs__line" /> : null}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View className="message-list">
|
||||||
|
{currentMessages.map((item) => (
|
||||||
|
<View className="message-card" key={item.id}>
|
||||||
|
<Text className="message-card__title">{item.title}</Text>
|
||||||
|
|
||||||
|
<View className="message-card__row">
|
||||||
|
<Text className="message-card__label">{fieldLabels.deviceId}</Text>
|
||||||
|
<Text className="message-card__value">{item.deviceId}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View className="message-card__row">
|
||||||
|
<Text className="message-card__label">{fieldLabels.userName}</Text>
|
||||||
|
<Text className="message-card__value">{item.userName}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View className="message-card__row">
|
||||||
|
<Text className="message-card__label">{fieldLabels.messageType}</Text>
|
||||||
|
<Text className="message-card__value">{item.messageType}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View className="message-card__row">
|
||||||
|
<Text className="message-card__label">{fieldLabels.valueText}</Text>
|
||||||
|
<Text className="message-card__value">{item.valueText}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View className="message-card__row">
|
||||||
|
<Text className="message-card__label">{fieldLabels.occurredAt}</Text>
|
||||||
|
<Text className="message-card__value">{item.occurredAt}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<TabBar activeKey="message" />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user