diff --git a/src/apis.js b/src/apis.js index 74b83e8..eb20f8f 100644 --- a/src/apis.js +++ b/src/apis.js @@ -599,14 +599,13 @@ export const getDeviceWifiStatusAPI = async () => { }); }; -// 获取硬件盒子版本信息,用于判断当前设备是否需要 OTA 升级。 -export const getHardwareBoxVersionAPI = async () => { - return request("GET", "/user/hardwareBox/version"); -}; - // 发送硬件盒子 OTA 更新指令,服务端会返回后续轮询使用的任务 ID。 -export const sendHardwareBoxUpdateAPI = async (data) => { - return request("POST", "/user/hardwareBox/sendUpdate", data); +export const sendHardwareBoxUpdateAPI = async ({versionNumber, wifiSsid, wifiPassword}) => { + return request("POST", "/user/hardwareBox/sendUpdate", { + versionNumber, + wifiSsid, + wifiPassword, + }); }; export const addNoteAPI = async (id, remark) => { diff --git a/src/composables/useOtaUpdate.js b/src/composables/useOtaUpdate.js index 2fcc788..7c6c948 100644 --- a/src/composables/useOtaUpdate.js +++ b/src/composables/useOtaUpdate.js @@ -13,6 +13,15 @@ const phaseTextMap = { installing: "正在安装固件", }; +// 设备详情中的 latestVersion 是升级目标,version 是当前固件版本。 +export const getOtaInfoFromDetail = (detail) => ({ + versionNumber: String(detail?.latestVersion ?? "").trim(), + currentVersion: String(detail?.version ?? "").trim(), + versionInfo: String(detail?.versionInfo ?? "").trim(), + needUpdate: detail?.needUpdate === true || Number(detail?.needUpdate) === 1, + forceUpdate: detail?.forceUpdate === true || Number(detail?.forceUpdate) === 1, +}); + // OTA 状态由首页、WiFi 设置页和我的设备页共享,页面切换后仍可继续接收进度。 const updating = ref(false); const progress = ref(0); @@ -115,6 +124,7 @@ function handleSocketMessage(message) { } else if (!isCurrentVersionMessage(message.data)) { return; } + if (!targetVersion && messageVersion) targetVersion = messageVersion; const nextProgress = Math.min( 100, @@ -138,6 +148,7 @@ function handleSocketMessage(message) { } else if (!isCurrentVersionMessage(message.data)) { return; } + if (!targetVersion && messageVersion) targetVersion = messageVersion; if (message.data?.status === "success") { finishUpdate("success"); @@ -160,16 +171,20 @@ export const useOtaUpdate = () => { const startUpdate = async ({ versionNumber, - resourceUrl, wifiSsid = "", wifiPassword = "", onSuccess, }) => { if (updating.value) return false; + const nextVersion = String(versionNumber || "").trim(); + if (!nextVersion) { + uni.showToast({ title: "缺少固件目标版本", icon: "none" }); + return false; + } updateRunId += 1; const runId = updateRunId; - targetVersion = String(versionNumber || ""); + targetVersion = nextVersion; lastFinishedVersion = ""; successCallback = onSuccess || null; resultVisible.value = false; @@ -188,7 +203,6 @@ export const useOtaUpdate = () => { versionNumber: targetVersion, wifiSsid, wifiPassword, - resourceUrl, }); if (runId !== updateRunId || !updating.value) return false; if (!updateResult?.taskId) { diff --git a/src/pages/device/composables/useDeviceStatus.js b/src/pages/device/composables/useDeviceStatus.js index d99eefb..3c1c2c4 100644 --- a/src/pages/device/composables/useDeviceStatus.js +++ b/src/pages/device/composables/useDeviceStatus.js @@ -99,7 +99,7 @@ export function useDeviceStatus({ const refreshDeviceDetails = async () => { const deviceId = device.value.deviceId; - if (!deviceId) return; + if (!deviceId) return null; const requestVersion = ++deviceDetailRequestVersion; try { @@ -111,13 +111,17 @@ export function useDeviceStatus({ requestVersion !== deviceDetailRequestVersion || device.value.deviceId !== deviceId ) { - return; + return null; } deviceDetails.value = { ...deviceDetails.value, ...detail, deviceModelName: detail.deviceModelName ?? "", + latestVersion: detail.latestVersion ?? "", + needUpdate: detail.needUpdate ?? false, + forceUpdate: detail.forceUpdate ?? false, + version: detail.version ?? "", bindTime: String( detail.bindTime ?? deviceDetails.value.bindTime ?? "" ).trim(), @@ -126,9 +130,11 @@ export function useDeviceStatus({ ).trim(), }; updateDeviceUsageDuration(detail.onlineDuration, deviceId); + return detail; } catch (error) { // 实时刷新失败时保留当前页面数据,等待下次通知或页面重新显示。 console.log("刷新设备详情失败", error); + return null; } }; @@ -143,6 +149,10 @@ export function useDeviceStatus({ let latestDevice = { ...currentDevice, deviceModelName: "", + latestVersion: "", + needUpdate: false, + forceUpdate: false, + version: "", bindTime: "", qrCodeUrl: "", }; diff --git a/src/pages/device/my-device.vue b/src/pages/device/my-device.vue index 01ccfe9..911d1e9 100644 --- a/src/pages/device/my-device.vue +++ b/src/pages/device/my-device.vue @@ -8,7 +8,6 @@ import ScreenHint from "@/components/ScreenHint.vue"; import ModalDialog from "@/components/ModalDialog.vue"; import OtaModal from "@/components/OtaModal.vue"; import { - getHardwareBoxVersionAPI, laserAimAPI, updateDeviceAliasAPI, } from "@/apis"; @@ -19,7 +18,7 @@ import { DEVICE_NAME_STORAGE_KEY, useDeviceStatus, } from "./composables/useDeviceStatus"; -import { useOtaUpdate } from "@/composables/useOtaUpdate"; +import { getOtaInfoFromDetail, useOtaUpdate } from "@/composables/useOtaUpdate"; const store = useStore(); const { updateDevice, updateDeviceUsageDuration, clearDevice } = store; @@ -62,11 +61,8 @@ const showDeviceId = ref(false); const latestVersionDialogVisible = ref(false); const firmwareConfirmVisible = ref(false); const wifiRequiredVisible = ref(false); -const otaNeedUpdate = ref(false); const firmwareActionPending = ref(false); const pendingOtaInfo = ref(null); -let otaCheckPromise = null; -let otaCheckRequestVersion = 0; const { updating: otaUpdating, @@ -113,6 +109,12 @@ const wifiStatusText = computed(() => { const bindingDateText = computed(() => formatBindingDate(deviceDetails.value.bindTime) ); +const otaNeedUpdate = computed(() => { + const info = getOtaInfoFromDetail(deviceDetails.value); + return isDeviceOnline.value && + deviceDetails.value.deviceId === device.value.deviceId && + info.needUpdate && !!info.versionNumber; +}); // 固件版本统一以大写 V 开头,避免接口返回格式不一致影响弹窗展示。 const formatFirmwareVersion = (value) => { @@ -122,18 +124,12 @@ const formatFirmwareVersion = (value) => { }; const firmwareConfirmContent = computed(() => { - const currentVersion = formatFirmwareVersion(deviceStatus.value.version); - const latestVersion = formatFirmwareVersion( - pendingOtaInfo.value?.versionNumber - ); - + const currentVersion = formatFirmwareVersion(pendingOtaInfo.value?.currentVersion); + const latestVersion = formatFirmwareVersion(pendingOtaInfo.value?.versionNumber); if (currentVersion && latestVersion) { return `当前固件版本为 ${currentVersion},发现新固件版本 ${latestVersion},是否立即更新固件?`; } - if (latestVersion) { - return `发现新固件版本 ${latestVersion},是否立即更新固件?`; - } - return "发现新固件版本,是否立即更新固件?"; + return latestVersion ? `发现新固件版本 ${latestVersion},是否立即更新固件?` : "是否立即更新固件?"; }); const deviceIdText = computed(() => @@ -272,84 +268,20 @@ const joinWifi = () => { uni.navigateTo({ url: "/pages/device/ota-wifi" }); }; -const clearOtaState = () => { - otaCheckRequestVersion += 1; - otaCheckPromise = null; - otaNeedUpdate.value = false; -}; - -const loadOtaVersionInfo = async () => { - if (otaCheckPromise) return otaCheckPromise; - - const deviceId = device.value.deviceId; - if (!deviceId || !isDeviceOnline.value) return null; - - const requestVersion = ++otaCheckRequestVersion; - const request = getHardwareBoxVersionAPI() - .then((versionInfo) => { - if ( - requestVersion !== otaCheckRequestVersion || - device.value.deviceId !== deviceId || - !isDeviceOnline.value - ) { - return null; - } - - if (!versionInfo || typeof versionInfo !== "object") { - throw new Error("固件版本信息为空"); - } - - const needUpdate = - versionInfo.needUpdate === true || Number(versionInfo.needUpdate) === 1; - otaNeedUpdate.value = needUpdate; - return { - versionNumber: versionInfo.versionNumber || "", - resourceUrl: versionInfo.resourceUrl || "", - needUpdate, - }; - }) - .finally(() => { - if (otaCheckPromise === request) { - otaCheckPromise = null; - } - }); - - otaCheckPromise = request; - return request; -}; - -const refreshOtaUpdateState = async () => { - otaNeedUpdate.value = false; - if (!device.value.deviceId || !isDeviceOnline.value) { - clearOtaState(); - return; - } - - try { - await loadOtaVersionInfo(); - } catch (error) { - clearOtaState(); - console.log("检查固件更新失败", error); - } +const closeFirmwareConfirm = () => { + firmwareConfirmVisible.value = false; }; const closeLatestVersionDialog = () => { latestVersionDialogVisible.value = false; }; -const closeFirmwareConfirm = () => { - firmwareConfirmVisible.value = false; -}; - const runFirmwareUpdate = () => { - const versionInfo = pendingOtaInfo.value; - if (!versionInfo) return; + const otaInfo = pendingOtaInfo.value; + if (!otaInfo || otaInfo.deviceId !== device.value.deviceId) return; void startOtaUpdate({ - versionNumber: versionInfo.versionNumber, - resourceUrl: versionInfo.resourceUrl, - onSuccess: () => { - otaNeedUpdate.value = false; - }, + versionNumber: otaInfo.versionNumber, + onSuccess: () => void refreshDeviceDetails(), }); }; @@ -367,42 +299,43 @@ const confirmFirmwareUpdate = () => { }; const goWifiForFirmwareUpdate = () => { - const versionInfo = pendingOtaInfo.value; - if (!versionInfo) return; + const otaInfo = pendingOtaInfo.value; + if (!otaInfo || otaInfo.deviceId !== device.value.deviceId) return; wifiRequiredVisible.value = false; - const query = [ - "source=firmware-update", - `versionNumber=${encodeURIComponent(versionInfo.versionNumber)}`, - `resourceUrl=${encodeURIComponent(versionInfo.resourceUrl)}`, - ].join("&"); - uni.navigateTo({ url: `/pages/device/ota-wifi?${query}` }); + const versionNumber = encodeURIComponent(otaInfo.versionNumber); + uni.navigateTo({ url: `/pages/device/ota-wifi?source=firmware-update&versionNumber=${versionNumber}` }); }; const handleOtaResultClose = () => { closeOtaResult(); - void refreshOtaUpdateState(); + void refreshDeviceDetails(); }; const goFirmwareUpdate = async () => { - if (firmwareActionPending.value) return; + if (firmwareActionPending.value || otaUpdating.value) return; if (!isDeviceOnline.value) { uni.showToast({ title: "请先开启智能弓", icon: "none" }); return; } - firmwareActionPending.value = true; + const deviceId = device.value.deviceId; try { - const versionInfo = await loadOtaVersionInfo(); - if (!versionInfo) return; - if (!versionInfo.needUpdate) { + const detail = await refreshDeviceDetails(); + if (!detail || device.value.deviceId !== deviceId) { + uni.showToast({ title: "获取设备详情失败,请重试", icon: "none" }); + return; + } + const otaInfo = getOtaInfoFromDetail(detail); + if (!otaInfo.needUpdate) { latestVersionDialogVisible.value = true; return; } - - pendingOtaInfo.value = versionInfo; + if (!otaInfo.versionNumber) { + uni.showToast({ title: "缺少固件目标版本,请重试", icon: "none" }); + return; + } + pendingOtaInfo.value = { ...otaInfo, deviceId }; firmwareConfirmVisible.value = true; - } catch (error) { - uni.showToast({ title: "获取更新版本失败,请重试", icon: "none" }); } finally { firmwareActionPending.value = false; } @@ -451,15 +384,20 @@ watch( (isOnline, wasOnline) => { if (isOnline && !wasOnline) { void refreshDeviceDetails(); - void refreshOtaUpdateState(); - return; - } - if (!isOnline) { - clearOtaState(); + } else if (!isOnline) { + firmwareConfirmVisible.value = false; + wifiRequiredVisible.value = false; } } ); +watch(() => device.value.deviceId, () => { + pendingOtaInfo.value = null; + latestVersionDialogVisible.value = false; + firmwareConfirmVisible.value = false; + wifiRequiredVisible.value = false; +}); + onLoad((options = {}) => { retryScanOnShow.value = options.retryScan === "1"; }); @@ -475,7 +413,6 @@ onUnmounted(() => { onShow(async () => { calibration.value = uni.getStorageSync("calibration"); await syncDeviceBinding(); - void refreshOtaUpdateState(); if (retryScanOnShow.value) { retryScanOnShow.value = false; handleScan(); @@ -607,10 +544,7 @@ onShow(async () => { 固件更新 - New + New @@ -724,6 +658,7 @@ onShow(async () => { :content="firmwareConfirmContent" cancelText="暂不更新" confirmText="立即更新" + :showCancel="!pendingOtaInfo?.forceUpdate" :onCancel="closeFirmwareConfirm" :onConfirm="confirmFirmwareUpdate" > diff --git a/src/pages/device/ota-wifi.vue b/src/pages/device/ota-wifi.vue index 4929bb8..213a003 100644 --- a/src/pages/device/ota-wifi.vue +++ b/src/pages/device/ota-wifi.vue @@ -9,10 +9,10 @@ import useStore from "@/store"; import { capsuleHeight } from "@/util"; import { connectDeviceWifiAPI, + getDeviceDetailAPI, getDeviceWifiStatusAPI, - getHardwareBoxVersionAPI, } from "@/apis"; -import { useOtaUpdate } from "@/composables/useOtaUpdate"; +import { getOtaInfoFromDetail, useOtaUpdate } from "@/composables/useOtaUpdate"; const STATES = { SCANNING: "SCANNING", @@ -23,7 +23,7 @@ const STATES = { }; const isIOS = uni.getDeviceInfo().osName === "ios"; -const { deviceStatus } = storeToRefs(useStore()); +const { device, deviceStatus } = storeToRefs(useStore()); const currentState = ref(STATES.SCANNING); const connectedWifi = ref(null); const connectedWifiName = ref(""); @@ -45,10 +45,7 @@ const showPassword = ref(false); // 刷新防抖标志:扫描进行中为 true,禁止重复点击;扫描结束(成功/失败)后重置为 false。 const isRefreshing = ref(false); const fromFirmwareUpdate = ref(false); -const routeOtaInfo = ref({ - versionNumber: "", - resourceUrl: "", -}); +const routeOtaVersionNumber = ref(""); const countdownVisible = ref(false); const countdownSeconds = ref(3); const firmwareMessageVisible = ref(false); @@ -395,37 +392,38 @@ const joinNetwork = () => { submitDeviceWifiConfig({ ssid, password }); }; -// 获取 OTA 更新版本信息,正常使用入口传参,缺失时再请求后端兜底。 -const getOtaVersionInfo = async () => { - if (routeOtaInfo.value.versionNumber && routeOtaInfo.value.resourceUrl) { - return { - needUpdate: true, - versionNumber: routeOtaInfo.value.versionNumber, - resourceUrl: routeOtaInfo.value.resourceUrl, - }; - } - return getHardwareBoxVersionAPI(); -}; - const startFirmwareUpdate = async () => { if (!fromFirmwareUpdate.value || !connectedWifi.value || otaUpdating.value) return; + const deviceId = device.value.deviceId; + const wifi = connectedWifi.value; + if (!deviceId) return; try { - const versionInfo = await getOtaVersionInfo(); - if (!versionInfo?.needUpdate) { + const response = await getDeviceDetailAPI(deviceId); + const detail = response?.detail || response?.data?.detail; + if (!detail || device.value.deviceId !== deviceId) throw new Error("设备详情已失效"); + const otaInfo = getOtaInfoFromDetail(detail); + if (!otaInfo.needUpdate) { firmwareMessage.value = "当前已是最新版本"; firmwareMessageVisible.value = true; return; } - await startOtaUpdate({ - versionNumber: versionInfo.versionNumber, - wifiSsid: connectedWifi.value.SSID, - wifiPassword: connectedWifi.value.password || "", - resourceUrl: versionInfo.resourceUrl, - }); + if (!otaInfo.versionNumber) { + firmwareMessage.value = "缺少固件目标版本,请返回后重试"; + firmwareMessageVisible.value = true; + return; + } + // WiFi 连接可能耗时较长,以更新前的最新设备详情为准。 + routeOtaVersionNumber.value = otaInfo.versionNumber; } catch (error) { - firmwareMessage.value = "获取更新版本失败,请重试"; + firmwareMessage.value = "获取设备详情失败,请返回后重试"; firmwareMessageVisible.value = true; + return; } + await startOtaUpdate({ + versionNumber: routeOtaVersionNumber.value, + wifiSsid: wifi.SSID, + wifiPassword: wifi.password || "", + }); }; const clearFirmwareCountdown = () => { @@ -466,10 +464,7 @@ const togglePasswordVisibility = () => { // 页面加载时识别普通 WiFi 入口和固件更新入口。 onLoad((options = {}) => { fromFirmwareUpdate.value = options.source === "firmware-update"; - routeOtaInfo.value = { - versionNumber: decodeURIComponent(options.versionNumber || ""), - resourceUrl: decodeURIComponent(options.resourceUrl || ""), - }; + routeOtaVersionNumber.value = decodeURIComponent(options.versionNumber || ""); }); // 页面挂载后启动 WiFi 扫描流程。 diff --git a/src/pages/index.vue b/src/pages/index.vue index 244ef62..6e34ff2 100644 --- a/src/pages/index.vue +++ b/src/pages/index.vue @@ -13,14 +13,14 @@ import OtaModal from "@/components/OtaModal.vue"; import { checkUserBindAPI, getAppConfig, - getHardwareBoxVersionAPI, + getDeviceDetailAPI, getHomeData, getMyDevicesAPI, getScoreRankList, silentLoginAPI, } from "@/apis"; import {topThreeColors} from "@/constants"; -import {useOtaUpdate} from "@/composables/useOtaUpdate"; +import {getOtaInfoFromDetail, useOtaUpdate} from "@/composables/useOtaUpdate"; import useStore from "@/store"; import {storeToRefs} from "pinia"; @@ -74,16 +74,9 @@ const isDeviceCharging = computed( () => deviceCardState.value === "online" && deviceStatus.value?.charging === true ); -// OTA 相关 const otaVisible = ref(false); const wifiRequiredVisible = ref(false); -const otaInfo = ref({ - versionNumber: "", - versionInfo: "", - resourceUrl: "", - forceUpdate: false, - needUpdate: false, -}); +const otaInfo = ref({ versionNumber: "", versionInfo: "", needUpdate: false, forceUpdate: false }); const isStartingOta = ref(false); let isCheckingOta = false; let otaCheckQueuedForOnline = false; @@ -98,157 +91,122 @@ const { closeResult: closeOtaResult, } = useOtaUpdate(); -// 获取并保存后端返回的 OTA 版本信息,供弹窗展示和更新接口使用。 -const applyOtaVersionInfo = (versionInfo) => { - otaInfo.value = { - versionNumber: versionInfo?.versionNumber || "", - versionInfo: versionInfo?.versionInfo || "", - resourceUrl: versionInfo?.resourceUrl || "", - forceUpdate: Number(versionInfo?.forceUpdate) === 1, - needUpdate: - versionInfo?.needUpdate === true || Number(versionInfo?.needUpdate) === 1, - }; -}; - -// 检查当前设备盒子是否存在可升级版本。 +// 首页仅用绑定设备详情判断是否需要升级,不再请求旧版本接口。 const checkOtaUpdate = async () => { - if ( - isCheckingOta || - otaVisible.value || - otaUpdating.value || - otaResultVisible.value - ) return; + if (isCheckingOta || otaVisible.value || otaUpdating.value || otaResultVisible.value) return; + const deviceId = String(device.value.deviceId || ""); + if (!user.value.id || !deviceId || online.value !== true) return; isCheckingOta = true; - try { - if ( - online.value !== true || - otaVisible.value || - otaUpdating.value || - otaResultVisible.value - ) return; - - let versionInfo; - try { - versionInfo = await getHardwareBoxVersionAPI(); - } catch (err) { - return; - } + const response = await getDeviceDetailAPI(deviceId); + const detail = response?.detail || response?.data?.detail; + if (!detail || device.value.deviceId !== deviceId || online.value !== true) return; if (otaVisible.value || otaUpdating.value || otaResultVisible.value) return; - applyOtaVersionInfo(versionInfo); - if (!otaInfo.value.needUpdate) return; + otaInfo.value = getOtaInfoFromDetail(detail); + if (!otaInfo.value.needUpdate || !otaInfo.value.versionNumber) return; - const dismissedAt = uni.getStorageSync("ota_dismissed_at"); - const now = Date.now(); - if (!otaInfo.value.forceUpdate && dismissedAt && now - dismissedAt < 24 * 60 * 60 * 1000) return; + const dismissed = uni.getStorageSync("ota_dismissed_at"); + const recentlyDismissed = dismissed?.deviceId === deviceId && + dismissed?.versionNumber === otaInfo.value.versionNumber && + Date.now() - Number(dismissed?.at || 0) < 24 * 60 * 60 * 1000; + if (!otaInfo.value.forceUpdate && recentlyDismissed) return; otaVisible.value = true; + } catch (error) { + console.log("检查固件更新失败", error); } finally { isCheckingOta = false; - const shouldRecheckForOnline = otaCheckQueuedForOnline; - otaCheckQueuedForOnline = false; - if ( - shouldRecheckForOnline && - !otaVisible.value && - !otaUpdating.value && - !otaResultVisible.value - ) { + if (otaCheckQueuedForOnline) { + otaCheckQueuedForOnline = false; void checkOtaUpdate(); } } }; -// 设备由 WS 通知上线时补查 OTA;已显示任何 OTA 弹窗时保留当前流程和结果。 watch(online, (nextOnline, previousOnline) => { - if ( - previousOnline !== false || - nextOnline !== true || - otaVisible.value || - otaUpdating.value || - otaResultVisible.value - ) return; - if (isCheckingOta) { - otaCheckQueuedForOnline = true; + if (!nextOnline) { + otaVisible.value = false; return; } - void checkOtaUpdate(); + if (previousOnline === false) { + if (isCheckingOta) otaCheckQueuedForOnline = true; + else void checkOtaUpdate(); + } }); -// 任一页面发起或恢复 OTA 后,关闭首页的版本发现弹窗,避免两层弹窗重叠。 -watch([otaUpdating, otaResultVisible], ([updating, resultVisible]) => { - if (!updating && !resultVisible) return; +watch(() => device.value.deviceId, () => { otaVisible.value = false; - isStartingOta.value = false; + otaInfo.value = { versionNumber: "", versionInfo: "", needUpdate: false, forceUpdate: false }; }); -// 拼接 OTA WiFi 页参数,让未连 WiFi 的设备继续使用同一份版本信息。 -const getOtaWifiUrl = () => { - const { versionNumber, resourceUrl } = otaInfo.value; - const query = [ - "source=firmware-update", - `versionNumber=${encodeURIComponent(versionNumber)}`, - `resourceUrl=${encodeURIComponent(resourceUrl)}`, - ].join("&"); - return `/pages/device/ota-wifi?${query}`; -}; +watch([otaUpdating, otaResultVisible], ([updating, resultVisible]) => { + if (updating || resultVisible) otaVisible.value = false; +}); + +const getOtaWifiUrl = () => + `/pages/device/ota-wifi?source=firmware-update&versionNumber=${encodeURIComponent(otaInfo.value.versionNumber)}`; -// 处理 OTA 弹窗暂不更新,强制更新时不允许关闭。 const handleOtaDismiss = () => { if (otaInfo.value.forceUpdate) return; - uni.setStorageSync("ota_dismissed_at", Date.now()); - otaVisible.value = false; -}; - -// 设备盒子已连 WiFi 时,通过共享 OTA 状态发起更新。 -const startHomeOtaUpdate = async () => { - otaVisible.value = false; - await startOtaUpdate({ + uni.setStorageSync("ota_dismissed_at", { + deviceId: device.value.deviceId, versionNumber: otaInfo.value.versionNumber, - resourceUrl: otaInfo.value.resourceUrl, - onSuccess: () => { - otaInfo.value = {...otaInfo.value, needUpdate: false}; - }, + at: Date.now(), }); - isStartingOta.value = false; + otaVisible.value = false; }; -// 点击立即更新时先判断设备是否在线并已通过 WiFi 联网,未联网时先展示连接引导。 +// 点击更新或失败重试时检查设备网络状态,并使用详情中的目标版本号。 const handleOtaUpdate = async () => { if (isStartingOta.value) return; isStartingOta.value = true; - const currentDeviceStatus = deviceStatus.value; - - if (currentDeviceStatus?.online !== true) { + const deviceId = String(device.value.deviceId || ""); + try { + if (!deviceId || deviceStatus.value?.online !== true) { + uni.showToast({ title: "请先开启智能弓", icon: "none" }); + return; + } + const response = await getDeviceDetailAPI(deviceId); + const detail = response?.detail || response?.data?.detail; + if (!detail || device.value.deviceId !== deviceId) { + uni.showToast({ title: "获取设备详情失败,请重试", icon: "none" }); + return; + } + otaInfo.value = getOtaInfoFromDetail(detail); + if (!otaInfo.value.needUpdate) { + otaVisible.value = false; + uni.showToast({ title: "当前已是最新版本", icon: "none" }); + return; + } + if (!otaInfo.value.versionNumber) { + uni.showToast({ title: "缺少固件目标版本", icon: "none" }); + return; + } + const currentDeviceStatus = deviceStatus.value; + if (currentDeviceStatus?.online !== true) { + uni.showToast({ title: "请先开启智能弓", icon: "none" }); + return; + } + if (Date.now() - Number(currentDeviceStatus?.receivedAt || 0) > DEVICE_STATUS_STALE_TIME) { + uni.showToast({ title: "设备状态同步中,请稍后重试", icon: "none" }); + return; + } + otaVisible.value = false; + if (String(currentDeviceStatus?.netType || "").toLowerCase() === "wifi") { + await startOtaUpdate({ + versionNumber: otaInfo.value.versionNumber, + onSuccess: () => { otaInfo.value = { ...otaInfo.value, needUpdate: false }; }, + }); + } else { + wifiRequiredVisible.value = true; + } + } catch (error) { + uni.showToast({ title: "获取设备详情失败,请重试", icon: "none" }); + } finally { isStartingOta.value = false; - uni.showToast({ - title: "请先开启智能弓", - icon: "none", - }); - return; } - - if ( - Date.now() - Number(currentDeviceStatus?.receivedAt || 0) > - DEVICE_STATUS_STALE_TIME - ) { - isStartingOta.value = false; - uni.showToast({ - title: "设备状态同步中,请稍后重试", - icon: "none", - }); - return; - } - - if (String(currentDeviceStatus?.netType || "").toLowerCase() === "wifi") { - startHomeOtaUpdate(); - return; - } - - isStartingOta.value = false; - otaVisible.value = false; - wifiRequiredVisible.value = true; }; -// 从首页固件更新提示进入 WiFi 配置页,并继续沿用当前版本信息。 +// 从首页更新失败提示进入 WiFi 配置页。 const goWifiForOtaUpdate = () => { wifiRequiredVisible.value = false; uni.navigateTo({ url: getOtaWifiUrl() }); @@ -257,22 +215,13 @@ const goWifiForOtaUpdate = () => { // 处理 OTA 更新成功后的完成按钮,关闭共享结果弹窗。 const handleOtaDone = () => { closeOtaResult(); + otaInfo.value = { ...otaInfo.value, needUpdate: false }; }; -// 处理共享 OTA 更新失败后的重试,先刷新版本参数再重新判断网络状态。 +// 处理共享 OTA 更新失败后的重试。 const handleOtaRetry = async () => { closeOtaResult(); - try { - const versionInfo = await getHardwareBoxVersionAPI(); - applyOtaVersionInfo(versionInfo); - if (!otaInfo.value.needUpdate) return; - await handleOtaUpdate(); - } catch (error) { - uni.showToast({ - title: "获取更新版本失败,请重试", - icon: "none", - }); - } + await handleOtaUpdate(); }; // 提取积分榜接口返回的榜单数组,兼容数组和对象两种返回格式。 @@ -346,10 +295,6 @@ onShow(async () => { const env = uni.getAccountInfoSync().miniProgram.envVersion; const token = uni.getStorageSync(`${env}_token`); - if (token || user.value.id) { - await checkOtaUpdate(); - } - if (!user.value.id && !token) { // showModal.value = true; // try { @@ -401,6 +346,7 @@ onShow(async () => { }, 3000); } await syncHomeDevice(); + await checkOtaUpdate(); } } @@ -432,12 +378,10 @@ onShareTimeline(() => {