refactor(device): 优化设备详情字段与心跳数据加载逻辑

- 新增设备最后心跳查询接口及类型定义
- 设备在线状态字段统一更名为 online,移除重复字段
- 设备详情首次加载时从心跳接口获取最后上线时间
- WebSocket 推送在线状态时同步更新屏幕状态和最后心跳时间
- 编辑设备弹窗精简为仅可修改昵称,其余字段改为只读展示
This commit is contained in:
TongTongStudio
2026-08-12 08:28:10 +08:00
parent aebef55e0a
commit 9bdbefcfe2
5 changed files with 84 additions and 70 deletions

View File

@@ -14,15 +14,28 @@
<el-tag :type="deviceData.onlineStatus == 1 ? 'success' : 'danger'" size="small">
{{ deviceData.onlineStatus == 1 ? "在线" : "离线" }}
</el-tag>
<el-tag
v-if="deviceData.onlineStatus == 1"
:type="deviceData.screenState == 1 ? 'warning' : 'info'"
size="small"
>
{{
deviceData.screenState == 1
? "亮屏"
: deviceData.screenState === 0
? "熄屏"
: "未知"
}}
</el-tag>
</div>
<div class="info-grid">
<div class="info-item">
<span class="label">序列号</span>
<span class="value">{{ props.serialno }}</span>
<span class="value">{{ formatText(props.serialno) }}</span>
</div>
<div class="info-item">
<span class="label">IMEI</span>
<span class="value">{{ formatText(deviceData.imei) }}</span>
<span class="value">{{ formatText(deviceData.imei || networkInfo.mobileImei) }}</span>
</div>
<div class="info-item">
<span class="label">设备所有者</span>
@@ -50,11 +63,11 @@
</div>
<div class="info-item">
<span class="label">最后上线</span>
<span class="value">{{ formatText(deviceData.lastOnline) }}</span>
<span class="value">{{ formatDate(deviceData.lastOnline) }}</span>
</div>
<div class="info-item">
<span class="label">设备编号</span>
<span class="value">{{ formatText(deviceData.deviceSn) }}</span>
<span class="value">{{ formatText() }}</span>
</div>
</div>
</div>
@@ -491,9 +504,6 @@
<el-descriptions-item label="渠道">
{{ formatText(otherInfo.channel) }}
</el-descriptions-item>
<el-descriptions-item label="设备 ID">
{{ formatText(otherInfo.deviceId) }}
</el-descriptions-item>
<el-descriptions-item label="极光推送ID">
{{ formatText(otherInfo.pushId) }}
</el-descriptions-item>
@@ -509,9 +519,6 @@
<el-descriptions-item label="ICCID">
{{ formatText(otherInfo.iccid) }}
</el-descriptions-item>
<el-descriptions-item label="IMSI">
{{ formatText(otherInfo.imsi) }}
</el-descriptions-item>
<el-descriptions-item label="充电中">
{{ formatBool(otherInfo.isCharging) }}
</el-descriptions-item>
@@ -818,6 +825,7 @@ const activeTab = ref("deviceInfo");
const deviceData = reactive({
snName: "",
onlineStatus: 0,
screenState: null as number | null,
owner: "",
department: "",
group: "",
@@ -947,6 +955,9 @@ function assignTo<T extends object>(reactiveObj: T, data?: object) {
}
}
/** 首次进入时是否已加载过最后心跳时间 */
let lastHeartbeatLoaded = false;
/** 加载设备头部信息 */
async function loadDeviceDetail(serialno: string) {
try {
@@ -954,7 +965,7 @@ async function loadDeviceDetail(serialno: string) {
if (response) {
Object.assign(deviceData, {
snName: response.snName,
onlineStatus: response.onlineStatus,
onlineStatus: response.online,
deviceSn: response.serialno || serialno,
imei: response.snImei,
department: response.department,
@@ -971,20 +982,38 @@ async function loadDeviceDetail(serialno: string) {
}
// 加载完设备基础信息后,单独查询设备在线状态
loadOnlineStatus(serialno);
// 首次进入时从接口获取最后心跳时间作为最后上线时间
if (!lastHeartbeatLoaded) {
loadLastHeartbeat(serialno);
lastHeartbeatLoaded = true;
}
}
/** 查询单台设备在线状态 */
/** 查询单台设备在线状态(仅更新在线状态和屏幕状态,不更新最后上线时间) */
async function loadOnlineStatus(serialno: string) {
try {
const onlineInfo = await DeviceAPI.getOnlineStatus(serialno);
if (onlineInfo) {
deviceData.onlineStatus = onlineInfo.online ?? 0;
deviceData.screenState = onlineInfo.screenState ?? null;
}
} catch (error) {
console.error("查询设备在线状态失败:", error);
}
}
/** 查询设备最后心跳时间(仅首次进入时调用,作为最后上线时间) */
async function loadLastHeartbeat(serialno: string) {
try {
const heartbeat = await DeviceAPI.getLastHeartbeat(serialno);
if (heartbeat?.lastTime) {
deviceData.lastOnline = heartbeat.lastTime;
}
} catch (error) {
console.error("查询设备最后心跳时间失败:", error);
}
}
/** 基本信息 */
async function loadBasicInfo(serialno: string) {
loading.basic = true;
@@ -1017,6 +1046,10 @@ async function loadNetworkInfo(serialno: string) {
try {
const data = await DeviceAPI.getNetworkInfo(serialno);
assignTo(networkInfo, data);
// 同步 IMEI 到头部信息
if (data?.mobileImei) {
deviceData.imei = data.mobileImei;
}
} catch (e) {
console.error("加载网络信息失败", e);
} finally {
@@ -1357,6 +1390,10 @@ function handleDeviceOnlineStatus(data: DeviceOnlineVO) {
// 仅当推送的设备 SN 与当前详情页设备匹配时才更新
if (data.serialno === props.serialno) {
deviceData.onlineStatus = data.online ?? 0;
deviceData.screenState = data.screenState ?? null;
if (data.lastHeartbeatTime) {
deviceData.lastOnline = data.lastHeartbeatTime;
}
}
}