diff --git a/src/App.vue b/src/App.vue
index 738dbbb..5ccb912 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -8,9 +8,6 @@
} from "@dcloudio/uni-app";
import websocket from "@/websocket";
import matchWebsocket from "@/matchWebsocket";
- import {
- getDeviceBatteryAPI
- } from "@/apis";
import {
MESSAGETYPES
} from "@/constants";
@@ -27,8 +24,9 @@
} = storeToRefs(store);
const {
updateUser,
- updateOnline,
- updateDeviceBattery,
+ updateDeviceStatus,
+ setDeviceOnline,
+ clearDeviceStatus,
showDeviceChargingDialog,
clearSessionState,
clearDevice
@@ -70,14 +68,19 @@
});
}
- async function emitUpdateOnline() {
- const data = await getDeviceBatteryAPI();
+ function emitUpdateOnline(nextOnline) {
const wasOnline = Boolean(online.value);
- const nextOnline = Boolean(data.online);
- updateOnline(nextOnline);
- updateDeviceBattery(nextOnline ? data?.battery ?? data?.power : null);
- if (!device.value.deviceId || wasOnline === nextOnline) return;
- audioManager.play(nextOnline ? "设备已连接" : "设备连接已断开");
+ setDeviceOnline(nextOnline === true);
+ if (!device.value.deviceId || wasOnline === (nextOnline === true)) return;
+ audioManager.play(nextOnline === true ? "设备已连接" : "设备连接已断开");
+ }
+
+ function onDeviceStatusPush(status) {
+ updateDeviceStatus(status);
+ }
+
+ function onShootSocketDisconnected() {
+ clearDeviceStatus();
}
function onDeviceBindInvalid() {
@@ -113,6 +116,10 @@
}
function onShootWsMsg(content) {
+ if (content?.event === "/addons/shoot/battery") {
+ onDeviceStatusPush(content.data);
+ return;
+ }
if(content.type === 'shoot-trigger'){
onDeviceShoot()
}
@@ -124,6 +131,7 @@
void audioManager.warmButton();
uni.$on("update-user", emitUpdateUser);
uni.$on("update-online", emitUpdateOnline);
+ uni.$on("shoot-socket-disconnected", onShootSocketDisconnected);
uni.$on("session-kicked-out", onSessionKickedOut);
uni.$on("device-bind-invalid", onDeviceBindInvalid);
uni.$on("device-charging", onDeviceCharging);
@@ -150,6 +158,7 @@
onHide(() => {
uni.$off("update-user", emitUpdateUser);
uni.$off("update-online", emitUpdateOnline);
+ uni.$off("shoot-socket-disconnected", onShootSocketDisconnected);
uni.$off("session-kicked-out", onSessionKickedOut);
uni.$off("device-bind-invalid", onDeviceBindInvalid);
uni.$off("device-charging", onDeviceCharging);
@@ -159,6 +168,7 @@
matchWebsocket.closeMatchWebSocket({
reason: "app-hide"
});
+ clearDeviceStatus();
websocket.closeWebSocket();
});
diff --git a/src/apis.js b/src/apis.js
index 837ddd2..eb5690a 100644
--- a/src/apis.js
+++ b/src/apis.js
@@ -285,6 +285,10 @@ export const getDeviceDetailAPI = (deviceId) => {
return request("GET", `/user/device/getDetail?deviceId=${encodeURIComponent(deviceId)}`);
};
+export const updateDeviceAliasAPI = (deviceId, alias) => {
+ return request("POST", "/user/device/updateAlias", {deviceId, alias});
+};
+
export const createPractiseAPI = (arrows, time, target) => {
return request("POST", "/user/practice/create", {
shootNumber: arrows,
@@ -565,10 +569,6 @@ export const laserCloseAPI = async () => {
return request("POST", "/user/device/closeAim");
};
-export const getDeviceBatteryAPI = async () => {
- return request("GET", "/user/device/battery");
-};
-
// 设备连接指定 WiFi,只下发 WiFi 凭证,不触发 OTA 升级。
export const connectDeviceWifiAPI = async (ssid, password) => {
return request("POST", "/user/hardwareBox/connectWifi", {ssid, password});
diff --git a/src/components/BowPower.vue b/src/components/BowPower.vue
index 528c1e7..c0c3083 100644
--- a/src/components/BowPower.vue
+++ b/src/components/BowPower.vue
@@ -1,44 +1,15 @@
- 电量{{ power || 1 }}%
+ {{ power === null ? "电量--" : `电量${power}%` }}
diff --git a/src/components/OtaModal.vue b/src/components/OtaModal.vue
index 303c1a0..4861667 100644
--- a/src/components/OtaModal.vue
+++ b/src/components/OtaModal.vue
@@ -1,10 +1,11 @@
+
+
+
+
+
+
+
+ 二维码加载中...
+
+
+ 设备ID:{{ deviceId }}
+
+ 保存至相册
+
+
+ 该二维码为当前绑定弓箭的二维码,你可以截图保存到相册,以便当二维码丢失或不在身边时,可以扫描二维码进行设备绑定。
+
+ 注:解除绑定后将无法查看该二维码。
+
+ 暂无设备二维码
+
+
+
+
+
+
diff --git a/src/pages/device/my-device.vue b/src/pages/device/my-device.vue
index 66e6e67..8cae4fd 100644
--- a/src/pages/device/my-device.vue
+++ b/src/pages/device/my-device.vue
@@ -1,10 +1,15 @@
- 电量{{ power || 1 }}%
+ {{ power === null ? "电量--" : `电量${power}%` }}
diff --git a/src/static/device-assets/device-avatar.png b/src/static/device-assets/device-avatar.png
index 3d75f21..309eef3 100644
Binary files a/src/static/device-assets/device-avatar.png and b/src/static/device-assets/device-avatar.png differ
diff --git a/src/static/device-assets/device-bind-failure-hero.png b/src/static/device-assets/device-bind-failure-hero.png
index ca06f28..634fcff 100644
Binary files a/src/static/device-assets/device-bind-failure-hero.png and b/src/static/device-assets/device-bind-failure-hero.png differ
diff --git a/src/static/device-assets/device-bind-success-confetti.png b/src/static/device-assets/device-bind-success-confetti.png
index a43543f..df398ee 100644
Binary files a/src/static/device-assets/device-bind-success-confetti.png and b/src/static/device-assets/device-bind-success-confetti.png differ
diff --git a/src/static/device-assets/device-bind-success-hero-first.png b/src/static/device-assets/device-bind-success-hero-first.png
index b4d3d51..2fa5898 100644
Binary files a/src/static/device-assets/device-bind-success-hero-first.png and b/src/static/device-assets/device-bind-success-hero-first.png differ
diff --git a/src/static/device-assets/device-bind-success-hero-nonfirst.png b/src/static/device-assets/device-bind-success-hero-nonfirst.png
index c59cce5..b0ad3a9 100644
Binary files a/src/static/device-assets/device-bind-success-hero-nonfirst.png and b/src/static/device-assets/device-bind-success-hero-nonfirst.png differ
diff --git a/src/static/device-assets/device-bind-success-reward-gift.png b/src/static/device-assets/device-bind-success-reward-gift.png
index c949b62..83d619c 100644
Binary files a/src/static/device-assets/device-bind-success-reward-gift.png and b/src/static/device-assets/device-bind-success-reward-gift.png differ
diff --git a/src/static/device-assets/device-bind-success-title.png b/src/static/device-assets/device-bind-success-title.png
index 655b282..c12b0d7 100644
Binary files a/src/static/device-assets/device-bind-success-title.png and b/src/static/device-assets/device-bind-success-title.png differ
diff --git a/src/static/device-assets/device-help.png b/src/static/device-assets/device-help.png
index 6ce237f..8fe1879 100644
Binary files a/src/static/device-assets/device-help.png and b/src/static/device-assets/device-help.png differ
diff --git a/src/static/device-assets/device-qrcode.png b/src/static/device-assets/device-qrcode.png
index 16ccccd..e0bc225 100644
Binary files a/src/static/device-assets/device-qrcode.png and b/src/static/device-assets/device-qrcode.png differ
diff --git a/src/static/device-assets/my-device-avatar.png b/src/static/device-assets/my-device-avatar.png
index 3d75f21..309eef3 100644
Binary files a/src/static/device-assets/my-device-avatar.png and b/src/static/device-assets/my-device-avatar.png differ
diff --git a/src/static/device-assets/my-device-qrcode.png b/src/static/device-assets/my-device-qrcode.png
index 16ccccd..e0bc225 100644
Binary files a/src/static/device-assets/my-device-qrcode.png and b/src/static/device-assets/my-device-qrcode.png differ
diff --git a/src/static/device-assets/my-device-unbound-background.png b/src/static/device-assets/my-device-unbound-background.png
index 370aa1c..4222faf 100644
Binary files a/src/static/device-assets/my-device-unbound-background.png and b/src/static/device-assets/my-device-unbound-background.png differ
diff --git a/src/static/device-assets/my-device-unbound-help.png b/src/static/device-assets/my-device-unbound-help.png
index 6ce237f..8fe1879 100644
Binary files a/src/static/device-assets/my-device-unbound-help.png and b/src/static/device-assets/my-device-unbound-help.png differ
diff --git a/src/static/device-assets/my-device-unbound-product.png b/src/static/device-assets/my-device-unbound-product.png
index 830a936..c1335f2 100644
Binary files a/src/static/device-assets/my-device-unbound-product.png and b/src/static/device-assets/my-device-unbound-product.png differ
diff --git a/src/static/device-assets/my-device-unbound-qr-sample.png b/src/static/device-assets/my-device-unbound-qr-sample.png
index d51d824..42f85fa 100644
Binary files a/src/static/device-assets/my-device-unbound-qr-sample.png and b/src/static/device-assets/my-device-unbound-qr-sample.png differ
diff --git a/src/static/device-assets/my-device-unbound-scan.png b/src/static/device-assets/my-device-unbound-scan.png
index 55c0540..f3aeacc 100644
Binary files a/src/static/device-assets/my-device-unbound-scan.png and b/src/static/device-assets/my-device-unbound-scan.png differ
diff --git a/src/static/home-device/device-action-bg--bind.png b/src/static/home-device/device-action-bg--bind.png
index 80e0eba..021b20f 100644
Binary files a/src/static/home-device/device-action-bg--bind.png and b/src/static/home-device/device-action-bg--bind.png differ
diff --git a/src/static/home-device/device-action-wifi.png b/src/static/home-device/device-action-wifi.png
index 8a592b3..438927f 100644
Binary files a/src/static/home-device/device-action-wifi.png and b/src/static/home-device/device-action-wifi.png differ
diff --git a/src/static/home-device/device-bow--offline.png b/src/static/home-device/device-bow--offline.png
index 736c36e..411cf13 100644
Binary files a/src/static/home-device/device-bow--offline.png and b/src/static/home-device/device-bow--offline.png differ
diff --git a/src/static/home-device/device-bow--online.png b/src/static/home-device/device-bow--online.png
index 219d280..80109f5 100644
Binary files a/src/static/home-device/device-bow--online.png and b/src/static/home-device/device-bow--online.png differ
diff --git a/src/static/home-device/device-bow--unbound.png b/src/static/home-device/device-bow--unbound.png
index e914429..19ed666 100644
Binary files a/src/static/home-device/device-bow--unbound.png and b/src/static/home-device/device-bow--unbound.png differ
diff --git a/src/static/home-device/device-bow.png b/src/static/home-device/device-bow.png
index 2e2776d..c5b5db3 100644
Binary files a/src/static/home-device/device-bow.png and b/src/static/home-device/device-bow.png differ
diff --git a/src/static/home-device/device-card-bg--bound.png b/src/static/home-device/device-card-bg--bound.png
index c1c487e..1a8aa09 100644
Binary files a/src/static/home-device/device-card-bg--bound.png and b/src/static/home-device/device-card-bg--bound.png differ
diff --git a/src/static/home-device/device-card-bg--unbound.png b/src/static/home-device/device-card-bg--unbound.png
index 2f8eb8a..673c250 100644
Binary files a/src/static/home-device/device-card-bg--unbound.png and b/src/static/home-device/device-card-bg--unbound.png differ
diff --git a/src/static/home-device/device-edit.png b/src/static/home-device/device-edit.png
index 3de03f7..1ba518d 100644
Binary files a/src/static/home-device/device-edit.png and b/src/static/home-device/device-edit.png differ
diff --git a/src/static/home-device/device-id-hidden.png b/src/static/home-device/device-id-hidden.png
new file mode 100644
index 0000000..17eb29d
Binary files /dev/null and b/src/static/home-device/device-id-hidden.png differ
diff --git a/src/static/home-device/device-id-visibility.png b/src/static/home-device/device-id-visible.png
similarity index 100%
rename from src/static/home-device/device-id-visibility.png
rename to src/static/home-device/device-id-visible.png
diff --git a/src/static/home-device/device-name-confirm.png b/src/static/home-device/device-name-confirm.png
new file mode 100644
index 0000000..29d2e84
Binary files /dev/null and b/src/static/home-device/device-name-confirm.png differ
diff --git a/src/static/home-device/device-name-mascot.png b/src/static/home-device/device-name-mascot.png
new file mode 100644
index 0000000..8829e06
Binary files /dev/null and b/src/static/home-device/device-name-mascot.png differ
diff --git a/src/static/home-device/device-platform.png b/src/static/home-device/device-platform.png
index b7eb152..1f177ac 100644
Binary files a/src/static/home-device/device-platform.png and b/src/static/home-device/device-platform.png differ
diff --git a/src/static/home-device/device-state-battery.png b/src/static/home-device/device-state-battery.png
index 274b829..29bd1c7 100644
Binary files a/src/static/home-device/device-state-battery.png and b/src/static/home-device/device-state-battery.png differ
diff --git a/src/static/home-device/device-state-dot--offline.png b/src/static/home-device/device-state-dot--offline.png
index 32e32e7..30cc493 100644
Binary files a/src/static/home-device/device-state-dot--offline.png and b/src/static/home-device/device-state-dot--offline.png differ
diff --git a/src/static/home-device/device-state-dot--online.png b/src/static/home-device/device-state-dot--online.png
index 7d69c0f..96938f8 100644
Binary files a/src/static/home-device/device-state-dot--online.png and b/src/static/home-device/device-state-dot--online.png differ
diff --git a/src/static/home-device/device-state-refresh.png b/src/static/home-device/device-state-refresh.png
index 7957a13..9dd1d7b 100644
Binary files a/src/static/home-device/device-state-refresh.png and b/src/static/home-device/device-state-refresh.png differ
diff --git a/src/static/home-device/device-unbind.png b/src/static/home-device/device-unbind.png
index bc8d472..fe5823e 100644
Binary files a/src/static/home-device/device-unbind.png and b/src/static/home-device/device-unbind.png differ
diff --git a/src/store.js b/src/store.js
index 6df144b..6e0599f 100644
--- a/src/store.js
+++ b/src/store.js
@@ -17,6 +17,15 @@ const getDefaultDevice = () => ({
deviceName: "",
});
+const getDefaultDeviceStatus = () => ({
+ battery: null,
+ version: "",
+ online: false,
+ netType: "",
+ onlineDuration: null,
+ receivedAt: 0,
+});
+
const getDefaultGame = () => ({
roomID: "",
inBattle: false,
@@ -102,6 +111,8 @@ export default defineStore("store", {
online: false,
// 设备电量属于运行时状态,null 表示当前没有有效数据。
deviceBattery: null,
+ // WebSocket 实时推送的设备状态,不参与持久化。
+ deviceStatus: getDefaultDeviceStatus(),
game: {
roomID: "",
inBattle: false,
@@ -136,7 +147,7 @@ export default defineStore("store", {
this.rankData = { ...(data || {}) };
},
updateOnline(online) {
- this.online = online;
+ this.setDeviceOnline(online);
},
updateDeviceBattery(value) {
if (value === null || value === undefined || value === "") {
@@ -149,6 +160,43 @@ export default defineStore("store", {
? Math.min(100, Math.max(0, battery))
: null;
},
+ updateDeviceStatus(status = {}) {
+ const battery = Number(status.battery ?? status.power);
+ const onlineDuration = Number(status.onlineDuration);
+ const online = status.online === true;
+ const nextStatus = {
+ battery: Number.isFinite(battery)
+ ? Math.min(100, Math.max(0, battery))
+ : null,
+ version: String(status.version ?? "").trim(),
+ online,
+ netType: String(status.netType ?? "").trim().toLowerCase(),
+ onlineDuration:
+ Number.isFinite(onlineDuration) && onlineDuration >= 0
+ ? onlineDuration
+ : null,
+ receivedAt: Date.now(),
+ };
+
+ this.deviceStatus = nextStatus;
+ this.online = online;
+ this.deviceBattery = online ? nextStatus.battery : null;
+ },
+ setDeviceOnline(online) {
+ const nextOnline = online === true;
+ this.online = nextOnline;
+ if (nextOnline) {
+ this.deviceStatus = { ...this.deviceStatus, online: true };
+ return;
+ }
+ this.deviceBattery = null;
+ this.deviceStatus = getDefaultDeviceStatus();
+ },
+ clearDeviceStatus() {
+ this.online = false;
+ this.deviceBattery = null;
+ this.deviceStatus = getDefaultDeviceStatus();
+ },
async updateUser(user = {}) {
this.user = { ...getDefaultUser(), ...user };
this.user.lvlName = getLvlNameByScore(this.user.scores, this.config.randInfos)
@@ -158,13 +206,15 @@ export default defineStore("store", {
);
},
updateDevice(deviceId, deviceName) {
+ if (String(this.device.deviceId || "") !== String(deviceId || "")) {
+ this.clearDeviceStatus();
+ }
this.device.deviceId = deviceId;
this.device.deviceName = deviceName;
},
clearDevice() {
this.device = getDefaultDevice();
- this.online = false;
- this.deviceBattery = null;
+ this.clearDeviceStatus();
},
async updateConfig(config) {
this.config = config;
@@ -214,6 +264,7 @@ export default defineStore("store", {
device: getDefaultDevice(),
online: false,
deviceBattery: null,
+ deviceStatus: getDefaultDeviceStatus(),
game: getDefaultGame(),
dailyCount: getDefaultDailyCount(),
deviceChargingDialogVisible: false,
diff --git a/src/websocket.js b/src/websocket.js
index 9a1902a..34be35a 100644
--- a/src/websocket.js
+++ b/src/websocket.js
@@ -77,17 +77,33 @@ function createWebSocket(token, onMessage) {
socketTask.onMessage((res) => {
if (socket !== socketTask) return;
- const { data, event } = JSON.parse(res.data);
+ let response;
+ try {
+ response = JSON.parse(res.data);
+ } catch (err) {
+ console.error("WebSocket 消息解析失败", err);
+ return;
+ }
+
+ const { data, event, code, timestamp } = response || {};
if (event === "pong") return;
- if (data.type) {
+ if (event === "/addons/shoot/battery") {
+ if ((code == null || Number(code) === 0) && onMessage && data && typeof data === "object") {
+ onMessage({ event, data, code, timestamp });
+ }
+ return;
+ }
+ if (data?.type) {
if (ENABLE_REALTIME_MESSAGE_LOG) {
console.log("收到 WebSocket 消息", getMessageTypeName(data.type));
}
if (onMessage) onMessage({ ...(data.data || {}), type: data.type });
return;
}
- if (onMessage && data.updates) onMessage(data.updates);
- const msg = data.updates[0];
+ const updates = Array.isArray(data?.updates) ? data.updates : [];
+ if (!updates.length) return;
+ if (onMessage) onMessage(updates);
+ const msg = updates[0];
if (msg) {
if (ENABLE_REALTIME_MESSAGE_LOG) {
console.log(
@@ -101,9 +117,9 @@ function createWebSocket(token, onMessage) {
} else if (msg.constructor === MESSAGETYPES.LvlUpdate) {
uni.setStorageSync("latestLvl", msg.lvl);
} else if (msg.constructor === MESSAGETYPES.DeviceOnline) {
- uni.$emit("update-online");
+ uni.$emit("update-online", true);
} else if (msg.constructor === MESSAGETYPES.DeviceOffline) {
- uni.$emit("update-online");
+ uni.$emit("update-online", false);
} else if (msg.constructor === MESSAGETYPES.DeviceCharging) {
uni.$emit("device-charging");
}
@@ -121,6 +137,7 @@ function createWebSocket(token, onMessage) {
stopHeartbeat();
socket = null;
isConnecting = false;
+ uni.$emit("shoot-socket-disconnected");
if (manualClose || kickedOut) return;
await handleUnexpectedClose(onMessage);