update:提交我的设备改版
This commit is contained in:
@@ -1,15 +1,19 @@
|
||||
<script setup>
|
||||
import { ref, computed, onMounted, onUnmounted } from "vue";
|
||||
import { ref, computed, onMounted, onUnmounted, watch } from "vue";
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||||
import Container from "@/components/Container.vue";
|
||||
import ScreenHint from "@/components/ScreenHint.vue";
|
||||
import {
|
||||
connectDeviceWifiAPI,
|
||||
getDeviceBatteryAPI,
|
||||
getHardwareBoxTaskStatusAPI,
|
||||
getHardwareBoxVersionAPI,
|
||||
sendHardwareBoxUpdateAPI,
|
||||
} from "@/apis";
|
||||
import useStore from "@/store";
|
||||
import { storeToRefs } from "pinia";
|
||||
|
||||
const store = useStore();
|
||||
const { deviceStatus } = storeToRefs(store);
|
||||
|
||||
const STATES = {
|
||||
SCANNING: "SCANNING",
|
||||
@@ -48,14 +52,13 @@ const progress = ref(0);
|
||||
let progressTimer = null;
|
||||
let timeoutTimer = null;
|
||||
let statusTimer = null;
|
||||
let wifiConnectTimer = null;
|
||||
let wifiConnectTimeoutTimer = null;
|
||||
let stopWifiStatusWatcher = null;
|
||||
let settleWifiConnectWaiting = null;
|
||||
let wifiConnectRequestId = 0;
|
||||
let wifiConnectPollCount = 0;
|
||||
const WIFI_CONNECT_POLL_INTERVAL = 2000;
|
||||
const WIFI_CONNECT_MAX_POLL_COUNT = 30;
|
||||
const WIFI_CONNECT_TIMEOUT = 60000;
|
||||
const DEVICE_STATUS_STALE_TIME = 6000;
|
||||
const WIFI_CONNECT_FAILED_TEXT = "连接失败,请检查WiFi密码或WiFi状态";
|
||||
const OTA_MIN_BATTERY = 50;
|
||||
const OTA_LOW_BATTERY_TEXT = "电量不足 50%,暂不支持 OTA 升级";
|
||||
// 控制授权拒绝弹窗显示/隐藏
|
||||
const wifiAuthDeniedVisible = ref(false);
|
||||
|
||||
@@ -207,7 +210,7 @@ const startScanning = () => {
|
||||
|
||||
// 选择列表中的 WiFi,并打开密码输入弹窗。
|
||||
const selectWifi = (wifi) => {
|
||||
cancelWifiConnectPolling();
|
||||
cancelWifiConnectWaiting();
|
||||
connectingWifi.value = wifi;
|
||||
connectInput.value = { ssid: wifi.SSID, password: "" };
|
||||
connectMode.value = wifi.secure ? "secure" : "open";
|
||||
@@ -217,7 +220,7 @@ const selectWifi = (wifi) => {
|
||||
|
||||
// 选择手动输入 WiFi,并打开手动输入弹窗。
|
||||
const selectOther = () => {
|
||||
cancelWifiConnectPolling();
|
||||
cancelWifiConnectWaiting();
|
||||
connectingWifi.value = null;
|
||||
connectInput.value = { ssid: "", password: "" };
|
||||
connectMode.value = "manual";
|
||||
@@ -225,9 +228,9 @@ const selectOther = () => {
|
||||
currentState.value = STATES.CONNECTING;
|
||||
};
|
||||
|
||||
// 关闭连接弹窗,并停止当前 WiFi 连接轮询。
|
||||
// 关闭连接弹窗,并停止等待当前 WiFi 连接结果。
|
||||
const closeConnectSheet = () => {
|
||||
cancelWifiConnectPolling();
|
||||
cancelWifiConnectWaiting();
|
||||
connectError.value = "";
|
||||
currentState.value = connectedWifi.value ? STATES.CONNECTED : STATES.LIST;
|
||||
};
|
||||
@@ -257,89 +260,84 @@ const wifiListScrollHeight = computed(() => {
|
||||
return `${Math.min(itemCount * 92, maxHeight)}rpx`;
|
||||
});
|
||||
|
||||
// 清理 WiFi 连接轮询定时器。
|
||||
const clearWifiConnectTimer = () => {
|
||||
clearTimeout(wifiConnectTimer);
|
||||
wifiConnectTimer = null;
|
||||
wifiConnectPollCount = 0;
|
||||
// 清理本次 WiFi 连接状态监听和超时计时器。
|
||||
const clearWifiConnectWatcher = () => {
|
||||
clearTimeout(wifiConnectTimeoutTimer);
|
||||
wifiConnectTimeoutTimer = null;
|
||||
if (stopWifiStatusWatcher) {
|
||||
stopWifiStatusWatcher();
|
||||
stopWifiStatusWatcher = null;
|
||||
}
|
||||
};
|
||||
|
||||
// 取消当前 WiFi 连接轮询,并恢复弹窗提交状态。
|
||||
const cancelWifiConnectPolling = () => {
|
||||
// 取消当前 WiFi 连接确认,并恢复弹窗提交状态。
|
||||
const cancelWifiConnectWaiting = () => {
|
||||
wifiConnectRequestId += 1;
|
||||
clearWifiConnectTimer();
|
||||
if (settleWifiConnectWaiting) {
|
||||
settleWifiConnectWaiting(false);
|
||||
}
|
||||
clearWifiConnectWatcher();
|
||||
connectStatusText.value = "";
|
||||
isSubmittingWifi.value = false;
|
||||
uni.hideLoading();
|
||||
};
|
||||
|
||||
// 判断设备电量接口返回的 online/netType 字段,确定设备是否已通过 WiFi 在线。
|
||||
// 返回值含义:true → WiFi 在线成功;"net_fail" → 设备走 4g 失败;false → 未就绪,需继续轮询。
|
||||
// 根据实时推送的 online/netType 判断设备是否已通过 WiFi 在线。
|
||||
// 返回值含义:true → WiFi 在线成功;"net_fail" → 设备走 4g 失败;false → 未就绪。
|
||||
const isDeviceConnectedByWifi = (deviceStatus) => {
|
||||
// online 不为 true → 设备不在线,需继续轮询
|
||||
// online 不为 true → 设备尚未在线,继续等待推送
|
||||
if (deviceStatus?.online !== true) return false;
|
||||
const netType = String(deviceStatus?.netType || "").toLowerCase();
|
||||
// online:true + netType:4g → 设备已切 4g,WiFi 连接失败
|
||||
if (netType === "4g") return "net_fail";
|
||||
// online:true + netType:wifi → WiFi 连接成功
|
||||
// online:true + netType:"" → 设备在线但 netType 暂未上报,继续轮询等待
|
||||
// online:true + netType:"" → 设备在线但 netType 暂未上报,继续等待推送
|
||||
return netType === "wifi";
|
||||
};
|
||||
|
||||
// 轮询设备电量接口,等待设备切到 WiFi 在线;netType:4g 快速失败,超时 30 次后放弃。
|
||||
const waitForDeviceWifiConnected = (requestId) => {
|
||||
// 等待提交配置后的新 WS 状态;忽略提交前的旧状态,超时后按连接失败处理。
|
||||
const waitForDeviceWifiConnected = (requestId, receivedAfter) => {
|
||||
return new Promise((resolve) => {
|
||||
const poll = async () => {
|
||||
if (requestId !== wifiConnectRequestId) {
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
wifiConnectPollCount += 1;
|
||||
try {
|
||||
const deviceStatus = await getDeviceBatteryAPI();
|
||||
if (requestId !== wifiConnectRequestId) {
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
const connResult = isDeviceConnectedByWifi(deviceStatus);
|
||||
// online:true + netType:wifi → 成功
|
||||
if (connResult === true) {
|
||||
resolve(true);
|
||||
return;
|
||||
}
|
||||
// online:true + netType:4g → 立即失败(设备已切 4g,WiFi 连不上)
|
||||
if (connResult === "net_fail") {
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
// online:false + netType:"" → 继续轮询
|
||||
// online:true + netType:"" → 忽略,继续轮询(netType 暂未上报)
|
||||
} catch (err) {
|
||||
if (requestId !== wifiConnectRequestId) {
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (wifiConnectPollCount >= WIFI_CONNECT_MAX_POLL_COUNT) {
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
wifiConnectTimer = setTimeout(poll, WIFI_CONNECT_POLL_INTERVAL);
|
||||
let settled = false;
|
||||
const finish = (result) => {
|
||||
if (settled) return;
|
||||
settled = true;
|
||||
clearWifiConnectWatcher();
|
||||
settleWifiConnectWaiting = null;
|
||||
resolve(result);
|
||||
};
|
||||
|
||||
poll();
|
||||
settleWifiConnectWaiting = finish;
|
||||
stopWifiStatusWatcher = watch(
|
||||
deviceStatus,
|
||||
(status) => {
|
||||
if (requestId !== wifiConnectRequestId) {
|
||||
finish(false);
|
||||
return;
|
||||
}
|
||||
if (Number(status?.receivedAt) <= receivedAfter) return;
|
||||
|
||||
const connResult = isDeviceConnectedByWifi(status);
|
||||
if (connResult === true) {
|
||||
finish(true);
|
||||
} else if (connResult === "net_fail") {
|
||||
finish(false);
|
||||
}
|
||||
}
|
||||
);
|
||||
wifiConnectTimeoutTimer = setTimeout(
|
||||
() => finish(false),
|
||||
WIFI_CONNECT_TIMEOUT
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
// 提交 WiFi 配置给游戏设备,并轮询确认设备真实连上 WiFi 后再展示成功。
|
||||
// 提交 WiFi 配置给游戏设备,并通过 WS 确认设备真实连上 WiFi 后再展示成功。
|
||||
const submitDeviceWifiConfig = async ({ ssid, password }) => {
|
||||
if (isSubmittingWifi.value) return;
|
||||
wifiConnectRequestId += 1;
|
||||
const requestId = wifiConnectRequestId;
|
||||
clearWifiConnectTimer();
|
||||
clearWifiConnectWatcher();
|
||||
isSubmittingWifi.value = true;
|
||||
connectStatusText.value = "WiFi连接中...";
|
||||
uni.showLoading({
|
||||
@@ -348,7 +346,8 @@ const submitDeviceWifiConfig = async ({ ssid, password }) => {
|
||||
});
|
||||
try {
|
||||
await connectDeviceWifiAPI(ssid, password);
|
||||
const isConnected = await waitForDeviceWifiConnected(requestId);
|
||||
if (requestId !== wifiConnectRequestId) return;
|
||||
const isConnected = await waitForDeviceWifiConnected(requestId, Date.now());
|
||||
if (requestId !== wifiConnectRequestId) return;
|
||||
if (!isConnected) {
|
||||
connectError.value = WIFI_CONNECT_FAILED_TEXT;
|
||||
@@ -369,7 +368,7 @@ const submitDeviceWifiConfig = async ({ ssid, password }) => {
|
||||
}
|
||||
} finally {
|
||||
if (requestId === wifiConnectRequestId) {
|
||||
clearWifiConnectTimer();
|
||||
clearWifiConnectWatcher();
|
||||
connectStatusText.value = "";
|
||||
isSubmittingWifi.value = false;
|
||||
uni.hideLoading();
|
||||
@@ -456,7 +455,9 @@ const pollUpdateTaskStatus = (taskId) => {
|
||||
// 判断设备是否满足 OTA 更新条件,不满足时返回精确提示文案。
|
||||
const getUpdateDisabledReason = (deviceStatus) => {
|
||||
if (deviceStatus?.online !== true) return "请先开启智能弓";
|
||||
if (Number(deviceStatus?.battery) <= OTA_MIN_BATTERY) return OTA_LOW_BATTERY_TEXT;
|
||||
if (Date.now() - Number(deviceStatus?.receivedAt || 0) > DEVICE_STATUS_STALE_TIME) {
|
||||
return "设备状态同步中,请稍后重试";
|
||||
}
|
||||
if (String(deviceStatus?.netType || "").toLowerCase() !== "wifi") return "设备当前未连接 WiFi,请先连接 WiFi 后再更新";
|
||||
return "";
|
||||
};
|
||||
@@ -480,8 +481,7 @@ const startUpdate = async () => {
|
||||
isStartingUpdate.value = true;
|
||||
|
||||
try {
|
||||
const deviceStatus = await getDeviceBatteryAPI();
|
||||
const disabledReason = getUpdateDisabledReason(deviceStatus);
|
||||
const disabledReason = getUpdateDisabledReason(deviceStatus.value);
|
||||
if (disabledReason) {
|
||||
isStartingUpdate.value = false;
|
||||
uni.showToast({
|
||||
@@ -612,7 +612,7 @@ onUnmounted(() => {
|
||||
if (typeof uni.offKeyboardHeightChange === "function") {
|
||||
uni.offKeyboardHeightChange(handleKeyboardHeightChange);
|
||||
}
|
||||
cancelWifiConnectPolling();
|
||||
cancelWifiConnectWaiting();
|
||||
clearUpdateTimers();
|
||||
wx.offGetWifiList && wx.offGetWifiList();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user