feat:自动门点连接状态渲染矩形光圈,

This commit is contained in:
xudan 2025-09-02 10:09:21 +08:00
parent b0cf3a896d
commit ca252acff9
2 changed files with 47 additions and 36 deletions

View File

@ -93,8 +93,8 @@ export class AutoDoorService {
{ deviceId: string; deviceStatus: number; active: boolean; isConnected: boolean } { deviceId: string; deviceStatus: number; active: boolean; isConnected: boolean }
>(); >();
// 设备ID到自动门点ID的映射缓存,避免每次都遍历查找 // 设备ID到自动门点ID列表的映射缓存,支持同一设备绑定多个点位
private deviceIdToPointIdMap = new Map<string, string>(); private deviceIdToPointIdMap = new Map<string, string[]>();
/** /**
* *
@ -127,13 +127,14 @@ export class AutoDoorService {
if (pen.name === 'point' && (pen as MapPen).point?.type === MapPointType.) { if (pen.name === 'point' && (pen as MapPen).point?.type === MapPointType.) {
const deviceId = (pen as MapPen).point?.deviceId; const deviceId = (pen as MapPen).point?.deviceId;
if (deviceId && pen.id) { if (deviceId && pen.id) {
this.deviceIdToPointIdMap.set(deviceId, pen.id); const list = this.deviceIdToPointIdMap.get(deviceId) ?? [];
list.push(pen.id);
this.deviceIdToPointIdMap.set(deviceId, list);
autoDoorCount++; autoDoorCount++;
} }
} }
}); });
console.log(`🚪 自动门点映射初始化完成: 共找到 ${autoDoorCount} 个自动门点`);
} }
/** /**
@ -172,7 +173,7 @@ export class AutoDoorService {
// 注意:这里不需要创建完整的模拟数据对象,只需要更新状态 // 注意:这里不需要创建完整的模拟数据对象,只需要更新状态
if (enableLogging) { if (enableLogging) {
console.log(`🚪 自动门点状态更新: ${newStatus === 0 ? '关门(红色)' : '开门(蓝色)'} (deviceId: ${deviceId})`); // console.log(`🚪 自动门点状态更新: ${newStatus === 0 ? '关门(红色)' : '开门(蓝色)'} (deviceId: ${deviceId})`);
} }
// 更新编辑器中的自动门点状态 // 更新编辑器中的自动门点状态
@ -236,7 +237,7 @@ export class AutoDoorService {
if (this.editorService) { if (this.editorService) {
this.editorService.updateAutoDoorByDeviceId(deviceId, status, true); this.editorService.updateAutoDoorByDeviceId(deviceId, status, true);
console.log(`🚪 手动设置自动门点状态: ${status === 0 ? '关门(红色)' : '开门(蓝色)'} (deviceId: ${deviceId})`); // console.log(`🚪 手动设置自动门点状态: ${status === 0 ? '关门(红色)' : '开门(蓝色)'} (deviceId: ${deviceId})`);
} }
} }
@ -263,9 +264,9 @@ export class AutoDoorService {
// 缓存最新数据 // 缓存最新数据
this.latestAutoDoorData.set(deviceId, { deviceId, deviceStatus, active, isConnected }); this.latestAutoDoorData.set(deviceId, { deviceId, deviceStatus, active, isConnected });
console.log( // console.log(
`🚪 收到自动门点WebSocket数据: ${deviceStatus === 0 ? '关门(红色)' : '开门(蓝色)'} (deviceId: ${deviceId})`, // `🚪 收到自动门点WebSocket数据: ${deviceStatus === 0 ? '关门(红色)' : '开门(蓝色)'} (deviceId: ${deviceId})`,
); // );
} }
/** /**
@ -284,23 +285,25 @@ export class AutoDoorService {
const [deviceId, data] = entry; const [deviceId, data] = entry;
this.latestAutoDoorData.delete(deviceId); this.latestAutoDoorData.delete(deviceId);
// 使用映射缓存快速查找点位ID // 使用映射缓存快速查找点位ID列表
const pointId = this.deviceIdToPointIdMap.get(data.deviceId); const pointIds = this.deviceIdToPointIdMap.get(data.deviceId);
if (!pointId) { if (!pointIds || pointIds.length === 0) {
console.warn(`⚠️ 未找到设备ID ${data.deviceId} 对应的自动门点,可能需要刷新映射`); console.warn(`⚠️ 未找到设备ID ${data.deviceId} 对应的自动门点,可能需要刷新映射`);
continue; continue;
} }
// 更新自动门点状态使用pointId直接更新避免查找 // 更新该设备对应的所有自动门点状态
if (this.editorService) { if (this.editorService) {
this.editorService.updateAutoDoorByDeviceId( for (const pid of pointIds) {
data.deviceId, this.editorService.updateAutoDoorByDeviceId(
data.deviceStatus, data.deviceId,
data.isConnected, data.deviceStatus,
data.active, data.isConnected,
pointId, data.active,
); pid,
);
}
} }
} }

View File

@ -1452,31 +1452,39 @@ function drawPoint(ctx: CanvasRenderingContext2D, pen: MapPen): void {
const theme = sTheme.editor; const theme = sTheme.editor;
const { active, iconSize: r = 0, fontSize = 14, lineHeight = 1.5, fontFamily } = pen.calculative ?? {}; const { active, iconSize: r = 0, fontSize = 14, lineHeight = 1.5, fontFamily } = pen.calculative ?? {};
const { x = 0, y = 0, width: w = 0, height: h = 0 } = pen.calculative?.worldRect ?? {}; const { x = 0, y = 0, width: w = 0, height: h = 0 } = pen.calculative?.worldRect ?? {};
const { type, deviceStatus, active: pointActive } = pen.point ?? {}; const { type, isConnected, deviceStatus, active: pointActive } = pen.point ?? {};
const { label = '', statusStyle } = pen ?? {}; const { label = '', statusStyle } = pen ?? {};
ctx.save(); ctx.save();
// 为自动门点绘制光圈 // 自动门点:根据连接与开关状态绘制矩形光圈(无边框)
if (type === MapPointType. && pointActive && deviceStatus !== undefined) { if (type === MapPointType. && pointActive) {
const ox = x + w / 2; // 让光圈随点位尺寸等比缩放,避免缩放画布时视觉上变大
const oy = y + h / 2; const base = Math.min(w, h);
console.log(ox, oy); const padding = Math.max(2, Math.min(10, base * 0.2));
const haloRadius = Math.max(w, h) / 2 + 6; // 光圈半径比点位本身大一些 const rx = x - padding;
const ry = y - padding;
const rw = w + padding * 2;
const rh = h + padding * 2;
ctx.ellipse(ox, oy, haloRadius, haloRadius, 0, 0, Math.PI * 2); // 使用与点位相同的圆角半径,使观感统一
ctx.beginPath();
ctx.roundRect(rx, ry, rw, rh, r);
// 根据设备状态选择颜色0=关门红色1=开门(蓝色) if (isConnected === false) {
if (deviceStatus === 0) { // 未连接:深红色实心,不描边
ctx.fillStyle = get(theme, 'autoDoor.fill-closed') ?? '#FF4D4F33'; ctx.fillStyle = '#fe5a5ae0';
ctx.strokeStyle = get(theme, 'autoDoor.stroke-closed') ?? '#FF4D4F99';
} else { } else {
ctx.fillStyle = get(theme, 'autoDoor.fill-open') ?? '#1890FF33'; // 已连接根据门状态显示颜色0=关门-浅红1=开门-蓝色)
ctx.strokeStyle = get(theme, 'autoDoor.stroke-open') ?? '#1890FF99'; if (deviceStatus === 0) {
ctx.fillStyle = '#cddc39';
} else {
ctx.fillStyle = '#1890FF';
}
} }
ctx.fill(); ctx.fill();
ctx.stroke(); // 重置路径,避免后续对点位边框的 stroke 影响到光圈路径
ctx.beginPath();
} }
switch (type) { switch (type) {