From 8405d98fe0b1c7814f9fbfd17774dad9c1ce57ff Mon Sep 17 00:00:00 2001 From: xudan Date: Mon, 8 Sep 2025 18:02:19 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E6=97=A0=E8=B7=AF?= =?UTF-8?q?=E7=BA=BF=E9=A2=9C=E8=89=B2=E9=85=8D=E7=BD=AE=EF=BC=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E9=A2=9C=E8=89=B2=E7=AE=A1=E7=90=86=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E4=BB=A5=E6=94=AF=E6=8C=81=E6=9A=97=E8=89=B2=E4=B8=BB=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/color/color-config.service.ts | 201 ++++++++++++++++++++- src/services/editor.service.ts | 7 +- 2 files changed, 196 insertions(+), 12 deletions(-) diff --git a/src/services/color/color-config.service.ts b/src/services/color/color-config.service.ts index 2f5e495..67494c1 100644 --- a/src/services/color/color-config.service.ts +++ b/src/services/color/color-config.service.ts @@ -1,7 +1,8 @@ import { MapAreaType, MapPointType } from '@api/map'; -import sTheme from '@core/theme.service'; import { ref, watch } from 'vue'; +import sTheme from '../theme.service'; + /** * 点位类型常量 - 从枚举中提取数字类型 */ @@ -47,6 +48,7 @@ export interface EditorColorConfig { // 路线颜色 route: { strokeActive: string; + strokeNone: string; // 无路线颜色 strokeEmpty: string; // 空载路线颜色 strokeLoaded: string; // 载货路线颜色 strokeForbidden: string; // 禁行路线颜色 @@ -249,7 +251,7 @@ function generateAreaBorderColors(): Record { } /** - * 默认颜色配置 + * 默认颜色配置(亮色主题) */ const DEFAULT_COLORS: EditorColorConfig = { point: { @@ -279,6 +281,7 @@ const DEFAULT_COLORS: EditorColorConfig = { }, route: { strokeActive: '#EBB214', + strokeNone: '#8C8C8C', // 无路线 - 灰色 strokeEmpty: '#52C41A', // 空载路线 - 绿色 strokeLoaded: '#1982F3', // 载货路线 - 蓝色 strokeForbidden: '#E63A3A' // 禁行路线 - 红色 @@ -331,6 +334,149 @@ const DEFAULT_COLORS: EditorColorConfig = { } }; +/** + * 暗色主题默认颜色配置 + */ +const DARK_THEME_COLORS: EditorColorConfig = { + point: { + small: { + stroke: '#8C8C8C', + strokeActive: '#FCC947', + fill: { + 1: '#14D1A5', + 2: '#69C6F5', + 3: '#E48B1D', + 4: '#E48B1D', + 5: '#a72b69' + } + }, + large: { + stroke: '#595959', + strokeActive: '#FCC947', + strokeOccupied: '#ff4d4f', + strokeUnoccupied: '#52c41a', + strokeEmpty: '#1890ff', + strokeDisabled: '#bfbfbf', + strokeEnabled: '#52c41a', + strokeLocked: '#faad14', + strokeUnlocked: '#52c41a' + }, + types: generatePointTypeColors() + }, + route: { + strokeActive: '#FCC947', + strokeNone: '#8C8C8C', // 无路线 - 灰色 + strokeEmpty: '#49AA19', // 空载路线 - 绿色 + strokeLoaded: '#1982F3', // 载货路线 - 蓝色 + strokeForbidden: '#E63A3A' // 禁行路线 - 红色 + }, + area: { + strokeActive: '#FCC947', + stroke: { + 1: '#9ACDFF99', + 11: '#FF535399', + 12: '#0DBB8A99', + 13: '#e61e4aad', + 14: '#FFD70099' + }, + fill: { + 1: '#9ACDFF33', + 11: '#FF9A9A33', + 12: '#0DBB8A33', + 13: '#e61e4a33', + 14: '#FFD70033' + }, + // 边框配置 + border: { + width: 1, // 默认边框宽度 + opacity: 0.15, // 默认边框透明度 15% + colors: { + 1: '#1890FF', + 11: '#FF4D4F', + 12: '#52C41A', + 13: '#FA8C16', + 14: '#722ED1' + } + }, + types: { + 1: { + stroke: '#9ACDFF99', + strokeActive: '#FCC947', + fill: '#9ACDFF33', + borderColor: '#1890FF', + borderWidth: 1, + borderOpacity: 0.15 + }, + 11: { + stroke: '#FF535399', + strokeActive: '#FCC947', + fill: '#FF9A9A33', + borderColor: '#FF4D4F', + borderWidth: 1, + borderOpacity: 0.15 + }, + 12: { + stroke: '#0DBB8A99', + strokeActive: '#FCC947', + fill: '#0DBB8A33', + borderColor: '#52C41A', + borderWidth: 1, + borderOpacity: 0.15 + }, + 13: { + stroke: '#e61e4aad', + strokeActive: '#FCC947', + fill: '#e61e4a33', + borderColor: '#FA8C16', + borderWidth: 1, + borderOpacity: 0.15 + }, + 14: { + stroke: '#FFD70099', + strokeActive: '#FCC947', + fill: '#FFD70033', + borderColor: '#722ED1', + borderWidth: 1, + borderOpacity: 0.15 + } + } + }, + robot: { + stroke: '#01FDAF99', + fill: '#01FAAD33', + line: '#01fdaf', + strokeNormal: '#01FDAF99', + fillNormal: '#01FAAD33', + strokeWarning: '#FF851B99', + fillWarning: '#FF851B33', + strokeFault: '#FF4D4F99', + fillFault: '#FF4D4F33', + imageWidth: 42, // 机器人图片宽度 - 42像素 + imageHeight: 76 // 机器人图片高度 - 76像素 + }, + storage: { + occupied: '#ff4d4f', + available: '#52c41a', + default: '#f5f5f5', + locked: '#faad14', + moreButton: { + background: '#e6f4ff', + border: '#1677ff', + text: '#1677ff' + } + }, + autoDoor: { + strokeClosed: '#FF4D4F99', + fillClosed: '#FF4D4F33', + strokeOpen: '#1890FF99', + fillOpen: '#1890FF33' + }, + common: { + color: '#BFBFBF', + background: '#2A2C2C' + } +}; + /** * 颜色配置管理服务 */ @@ -372,6 +518,21 @@ class ColorConfigService { return this.config.value; } + /** + * 获取当前主题的基础配置 + */ + public get currentBaseConfig(): EditorColorConfig { + const isDarkTheme = sTheme.theme === 'dark'; + return isDarkTheme ? DARK_THEME_COLORS : DEFAULT_COLORS; + } + + /** + * 检查当前是否为暗色主题 + */ + public get isDarkTheme(): boolean { + return sTheme.theme === 'dark'; + } + /** * 设置编辑器服务实例 */ @@ -410,13 +571,22 @@ class ColorConfigService { const stored = localStorage.getItem(this.STORAGE_KEY); if (stored) { const parsedConfig = JSON.parse(stored); - this.config.value = this.mergeConfig(DEFAULT_COLORS, parsedConfig); + // 根据当前主题选择基础配置 + const isDarkTheme = sTheme.theme === 'dark'; + const baseConfig = isDarkTheme ? DARK_THEME_COLORS : DEFAULT_COLORS; + this.config.value = this.mergeConfig(baseConfig, parsedConfig); } else { - this.config.value = { ...DEFAULT_COLORS }; + // 根据当前主题选择基础配置 + const isDarkTheme = sTheme.theme === 'dark'; + const baseConfig = isDarkTheme ? DARK_THEME_COLORS : DEFAULT_COLORS; + this.config.value = { ...baseConfig }; } } catch (error) { console.warn('Failed to load color config from localStorage:', error); - this.config.value = { ...DEFAULT_COLORS }; + // 根据当前主题选择基础配置 + const isDarkTheme = sTheme.theme === 'dark'; + const baseConfig = isDarkTheme ? DARK_THEME_COLORS : DEFAULT_COLORS; + this.config.value = { ...baseConfig }; } } @@ -472,8 +642,12 @@ class ColorConfigService { // 清除本地存储 localStorage.removeItem(this.STORAGE_KEY); + // 根据当前主题选择基础配置 + const isDarkTheme = sTheme.theme === 'dark'; + const baseConfig = isDarkTheme ? DARK_THEME_COLORS : DEFAULT_COLORS; + // 重置为默认配置,使用深度复制确保完全重置 - this.config.value = JSON.parse(JSON.stringify(DEFAULT_COLORS)); + this.config.value = JSON.parse(JSON.stringify(baseConfig)); // 重置标记,允许后续自动保存 this.isResetting = false; @@ -598,9 +772,13 @@ class ColorConfigService { const theme = sTheme.editor as any; if (!theme) return; + // 根据当前主题选择基础配置 + const isDarkTheme = sTheme.theme === 'dark'; + const baseConfig = isDarkTheme ? DARK_THEME_COLORS : DEFAULT_COLORS; + // 使用简化的主题配置映射 const themeConfig = this.buildThemeConfig(theme); - this.config.value = this.mergeConfig(DEFAULT_COLORS, themeConfig); + this.config.value = this.mergeConfig(baseConfig, themeConfig); } /** @@ -636,9 +814,12 @@ class ColorConfigService { 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, + strokeNone: theme.route['stroke-0'] || DEFAULT_COLORS.route.strokeNone, + strokeEmpty: theme.route['stroke-1'] || theme.route['stroke-empty'] || DEFAULT_COLORS.route.strokeEmpty, + strokeLoaded: theme.route['stroke-2'] || theme.route['stroke-loaded'] || DEFAULT_COLORS.route.strokeLoaded, + strokeForbidden: theme.route['stroke-10'] || + theme.route['stroke-forbidden'] || + DEFAULT_COLORS.route.strokeForbidden, }; } diff --git a/src/services/editor.service.ts b/src/services/editor.service.ts index 7478c06..9b0ea5d 100644 --- a/src/services/editor.service.ts +++ b/src/services/editor.service.ts @@ -1875,6 +1875,9 @@ function drawLine(ctx: CanvasRenderingContext2D, pen: MapPen): void { } else { // 根据通行类型选择颜色 switch (pass) { + case MapRoutePassType.无: + routeColor = colorConfig.getColor('route.strokeNone') || get(theme, 'route.stroke-0') || ''; + break; case MapRoutePassType.仅空载可通行: routeColor = colorConfig.getColor('route.strokeEmpty') || get(theme, 'route.stroke-empty') || ''; break; @@ -1885,8 +1888,8 @@ function drawLine(ctx: CanvasRenderingContext2D, pen: MapPen): void { routeColor = colorConfig.getColor('route.strokeForbidden') || get(theme, 'route.stroke-forbidden') || ''; break; default: - // 无限制路线使用空载路线颜色作为默认 - routeColor = colorConfig.getColor('route.strokeEmpty') || get(theme, 'route.stroke-empty') || ''; + // 无限制路线使用无路线颜色作为默认 + routeColor = colorConfig.getColor('route.strokeNone') || get(theme, 'route.stroke-0') || ''; break; } }