update:修复bug
This commit is contained in:
@@ -11,8 +11,10 @@ export function useDeviceStatus({
|
|||||||
user,
|
user,
|
||||||
device,
|
device,
|
||||||
deviceStatus,
|
deviceStatus,
|
||||||
|
deviceUsageDuration,
|
||||||
online,
|
online,
|
||||||
updateDevice,
|
updateDevice,
|
||||||
|
updateDeviceUsageDuration,
|
||||||
clearDevice,
|
clearDevice,
|
||||||
unbindDialogVisible,
|
unbindDialogVisible,
|
||||||
}) {
|
}) {
|
||||||
@@ -41,14 +43,28 @@ export function useDeviceStatus({
|
|||||||
const batteryText = computed(() =>
|
const batteryText = computed(() =>
|
||||||
battery.value === null ? "暂无数据" : `${battery.value}%`
|
battery.value === null ? "暂无数据" : `${battery.value}%`
|
||||||
);
|
);
|
||||||
|
const normalizeDuration = (value) => {
|
||||||
|
if (value == null || String(value).trim() === "") return null;
|
||||||
|
const seconds = Number(value);
|
||||||
|
return Number.isFinite(seconds) && seconds >= 0 ? seconds : null;
|
||||||
|
};
|
||||||
|
|
||||||
const onlineDurationText = computed(() => {
|
const onlineDurationText = computed(() => {
|
||||||
const rawDuration = deviceStatus.value.onlineDuration;
|
const currentDeviceId = String(device.value.deviceId || "");
|
||||||
if (rawDuration == null || String(rawDuration).trim() === "") return "--";
|
const cachedDuration =
|
||||||
|
String(deviceUsageDuration.value.deviceId || "") === currentDeviceId
|
||||||
|
? normalizeDuration(deviceUsageDuration.value.seconds)
|
||||||
|
: null;
|
||||||
|
const durations = [
|
||||||
|
normalizeDuration(deviceStatus.value.onlineDuration),
|
||||||
|
normalizeDuration(deviceDetails.value.onlineDuration),
|
||||||
|
cachedDuration,
|
||||||
|
].filter((value) => value !== null);
|
||||||
|
|
||||||
const seconds = Number(rawDuration);
|
if (!durations.length) return "--";
|
||||||
if (!Number.isFinite(seconds) || seconds < 0) return "--";
|
const seconds = Math.max(...durations);
|
||||||
|
|
||||||
// WS 推送秒数,页面按完整分钟展示累计使用时间。
|
// 累计时长应单调递增,页面按完整分钟展示当前已知最大值。
|
||||||
const totalMinutes = Math.floor(seconds / 60);
|
const totalMinutes = Math.floor(seconds / 60);
|
||||||
const hours = Math.floor(totalMinutes / 60);
|
const hours = Math.floor(totalMinutes / 60);
|
||||||
const minutes = totalMinutes % 60;
|
const minutes = totalMinutes % 60;
|
||||||
@@ -109,6 +125,7 @@ export function useDeviceStatus({
|
|||||||
detail.qrCodeUrl ?? deviceDetails.value.qrCodeUrl ?? ""
|
detail.qrCodeUrl ?? deviceDetails.value.qrCodeUrl ?? ""
|
||||||
).trim(),
|
).trim(),
|
||||||
};
|
};
|
||||||
|
updateDeviceUsageDuration(detail.onlineDuration, deviceId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 实时刷新失败时保留当前页面数据,等待下次通知或页面重新显示。
|
// 实时刷新失败时保留当前页面数据,等待下次通知或页面重新显示。
|
||||||
console.log("刷新设备详情失败", error);
|
console.log("刷新设备详情失败", error);
|
||||||
@@ -158,6 +175,7 @@ export function useDeviceStatus({
|
|||||||
latestDevice.name ||
|
latestDevice.name ||
|
||||||
"我的智能弓"
|
"我的智能弓"
|
||||||
);
|
);
|
||||||
|
updateDeviceUsageDuration(latestDevice.onlineDuration, latestDevice.deviceId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
clearDevice();
|
clearDevice();
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ import {
|
|||||||
import { useOtaUpdate } from "@/composables/useOtaUpdate";
|
import { useOtaUpdate } from "@/composables/useOtaUpdate";
|
||||||
|
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
const { updateDevice, clearDevice } = store;
|
const { updateDevice, updateDeviceUsageDuration, clearDevice } = store;
|
||||||
const { user, device, deviceStatus, online } = storeToRefs(store);
|
const { user, device, deviceStatus, deviceUsageDuration, online } = storeToRefs(store);
|
||||||
const DEVICE_NAME_MAX_LENGTH = 10;
|
const DEVICE_NAME_MAX_LENGTH = 10;
|
||||||
|
|
||||||
const formatBindingDate = (value) => {
|
const formatBindingDate = (value) => {
|
||||||
@@ -97,8 +97,10 @@ const {
|
|||||||
user,
|
user,
|
||||||
device,
|
device,
|
||||||
deviceStatus,
|
deviceStatus,
|
||||||
|
deviceUsageDuration,
|
||||||
online,
|
online,
|
||||||
updateDevice,
|
updateDevice,
|
||||||
|
updateDeviceUsageDuration,
|
||||||
clearDevice,
|
clearDevice,
|
||||||
unbindDialogVisible,
|
unbindDialogVisible,
|
||||||
});
|
});
|
||||||
@@ -112,6 +114,28 @@ const bindingDateText = computed(() =>
|
|||||||
formatBindingDate(deviceDetails.value.bindTime)
|
formatBindingDate(deviceDetails.value.bindTime)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 固件版本统一以大写 V 开头,避免接口返回格式不一致影响弹窗展示。
|
||||||
|
const formatFirmwareVersion = (value) => {
|
||||||
|
const version = String(value ?? "").trim();
|
||||||
|
if (!version) return "";
|
||||||
|
return /^v/i.test(version) ? `V${version.slice(1)}` : `V${version}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const firmwareConfirmContent = computed(() => {
|
||||||
|
const currentVersion = formatFirmwareVersion(deviceStatus.value.version);
|
||||||
|
const latestVersion = formatFirmwareVersion(
|
||||||
|
pendingOtaInfo.value?.versionNumber
|
||||||
|
);
|
||||||
|
|
||||||
|
if (currentVersion && latestVersion) {
|
||||||
|
return `当前固件版本为 ${currentVersion},发现新固件版本 ${latestVersion},是否立即更新固件?`;
|
||||||
|
}
|
||||||
|
if (latestVersion) {
|
||||||
|
return `发现新固件版本 ${latestVersion},是否立即更新固件?`;
|
||||||
|
}
|
||||||
|
return "发现新固件版本,是否立即更新固件?";
|
||||||
|
});
|
||||||
|
|
||||||
const deviceIdText = computed(() =>
|
const deviceIdText = computed(() =>
|
||||||
showDeviceId.value && device.value.deviceName
|
showDeviceId.value && device.value.deviceName
|
||||||
? device.value.deviceName
|
? device.value.deviceName
|
||||||
@@ -519,7 +543,7 @@ onShow(async () => {
|
|||||||
class="device-bow"
|
class="device-bow"
|
||||||
:class="{ 'device-bow--online': isDeviceOnline }"
|
:class="{ 'device-bow--online': isDeviceOnline }"
|
||||||
:src="isDeviceOnline
|
:src="isDeviceOnline
|
||||||
? 'https://static.shelingxingqiu.com/shootmini/static/home-device/device-bow--online.png'
|
? 'https://static.shelingxingqiu.com/shootmini/static/home-device/device-bow.png'
|
||||||
: 'https://static.shelingxingqiu.com/shootmini/static/home-device/device-bow.png'"
|
: 'https://static.shelingxingqiu.com/shootmini/static/home-device/device-bow.png'"
|
||||||
:mode="isDeviceOnline ? 'aspectFit' : 'widthFix'"
|
:mode="isDeviceOnline ? 'aspectFit' : 'widthFix'"
|
||||||
/>
|
/>
|
||||||
@@ -697,9 +721,9 @@ onShow(async () => {
|
|||||||
<ModalDialog
|
<ModalDialog
|
||||||
:show="firmwareConfirmVisible"
|
:show="firmwareConfirmVisible"
|
||||||
title="固件更新"
|
title="固件更新"
|
||||||
content="是否现在进行固件更新?"
|
:content="firmwareConfirmContent"
|
||||||
cancelText="取消"
|
cancelText="暂不更新"
|
||||||
confirmText="确定"
|
confirmText="立即更新"
|
||||||
:onCancel="closeFirmwareConfirm"
|
:onCancel="closeFirmwareConfirm"
|
||||||
:onConfirm="confirmFirmwareUpdate"
|
:onConfirm="confirmFirmwareUpdate"
|
||||||
></ModalDialog>
|
></ModalDialog>
|
||||||
@@ -975,7 +999,7 @@ onShow(async () => {
|
|||||||
|
|
||||||
.device-bow {
|
.device-bow {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: -2rpx;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
z-index: 4;
|
z-index: 4;
|
||||||
width: 562rpx;
|
width: 562rpx;
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 17 KiB |
@@ -27,6 +27,11 @@ const getDefaultDeviceStatus = () => ({
|
|||||||
receivedAt: 0,
|
receivedAt: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const getDefaultDeviceUsageDuration = () => ({
|
||||||
|
deviceId: "",
|
||||||
|
seconds: null,
|
||||||
|
});
|
||||||
|
|
||||||
const getDefaultGame = () => ({
|
const getDefaultGame = () => ({
|
||||||
roomID: "",
|
roomID: "",
|
||||||
inBattle: false,
|
inBattle: false,
|
||||||
@@ -114,6 +119,8 @@ export default defineStore("store", {
|
|||||||
deviceBattery: null,
|
deviceBattery: null,
|
||||||
// WebSocket 实时推送的设备状态,不参与持久化。
|
// WebSocket 实时推送的设备状态,不参与持久化。
|
||||||
deviceStatus: getDefaultDeviceStatus(),
|
deviceStatus: getDefaultDeviceStatus(),
|
||||||
|
// 按设备记录本次运行期间已知的最大累计使用时长,离线时保持数值不回退。
|
||||||
|
deviceUsageDuration: getDefaultDeviceUsageDuration(),
|
||||||
game: {
|
game: {
|
||||||
roomID: "",
|
roomID: "",
|
||||||
inBattle: false,
|
inBattle: false,
|
||||||
@@ -183,6 +190,27 @@ export default defineStore("store", {
|
|||||||
this.deviceStatus = nextStatus;
|
this.deviceStatus = nextStatus;
|
||||||
this.online = online;
|
this.online = online;
|
||||||
this.deviceBattery = online ? nextStatus.battery : null;
|
this.deviceBattery = online ? nextStatus.battery : null;
|
||||||
|
this.updateDeviceUsageDuration(nextStatus.onlineDuration);
|
||||||
|
},
|
||||||
|
updateDeviceUsageDuration(value, deviceId = this.device.deviceId) {
|
||||||
|
if (value === null || value === undefined || String(value).trim() === "") return;
|
||||||
|
|
||||||
|
const seconds = Number(value);
|
||||||
|
const normalizedDeviceId = String(deviceId || "");
|
||||||
|
if (!normalizedDeviceId || !Number.isFinite(seconds) || seconds < 0) return;
|
||||||
|
|
||||||
|
const cachedDeviceId = String(this.deviceUsageDuration.deviceId || "");
|
||||||
|
const cachedSeconds = Number(this.deviceUsageDuration.seconds);
|
||||||
|
this.deviceUsageDuration = {
|
||||||
|
deviceId: normalizedDeviceId,
|
||||||
|
seconds:
|
||||||
|
cachedDeviceId === normalizedDeviceId && Number.isFinite(cachedSeconds)
|
||||||
|
? Math.max(cachedSeconds, seconds)
|
||||||
|
: seconds,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
clearDeviceUsageDuration() {
|
||||||
|
this.deviceUsageDuration = getDefaultDeviceUsageDuration();
|
||||||
},
|
},
|
||||||
setDeviceOnline(online) {
|
setDeviceOnline(online) {
|
||||||
const nextOnline = online === true;
|
const nextOnline = online === true;
|
||||||
@@ -210,6 +238,7 @@ export default defineStore("store", {
|
|||||||
updateDevice(deviceId, deviceName) {
|
updateDevice(deviceId, deviceName) {
|
||||||
if (String(this.device.deviceId || "") !== String(deviceId || "")) {
|
if (String(this.device.deviceId || "") !== String(deviceId || "")) {
|
||||||
this.clearDeviceStatus();
|
this.clearDeviceStatus();
|
||||||
|
this.clearDeviceUsageDuration();
|
||||||
}
|
}
|
||||||
this.device.deviceId = deviceId;
|
this.device.deviceId = deviceId;
|
||||||
this.device.deviceName = deviceName;
|
this.device.deviceName = deviceName;
|
||||||
@@ -217,6 +246,7 @@ export default defineStore("store", {
|
|||||||
clearDevice() {
|
clearDevice() {
|
||||||
this.device = getDefaultDevice();
|
this.device = getDefaultDevice();
|
||||||
this.clearDeviceStatus();
|
this.clearDeviceStatus();
|
||||||
|
this.clearDeviceUsageDuration();
|
||||||
},
|
},
|
||||||
async updateConfig(config) {
|
async updateConfig(config) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
@@ -267,6 +297,7 @@ export default defineStore("store", {
|
|||||||
online: false,
|
online: false,
|
||||||
deviceBattery: null,
|
deviceBattery: null,
|
||||||
deviceStatus: getDefaultDeviceStatus(),
|
deviceStatus: getDefaultDeviceStatus(),
|
||||||
|
deviceUsageDuration: getDefaultDeviceUsageDuration(),
|
||||||
game: getDefaultGame(),
|
game: getDefaultGame(),
|
||||||
dailyCount: getDefaultDailyCount(),
|
dailyCount: getDefaultDailyCount(),
|
||||||
deviceChargingDialogVisible: false,
|
deviceChargingDialogVisible: false,
|
||||||
|
|||||||
Reference in New Issue
Block a user