mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-23 23:53:55 +08:00
fix: 修复设备跨时区时间与在线状态
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
export function hasTimestampValue(timestamp) {
|
||||
if (timestamp === null || timestamp === undefined) return false;
|
||||
return typeof timestamp !== 'string' || timestamp.trim() !== '';
|
||||
}
|
||||
|
||||
export function parseTimestamp(timestamp) {
|
||||
if (!hasTimestampValue(timestamp)) return null;
|
||||
if (typeof timestamp !== 'number' && typeof timestamp !== 'string') return null;
|
||||
|
||||
const normalizedTimestamp = typeof timestamp === 'string' ? timestamp.trim() : timestamp;
|
||||
const parsedTimestamp = Number(normalizedTimestamp);
|
||||
if (!Number.isFinite(parsedTimestamp)) return null;
|
||||
|
||||
return Number.isNaN(new Date(parsedTimestamp).getTime()) ? null : parsedTimestamp;
|
||||
}
|
||||
|
||||
export function parseLegacyDate(dateValue) {
|
||||
if (!dateValue) return null;
|
||||
const timestamp = new Date(dateValue).getTime();
|
||||
return Number.isNaN(timestamp) ? null : timestamp;
|
||||
}
|
||||
|
||||
export function formatTimestamp(timestamp, formatter = value => new Date(value).toLocaleString()) {
|
||||
const parsedTimestamp = parseTimestamp(timestamp);
|
||||
return parsedTimestamp === null ? '-' : formatter(parsedTimestamp);
|
||||
}
|
||||
|
||||
export function formatCreateDate(timestamp, legacyDate, formatter) {
|
||||
if (!hasTimestampValue(timestamp)) return legacyDate || '-';
|
||||
return formatTimestamp(timestamp, formatter);
|
||||
}
|
||||
|
||||
export function compareTimestamps(firstTimestamp, secondTimestamp) {
|
||||
const firstIsValid = Number.isFinite(firstTimestamp);
|
||||
const secondIsValid = Number.isFinite(secondTimestamp);
|
||||
|
||||
if (firstIsValid && secondIsValid) return firstTimestamp - secondTimestamp;
|
||||
if (firstIsValid) return -1;
|
||||
if (secondIsValid) return 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -120,7 +120,7 @@
|
||||
<i class="el-icon-time"></i>
|
||||
<div class="stat-content">
|
||||
<div class="stat-label">{{ $t('addressBookManagement.addTime') }}</div>
|
||||
<div class="stat-value">{{ selectedDevice.createDate || '-' }}</div>
|
||||
<div class="stat-value">{{ formatDeviceCreateDate(selectedDevice) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
@@ -207,6 +207,7 @@ import Api from "@/apis/api.js";
|
||||
import AddressBookApi from "@/apis/module/addressBook.js";
|
||||
import MacAddressMask from "@/components/MacAddressMask.vue";
|
||||
import CustomButton from "@/components/CustomButton.vue";
|
||||
import { formatCreateDate, parseTimestamp } from '@/utils/deviceTime.mjs';
|
||||
|
||||
export default {
|
||||
name: "AddressBookManagement",
|
||||
@@ -281,6 +282,7 @@ export default {
|
||||
remarks: device.alias || '',
|
||||
online: false,
|
||||
createDate: device.createDate,
|
||||
createDateTimestamp: device.createDateTimestamp,
|
||||
lastConnectedAt: device.lastConnectedAtTimestamp,
|
||||
deviceStatus: 'offline'
|
||||
}));
|
||||
@@ -526,9 +528,10 @@ export default {
|
||||
this.isEditingAgentName = false;
|
||||
},
|
||||
getTimeAgo(timestamp) {
|
||||
if (!timestamp) return '-';
|
||||
const ts = parseTimestamp(timestamp);
|
||||
if (ts === null) return '-';
|
||||
const now = new Date();
|
||||
const date = new Date(Number(timestamp));
|
||||
const date = new Date(ts);
|
||||
const diff = now - date;
|
||||
|
||||
const seconds = Math.floor(diff / 1000);
|
||||
@@ -545,6 +548,10 @@ export default {
|
||||
if (months < 12) return this.$t('addressBookManagement.monthsAgo', { months });
|
||||
return this.$t('addressBookManagement.yearsAgo', { years });
|
||||
},
|
||||
formatDeviceCreateDate(device) {
|
||||
if (!device) return '-';
|
||||
return formatCreateDate(device.createDateTimestamp, device.createDate);
|
||||
},
|
||||
getDeviceAvatar(deviceId) {
|
||||
// 根据 deviceId 计算 MD5,选择对应的头像
|
||||
const avatars = [
|
||||
|
||||
@@ -103,6 +103,14 @@ import VersionFooter from "@/components/VersionFooter.vue";
|
||||
import MacAddressMask from "@/components/MacAddressMask.vue";
|
||||
import CustomButton from "@/components/CustomButton.vue";
|
||||
import CustomTable from "@/components/CustomTable.vue";
|
||||
import {
|
||||
compareTimestamps,
|
||||
formatCreateDate,
|
||||
formatTimestamp,
|
||||
hasTimestampValue,
|
||||
parseLegacyDate,
|
||||
parseTimestamp,
|
||||
} from '@/utils/deviceTime.mjs';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -327,26 +335,31 @@ export default {
|
||||
this.loading = false;
|
||||
if (data.code === 0) {
|
||||
this.deviceList = data.data.map(device => {
|
||||
const hasCreateDateTimestamp = hasTimestampValue(device.createDateTimestamp);
|
||||
const rawBindTime = hasCreateDateTimestamp
|
||||
? parseTimestamp(device.createDateTimestamp)
|
||||
: parseLegacyDate(device.createDate);
|
||||
return {
|
||||
device_id: device.id,
|
||||
model: device.board,
|
||||
firmwareVersion: device.appVersion,
|
||||
macAddress: device.macAddress,
|
||||
bindTime: device.createDate,
|
||||
lastConversation: device.lastConnectedAtTimestamp
|
||||
? this.formatRelativeTime(device.lastConnectedAtTimestamp)
|
||||
: '-',
|
||||
bindTime: formatCreateDate(device.createDateTimestamp, device.createDate),
|
||||
lastConversation: formatTimestamp(device.lastConnectedAtTimestamp),
|
||||
remark: device.alias,
|
||||
_originalRemark: device.alias,
|
||||
isEdit: false,
|
||||
_submitting: false,
|
||||
otaSwitch: device.autoUpdate === 1,
|
||||
rawBindTime: new Date(device.createDate).getTime(),
|
||||
rawBindTime,
|
||||
selected: false,
|
||||
deviceStatus: 'offline'
|
||||
};
|
||||
})
|
||||
.sort((a, b) => a.rawBindTime - b.rawBindTime);
|
||||
.sort((firstDevice, secondDevice) => compareTimestamps(
|
||||
firstDevice.rawBindTime,
|
||||
secondDevice.rawBindTime,
|
||||
));
|
||||
this.activeSearchKeyword = "";
|
||||
this.searchKeyword = "";
|
||||
|
||||
@@ -429,14 +442,6 @@ export default {
|
||||
const version = row.firmwareVersion.replace(/\./g, '');
|
||||
return Number(version) >= 200;
|
||||
},
|
||||
formatRelativeTime(timestamp) {
|
||||
if (!timestamp) return '-';
|
||||
const ts = Number(timestamp);
|
||||
if (isNaN(ts)) return '-';
|
||||
const date = new Date(ts);
|
||||
if (isNaN(date.getTime())) return '-';
|
||||
return date.toLocaleString();
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user