diff --git a/.env.development b/.env.development index 3f57635..8d42708 100644 --- a/.env.development +++ b/.env.development @@ -4,5 +4,5 @@ ENV_WEBSOCKET_BASE=/ws ENV_STORAGE_WEBSOCKET_BASE=/vwedWs # 开发环境token配置 - 可以手动设置或从另一个项目获取后填入 -ENV_DEV_TOKEN=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3NTAzMzkwMTcsInVzZXJuYW1lIjoiYWRtaW4ifQ.uGWMIPH9-sdyEwr0bQBMKQSTAjYBZhlIVDRHGtheENE +ENV_DEV_TOKEN=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3NTc0NDc3NzMsInVzZXJuYW1lIjoiYWRtaW4ifQ.kCwSuHfYWZS5uVZLL912gTT2OrCEO4dyHJAjkDz7hE0 ENV_DEV_TENANT_ID=1000 diff --git a/src/components/color/color-config-panel.vue b/src/components/color/color-config-panel.vue index fdd5c83..e91121a 100644 --- a/src/components/color/color-config-panel.vue +++ b/src/components/color/color-config-panel.vue @@ -10,35 +10,35 @@
@@ -55,35 +55,35 @@
@@ -170,21 +170,21 @@
@@ -196,28 +196,28 @@
@@ -276,14 +276,14 @@
@@ -331,14 +331,12 @@ const hasRobotSizeChanged = computed(() => { tempRobotSize.value.imageHeight !== config.value.robot.imageHeight; }); -const updateColor = (path: string, event: Event | { target: { value: string } }) => { - const target = event.target as HTMLInputElement; - if (target) { - colorConfig.setColor(path, target.value); - } +// 通用颜色更新方法 +const updateColor = (path: string, value: string) => { + colorConfig.setColor(path, value); }; -// 更新临时机器人尺寸 +// 机器人尺寸相关方法 const updateTempRobotSize = (key: 'imageWidth' | 'imageHeight', event: Event) => { const target = event.target as HTMLInputElement; if (target) { @@ -346,51 +344,45 @@ const updateTempRobotSize = (key: 'imageWidth' | 'imageHeight', event: Event) => } }; -// 应用机器人尺寸更改 const applyRobotSize = () => { colorConfig.setColor('robot.imageWidth', tempRobotSize.value.imageWidth.toString()); colorConfig.setColor('robot.imageHeight', tempRobotSize.value.imageHeight.toString()); }; -// 重置机器人尺寸到当前配置值 const resetRobotSize = () => { tempRobotSize.value.imageWidth = config.value.robot.imageWidth; tempRobotSize.value.imageHeight = config.value.robot.imageHeight; }; -// 更新边框属性 +// 边框配置相关方法 const updateBorderProperty = (property: 'width', event: Event) => { const target = event.target as HTMLInputElement; - if (target) { - const value = Number(target.value); - // 更新全局边框宽度 - colorConfig.setColor(`area.border.${property}`, value.toString()); - - // 同时更新所有区域类型的边框宽度 - const areaTypes = [1, 11, 12, 13, 14]; - areaTypes.forEach(type => { - colorConfig.setAreaBorderWidth(type, value); - }); - } + if (!target) return; + + const value = Number(target.value); + colorConfig.setColor(`area.border.${property}`, value.toString()); + + // 同时更新所有区域类型的边框属性 + const areaTypes = [1, 11, 12, 13, 14]; + areaTypes.forEach(type => { + colorConfig.setAreaBorderWidth(type, value); + }); }; -// 更新边框透明度 const updateBorderOpacity = (event: Event) => { const target = event.target as HTMLInputElement; - if (target) { - const opacity = Number(target.value) / 100; - // 更新全局边框透明度 - colorConfig.setColor('area.border.opacity', opacity.toString()); - - // 同时更新所有区域类型的边框透明度 - const areaTypes = [1, 11, 12, 13, 14]; - areaTypes.forEach(type => { - colorConfig.setAreaBorderOpacity(type, opacity); - }); - } + if (!target) return; + + const opacity = Number(target.value) / 100; + colorConfig.setColor('area.border.opacity', opacity.toString()); + + // 同时更新所有区域类型的边框透明度 + const areaTypes = [1, 11, 12, 13, 14]; + areaTypes.forEach(type => { + colorConfig.setAreaBorderOpacity(type, opacity); + }); }; -// 更新区域边框颜色 const updateAreaBorderColor = (areaType: number, color: string) => { colorConfig.setAreaBorderColor(areaType, color); }; diff --git a/src/services/color/color-config.service.ts b/src/services/color/color-config.service.ts index ff77bd6..4de8cec 100644 --- a/src/services/color/color-config.service.ts +++ b/src/services/color/color-config.service.ts @@ -1,6 +1,17 @@ +import { MapAreaType, MapPointType } from '@api/map'; import sTheme from '@core/theme.service'; import { ref, watch } from 'vue'; +/** + * 点位类型常量 - 从枚举中提取数字类型 + */ +const POINT_TYPES = Object.values(MapPointType).filter(value => typeof value === 'number') as number[]; + +/** + * 区域类型常量 - 从枚举中提取数字类型 + */ +const AREA_TYPES = Object.values(MapAreaType).filter(value => typeof value === 'number') as number[]; + /** * 编辑器颜色配置接口 */ @@ -110,6 +121,129 @@ export interface EditorColorConfig { }; } +/** + * 生成点位类型的默认颜色配置 + */ +function generatePointTypeColors(): Record { + const colors: Record = {}; + + // 预定义的颜色方案 + const colorSchemes = { + // 小点位颜色 (1-9) + small: { + stroke: '#8C8C8C', + strokeActive: '#EBB214', + fills: ['#14D1A5', '#69C6F5', '#E48B1D', '#E48B1D', '#a72b69'] + }, + // 大点位颜色 (11+) + large: { + stroke: '#595959', + strokeActive: '#EBB214', + fills: ['#1890ff', '#52c41a', '#faad14', '#722ed1', '#13c2c2', '#ff4d4f'] + } + }; + + POINT_TYPES.forEach(type => { + const isSmallPoint = type >= 1 && type <= 9; + const scheme = isSmallPoint ? colorSchemes.small : colorSchemes.large; + const fillIndex = isSmallPoint ? (type - 1) : (type - 11); + + colors[type] = { + stroke: scheme.stroke, + strokeActive: scheme.strokeActive, + fill: scheme.fills[fillIndex] || scheme.fills[0] + }; + }); + + return colors; +} + +/** + * 生成区域类型的默认颜色配置 + */ +function generateAreaTypeColors(): Record { + const colors: Record = {}; + + // 预定义的颜色方案 + const colorSchemes = [ + { stroke: '#9ACDFF99', fill: '#9ACDFF33', borderColor: '#1890FF' }, // 库区 + { stroke: '#FF535399', fill: '#FF9A9A33', borderColor: '#FF4D4F' }, // 互斥区 + { stroke: '#0DBB8A99', fill: '#0DBB8A33', borderColor: '#52C41A' }, // 非互斥区 + { stroke: '#e61e4aad', fill: '#e61e4a33', borderColor: '#FA8C16' }, // 约束区 + { stroke: '#FFD70099', fill: '#FFD70033', borderColor: '#722ED1' } // 描述区 + ]; + + AREA_TYPES.forEach((type, index) => { + const scheme = colorSchemes[index] || colorSchemes[0]; + colors[type] = { + stroke: scheme.stroke, + strokeActive: '#EBB214', + fill: scheme.fill, + borderColor: scheme.borderColor, + borderWidth: 1, + borderOpacity: 0.15 + }; + }); + + return colors; +} + +/** + * 生成区域描边颜色配置 + */ +function generateAreaStrokeColors(): Record { + const colors: Record = {}; + const colorSchemes = ['#9ACDFF99', '#FF535399', '#0DBB8A99', '#e61e4aad', '#FFD70099']; + + AREA_TYPES.forEach((type, index) => { + colors[type] = colorSchemes[index] || colorSchemes[0]; + }); + + return colors; +} + +/** + * 生成区域填充颜色配置 + */ +function generateAreaFillColors(): Record { + const colors: Record = {}; + const colorSchemes = ['#9ACDFF33', '#FF9A9A33', '#0DBB8A33', '#e61e4a33', '#FFD70033']; + + AREA_TYPES.forEach((type, index) => { + colors[type] = colorSchemes[index] || colorSchemes[0]; + }); + + return colors; +} + +/** + * 生成区域边框颜色配置 + */ +function generateAreaBorderColors(): Record { + const colors: Record = {}; + const colorSchemes = ['#1890FF', '#FF4D4F', '#52C41A', '#FA8C16', '#722ED1']; + + AREA_TYPES.forEach((type, index) => { + colors[type] = colorSchemes[index] || colorSchemes[0]; + }); + + return colors; +} + /** * 默认颜色配置 */ @@ -137,21 +271,7 @@ const DEFAULT_COLORS: EditorColorConfig = { strokeLocked: '#faad14', strokeUnlocked: '#52c41a' }, - types: { - // 小点位类型 (1-9) - 1: { stroke: '#8C8C8C', strokeActive: '#EBB214', fill: '#14D1A5' }, // 普通点 - 2: { stroke: '#8C8C8C', strokeActive: '#EBB214', fill: '#69C6F5' }, // 等待点 - 3: { stroke: '#8C8C8C', strokeActive: '#EBB214', fill: '#E48B1D' }, // 避让点 - 4: { stroke: '#8C8C8C', strokeActive: '#EBB214', fill: '#E48B1D' }, // 临时避让点 - 5: { stroke: '#8C8C8C', strokeActive: '#EBB214', fill: '#a72b69' }, // 库区点 - // 大点位类型 (11+) - 11: { stroke: '#595959', strokeActive: '#EBB214', fill: '#1890ff' }, // 电梯点 - 12: { stroke: '#595959', strokeActive: '#EBB214', fill: '#52c41a' }, // 自动门点 - 13: { stroke: '#595959', strokeActive: '#EBB214', fill: '#faad14' }, // 充电点 - 14: { stroke: '#595959', strokeActive: '#EBB214', fill: '#722ed1' }, // 停靠点 - 15: { stroke: '#595959', strokeActive: '#EBB214', fill: '#13c2c2' }, // 动作点 - 16: { stroke: '#595959', strokeActive: '#EBB214', fill: '#ff4d4f' }, // 禁行点 - } + types: generatePointTypeColors() }, route: { strokeActive: '#EBB214', @@ -161,75 +281,15 @@ const DEFAULT_COLORS: EditorColorConfig = { }, area: { strokeActive: '#EBB214', - stroke: { - 1: '#9ACDFF99', - 11: '#FF535399', - 12: '#0DBB8A99', - 13: '#e61e4aad', - 14: '#FFD70099' - }, - fill: { - 1: '#9ACDFF33', - 11: '#FF9A9A33', - 12: '#0DBB8A33', - 13: '#e61e4a33', - 14: '#FFD70033' - }, + stroke: generateAreaStrokeColors(), + fill: generateAreaFillColors(), // 边框配置 border: { width: 1, // 默认边框宽度 opacity: 0.15, // 默认边框透明度 15% - colors: { - 1: '#1890FF', // 库区边框颜色 - 11: '#FF4D4F', // 互斥区边框颜色 - 12: '#52C41A', // 非互斥区边框颜色 - 13: '#FA8C16', // 约束区边框颜色 - 14: '#722ED1' // 描述区边框颜色 - } + colors: generateAreaBorderColors() }, - types: { - // 区域类型 - 1: { - stroke: '#9ACDFF99', - strokeActive: '#EBB214', - fill: '#9ACDFF33', - borderColor: '#1890FF', - borderWidth: 1, - borderOpacity: 0.15 - }, // 库区 - 11: { - stroke: '#FF535399', - strokeActive: '#EBB214', - fill: '#FF9A9A33', - borderColor: '#FF4D4F', - borderWidth: 1, - borderOpacity: 0.15 - }, // 互斥区 - 12: { - stroke: '#0DBB8A99', - strokeActive: '#EBB214', - fill: '#0DBB8A33', - borderColor: '#52C41A', - borderWidth: 1, - borderOpacity: 0.15 - }, // 非互斥区 - 13: { - stroke: '#e61e4aad', - strokeActive: '#EBB214', - fill: '#e61e4a33', - borderColor: '#FA8C16', - borderWidth: 1, - borderOpacity: 0.15 - }, // 约束区 - 14: { - stroke: '#FFD70099', - strokeActive: '#EBB214', - fill: '#FFD70033', - borderColor: '#722ED1', - borderWidth: 1, - borderOpacity: 0.15 - }, // 描述区 - } + types: generateAreaTypeColors() }, robot: { stroke: '#01FDAF99', @@ -414,6 +474,9 @@ class ColorConfigService { // 重置标记,允许后续自动保存 this.isResetting = false; + // 更新所有机器人的图片尺寸 + this.updateAllRobotImageSizes(); + // 触发编辑器重新渲染 this.triggerRender(); } @@ -526,138 +589,164 @@ class ColorConfigService { * 从主题配置加载默认颜色 */ private loadConfig(): void { - // 如果正在重置,不加载主题配置 - if (this.isResetting) { - return; - } + if (this.isResetting) return; const theme = sTheme.editor as any; - if (theme) { - // 从主题配置中加载颜色,如果没有则使用默认值 - this.config.value = this.mergeConfig(DEFAULT_COLORS, { - point: { - small: { - stroke: theme['point-s']?.stroke || DEFAULT_COLORS.point.small.stroke, - strokeActive: theme['point-s']?.strokeActive || DEFAULT_COLORS.point.small.strokeActive, - fill: { - 1: theme['point-s']?.['fill-1'] || DEFAULT_COLORS.point.small.fill[1], - 2: theme['point-s']?.['fill-2'] || DEFAULT_COLORS.point.small.fill[2], - 3: theme['point-s']?.['fill-3'] || DEFAULT_COLORS.point.small.fill[3], - 4: theme['point-s']?.['fill-4'] || DEFAULT_COLORS.point.small.fill[4], - 5: theme['point-s']?.['fill-5'] || DEFAULT_COLORS.point.small.fill[5], - } - }, - large: { - stroke: theme['point-l']?.stroke || DEFAULT_COLORS.point.large.stroke, - strokeActive: theme['point-l']?.strokeActive || DEFAULT_COLORS.point.large.strokeActive, - strokeOccupied: theme['point-l']?.['stroke-occupied'] || DEFAULT_COLORS.point.large.strokeOccupied, - strokeUnoccupied: theme['point-l']?.['stroke-unoccupied'] || DEFAULT_COLORS.point.large.strokeUnoccupied, - strokeEmpty: theme['point-l']?.['stroke-empty'] || DEFAULT_COLORS.point.large.strokeEmpty, - strokeDisabled: theme['point-l']?.['stroke-disabled'] || DEFAULT_COLORS.point.large.strokeDisabled, - strokeEnabled: theme['point-l']?.['stroke-enabled'] || DEFAULT_COLORS.point.large.strokeEnabled, - strokeLocked: theme['point-l']?.['stroke-locked'] || DEFAULT_COLORS.point.large.strokeLocked, - strokeUnlocked: theme['point-l']?.['stroke-unlocked'] || DEFAULT_COLORS.point.large.strokeUnlocked, - } + if (!theme) return; + + // 使用简化的主题配置映射 + const themeConfig = this.buildThemeConfig(theme); + this.config.value = this.mergeConfig(DEFAULT_COLORS, themeConfig); + } + + /** + * 构建主题配置对象 + */ + private buildThemeConfig(theme: any): Partial { + const config: Partial = {}; + + // 点位配置 + if (theme['point-s'] || theme['point-l']) { + config.point = { + small: { + stroke: theme['point-s']?.stroke || DEFAULT_COLORS.point.small.stroke, + strokeActive: theme['point-s']?.strokeActive || DEFAULT_COLORS.point.small.strokeActive, + fill: this.buildFillConfig(theme['point-s'], 'fill', DEFAULT_COLORS.point.small.fill) }, - route: { - strokeActive: theme.route?.strokeActive || DEFAULT_COLORS.route.strokeActive, - strokeEmpty: theme.route?.['stroke-empty'] || DEFAULT_COLORS.route.strokeEmpty, - strokeLoaded: theme.route?.['stroke-loaded'] || DEFAULT_COLORS.route.strokeLoaded, - strokeForbidden: theme.route?.['stroke-forbidden'] || DEFAULT_COLORS.route.strokeForbidden, + large: { + stroke: theme['point-l']?.stroke || DEFAULT_COLORS.point.large.stroke, + strokeActive: theme['point-l']?.strokeActive || DEFAULT_COLORS.point.large.strokeActive, + strokeOccupied: theme['point-l']?.['stroke-occupied'] || DEFAULT_COLORS.point.large.strokeOccupied, + strokeUnoccupied: theme['point-l']?.['stroke-unoccupied'] || DEFAULT_COLORS.point.large.strokeUnoccupied, + strokeEmpty: theme['point-l']?.['stroke-empty'] || DEFAULT_COLORS.point.large.strokeEmpty, + strokeDisabled: theme['point-l']?.['stroke-disabled'] || DEFAULT_COLORS.point.large.strokeDisabled, + strokeEnabled: theme['point-l']?.['stroke-enabled'] || DEFAULT_COLORS.point.large.strokeEnabled, + strokeLocked: theme['point-l']?.['stroke-locked'] || DEFAULT_COLORS.point.large.strokeLocked, + strokeUnlocked: theme['point-l']?.['stroke-unlocked'] || DEFAULT_COLORS.point.large.strokeUnlocked, }, - area: { - strokeActive: theme.area?.strokeActive || DEFAULT_COLORS.area.strokeActive, - stroke: { - 1: theme.area?.['stroke-1'] || DEFAULT_COLORS.area.stroke[1], - 11: theme.area?.['stroke-11'] || DEFAULT_COLORS.area.stroke[11], - 12: theme.area?.['stroke-12'] || DEFAULT_COLORS.area.stroke[12], - 13: theme.area?.['stroke-13'] || DEFAULT_COLORS.area.stroke[13], - 14: theme.area?.['stroke-14'] || DEFAULT_COLORS.area.stroke[14], - }, - fill: { - 1: theme.area?.['fill-1'] || DEFAULT_COLORS.area.fill[1], - 11: theme.area?.['fill-11'] || DEFAULT_COLORS.area.fill[11], - 12: theme.area?.['fill-12'] || DEFAULT_COLORS.area.fill[12], - 13: theme.area?.['fill-13'] || DEFAULT_COLORS.area.fill[13], - 14: theme.area?.['fill-14'] || DEFAULT_COLORS.area.fill[14], - }, - border: { - width: theme.area?.border?.width || DEFAULT_COLORS.area.border.width, - opacity: theme.area?.border?.opacity || DEFAULT_COLORS.area.border.opacity, - colors: { - 1: theme.area?.border?.['color-1'] || DEFAULT_COLORS.area.border.colors[1], - 11: theme.area?.border?.['color-11'] || DEFAULT_COLORS.area.border.colors[11], - 12: theme.area?.border?.['color-12'] || DEFAULT_COLORS.area.border.colors[12], - 13: theme.area?.border?.['color-13'] || DEFAULT_COLORS.area.border.colors[13], - 14: theme.area?.border?.['color-14'] || DEFAULT_COLORS.area.border.colors[14], - } - }, - types: { - 1: { - stroke: theme.area?.['stroke-1'] || DEFAULT_COLORS.area.types[1].stroke, - strokeActive: theme.area?.strokeActive || DEFAULT_COLORS.area.types[1].strokeActive, - fill: theme.area?.['fill-1'] || DEFAULT_COLORS.area.types[1].fill, - borderColor: theme.area?.border?.['color-1'] || DEFAULT_COLORS.area.types[1].borderColor, - borderWidth: theme.area?.border?.width || DEFAULT_COLORS.area.types[1].borderWidth, - borderOpacity: theme.area?.border?.opacity || DEFAULT_COLORS.area.types[1].borderOpacity, - }, - 11: { - stroke: theme.area?.['stroke-11'] || DEFAULT_COLORS.area.types[11].stroke, - strokeActive: theme.area?.strokeActive || DEFAULT_COLORS.area.types[11].strokeActive, - fill: theme.area?.['fill-11'] || DEFAULT_COLORS.area.types[11].fill, - borderColor: theme.area?.border?.['color-11'] || DEFAULT_COLORS.area.types[11].borderColor, - borderWidth: theme.area?.border?.width || DEFAULT_COLORS.area.types[11].borderWidth, - borderOpacity: theme.area?.border?.opacity || DEFAULT_COLORS.area.types[11].borderOpacity, - }, - 12: { - stroke: theme.area?.['stroke-12'] || DEFAULT_COLORS.area.types[12].stroke, - strokeActive: theme.area?.strokeActive || DEFAULT_COLORS.area.types[12].strokeActive, - fill: theme.area?.['fill-12'] || DEFAULT_COLORS.area.types[12].fill, - borderColor: theme.area?.border?.['color-12'] || DEFAULT_COLORS.area.types[12].borderColor, - borderWidth: theme.area?.border?.width || DEFAULT_COLORS.area.types[12].borderWidth, - borderOpacity: theme.area?.border?.opacity || DEFAULT_COLORS.area.types[12].borderOpacity, - }, - 13: { - stroke: theme.area?.['stroke-13'] || DEFAULT_COLORS.area.types[13].stroke, - strokeActive: theme.area?.strokeActive || DEFAULT_COLORS.area.types[13].strokeActive, - fill: theme.area?.['fill-13'] || DEFAULT_COLORS.area.types[13].fill, - borderColor: theme.area?.border?.['color-13'] || DEFAULT_COLORS.area.types[13].borderColor, - borderWidth: theme.area?.border?.width || DEFAULT_COLORS.area.types[13].borderWidth, - borderOpacity: theme.area?.border?.opacity || DEFAULT_COLORS.area.types[13].borderOpacity, - }, - 14: { - stroke: theme.area?.['stroke-14'] || DEFAULT_COLORS.area.types[14].stroke, - strokeActive: theme.area?.strokeActive || DEFAULT_COLORS.area.types[14].strokeActive, - fill: theme.area?.['fill-14'] || DEFAULT_COLORS.area.types[14].fill, - borderColor: theme.area?.border?.['color-14'] || DEFAULT_COLORS.area.types[14].borderColor, - borderWidth: theme.area?.border?.width || DEFAULT_COLORS.area.types[14].borderWidth, - borderOpacity: theme.area?.border?.opacity || DEFAULT_COLORS.area.types[14].borderOpacity, - } - } - }, - robot: { - stroke: theme.robot?.stroke || DEFAULT_COLORS.robot.stroke, - fill: theme.robot?.fill || DEFAULT_COLORS.robot.fill, - line: theme.robot?.line || DEFAULT_COLORS.robot.line, - strokeNormal: theme.robot?.['stroke-normal'] || DEFAULT_COLORS.robot.strokeNormal, - fillNormal: theme.robot?.['fill-normal'] || DEFAULT_COLORS.robot.fillNormal, - strokeWarning: theme.robot?.['stroke-warning'] || DEFAULT_COLORS.robot.strokeWarning, - fillWarning: theme.robot?.['fill-warning'] || DEFAULT_COLORS.robot.fillWarning, - strokeFault: theme.robot?.['stroke-fault'] || DEFAULT_COLORS.robot.strokeFault, - fillFault: theme.robot?.['fill-fault'] || DEFAULT_COLORS.robot.fillFault, - }, - autoDoor: { - strokeClosed: theme.autoDoor?.['stroke-closed'] || DEFAULT_COLORS.autoDoor.strokeClosed, - fillClosed: theme.autoDoor?.['fill-closed'] || DEFAULT_COLORS.autoDoor.fillClosed, - strokeOpen: theme.autoDoor?.['stroke-open'] || DEFAULT_COLORS.autoDoor.strokeOpen, - fillOpen: theme.autoDoor?.['fill-open'] || DEFAULT_COLORS.autoDoor.fillOpen, - }, - common: { - color: theme.color || DEFAULT_COLORS.common.color, - background: theme.background || DEFAULT_COLORS.common.background, - } - }); + types: this.buildPointTypesConfig(theme) + }; } + + // 路线配置 + if (theme.route) { + config.route = { + strokeActive: theme.route.strokeActive || DEFAULT_COLORS.route.strokeActive, + strokeEmpty: theme.route['stroke-empty'] || DEFAULT_COLORS.route.strokeEmpty, + strokeLoaded: theme.route['stroke-loaded'] || DEFAULT_COLORS.route.strokeLoaded, + strokeForbidden: theme.route['stroke-forbidden'] || DEFAULT_COLORS.route.strokeForbidden, + }; + } + + // 区域配置 + if (theme.area) { + config.area = { + strokeActive: theme.area.strokeActive || DEFAULT_COLORS.area.strokeActive, + stroke: this.buildFillConfig(theme.area, 'stroke', DEFAULT_COLORS.area.stroke), + fill: this.buildFillConfig(theme.area, 'fill', DEFAULT_COLORS.area.fill), + border: { + width: theme.area.border?.width || DEFAULT_COLORS.area.border.width, + opacity: theme.area.border?.opacity || DEFAULT_COLORS.area.border.opacity, + colors: this.buildFillConfig(theme.area.border, 'color', DEFAULT_COLORS.area.border.colors) + }, + types: this.buildAreaTypesConfig(theme.area) + }; + } + + // 机器人配置 + if (theme.robot) { + config.robot = { + stroke: theme.robot.stroke || DEFAULT_COLORS.robot.stroke, + fill: theme.robot.fill || DEFAULT_COLORS.robot.fill, + line: theme.robot.line || DEFAULT_COLORS.robot.line, + strokeNormal: theme.robot['stroke-normal'] || DEFAULT_COLORS.robot.strokeNormal, + fillNormal: theme.robot['fill-normal'] || DEFAULT_COLORS.robot.fillNormal, + strokeWarning: theme.robot['stroke-warning'] || DEFAULT_COLORS.robot.strokeWarning, + fillWarning: theme.robot['fill-warning'] || DEFAULT_COLORS.robot.fillWarning, + strokeFault: theme.robot['stroke-fault'] || DEFAULT_COLORS.robot.strokeFault, + fillFault: theme.robot['fill-fault'] || DEFAULT_COLORS.robot.fillFault, + imageWidth: DEFAULT_COLORS.robot.imageWidth, + imageHeight: DEFAULT_COLORS.robot.imageHeight + }; + } + + // 自动门配置 + if (theme.autoDoor) { + config.autoDoor = { + strokeClosed: theme.autoDoor['stroke-closed'] || DEFAULT_COLORS.autoDoor.strokeClosed, + fillClosed: theme.autoDoor['fill-closed'] || DEFAULT_COLORS.autoDoor.fillClosed, + strokeOpen: theme.autoDoor['stroke-open'] || DEFAULT_COLORS.autoDoor.strokeOpen, + fillOpen: theme.autoDoor['fill-open'] || DEFAULT_COLORS.autoDoor.fillOpen, + }; + } + + // 通用配置 + if (theme.color || theme.background) { + config.common = { + color: theme.color || DEFAULT_COLORS.common.color, + background: theme.background || DEFAULT_COLORS.common.background, + }; + } + + return config; + } + + /** + * 构建填充颜色配置 + */ + private buildFillConfig(theme: any, prefix: string, defaultConfig: Record): Record { + const config: Record = {}; + + AREA_TYPES.forEach(type => { + const key = `${prefix}-${type}`; + config[type] = theme[key] || defaultConfig[type]; + }); + + return config; + } + + /** + * 构建点位类型配置 + */ + private buildPointTypesConfig(theme: any): Record { + const types: Record = {}; + + POINT_TYPES.forEach(type => { + types[type] = { + stroke: theme['point-s']?.stroke || + DEFAULT_COLORS.point.types[type]?.stroke || + DEFAULT_COLORS.point.small.stroke, + strokeActive: theme['point-s']?.strokeActive || + DEFAULT_COLORS.point.types[type]?.strokeActive || + DEFAULT_COLORS.point.small.strokeActive, + fill: theme['point-s']?.[`fill-${type}`] || + DEFAULT_COLORS.point.types[type]?.fill || + DEFAULT_COLORS.point.small.fill[type] || + DEFAULT_COLORS.point.small.fill[1] + }; + }); + + return types; + } + + /** + * 构建区域类型配置 + */ + private buildAreaTypesConfig(theme: any): Record { + const types: Record = {}; + + AREA_TYPES.forEach(type => { + types[type] = { + stroke: theme[`stroke-${type}`] || DEFAULT_COLORS.area.types[type].stroke, + strokeActive: theme.strokeActive || DEFAULT_COLORS.area.types[type].strokeActive, + fill: theme[`fill-${type}`] || DEFAULT_COLORS.area.types[type].fill, + borderColor: theme.border?.[`color-${type}`] || DEFAULT_COLORS.area.types[type].borderColor, + borderWidth: theme.border?.width || DEFAULT_COLORS.area.types[type].borderWidth, + borderOpacity: theme.border?.opacity || DEFAULT_COLORS.area.types[type].borderOpacity, + }; + }); + + return types; } /**