From f4b37fba00cbc44ccbd33841bd52ee20f94d8055 Mon Sep 17 00:00:00 2001
From: zhangyibo95 <690096405@qq.com>
Date: Thu, 24 Sep 2026 15:16:14 +0800
Subject: [PATCH] =?UTF-8?q?update=EF=BC=9A=E4=BC=98=E5=8C=96ota?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/apis.js | 13 +-
src/composables/useOtaUpdate.js | 20 +-
.../device/composables/useDeviceStatus.js | 14 +-
src/pages/device/my-device.vue | 159 ++++--------
src/pages/device/ota-wifi.vue | 59 ++---
src/pages/index.vue | 238 +++++++-----------
6 files changed, 200 insertions(+), 303 deletions(-)
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(() => {
-
{
:class="{ 'device-status-badge--charging': isDeviceCharging }"
@click.stop="$clickSound(() => toPage('/pages/device/my-device'))"
>
-