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

View File

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