feat(devices): skip realtime requests when device offline

This commit is contained in:
stu2not
2026-05-25 17:45:16 +08:00
parent 3449224cd2
commit 6c77672ca7
6 changed files with 135 additions and 6 deletions

View File

@@ -3,6 +3,7 @@ import { useState } from 'react'
import Taro, { useDidShow } from '@tarojs/taro'
import { getToken } from '@/services/auth'
import { loadCurrentChildBindingContext } from '@/services/binding'
import { getDeviceOnlineStatus } from '@/services/device'
import {
getCurrentDeviceLocation,
getDeviceTrajectory,
@@ -125,6 +126,7 @@ export default function Location() {
const [selectedPoint, setSelectedPoint] = useState<DeviceTrajectoryPoint | null>(null)
const [trajectoryMode, setTrajectoryMode] = useState<TrajectoryMode>('current')
const [coordinates, setCoordinates] = useState(DEFAULT_COORDINATES)
const [locationNotice, setLocationNotice] = useState<string | null>(null)
const [emptyState, setEmptyState] = useState<{ title: string; desc: string; actionText: string; actionUrl: string } | null>(
null
)
@@ -147,6 +149,7 @@ export default function Location() {
setLoading(true)
setEmptyState(null)
setLocationNotice(null)
if (nextMode) {
setTrajectoryMode(nextMode)
setSelectedPoint(null)
@@ -183,6 +186,16 @@ export default function Location() {
return
}
const onlineStatus = await getDeviceOnlineStatus(resolvedDeviceId)
if (onlineStatus && !onlineStatus.online) {
setDeviceLocation(null)
setTrajectory([])
setSelectedPoint(null)
setCoordinates(DEFAULT_COORDINATES)
setLocationNotice(onlineStatus.message || '设备不在线或暂时无法上报位置')
return
}
const currentLocation = await getCurrentDeviceLocation(resolvedDeviceId)
setDeviceLocation(currentLocation)
@@ -413,7 +426,9 @@ export default function Location() {
<View className='header-left'>
<Text className='location-title'>{summaryTitle}</Text>
<Text className='location-update'>
{loading
{locationNotice
? locationNotice
: loading
? '正在获取设备位置...'
: trajectoryMode === 'current'
? `更新于 ${formatTime(deviceLocation?.updated_at)}`
@@ -444,7 +459,8 @@ export default function Location() {
</View>
) : (
<View className='location-empty'>
<Text className='location-empty-title'></Text>
<Text className='location-empty-title'>{locationNotice || '当前孩子暂无设备位置'}</Text>
{locationNotice && <Text className='location-empty-desc'></Text>}
</View>
)
) : trajectory.length > 0 ? (

View File

@@ -15,6 +15,7 @@ import {
DeviceFirmwareStatus,
DeviceRoleSummary,
getDeviceFirmwareStatus,
getDeviceOnlineStatus,
getDeviceRole,
getDeviceRoles,
startDeviceFirmwareUpdate,
@@ -258,6 +259,15 @@ export default function Sleep() {
setIsUpdatingFirmware(true)
try {
const onlineStatus = await getDeviceOnlineStatus(binding.device_id)
if (onlineStatus && !onlineStatus.online) {
Taro.showToast({
title: '设备不在线,暂时无法发送更新指令',
icon: 'none',
})
return
}
const nextFirmwareStatus = await startDeviceFirmwareUpdate(binding.device_id)
setFirmwareStatus(nextFirmwareStatus)
Taro.showToast({

View File

@@ -28,6 +28,15 @@ export interface DeviceStatus {
location_updated_at?: string | null
}
export interface DeviceOnlineStatus {
device_id: string
online: boolean
reason: string
message: string
last_location_at?: string | null
checked_at: string
}
export interface DeviceAlarmItem {
alarm_id: number
device_id: string
@@ -136,6 +145,18 @@ export async function getDeviceStatus(deviceId?: string): Promise<DeviceStatus |
}
}
export async function getDeviceOnlineStatus(deviceId?: string): Promise<DeviceOnlineStatus | null> {
const resolvedDeviceId = await resolveDeviceId(deviceId)
if (!resolvedDeviceId) return null
try {
return await request<DeviceOnlineStatus>(`/banban/devices/${resolvedDeviceId}/online-status`)
} catch (error: any) {
if (error?.status === 404) return null
throw error
}
}
export async function setDeviceVolume(level: number, deviceId?: string): Promise<DeviceVolumeUpdateResponse> {
const resolvedDeviceId = await resolveDeviceId(deviceId)
if (!resolvedDeviceId) {