diff --git a/src/App.vue b/src/App.vue index 4e6d0d8..738dbbb 100644 --- a/src/App.vue +++ b/src/App.vue @@ -28,6 +28,7 @@ const { updateUser, updateOnline, + updateDeviceBattery, showDeviceChargingDialog, clearSessionState, clearDevice @@ -74,6 +75,7 @@ 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 ? "设备已连接" : "设备连接已断开"); } diff --git a/src/apis.js b/src/apis.js index 6bf5715..837ddd2 100644 --- a/src/apis.js +++ b/src/apis.js @@ -281,6 +281,10 @@ export const getMyDevicesAPI = () => { return request("GET", "/user/device/getBindings"); }; +export const getDeviceDetailAPI = (deviceId) => { + return request("GET", `/user/device/getDetail?deviceId=${encodeURIComponent(deviceId)}`); +}; + export const createPractiseAPI = (arrows, time, target) => { return request("POST", "/user/practice/create", { shootNumber: arrows, diff --git a/src/components/AppBackground.vue b/src/components/AppBackground.vue index 7feadea..94391f8 100644 --- a/src/components/AppBackground.vue +++ b/src/components/AppBackground.vue @@ -81,6 +81,13 @@ const props = defineProps({ src="https://static.shelingxingqiu.com/shootmini/static/app-bg9.png" mode="widthFix" /> + + { const goCalibration = async () => { await laserAimAPI(); uni.navigateTo({ - url: "/pages/calibration", + url: "/pages/device/calibration", }); }; diff --git a/src/pages.json b/src/pages.json index 524b208..36393ba 100644 --- a/src/pages.json +++ b/src/pages.json @@ -21,9 +21,6 @@ { "path": "pages/audio-test" }, - { - "path": "pages/calibration" - }, { "path": "pages/about-us" }, @@ -60,12 +57,6 @@ { "path": "pages/match-page" }, - { - "path": "pages/my-device" - }, - { - "path": "pages/device-intro" - }, { "path": "pages/user" }, @@ -105,16 +96,10 @@ { "path": "pages/melee-bow-data" }, - { - "path": "pages/mine-bow-data" - }, - { - "path": "pages/ota-wifi", - "style": { - "navigationStyle": "custom" - } - } - ], + { + "path": "pages/mine-bow-data" + } + ], "globalStyle": { "backgroundColor": "@bgColor", "backgroundColorBottom": "@bgColorBottom", @@ -159,6 +144,27 @@ { "root": "pages/device", "pages": [ + { + "path": "my-device" + }, + { + "path": "device-bind-success" + }, + { + "path": "device-bind-failure" + }, + { + "path": "device-intro" + }, + { + "path": "ota-wifi", + "style": { + "navigationStyle": "custom" + } + }, + { + "path": "calibration" + }, { "path": "unbind-device" } diff --git a/src/pages/calibration.vue b/src/pages/device/calibration.vue similarity index 100% rename from src/pages/calibration.vue rename to src/pages/device/calibration.vue diff --git a/src/pages/device/composables/useDeviceBinding.js b/src/pages/device/composables/useDeviceBinding.js new file mode 100644 index 0000000..568f555 --- /dev/null +++ b/src/pages/device/composables/useDeviceBinding.js @@ -0,0 +1,88 @@ +import { bindDeviceAPIV2 } from "@/apis"; + +export function useDeviceBinding({ + token, + confirmBindTip, + binding, + updateDevice, + deviceDetails, + refreshDeviceStatus, +}) { + const showBindFailurePage = () => { + uni.hideToast(); + uni.navigateTo({ + url: "/pages/device/device-bind-failure", + fail: (error) => { + console.error("打开绑定失败页失败", error); + uni.showToast({ title: "二维码不正确,请重新扫码", icon: "none" }); + }, + }); + }; + + const handleScan = () => { + uni.scanCode({ + onlyFromCamera: true, + scanType: ["qrCode"], + success: (result) => { + if (!result?.result) { + showBindFailurePage(); + return; + } + token.value = result.result; + confirmBindTip.value = true; + }, + fail: (error) => { + const message = String(error?.errMsg || error?.message || ""); + if (/cancel|取消/i.test(message)) return; + showBindFailurePage(); + }, + }); + }; + + const confirmBind = async () => { + if (!token.value || binding.value) return; + binding.value = true; + try { + const result = await bindDeviceAPIV2(token.value); + confirmBindTip.value = false; + if (result?.binded) { + uni.showToast({ + title: "设备已绑定其他账号,请解绑后再绑定", + icon: "none", + }); + return; + } + const deviceId = String(result?.deviceId || "").trim(); + const deviceName = String(result?.name || result?.deviceName || "").trim(); + if (!deviceId || !deviceName) { + confirmBindTip.value = false; + token.value = ""; + showBindFailurePage(); + return; + } + const applyBoundDevice = () => { + updateDevice(deviceId, deviceName); + deviceDetails.value = result || {}; + void refreshDeviceStatus(); + }; + uni.navigateTo({ + url: `/pages/device/device-bind-success?deviceId=${encodeURIComponent(deviceId)}`, + success: applyBoundDevice, + fail: (navigationError) => { + applyBoundDevice(); + console.error("打开绑定成功页失败", navigationError); + uni.showToast({ title: "绑定成功,请返回查看设备", icon: "none" }); + }, + }); + } catch (error) { + console.error("绑定设备失败", error); + confirmBindTip.value = false; + token.value = ""; + showBindFailurePage(); + } finally { + binding.value = false; + } + }; + + return { confirmBind, handleScan, showBindFailurePage }; +} diff --git a/src/pages/device/composables/useDeviceStatus.js b/src/pages/device/composables/useDeviceStatus.js new file mode 100644 index 0000000..bea7bb2 --- /dev/null +++ b/src/pages/device/composables/useDeviceStatus.js @@ -0,0 +1,129 @@ +import { computed, ref } from "vue"; +import { getDeviceBatteryAPI, getMyDevicesAPI, unbindDeviceAPI } from "@/apis"; + +export const DEVICE_NAME_STORAGE_KEY = "device_name_overrides"; + +export function useDeviceStatus({ + user, + device, + online, + updateDevice, + updateOnline, + clearDevice, + unbindDialogVisible, +}) { + const deviceStatus = ref({}); + const deviceDetails = ref({}); + + const isDeviceOnline = computed( + () => deviceStatus.value.online === true || online.value === true + ); + const statusText = computed(() => (isDeviceOnline.value ? "已连接" : "未连接")); + const statusClass = computed(() => + isDeviceOnline.value ? "device-status--online" : "device-status--offline" + ); + const battery = computed(() => { + const value = Number( + deviceStatus.value.battery ?? deviceStatus.value.power ?? 0 + ); + return Number.isFinite(value) && value > 0 ? Math.min(100, value) : 0; + }); + const batteryText = computed(() => + battery.value ? `${battery.value}%` : "暂无数据" + ); + const networkText = computed(() => { + const netType = String(deviceStatus.value.netType || "").toLowerCase(); + if (netType === "wifi") return "WiFi"; + if (netType === "4g") return "4G"; + return isDeviceOnline.value ? "在线" : "未连接"; + }); + const maskedDeviceId = computed(() => { + const id = String(device.value.deviceId || ""); + if (!id) return "暂无设备编号"; + if (id.length <= 3) return id; + return `${"*".repeat(Math.min(5, id.length - 3))}${id.slice(-3)}`; + }); + const deviceRows = computed(() => [ + { label: "设备型号", value: deviceDetails.value.model || "射灵智能弓" }, + { label: "当前电量", value: batteryText.value }, + { label: "连接方式", value: networkText.value }, + { label: "设备编号", value: maskedDeviceId.value }, + ]); + + const getDeviceNameOverrides = () => { + const value = uni.getStorageSync(DEVICE_NAME_STORAGE_KEY); + return value && typeof value === "object" ? value : {}; + }; + + const refreshDeviceStatus = async () => { + if (!device.value.deviceId) return; + try { + const result = await getDeviceBatteryAPI(); + deviceStatus.value = result || {}; + updateOnline(result?.online === true); + } catch (error) { + deviceStatus.value = {}; + console.log("获取设备状态失败", error); + } + }; + + const syncDeviceBinding = async () => { + if (!user.value.id) return; + try { + const devices = await getMyDevicesAPI(); + if (Array.isArray(devices?.bindings) && devices.bindings.length > 0) { + const currentDevice = devices.bindings[0]; + const nameOverrides = getDeviceNameOverrides(); + deviceDetails.value = currentDevice; + updateDevice( + currentDevice.deviceId, + nameOverrides[currentDevice.deviceId] || + currentDevice.deviceName || + currentDevice.name || + "我的智能弓" + ); + await refreshDeviceStatus(); + return; + } + clearDevice(); + deviceStatus.value = {}; + deviceDetails.value = {}; + } catch (error) { + console.log("同步设备绑定失败", error); + } + }; + + const unbindDevice = async () => { + if (!device.value.deviceId) return; + try { + await unbindDeviceAPI(device.value.deviceId); + uni.setStorageSync("calibration", false); + clearDevice(); + deviceStatus.value = {}; + deviceDetails.value = {}; + unbindDialogVisible.value = false; + uni.showToast({ title: "解绑成功", icon: "success" }); + } catch (error) { + console.error("解绑设备失败", error); + if (error?.type === "DEVICE_BIND_INVALID") { + clearDevice(); + unbindDialogVisible.value = false; + } + } + }; + + return { + batteryText, + deviceDetails, + deviceRows, + getDeviceNameOverrides, + isDeviceOnline, + maskedDeviceId, + networkText, + refreshDeviceStatus, + statusClass, + statusText, + syncDeviceBinding, + unbindDevice, + }; +} diff --git a/src/pages/device/device-bind-failure.vue b/src/pages/device/device-bind-failure.vue new file mode 100644 index 0000000..ccfcb12 --- /dev/null +++ b/src/pages/device/device-bind-failure.vue @@ -0,0 +1,156 @@ + + + + + diff --git a/src/pages/device/device-bind-success.vue b/src/pages/device/device-bind-success.vue new file mode 100644 index 0000000..680334c --- /dev/null +++ b/src/pages/device/device-bind-success.vue @@ -0,0 +1,248 @@ + + + + + diff --git a/src/pages/device-intro.vue b/src/pages/device/device-intro.vue similarity index 96% rename from src/pages/device-intro.vue rename to src/pages/device/device-intro.vue index f780e14..9053872 100644 --- a/src/pages/device-intro.vue +++ b/src/pages/device/device-intro.vue @@ -38,7 +38,7 @@ const onScrollView = (e) => { mode="widthFix" /> - + +import { computed, onMounted, onUnmounted, ref } from "vue"; +import { onLoad, onShow } from "@dcloudio/uni-app"; +import Container from "@/components/Container.vue"; +import ScreenHint from "@/components/ScreenHint.vue"; +import ModalDialog from "@/components/ModalDialog.vue"; +import { laserAimAPI } from "@/apis"; +import useStore from "@/store"; +import { storeToRefs } from "pinia"; +import { useDeviceBinding } from "./composables/useDeviceBinding"; +import { + DEVICE_NAME_STORAGE_KEY, + useDeviceStatus, +} from "./composables/useDeviceStatus"; + +const store = useStore(); +const { updateDevice, updateOnline, clearDevice } = store; +const { user, device, online } = storeToRefs(store); + +const showTip = ref(false); +const confirmBindTip = ref(false); +const unbindDialogVisible = ref(false); +const nameEditorVisible = ref(false); +const qrVisible = ref(false); +const qrSaved = ref(false); +const editingName = ref(""); +const token = ref(""); +const binding = ref(false); +const retryScanOnShow = ref(false); +const calibration = ref(false); + +const { + deviceDetails, + deviceRows, + getDeviceNameOverrides, + isDeviceOnline, + maskedDeviceId, + refreshDeviceStatus, + statusClass, + statusText, + syncDeviceBinding, + unbindDevice, +} = useDeviceStatus({ + user, + device, + online, + updateDevice, + updateOnline, + clearDevice, + unbindDialogVisible, +}); + +const { confirmBind, handleScan } = useDeviceBinding({ + token, + confirmBindTip, + binding, + updateDevice, + deviceDetails, + refreshDeviceStatus, +}); + +const qrImageUrl = computed( + () => + deviceDetails.value.qrCode || + deviceDetails.value.qrcode || + deviceDetails.value.qrUrl || + "../../static/device-assets/my-device-qrcode.png" +); +const isScanPage = computed(() => !device.value.deviceId && !qrVisible.value); +const containerBgType = computed(() => + isScanPage.value ? 12 : 0 +); +const containerBgColor = computed(() => + containerBgType.value === 12 || containerBgType.value === -1 + ? "transparent" + : "#050b19" +); + +// 解绑前展示统一确认弹窗,避免误触解除绑定。 +const openUnbindDialog = () => { + unbindDialogVisible.value = true; +}; + +const closeUnbindDialog = () => { + unbindDialogVisible.value = false; +}; + +const openNameEditor = () => { + editingName.value = device.value.deviceName || "我的智能弓"; + nameEditorVisible.value = true; +}; + +const closeNameEditor = () => { + nameEditorVisible.value = false; +}; + +// 当前接口列表没有设备改名接口,先更新页面和本地缓存,后端接口接入时可替换为请求。 +const confirmName = () => { + const name = String(editingName.value || "").trim(); + if (!name) { + uni.showToast({ title: "请输入设备名", icon: "none" }); + return; + } + if (name.length > 10 || !/^[\u4e00-\u9fa5A-Za-z0-9_-]+$/.test(name)) { + uni.showToast({ title: "设备名格式不正确", icon: "none" }); + return; + } + updateDevice(device.value.deviceId, name); + deviceDetails.value = { ...deviceDetails.value, deviceName: name }; + const nameOverrides = getDeviceNameOverrides(); + nameOverrides[device.value.deviceId] = name; + uni.setStorageSync(DEVICE_NAME_STORAGE_KEY, nameOverrides); + nameEditorVisible.value = false; + uni.showToast({ title: "设备名已更新", icon: "success" }); +}; + +const toDeviceIntroPage = () => { + uni.navigateTo({ url: "/pages/device/device-intro" }); +}; + +const joinWifi = () => { + uni.navigateTo({ url: "/pages/device/ota-wifi" }); +}; + +const goFirmwareUpdate = () => { + if (!isDeviceOnline.value) { + uni.showToast({ title: "请先开启智能弓", icon: "none" }); + return; + } + uni.navigateTo({ url: "/pages/device/ota-wifi" }); +}; + +const goCalibration = async () => { + try { + await laserAimAPI(); + uni.navigateTo({ url: "/pages/device/calibration" }); + } catch (error) { + uni.showToast({ title: "设备未连接,暂时无法调瞄", icon: "none" }); + } +}; + +const copyEmail = () => { + uni.setClipboardData({ + data: "shelingxingqiu@163.com", + success: () => uni.showToast({ title: "邮箱已复制", icon: "success" }), + }); +}; + +const openQr = () => { + qrSaved.value = false; + qrVisible.value = true; +}; + +const closeTip = () => { + showTip.value = false; +}; + +const closeConfirmBindTip = () => { + confirmBindTip.value = false; +}; + +const closeQr = () => { + qrVisible.value = false; +}; + +// 保存二维码到相册;远程二维码先下载到临时目录,失败时保留长按保存提示。 +const saveQrCode = async () => { + let filePath = qrImageUrl.value; + try { + if (/^https?:\/\//.test(filePath)) { + filePath = await new Promise((resolve, reject) => { + uni.downloadFile({ + url: filePath, + success: (result) => + result.statusCode === 200 + ? resolve(result.tempFilePath) + : reject(new Error("二维码下载失败")), + fail: reject, + }); + }); + } + await new Promise((resolve, reject) => { + uni.saveImageToPhotosAlbum({ success: resolve, fail: reject, filePath }); + }); + qrSaved.value = true; + uni.showToast({ title: "已保存至相册", icon: "success" }); + } catch (error) { + uni.showToast({ title: "请长按二维码保存", icon: "none" }); + } +}; + +onLoad((options = {}) => { + retryScanOnShow.value = options.retryScan === "1"; +}); + +onMounted(() => { + uni.$on("device-bind-retry-scan", handleScan); +}); + +onUnmounted(() => { + uni.$off("device-bind-retry-scan", handleScan); +}); + +onShow(async () => { + calibration.value = uni.getStorageSync("calibration"); + await syncDeviceBinding(); + if (retryScanOnShow.value) { + retryScanOnShow.value = false; + handleScan(); + } +}); + + + + + diff --git a/src/pages/ota-wifi.vue b/src/pages/device/ota-wifi.vue similarity index 96% rename from src/pages/ota-wifi.vue rename to src/pages/device/ota-wifi.vue index 9a8e9b7..245597f 100644 --- a/src/pages/ota-wifi.vue +++ b/src/pages/device/ota-wifi.vue @@ -1,4 +1,4 @@ - - - - - diff --git a/src/pages/team-battle/components/Container.vue b/src/pages/team-battle/components/Container.vue index f6ffeda..0b6d016 100644 --- a/src/pages/team-battle/components/Container.vue +++ b/src/pages/team-battle/components/Container.vue @@ -111,7 +111,7 @@ const cancelMatching = async () => { const goCalibration = async () => { await laserAimAPI(); uni.navigateTo({ - url: "/pages/calibration", + url: "/pages/device/calibration", }); }; diff --git a/src/static/device-assets/device-avatar.png b/src/static/device-assets/device-avatar.png new file mode 100644 index 0000000..3d75f21 Binary files /dev/null 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 new file mode 100644 index 0000000..ca06f28 Binary files /dev/null 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 new file mode 100644 index 0000000..a43543f Binary files /dev/null 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 new file mode 100644 index 0000000..b4d3d51 Binary files /dev/null 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 new file mode 100644 index 0000000..c59cce5 Binary files /dev/null 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 new file mode 100644 index 0000000..c949b62 Binary files /dev/null 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 new file mode 100644 index 0000000..655b282 Binary files /dev/null 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 new file mode 100644 index 0000000..6ce237f Binary files /dev/null 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 new file mode 100644 index 0000000..16ccccd Binary files /dev/null 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 new file mode 100644 index 0000000..3d75f21 Binary files /dev/null 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 new file mode 100644 index 0000000..16ccccd Binary files /dev/null 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 new file mode 100644 index 0000000..370aa1c Binary files /dev/null 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 new file mode 100644 index 0000000..6ce237f Binary files /dev/null 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 new file mode 100644 index 0000000..830a936 Binary files /dev/null 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 new file mode 100644 index 0000000..d51d824 Binary files /dev/null and b/src/static/device-assets/my-device-unbound-qr-sample.png differ diff --git a/src/static/device-assets/my-device-unbound-scan-tip.png b/src/static/device-assets/my-device-unbound-scan-tip.png new file mode 100644 index 0000000..d5d0f65 Binary files /dev/null and b/src/static/device-assets/my-device-unbound-scan-tip.png differ diff --git a/src/static/device-assets/my-device-unbound-scan.png b/src/static/device-assets/my-device-unbound-scan.png new file mode 100644 index 0000000..55c0540 Binary files /dev/null and b/src/static/device-assets/my-device-unbound-scan.png differ diff --git a/src/static/device-assets/ota-bind-success.png b/src/static/device-assets/ota-bind-success.png new file mode 100644 index 0000000..aa95e5e Binary files /dev/null and b/src/static/device-assets/ota-bind-success.png differ diff --git a/src/static/device-assets/ota-bind.png b/src/static/device-assets/ota-bind.png new file mode 100644 index 0000000..a925a26 Binary files /dev/null and b/src/static/device-assets/ota-bind.png differ diff --git a/src/static/device-assets/ota-calibration-tip.png b/src/static/device-assets/ota-calibration-tip.png new file mode 100644 index 0000000..d5d0f65 Binary files /dev/null and b/src/static/device-assets/ota-calibration-tip.png differ diff --git a/src/static/device-assets/ota-device-icon.png b/src/static/device-assets/ota-device-icon.png new file mode 100644 index 0000000..3d75f21 Binary files /dev/null and b/src/static/device-assets/ota-device-icon.png differ diff --git a/src/static/device-assets/ota-enter-arrow-blue.png b/src/static/device-assets/ota-enter-arrow-blue.png new file mode 100644 index 0000000..18ed17d Binary files /dev/null and b/src/static/device-assets/ota-enter-arrow-blue.png differ diff --git a/src/static/device-assets/ota-no-device.png b/src/static/device-assets/ota-no-device.png new file mode 100644 index 0000000..830a936 Binary files /dev/null and b/src/static/device-assets/ota-no-device.png differ diff --git a/src/static/device-assets/ota-scan-tip.png b/src/static/device-assets/ota-scan-tip.png new file mode 100644 index 0000000..d5d0f65 Binary files /dev/null and b/src/static/device-assets/ota-scan-tip.png differ diff --git a/src/static/device-assets/ota-scan.png b/src/static/device-assets/ota-scan.png new file mode 100644 index 0000000..55c0540 Binary files /dev/null and b/src/static/device-assets/ota-scan.png differ diff --git a/src/static/device-assets/ota-user-icon.png b/src/static/device-assets/ota-user-icon.png new file mode 100644 index 0000000..1d4350c Binary files /dev/null and b/src/static/device-assets/ota-user-icon.png differ diff --git a/src/static/home-device/device-action-bg--bind.png b/src/static/home-device/device-action-bg--bind.png new file mode 100644 index 0000000..80e0eba Binary files /dev/null and b/src/static/home-device/device-action-bg--bind.png differ diff --git a/src/static/home-device/device-action-bg--device.png b/src/static/home-device/device-action-bg--device.png new file mode 100644 index 0000000..5e8da2e Binary files /dev/null and b/src/static/home-device/device-action-bg--device.png differ diff --git a/src/static/home-device/device-action-bind-icon.png b/src/static/home-device/device-action-bind-icon.png new file mode 100644 index 0000000..6777f33 Binary files /dev/null and b/src/static/home-device/device-action-bind-icon.png differ diff --git a/src/static/home-device/device-bow--offline.png b/src/static/home-device/device-bow--offline.png new file mode 100644 index 0000000..736c36e Binary files /dev/null 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 new file mode 100644 index 0000000..219d280 Binary files /dev/null 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 new file mode 100644 index 0000000..e914429 Binary files /dev/null and b/src/static/home-device/device-bow--unbound.png differ diff --git a/src/static/home-device/device-card-bg--bound.png b/src/static/home-device/device-card-bg--bound.png new file mode 100644 index 0000000..c1c487e Binary files /dev/null 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 new file mode 100644 index 0000000..2f8eb8a Binary files /dev/null and b/src/static/home-device/device-card-bg--unbound.png differ diff --git a/src/static/home-device/device-state-battery.png b/src/static/home-device/device-state-battery.png new file mode 100644 index 0000000..274b829 Binary files /dev/null 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 new file mode 100644 index 0000000..32e32e7 Binary files /dev/null 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 new file mode 100644 index 0000000..7d69c0f Binary files /dev/null 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 new file mode 100644 index 0000000..7957a13 Binary files /dev/null and b/src/static/home-device/device-state-refresh.png differ diff --git a/src/store.js b/src/store.js index a348202..6df144b 100644 --- a/src/store.js +++ b/src/store.js @@ -100,6 +100,8 @@ export default defineStore("store", { ringRank: [], }, online: false, + // 设备电量属于运行时状态,null 表示当前没有有效数据。 + deviceBattery: null, game: { roomID: "", inBattle: false, @@ -136,6 +138,17 @@ export default defineStore("store", { updateOnline(online) { this.online = online; }, + updateDeviceBattery(value) { + if (value === null || value === undefined || value === "") { + this.deviceBattery = null; + return; + } + + const battery = Number(value); + this.deviceBattery = Number.isFinite(battery) + ? Math.min(100, Math.max(0, battery)) + : null; + }, async updateUser(user = {}) { this.user = { ...getDefaultUser(), ...user }; this.user.lvlName = getLvlNameByScore(this.user.scores, this.config.randInfos) @@ -151,6 +164,7 @@ export default defineStore("store", { clearDevice() { this.device = getDefaultDevice(); this.online = false; + this.deviceBattery = null; }, async updateConfig(config) { this.config = config; @@ -199,6 +213,7 @@ export default defineStore("store", { user: getDefaultUser(), device: getDefaultDevice(), online: false, + deviceBattery: null, game: getDefaultGame(), dailyCount: getDefaultDailyCount(), deviceChargingDialogVisible: false,