feat(ui): 新增 StateView 统一加载失败态与重试按钮

This commit is contained in:
ozh 2026-09-09 10:56:10 +08:00
parent f408a29e13
commit 9679e4062b
10 changed files with 58 additions and 72 deletions

View File

@ -0,0 +1,19 @@
.stateView {
margin-top: 80px;
display: flex;
flex-direction: column;
align-items: center;
}
.retryBtn {
margin-top: 40px;
width: 240px;
height: 80px;
background: $color-primary;
border-radius: 40px;
display: flex;
align-items: center;
justify-content: center;
color: #ffffff;
font-size: 28px;
}

View File

@ -0,0 +1,30 @@
import { View, Text } from '@tarojs/components'
import { Empty } from '@/components/empty'
import styles from './index.module.scss'
interface Props {
status: 'error'
mode?: 'list' | 'wifi' | 'error' | 'message'
text?: string
onRetry?: () => void
retryText?: string
}
export function StateView({
status,
mode = 'wifi',
text = '加载失败,请检查网络',
onRetry,
retryText = '重试'
}: Props) {
return (
<View className={styles.stateView}>
<Empty mode={mode} text={text} />
{onRetry && (
<View className={styles.retryBtn} onClick={onRetry}>
<Text>{retryText}</Text>
</View>
)}
</View>
)
}

View File

@ -10,18 +10,6 @@
align-items: center;
}
.retryBtn {
margin-top: 40px;
width: 240px;
height: 80px;
background: $color-primary;
border-radius: 40px;
display: flex;
align-items: center;
justify-content: center;
color: #ffffff;
}
.heartCard {
margin: 24px;
padding: 32px;

View File

@ -3,7 +3,7 @@ import Taro, { useRouter, useDidShow, useDidHide } from '@tarojs/taro'
import { View, Text } from '@tarojs/components'
import { Navbar } from '@/components/navbar'
import { Loading } from '@/components/loading'
import { Empty } from '@/components/empty'
import { StateView } from '@/components/state-view'
import { VitalWave } from '@/components/vital-wave'
import { getVitalSigns, getHeartRateHistory, type VitalSigns } from '@/api/device'
import { MOVE_STATE_MAP, BODY_STATUS_MAP, ONBED_STATUS_MAP, type DeviceModel } from '@/constants/enums'
@ -108,10 +108,7 @@ export default function Detail() {
{loading ? (
<View className={styles.stateWrap}><Loading /></View>
) : loadError ? (
<View className={styles.stateWrap}>
<Empty text="加载失败,请检查网络" mode="wifi" />
<View className={styles.retryBtn} onClick={loadVitals}><Text>重试</Text></View>
</View>
<StateView status="error" onRetry={loadVitals} />
) : (
<>
<View className={styles.heartCard}>

View File

@ -32,19 +32,6 @@
align-items: center;
}
.retryBtn {
margin-top: 40px;
width: 240px;
height: 80px;
background: $color-primary;
border-radius: 40px;
display: flex;
align-items: center;
justify-content: center;
color: #ffffff;
font-size: 28px;
}
.grid {
display: flex;
flex-wrap: wrap;

View File

@ -5,7 +5,7 @@ import { useAppSelector, useAppDispatch } from '@/store/hooks'
import { setDeviceList, type Device } from '@/store/deviceSlice'
import { Navbar } from '@/components/navbar'
import { Loading } from '@/components/loading'
import { Empty } from '@/components/empty'
import { StateView } from '@/components/state-view'
import { getDeviceList } from '@/api/device'
import { DEVICE_ICON_MAP, type DeviceModel } from '@/constants/enums'
import { ROUTES } from '@/constants/routes'
@ -62,15 +62,9 @@ export default function DeviceList() {
{loading ? (
<View className={styles.stateWrap}><Loading /></View>
) : loadError ? (
<View className={styles.stateWrap}>
<Empty text="加载失败,请检查网络" mode="wifi" />
<View className={styles.retryBtn} onClick={loadDevices}><Text>重试</Text></View>
</View>
<StateView status="error" onRetry={loadDevices} />
) : deviceList.length === 0 ? (
<View className={styles.stateWrap}>
<Empty text="暂无设备" />
<View className={styles.retryBtn} onClick={goAdd}><Text>添加设备</Text></View>
</View>
<StateView status="error" mode="list" text="暂无设备" retryText="添加设备" onRetry={goAdd} />
) : (
<View className={styles.grid}>
{deviceList.map((device) => (

View File

@ -11,19 +11,6 @@
align-items: center;
}
.retryBtn {
margin-top: 40px;
width: 240px;
height: 80px;
background: $color-primary;
border-radius: 40px;
display: flex;
align-items: center;
justify-content: center;
color: #ffffff;
font-size: 28px;
}
// ===== 家庭圈入口 =====
.familyEntry {
margin: 24px;

View File

@ -4,6 +4,7 @@ import { View, Text } from '@tarojs/components'
import { Navbar } from '@/components/navbar'
import { Loading } from '@/components/loading'
import { Empty } from '@/components/empty'
import { StateView } from '@/components/state-view'
import { getEventList, type EventItem } from '@/api/event'
import { ROUTES } from '@/constants/routes'
import { navigateTo } from '@/utils/navigation'
@ -46,10 +47,7 @@ export default function Index() {
{loading ? (
<View className={styles.stateWrap}><Loading /></View>
) : loadError ? (
<View className={styles.stateWrap}>
<Empty text="加载失败,请检查网络" mode="wifi" />
<View className={styles.retryBtn} onClick={loadAlerts}><Text>重试</Text></View>
</View>
<StateView status="error" onRetry={loadAlerts} />
) : (
<>
<FamilyEntry onClick={goFamily} />

View File

@ -10,18 +10,6 @@
align-items: center;
}
.retryBtn {
margin-top: 40px;
width: 240px;
height: 80px;
background: $color-primary;
border-radius: 40px;
display: flex;
align-items: center;
justify-content: center;
color: #ffffff;
}
.list { margin-top: 20px; }
.item {

View File

@ -5,6 +5,7 @@ import { setScene, type Scene } from '@/store/sceneSlice'
import { Navbar } from '@/components/navbar'
import { Loading } from '@/components/loading'
import { Empty } from '@/components/empty'
import { StateView } from '@/components/state-view'
import { getSceneList } from '@/api/scene'
import { navigateBack } from '@/utils/navigation'
import styles from './select.module.scss'
@ -43,10 +44,7 @@ export default function SceneSelect() {
{loading ? (
<View className={styles.stateWrap}><Loading /></View>
) : loadError ? (
<View className={styles.stateWrap}>
<Empty text="加载失败,请检查网络" mode="wifi" />
<View className={styles.retryBtn} onClick={load}><Text>重试</Text></View>
</View>
<StateView status="error" onRetry={load} />
) : list.length === 0 ? (
<View className={styles.stateWrap}><Empty text="暂无场景" /></View>
) : (