fix(ota): settle stale firmware update states

This commit is contained in:
stu2not
2026-09-22 10:35:37 +08:00
parent 5e163c4bb7
commit 2467656806
6 changed files with 240 additions and 10 deletions
@@ -1,9 +1,10 @@
import type { DeviceFirmwareStatus } from '@/services/device'
import { isFirmwareCurrent, isFirmwareUpdateInProgress } from '../../utils/firmware-status'
import { isFirmwareCurrent, isFirmwareTargetReached, isFirmwareUpdateInProgress } from '../../utils/firmware-status'
export function firmwareProgressView(status: DeviceFirmwareStatus | null, refreshError = false) {
const state = String(status?.update_status || '').trim().toLowerCase()
const complete = state === 'success' || state === 'completed'
|| (isFirmwareUpdateInProgress(state) && isFirmwareTargetReached(status))
const current = !complete && !isFirmwareUpdateInProgress(state) && isFirmwareCurrent(status)
const failed = state === 'failed' && !current
const value = Number(status?.progress)
+8 -5
View File
@@ -1,7 +1,7 @@
import FirmwareProgress from '@/components/firmware-progress'
import PageTitle from '@/components/page-title'
import { getParticipantArtwork, getRoleArtwork } from '@/utils/artwork'
import { firmwareSummaryView, isFirmwareCurrent, isFirmwareUpdateInProgress, normalizeFirmwareUpdateStatus } from '@/utils/firmware-status'
import { firmwareSummaryView, isFirmwareCurrent, isFirmwareTargetReached, isFirmwareUpdateInProgress, normalizeFirmwareUpdateStatus } from '@/utils/firmware-status'
import { getPageStyle } from '@/utils/page-style'
import { setActiveTabRoute } from '@/utils/tab-bar'
import { View, Text, Image, Input, Button } from '@tarojs/components'
@@ -248,7 +248,7 @@ export default function Sleep() {
return
}
if (isFirmwareUpdateInProgress(nextFirmwareStatus?.update_status)) {
if (isFirmwareUpdateInProgress(nextFirmwareStatus?.update_status) && !isFirmwareTargetReached(nextFirmwareStatus)) {
startFirmwareStatusPolling(normalizedDeviceId)
} else {
stopFirmwareStatusPolling()
@@ -272,14 +272,14 @@ export default function Sleep() {
setFirmwareStatus(nextFirmwareStatus)
setFirmwareRefreshError(false)
if (isFirmwareUpdateInProgress(nextFirmwareStatus?.update_status)) {
if (isFirmwareUpdateInProgress(nextFirmwareStatus?.update_status) && !isFirmwareTargetReached(nextFirmwareStatus)) {
scheduleFirmwareStatusPoll(normalizedDeviceId)
return
}
stopFirmwareStatusPolling()
const nextStatus = normalizeFirmwareUpdateStatus(nextFirmwareStatus?.update_status)
if (isFirmwareUpdateSuccessful(nextStatus)) {
if (isFirmwareUpdateSuccessful(nextStatus) || isFirmwareTargetReached(nextFirmwareStatus)) {
Taro.showToast({ title: '系统更新完成', icon: 'success' })
} else if (isFirmwareCurrent(nextFirmwareStatus)) {
Taro.showToast({ title: '当前已是最新版本', icon: 'none' })
@@ -319,7 +319,9 @@ export default function Sleep() {
if (generation !== firmwareLoadGenerationRef.current) return
setFirmwareStatus(nextFirmwareStatus)
setFirmwareRefreshError(false)
if (isFirmwareUpdateInProgress(nextFirmwareStatus?.update_status)) setShowFirmwareProgress(true)
if (isFirmwareUpdateInProgress(nextFirmwareStatus?.update_status) && !isFirmwareTargetReached(nextFirmwareStatus)) {
setShowFirmwareProgress(true)
}
syncFirmwareStatusPolling(normalizedDeviceId, nextFirmwareStatus)
} catch (error: any) {
if (generation !== firmwareLoadGenerationRef.current) return
@@ -1060,6 +1062,7 @@ export default function Sleep() {
isFamilyOwner
)
const isFirmwareUpdatingByStatus = isFirmwareUpdateInProgress(firmwareStatus?.update_status)
&& !isFirmwareTargetReached(firmwareStatus)
const firmwareSummary = firmwareSummaryView(firmwareStatus)
const canUpdateFirmware = Boolean(
binding?.device_id &&
+25 -1
View File
@@ -8,6 +8,28 @@ export function isFirmwareUpdateInProgress(status?: string | null): boolean {
return ['sent', 'accepted', 'updating'].includes(normalizeFirmwareUpdateStatus(status))
}
function firmwareVersionParts(value?: string | null): number[] | null {
const normalized = String(value || '').trim().toLowerCase()
if (!normalized || ['unknown', 'updating', '0.0.0', '--'].includes(normalized)) return null
const parts = normalized.split('.')
if (parts.some((part) => !/^\d+$/.test(part))) return null
return parts.map((part) => Number(part))
}
export function isFirmwareTargetReached(status: DeviceFirmwareStatus | null): boolean {
if (!status) return false
const current = firmwareVersionParts(status.current_version)
const target = firmwareVersionParts(status.target_version)
if (!current || !target) return false
const length = Math.max(current.length, target.length)
for (let index = 0; index < length; index += 1) {
const currentPart = current[index] || 0
const targetPart = target[index] || 0
if (currentPart !== targetPart) return currentPart > targetPart
}
return true
}
export function isFirmwareCurrent(status: DeviceFirmwareStatus | null): boolean {
const knownVersion = (value?: string | null) => Boolean(value?.trim() && !['unknown', 'updating', '0.0.0', '--'].includes(value.trim().toLowerCase()))
return Boolean(status && !status.update_available && knownVersion(status.current_version) && knownVersion(status.latest_version))
@@ -15,7 +37,9 @@ export function isFirmwareCurrent(status: DeviceFirmwareStatus | null): boolean
export function firmwareSummaryView(status: DeviceFirmwareStatus | null) {
if (!status) return { action: '暂不可用', subtitle: '暂时无法获取版本,请稍后重试' }
if (isFirmwareUpdateInProgress(status.update_status)) return { action: '查看进度', subtitle: '设备正在更新,请稍候' }
if (isFirmwareUpdateInProgress(status.update_status) && !isFirmwareTargetReached(status)) {
return { action: '查看进度', subtitle: '设备正在更新,请稍候' }
}
if (isFirmwareCurrent(status)) return { action: '已最新', subtitle: '当前已是最新版本' }
if (normalizeFirmwareUpdateStatus(status.update_status) === 'failed') {
return { action: status.update_available ? '更新' : '版本待确认', subtitle: status.can_update ? '更新失败,可重试' : '上次更新失败,当前版本待确认' }