feat:新增自动门点连接状态卡片详情显示
This commit is contained in:
parent
fbdcc718c4
commit
95f7894328
@ -32,6 +32,7 @@ export interface MapPointInfo {
|
|||||||
deviceId?: string; // 设备ID
|
deviceId?: string; // 设备ID
|
||||||
enabled?: 0 | 1; // 是否启用(仅停靠点使用,0=禁用,1=启用)
|
enabled?: 0 | 1; // 是否启用(仅停靠点使用,0=禁用,1=启用)
|
||||||
deviceStatus?: number; // 设备状态(仅自动门点使用,0=关门,1=开门)
|
deviceStatus?: number; // 设备状态(仅自动门点使用,0=关门,1=开门)
|
||||||
|
isConnected?: boolean; // 连接状态(仅自动门点使用,true=已连接,false=未连接)
|
||||||
active?: boolean; // 是否激活状态,用于控制光圈显示
|
active?: boolean; // 是否激活状态,用于控制光圈显示
|
||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
@ -198,6 +198,19 @@ const binTaskData = computed(() => {
|
|||||||
<a-typography-text type="secondary">{{ $t('设备ID') }}</a-typography-text>
|
<a-typography-text type="secondary">{{ $t('设备ID') }}</a-typography-text>
|
||||||
<a-typography-text>{{ point.deviceId }}</a-typography-text>
|
<a-typography-text>{{ point.deviceId }}</a-typography-text>
|
||||||
</a-list-item>
|
</a-list-item>
|
||||||
|
<a-list-item v-if="point.type === MapPointType.自动门点">
|
||||||
|
<a-typography-text type="secondary">{{ $t('连接状态') }}</a-typography-text>
|
||||||
|
<a-flex align="center" :gap="8" class="conn-status">
|
||||||
|
<span
|
||||||
|
class="status-dot"
|
||||||
|
:class="point.isConnected ? 'online' : 'offline'"
|
||||||
|
:title="point.isConnected ? $t('已连接') : $t('未连接')"
|
||||||
|
/>
|
||||||
|
<a-typography-text>
|
||||||
|
{{ point.isConnected ? $t('已连接') : $t('未连接') }}
|
||||||
|
</a-typography-text>
|
||||||
|
</a-flex>
|
||||||
|
</a-list-item>
|
||||||
<a-list-item v-if="point.extensionType">
|
<a-list-item v-if="point.extensionType">
|
||||||
<a-typography-text type="secondary">{{ $t('扩展类型') }}</a-typography-text>
|
<a-typography-text type="secondary">{{ $t('扩展类型') }}</a-typography-text>
|
||||||
<a-typography-text>{{ $t(MapPointType[point.extensionType]) }}</a-typography-text>
|
<a-typography-text>{{ $t(MapPointType[point.extensionType]) }}</a-typography-text>
|
||||||
@ -315,6 +328,24 @@ const binTaskData = computed(() => {
|
|||||||
@use '/src/assets/themes/theme' as *;
|
@use '/src/assets/themes/theme' as *;
|
||||||
|
|
||||||
@include themed {
|
@include themed {
|
||||||
|
.conn-status {
|
||||||
|
.status-dot {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: inline-block;
|
||||||
|
box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.05);
|
||||||
|
&.online {
|
||||||
|
background-color: get-color(success);
|
||||||
|
box-shadow: 0 0 0 2px rgba(82, 196, 26, 0.15);
|
||||||
|
}
|
||||||
|
&.offline {
|
||||||
|
background-color: get-color(error);
|
||||||
|
box-shadow: 0 0 0 2px rgba(255, 77, 79, 0.15);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.storage-locations {
|
.storage-locations {
|
||||||
.storage-item {
|
.storage-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -312,6 +312,11 @@ const handleAutoSaveAndRestoreViewState = async () => {
|
|||||||
//#region UI状态管理
|
//#region UI状态管理
|
||||||
const show = ref<boolean>(true);
|
const show = ref<boolean>(true);
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
|
// 返回到父级 iframe 的场景卡片
|
||||||
|
const backToCards = () => {
|
||||||
|
window.parent?.postMessage({ type: 'scene_return_to_cards' }, '*');
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -319,7 +324,10 @@ const show = ref<boolean>(true);
|
|||||||
<a-layout-header class="p-16" style="height: 64px">
|
<a-layout-header class="p-16" style="height: 64px">
|
||||||
<a-flex justify="space-between" align="center">
|
<a-flex justify="space-between" align="center">
|
||||||
<a-typography-text class="title">{{ title }}--{{ isMonitorMode ? '场景监控' : '场景仿真' }}</a-typography-text>
|
<a-typography-text class="title">{{ title }}--{{ isMonitorMode ? '场景监控' : '场景仿真' }}</a-typography-text>
|
||||||
<a-button type="primary" :loading="isSaving" @click="handleSaveViewState"> 保存比例 </a-button>
|
<a-space align="center">
|
||||||
|
<!-- <a-button @click="backToCards"> 返回 </a-button> -->
|
||||||
|
<a-button type="primary" :loading="isSaving" @click="handleSaveViewState"> 保存比例 </a-button>
|
||||||
|
</a-space>
|
||||||
</a-flex>
|
</a-flex>
|
||||||
</a-layout-header>
|
</a-layout-header>
|
||||||
|
|
||||||
|
@ -157,6 +157,10 @@ const handleAutoSaveAndRestoreViewState = async () => {
|
|||||||
|
|
||||||
await autoSaveAndRestoreViewState(editor.value, props.id);
|
await autoSaveAndRestoreViewState(editor.value, props.id);
|
||||||
};
|
};
|
||||||
|
// 返回到父级 iframe 的场景卡片
|
||||||
|
const backToCards = () => {
|
||||||
|
window.parent?.postMessage({ type: 'scene_return_to_cards' }, '*');
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -165,6 +169,7 @@ const handleAutoSaveAndRestoreViewState = async () => {
|
|||||||
<a-flex justify="space-between" align="center">
|
<a-flex justify="space-between" align="center">
|
||||||
<a-typography-text class="title">{{ title }} --场景编辑</a-typography-text>
|
<a-typography-text class="title">{{ title }} --场景编辑</a-typography-text>
|
||||||
<a-space align="center">
|
<a-space align="center">
|
||||||
|
<!-- <a-button @click="backToCards"> 返回 </a-button> -->
|
||||||
<a-button type="primary" :loading="isSaving" @click="handleSaveViewState"> 保存比例 </a-button>
|
<a-button type="primary" :loading="isSaving" @click="handleSaveViewState"> 保存比例 </a-button>
|
||||||
<a-button v-if="editable" class="warning" @click="editable = false">
|
<a-button v-if="editable" class="warning" @click="editable = false">
|
||||||
<i class="icon exit size-18 mr-8" />
|
<i class="icon exit size-18 mr-8" />
|
||||||
|
@ -88,7 +88,10 @@ export class AutoDoorService {
|
|||||||
private timers = new Map<string, NodeJS.Timeout>();
|
private timers = new Map<string, NodeJS.Timeout>();
|
||||||
private statusMap = new Map<string, 0 | 1>();
|
private statusMap = new Map<string, 0 | 1>();
|
||||||
private editorService: EditorService | null = null;
|
private editorService: EditorService | null = null;
|
||||||
private latestAutoDoorData = new Map<string, { deviceId: string; deviceStatus: number; active: boolean }>();
|
private latestAutoDoorData = new Map<
|
||||||
|
string,
|
||||||
|
{ deviceId: string; deviceStatus: number; active: boolean; isConnected: boolean }
|
||||||
|
>();
|
||||||
|
|
||||||
// 设备ID到自动门点ID的映射缓存,避免每次都遍历查找
|
// 设备ID到自动门点ID的映射缓存,避免每次都遍历查找
|
||||||
private deviceIdToPointIdMap = new Map<string, string>();
|
private deviceIdToPointIdMap = new Map<string, string>();
|
||||||
@ -250,7 +253,7 @@ export class AutoDoorService {
|
|||||||
* @param data WebSocket推送的数据
|
* @param data WebSocket推送的数据
|
||||||
*/
|
*/
|
||||||
handleWebSocketData(data: AutoDoorWebSocketData): void {
|
handleWebSocketData(data: AutoDoorWebSocketData): void {
|
||||||
const { label: deviceId, deviceStatus, active = true } = data;
|
const { label: deviceId, deviceStatus, active = true, isConnected = true } = data;
|
||||||
|
|
||||||
if (!deviceId || deviceStatus === undefined) {
|
if (!deviceId || deviceStatus === undefined) {
|
||||||
console.warn('⚠️ 自动门点数据格式不正确', data);
|
console.warn('⚠️ 自动门点数据格式不正确', data);
|
||||||
@ -258,7 +261,7 @@ export class AutoDoorService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 缓存最新数据
|
// 缓存最新数据
|
||||||
this.latestAutoDoorData.set(deviceId, { deviceId, deviceStatus, active });
|
this.latestAutoDoorData.set(deviceId, { deviceId, deviceStatus, active, isConnected });
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
`🚪 收到自动门点WebSocket数据: ${deviceStatus === 0 ? '关门(红色)' : '开门(蓝色)'} (deviceId: ${deviceId})`,
|
`🚪 收到自动门点WebSocket数据: ${deviceStatus === 0 ? '关门(红色)' : '开门(蓝色)'} (deviceId: ${deviceId})`,
|
||||||
@ -291,7 +294,13 @@ export class AutoDoorService {
|
|||||||
|
|
||||||
// 更新自动门点状态(使用pointId直接更新,避免查找)
|
// 更新自动门点状态(使用pointId直接更新,避免查找)
|
||||||
if (this.editorService) {
|
if (this.editorService) {
|
||||||
this.editorService.updateAutoDoorByDeviceId(data.deviceId, data.deviceStatus, data.active, pointId);
|
this.editorService.updateAutoDoorByDeviceId(
|
||||||
|
data.deviceId,
|
||||||
|
data.deviceStatus,
|
||||||
|
data.isConnected,
|
||||||
|
data.active,
|
||||||
|
pointId,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -866,7 +866,6 @@ export class EditorService extends Meta2d {
|
|||||||
public updatePointBorderColor(pointId: string, color: string): void {
|
public updatePointBorderColor(pointId: string, color: string): void {
|
||||||
const pen = this.getPenById(pointId);
|
const pen = this.getPenById(pointId);
|
||||||
if (!pen || pen.name !== 'point') return;
|
if (!pen || pen.name !== 'point') return;
|
||||||
|
|
||||||
this.updatePen(pointId, { statusStyle: color }, false);
|
this.updatePen(pointId, { statusStyle: color }, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -874,10 +873,17 @@ export class EditorService extends Meta2d {
|
|||||||
* 根据设备ID更新自动门点状态
|
* 根据设备ID更新自动门点状态
|
||||||
* @param deviceId 设备ID
|
* @param deviceId 设备ID
|
||||||
* @param deviceStatus 设备状态(0=关门,1=开门)
|
* @param deviceStatus 设备状态(0=关门,1=开门)
|
||||||
|
* @param isConnected 连接状态(true=已连接,false=未连接)
|
||||||
* @param active 是否显示光圈
|
* @param active 是否显示光圈
|
||||||
* @param pointId 可选的点位ID,如果提供则直接使用,避免查找
|
* @param pointId 可选的点位ID,如果提供则直接使用,避免查找
|
||||||
*/
|
*/
|
||||||
public updateAutoDoorByDeviceId(deviceId: string, deviceStatus: number, active = true, pointId?: string): void {
|
public updateAutoDoorByDeviceId(
|
||||||
|
deviceId: string,
|
||||||
|
deviceStatus: number,
|
||||||
|
isConnected: boolean,
|
||||||
|
active = true,
|
||||||
|
pointId?: string,
|
||||||
|
): void {
|
||||||
let autoDoorPointId = pointId;
|
let autoDoorPointId = pointId;
|
||||||
|
|
||||||
// 如果没有提供pointId,则通过deviceId查找
|
// 如果没有提供pointId,则通过deviceId查找
|
||||||
@ -912,6 +918,7 @@ export class EditorService extends Meta2d {
|
|||||||
point: {
|
point: {
|
||||||
...autoDoorPoint.point,
|
...autoDoorPoint.point,
|
||||||
deviceStatus,
|
deviceStatus,
|
||||||
|
isConnected,
|
||||||
active,
|
active,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user