feat: 增强库位服务配置功能,添加常量定义和配置合并逻辑,支持动态更新和获取当前配置
This commit is contained in:
parent
95fc2f4a16
commit
0e38d2fff6
@ -8,6 +8,97 @@ import { type Ref, ref } from 'vue';
|
||||
|
||||
import { createStorageLocationPens } from './draw/storage-location-drawer';
|
||||
|
||||
// ==================== 常量定义 ====================
|
||||
|
||||
/**
|
||||
* 库位状态颜色常量
|
||||
*/
|
||||
const COLORS = {
|
||||
OCCUPIED: '#ff4d4f', // 占用状态 - 红色
|
||||
AVAILABLE: '#52c41a', // 可用状态 - 绿色
|
||||
DEFAULT: '#f5f5f5' // 默认状态 - 浅灰色
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* 消息类型常量
|
||||
*/
|
||||
const MESSAGE_TYPES = {
|
||||
BATCH_UPDATE: 'storage_location_update',
|
||||
SINGLE_UPDATE: 'storage_location_status_change',
|
||||
GET_STATUS: 'get_status'
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* 默认配置常量
|
||||
*/
|
||||
const DEFAULT_CONFIG = {
|
||||
MONITOR_INTERVAL: 3, // 默认监控间隔(秒)
|
||||
POINT_TYPE_ACTION: 15 // 动作点类型
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Pen类型常量
|
||||
*/
|
||||
const PEN_TYPES = {
|
||||
POINT: 'point',
|
||||
STORAGE_LOCATION: 'storage-location',
|
||||
STORAGE_MORE: 'storage-more',
|
||||
STORAGE_BACKGROUND: 'storage-background'
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* 标签常量
|
||||
*/
|
||||
const TAGS = {
|
||||
POINT_PREFIX: 'point-'
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* 库位服务配置接口
|
||||
*/
|
||||
export interface StorageLocationConfig {
|
||||
colors: {
|
||||
occupied: string;
|
||||
available: string;
|
||||
default: string;
|
||||
};
|
||||
penTypes: {
|
||||
point: string;
|
||||
storageLocation: string;
|
||||
storageMore: string;
|
||||
storageBackground: string;
|
||||
};
|
||||
tags: {
|
||||
pointPrefix: string;
|
||||
};
|
||||
monitoring: {
|
||||
defaultInterval: number;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认配置实例
|
||||
*/
|
||||
const DEFAULT_STORAGE_CONFIG: StorageLocationConfig = {
|
||||
colors: {
|
||||
occupied: COLORS.OCCUPIED,
|
||||
available: COLORS.AVAILABLE,
|
||||
default: COLORS.DEFAULT
|
||||
},
|
||||
penTypes: {
|
||||
point: PEN_TYPES.POINT,
|
||||
storageLocation: PEN_TYPES.STORAGE_LOCATION,
|
||||
storageMore: PEN_TYPES.STORAGE_MORE,
|
||||
storageBackground: PEN_TYPES.STORAGE_BACKGROUND
|
||||
},
|
||||
tags: {
|
||||
pointPrefix: TAGS.POINT_PREFIX
|
||||
},
|
||||
monitoring: {
|
||||
defaultInterval: DEFAULT_CONFIG.MONITOR_INTERVAL
|
||||
}
|
||||
};
|
||||
|
||||
// 提供给绘制层快速查询的全局状态映射:pointId -> (layerName -> { occupied, locked })
|
||||
export type StorageState = { occupied?: boolean; locked?: boolean };
|
||||
export const storageStateMap = new Map<string, Map<string, StorageState>>();
|
||||
@ -21,12 +112,28 @@ export class StorageLocationService {
|
||||
private storageLocations: Ref<Map<string, StorageLocationInfo[]>> = ref(new Map());
|
||||
private editor: EditorService | null = null;
|
||||
private sceneId: string = '';
|
||||
private config: StorageLocationConfig;
|
||||
// 渲染调度标记,避免在高频事件中重复 render
|
||||
private renderScheduled = false;
|
||||
|
||||
constructor(editor: EditorService, sceneId: string) {
|
||||
constructor(editor: EditorService, sceneId: string, config?: Partial<StorageLocationConfig>) {
|
||||
this.editor = editor;
|
||||
this.sceneId = sceneId;
|
||||
this.config = this.mergeConfig(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并配置,使用默认配置作为基础
|
||||
*/
|
||||
private mergeConfig(userConfig?: Partial<StorageLocationConfig>): StorageLocationConfig {
|
||||
if (!userConfig) return DEFAULT_STORAGE_CONFIG;
|
||||
|
||||
return {
|
||||
colors: { ...DEFAULT_STORAGE_CONFIG.colors, ...userConfig.colors },
|
||||
penTypes: { ...DEFAULT_STORAGE_CONFIG.penTypes, ...userConfig.penTypes },
|
||||
tags: { ...DEFAULT_STORAGE_CONFIG.tags, ...userConfig.tags },
|
||||
monitoring: { ...DEFAULT_STORAGE_CONFIG.monitoring, ...userConfig.monitoring }
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@ -48,6 +155,21 @@ export class StorageLocationService {
|
||||
return this.storageLocations;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新配置
|
||||
* @param newConfig 新的配置
|
||||
*/
|
||||
updateConfig(newConfig: Partial<StorageLocationConfig>): void {
|
||||
this.config = this.mergeConfig(newConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前配置
|
||||
*/
|
||||
getConfig(): StorageLocationConfig {
|
||||
return { ...this.config };
|
||||
}
|
||||
|
||||
/**
|
||||
* 建立站点名称到画布点ID的映射关系
|
||||
* @returns 站点名称到画布点ID的映射Map
|
||||
@ -56,8 +178,10 @@ export class StorageLocationService {
|
||||
const stationToPointIdMap = new Map<string, string>();
|
||||
if (!this.editor) return stationToPointIdMap;
|
||||
|
||||
// 获取所有动作点 (MapPointType.动作点 = 15)
|
||||
const actionPoints = this.editor.find('point').filter((pen) => pen.point?.type === 15);
|
||||
// 获取所有动作点
|
||||
const actionPoints = this.editor.find(this.config.penTypes.point).filter(
|
||||
(pen) => pen.point?.type === DEFAULT_CONFIG.POINT_TYPE_ACTION
|
||||
);
|
||||
|
||||
actionPoints.forEach((pen) => {
|
||||
const stationName = pen.label; // 如 "AP9"
|
||||
@ -114,7 +238,7 @@ export class StorageLocationService {
|
||||
const allOccupied = locations.every((loc) => loc.is_occupied);
|
||||
const allLocked = locations.every((loc) => loc.is_locked);
|
||||
|
||||
const color = allOccupied ? '#ff4d4f' : '#52c41a'; // 占用红色,否则绿色
|
||||
const color = allOccupied ? this.config.colors.occupied : this.config.colors.available;
|
||||
|
||||
// 更新边框颜色
|
||||
this.editor?.updatePointBorderColor(pointId, color);
|
||||
@ -137,7 +261,7 @@ export class StorageLocationService {
|
||||
* @param message 库位状态更新消息
|
||||
*/
|
||||
private handleStorageLocationUpdate(message: StorageLocationMessage) {
|
||||
if (message.type === 'storage_location_update') {
|
||||
if (message.type === MESSAGE_TYPES.BATCH_UPDATE) {
|
||||
// 优先使用后端提供的 operate_point_id 直接映射到画布点ID;
|
||||
// 若无该字段或为空,再回退通过站点名映射到点标签。
|
||||
const stationToPointIdMap = this.buildStationToPointIdMap();
|
||||
@ -181,7 +305,7 @@ export class StorageLocationService {
|
||||
|
||||
// 批量更新后触发一次重绘
|
||||
this.scheduleRender();
|
||||
} else if (message.type === 'storage_location_status_change') {
|
||||
} else if (message.type === MESSAGE_TYPES.SINGLE_UPDATE) {
|
||||
// 处理单个库位状态变化
|
||||
const { new_status } = message;
|
||||
const pointId = this.getPointIdByStorageLocationId(new_status.id);
|
||||
@ -228,7 +352,9 @@ export class StorageLocationService {
|
||||
this.stopMonitoring();
|
||||
|
||||
// 监控库位状态
|
||||
const ws = await monitorStorageLocationById(this.sceneId, { interval: options.interval || 3 });
|
||||
const ws = await monitorStorageLocationById(this.sceneId, {
|
||||
interval: options.interval || this.config.monitoring.defaultInterval
|
||||
});
|
||||
if (isNil(ws)) return;
|
||||
|
||||
ws.onmessage = (e) => {
|
||||
@ -243,7 +369,7 @@ export class StorageLocationService {
|
||||
// 连接成功后主动请求当前状态
|
||||
ws.onopen = () => {
|
||||
const message = {
|
||||
type: 'get_status',
|
||||
type: MESSAGE_TYPES.GET_STATUS,
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
ws.send(JSON.stringify(message));
|
||||
@ -278,7 +404,7 @@ export class StorageLocationService {
|
||||
if (!this.editor) return;
|
||||
|
||||
const pointPen = this.editor.getPenById(pointId);
|
||||
if (!pointPen || pointPen.name !== 'point' || pointPen.point?.type !== MapPointType.动作点) {
|
||||
if (!pointPen || pointPen.name !== this.config.penTypes.point || pointPen.point?.type !== MapPointType.动作点) {
|
||||
console.warn(`无法为 ${pointId} 创建库位: 不是动作点或点位不存在`);
|
||||
return;
|
||||
}
|
||||
@ -341,7 +467,7 @@ export class StorageLocationService {
|
||||
const updatedState = { ...storagePen.storageLocation, ...state };
|
||||
this.editor.updatePen(storagePen.id!, {
|
||||
storageLocation: updatedState,
|
||||
background: updatedState.occupied ? '#ff4d4f' : '#f5f5f5',
|
||||
background: updatedState.occupied ? this.config.colors.occupied : this.config.colors.default,
|
||||
}, false);
|
||||
}
|
||||
return;
|
||||
@ -368,7 +494,7 @@ export class StorageLocationService {
|
||||
const updatedState = { ...pen.storageLocation, ...state };
|
||||
this.editor.updatePen(pen.id!, {
|
||||
storageLocation: updatedState,
|
||||
background: updatedState.occupied ? '#ff4d4f' : '#f5f5f5',
|
||||
background: updatedState.occupied ? this.config.colors.occupied : this.config.colors.default,
|
||||
}, false);
|
||||
}
|
||||
}
|
||||
@ -383,8 +509,10 @@ export class StorageLocationService {
|
||||
public delete(pointId: string): void {
|
||||
if (!this.editor) return;
|
||||
|
||||
const storagePens = this.editor.find('storage-location,storage-more,storage-background').filter(
|
||||
(pen) => pen.tags?.includes(`point-${pointId}`)
|
||||
const storagePens = this.editor.find(
|
||||
`${this.config.penTypes.storageLocation},${this.config.penTypes.storageMore},${this.config.penTypes.storageBackground}`
|
||||
).filter(
|
||||
(pen) => pen.tags?.includes(`${this.config.tags.pointPrefix}${pointId}`)
|
||||
);
|
||||
if (storagePens.length > 0) {
|
||||
this.editor.delete(storagePens, true, true);
|
||||
@ -417,8 +545,8 @@ export class StorageLocationService {
|
||||
private getStorageLocationPens(pointId: string): MapPen[] {
|
||||
if (!this.editor) return [];
|
||||
|
||||
return this.editor.find('storage-location,storage-more').filter(
|
||||
(pen) => pen.tags?.includes(`point-${pointId}`)
|
||||
return this.editor.find(`${this.config.penTypes.storageLocation},${this.config.penTypes.storageMore}`).filter(
|
||||
(pen) => pen.tags?.includes(`${this.config.tags.pointPrefix}${pointId}`)
|
||||
);
|
||||
}
|
||||
|
||||
@ -431,7 +559,7 @@ export class StorageLocationService {
|
||||
private findStorageLocationPen(pointId: string, locationName: string): MapPen | undefined {
|
||||
if (!this.editor) return undefined;
|
||||
|
||||
return this.editor.find('storage-location').find(
|
||||
return this.editor.find(this.config.penTypes.storageLocation).find(
|
||||
(pen) => pen.storageLocation?.pointId === pointId && pen.storageLocation?.locationName === locationName
|
||||
);
|
||||
}
|
||||
@ -443,7 +571,7 @@ export class StorageLocationService {
|
||||
public createAll(): void {
|
||||
if (!this.editor) return;
|
||||
|
||||
const actionPoints = this.editor.find('point').filter(
|
||||
const actionPoints = this.editor.find(this.config.penTypes.point).filter(
|
||||
(pen) => pen.point?.type === MapPointType.动作点 && pen.point?.associatedStorageLocations?.length
|
||||
);
|
||||
|
||||
@ -542,3 +670,36 @@ export class StorageLocationUpdater {
|
||||
export function createStorageLocationUpdater(service: StorageLocationService): StorageLocationUpdater {
|
||||
return new StorageLocationUpdater(service);
|
||||
}
|
||||
|
||||
// ==================== 使用示例 ====================
|
||||
|
||||
/**
|
||||
* 创建自定义配置的库位服务示例
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // 使用默认配置
|
||||
* const service = new StorageLocationService(editor, sceneId);
|
||||
*
|
||||
* // 使用自定义配置
|
||||
* const customService = new StorageLocationService(editor, sceneId, {
|
||||
* colors: {
|
||||
* occupied: '#ff0000', // 自定义占用颜色
|
||||
* available: '#00ff00', // 自定义可用颜色
|
||||
* default: '#cccccc' // 自定义默认颜色
|
||||
* },
|
||||
* penTypes: {
|
||||
* point: 'custom-point', // 自定义点类型
|
||||
* storageLocation: 'custom-storage-location'
|
||||
* },
|
||||
* monitoring: {
|
||||
* defaultInterval: 5 // 自定义监控间隔
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* // 运行时更新配置
|
||||
* service.updateConfig({
|
||||
* colors: { occupied: '#ff4444' }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user