feat: 重构颜色配置服务,更新存储键管理逻辑,增强主题兼容性,优化配置加载和保存流程
This commit is contained in:
parent
874c3fade3
commit
c31f9d5bef
@ -508,10 +508,13 @@ const DARK_THEME_COLORS: EditorColorConfig = {
|
||||
class ColorConfigService {
|
||||
private config = ref<EditorColorConfig>({ ...DEFAULT_COLORS });
|
||||
private editorService: any = null;
|
||||
private readonly STORAGE_KEY = 'editor-color-config';
|
||||
private readonly STORAGE_KEY_PREFIX = 'editor-color-config';
|
||||
private isResetting = false; // 标记是否正在重置
|
||||
|
||||
constructor() {
|
||||
// 清理旧的存储键
|
||||
this.cleanupOldStorageKeys();
|
||||
|
||||
// 从本地存储加载配置
|
||||
this.loadFromLocalStorage();
|
||||
|
||||
@ -519,7 +522,7 @@ class ColorConfigService {
|
||||
watch(
|
||||
() => sTheme.theme,
|
||||
() => {
|
||||
this.loadConfig();
|
||||
this.loadFromLocalStorage();
|
||||
}
|
||||
);
|
||||
|
||||
@ -558,6 +561,25 @@ class ColorConfigService {
|
||||
return sTheme.theme === 'dark';
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前主题的存储键
|
||||
*/
|
||||
private getCurrentStorageKey(): string {
|
||||
const theme = sTheme.theme === 'dark' ? 'dark' : 'light';
|
||||
return `${this.STORAGE_KEY_PREFIX}-${theme}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理旧的存储键(向后兼容)
|
||||
*/
|
||||
private cleanupOldStorageKeys(): void {
|
||||
const oldKey = 'editor-color-config';
|
||||
if (localStorage.getItem(oldKey)) {
|
||||
localStorage.removeItem(oldKey);
|
||||
console.log('已清理旧的颜色配置存储键');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置编辑器服务实例
|
||||
*/
|
||||
@ -593,17 +615,17 @@ class ColorConfigService {
|
||||
}
|
||||
|
||||
try {
|
||||
const stored = localStorage.getItem(this.STORAGE_KEY);
|
||||
const storageKey = this.getCurrentStorageKey();
|
||||
const stored = localStorage.getItem(storageKey);
|
||||
|
||||
// 根据当前主题选择基础配置
|
||||
const isDarkTheme = sTheme.theme === 'dark';
|
||||
const baseConfig = isDarkTheme ? DARK_THEME_COLORS : DEFAULT_COLORS;
|
||||
|
||||
if (stored) {
|
||||
const parsedConfig = JSON.parse(stored);
|
||||
// 根据当前主题选择基础配置
|
||||
const isDarkTheme = sTheme.theme === 'dark';
|
||||
const baseConfig = isDarkTheme ? DARK_THEME_COLORS : DEFAULT_COLORS;
|
||||
this.config.value = this.mergeConfig(baseConfig, parsedConfig);
|
||||
} else {
|
||||
// 根据当前主题选择基础配置
|
||||
const isDarkTheme = sTheme.theme === 'dark';
|
||||
const baseConfig = isDarkTheme ? DARK_THEME_COLORS : DEFAULT_COLORS;
|
||||
this.config.value = { ...baseConfig };
|
||||
}
|
||||
} catch (error) {
|
||||
@ -620,7 +642,8 @@ class ColorConfigService {
|
||||
*/
|
||||
private saveToLocalStorage(config: EditorColorConfig): void {
|
||||
try {
|
||||
localStorage.setItem(this.STORAGE_KEY, JSON.stringify(config));
|
||||
const storageKey = this.getCurrentStorageKey();
|
||||
localStorage.setItem(storageKey, JSON.stringify(config));
|
||||
} catch (error) {
|
||||
console.warn('Failed to save color config to localStorage:', error);
|
||||
}
|
||||
@ -664,8 +687,9 @@ class ColorConfigService {
|
||||
// 设置重置标记,防止自动保存
|
||||
this.isResetting = true;
|
||||
|
||||
// 清除本地存储
|
||||
localStorage.removeItem(this.STORAGE_KEY);
|
||||
// 清除当前主题的本地存储
|
||||
const storageKey = this.getCurrentStorageKey();
|
||||
localStorage.removeItem(storageKey);
|
||||
|
||||
// 根据当前主题选择基础配置
|
||||
const isDarkTheme = sTheme.theme === 'dark';
|
||||
@ -813,52 +837,52 @@ class ColorConfigService {
|
||||
const baseConfig = isDarkTheme ? DARK_THEME_COLORS : DEFAULT_COLORS;
|
||||
|
||||
// 使用简化的主题配置映射
|
||||
const themeConfig = this.buildThemeConfig(theme);
|
||||
const themeConfig = this.buildThemeConfig(theme, baseConfig);
|
||||
this.config.value = this.mergeConfig(baseConfig, themeConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建主题配置对象
|
||||
*/
|
||||
private buildThemeConfig(theme: any): Partial<EditorColorConfig> {
|
||||
private buildThemeConfig(theme: any, baseConfig: EditorColorConfig): Partial<EditorColorConfig> {
|
||||
const config: Partial<EditorColorConfig> = {};
|
||||
|
||||
// 点位配置
|
||||
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)
|
||||
stroke: theme['point-s']?.stroke || baseConfig.point.small.stroke,
|
||||
strokeActive: theme['point-s']?.strokeActive || baseConfig.point.small.strokeActive,
|
||||
fill: this.buildFillConfig(theme['point-s'], 'fill', baseConfig.point.small.fill)
|
||||
},
|
||||
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,
|
||||
stroke: theme['point-l']?.stroke || baseConfig.point.large.stroke,
|
||||
strokeActive: theme['point-l']?.strokeActive || baseConfig.point.large.strokeActive,
|
||||
strokeOccupied: theme['point-l']?.['stroke-occupied'] || baseConfig.point.large.strokeOccupied,
|
||||
strokeUnoccupied: theme['point-l']?.['stroke-unoccupied'] || baseConfig.point.large.strokeUnoccupied,
|
||||
strokeEmpty: theme['point-l']?.['stroke-empty'] || baseConfig.point.large.strokeEmpty,
|
||||
strokeDisabled: theme['point-l']?.['stroke-disabled'] || baseConfig.point.large.strokeDisabled,
|
||||
strokeEnabled: theme['point-l']?.['stroke-enabled'] || baseConfig.point.large.strokeEnabled,
|
||||
strokeLocked: theme['point-l']?.['stroke-locked'] || baseConfig.point.large.strokeLocked,
|
||||
strokeUnlocked: theme['point-l']?.['stroke-unlocked'] || baseConfig.point.large.strokeUnlocked,
|
||||
},
|
||||
types: this.buildPointTypesConfig(theme)
|
||||
types: this.buildPointTypesConfig(theme, baseConfig)
|
||||
};
|
||||
}
|
||||
|
||||
// 路线配置
|
||||
if (theme.route) {
|
||||
config.route = {
|
||||
strokeActive: theme.route.strokeActive || DEFAULT_COLORS.route.strokeActive,
|
||||
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,
|
||||
strokeActive: theme.route.strokeActive || baseConfig.route.strokeActive,
|
||||
strokeNone: theme.route['stroke-0'] || baseConfig.route.strokeNone,
|
||||
strokeEmpty: theme.route['stroke-1'] || theme.route['stroke-empty'] || baseConfig.route.strokeEmpty,
|
||||
strokeLoaded: theme.route['stroke-2'] || theme.route['stroke-loaded'] || baseConfig.route.strokeLoaded,
|
||||
strokeForbidden: theme.route['stroke-10'] ||
|
||||
theme.route['stroke-forbidden'] ||
|
||||
DEFAULT_COLORS.route.strokeForbidden,
|
||||
baseConfig.route.strokeForbidden,
|
||||
width: {
|
||||
normal: theme.route.width?.normal || DEFAULT_COLORS.route.width.normal,
|
||||
active: theme.route.width?.active || DEFAULT_COLORS.route.width.active
|
||||
normal: theme.route.width?.normal || baseConfig.route.width.normal,
|
||||
active: theme.route.width?.active || baseConfig.route.width.active
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -866,56 +890,56 @@ class ColorConfigService {
|
||||
// 区域配置
|
||||
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),
|
||||
strokeActive: theme.area.strokeActive || baseConfig.area.strokeActive,
|
||||
stroke: this.buildFillConfig(theme.area, 'stroke', baseConfig.area.stroke),
|
||||
fill: this.buildFillConfig(theme.area, 'fill', baseConfig.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)
|
||||
width: theme.area.border?.width || baseConfig.area.border.width,
|
||||
opacity: theme.area.border?.opacity || baseConfig.area.border.opacity,
|
||||
colors: this.buildFillConfig(theme.area.border, 'color', baseConfig.area.border.colors)
|
||||
},
|
||||
types: this.buildAreaTypesConfig(theme.area)
|
||||
types: this.buildAreaTypesConfig(theme.area, baseConfig)
|
||||
};
|
||||
}
|
||||
|
||||
// 机器人配置
|
||||
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: theme.robot.imageWidth || DEFAULT_COLORS.robot.imageWidth,
|
||||
imageHeight: theme.robot.imageHeight || DEFAULT_COLORS.robot.imageHeight,
|
||||
customImages: theme.robot.customImages || DEFAULT_COLORS.robot.customImages,
|
||||
stroke: theme.robot.stroke || baseConfig.robot.stroke,
|
||||
fill: theme.robot.fill || baseConfig.robot.fill,
|
||||
line: theme.robot.line || baseConfig.robot.line,
|
||||
strokeNormal: theme.robot['stroke-normal'] || baseConfig.robot.strokeNormal,
|
||||
fillNormal: theme.robot['fill-normal'] || baseConfig.robot.fillNormal,
|
||||
strokeWarning: theme.robot['stroke-warning'] || baseConfig.robot.strokeWarning,
|
||||
fillWarning: theme.robot['fill-warning'] || baseConfig.robot.fillWarning,
|
||||
strokeFault: theme.robot['stroke-fault'] || baseConfig.robot.strokeFault,
|
||||
fillFault: theme.robot['fill-fault'] || baseConfig.robot.fillFault,
|
||||
imageWidth: theme.robot.imageWidth || baseConfig.robot.imageWidth,
|
||||
imageHeight: theme.robot.imageHeight || baseConfig.robot.imageHeight,
|
||||
customImages: theme.robot.customImages || baseConfig.robot.customImages,
|
||||
useCustomImages: theme.robot.useCustomImages !== undefined ?
|
||||
(typeof theme.robot.useCustomImages === 'string' ?
|
||||
theme.robot.useCustomImages === 'true' :
|
||||
theme.robot.useCustomImages) :
|
||||
DEFAULT_COLORS.robot.useCustomImages
|
||||
baseConfig.robot.useCustomImages
|
||||
};
|
||||
}
|
||||
|
||||
// 自动门配置
|
||||
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,
|
||||
strokeClosed: theme.autoDoor['stroke-closed'] || baseConfig.autoDoor.strokeClosed,
|
||||
fillClosed: theme.autoDoor['fill-closed'] || baseConfig.autoDoor.fillClosed,
|
||||
strokeOpen: theme.autoDoor['stroke-open'] || baseConfig.autoDoor.strokeOpen,
|
||||
fillOpen: theme.autoDoor['fill-open'] || baseConfig.autoDoor.fillOpen,
|
||||
};
|
||||
}
|
||||
|
||||
// 通用配置
|
||||
if (theme.color || theme.background) {
|
||||
config.common = {
|
||||
color: theme.color || DEFAULT_COLORS.common.color,
|
||||
background: theme.background || DEFAULT_COLORS.common.background,
|
||||
color: theme.color || baseConfig.common.color,
|
||||
background: theme.background || baseConfig.common.background,
|
||||
};
|
||||
}
|
||||
|
||||
@ -939,7 +963,7 @@ class ColorConfigService {
|
||||
/**
|
||||
* 构建点位类型配置
|
||||
*/
|
||||
private buildPointTypesConfig(theme: any): Record<number, any> {
|
||||
private buildPointTypesConfig(theme: any, baseConfig: EditorColorConfig): Record<number, any> {
|
||||
const types: Record<number, any> = {};
|
||||
|
||||
POINT_TYPES.forEach(type => {
|
||||
@ -947,19 +971,19 @@ class ColorConfigService {
|
||||
|
||||
types[type] = {
|
||||
stroke: theme['point-s']?.stroke ||
|
||||
DEFAULT_COLORS.point.types[type]?.stroke ||
|
||||
DEFAULT_COLORS.point.small.stroke,
|
||||
baseConfig.point.types[type]?.stroke ||
|
||||
baseConfig.point.small.stroke,
|
||||
strokeActive: theme['point-s']?.strokeActive ||
|
||||
DEFAULT_COLORS.point.types[type]?.strokeActive ||
|
||||
DEFAULT_COLORS.point.small.strokeActive
|
||||
baseConfig.point.types[type]?.strokeActive ||
|
||||
baseConfig.point.small.strokeActive
|
||||
};
|
||||
|
||||
// 只有小点位才设置填充颜色
|
||||
if (isSmallPoint) {
|
||||
types[type].fill = theme['point-s']?.[`fill-${type}`] ||
|
||||
DEFAULT_COLORS.point.types[type]?.fill ||
|
||||
DEFAULT_COLORS.point.small.fill[type] ||
|
||||
DEFAULT_COLORS.point.small.fill[1];
|
||||
baseConfig.point.types[type]?.fill ||
|
||||
baseConfig.point.small.fill[type] ||
|
||||
baseConfig.point.small.fill[1];
|
||||
}
|
||||
});
|
||||
|
||||
@ -969,17 +993,17 @@ class ColorConfigService {
|
||||
/**
|
||||
* 构建区域类型配置
|
||||
*/
|
||||
private buildAreaTypesConfig(theme: any): Record<number, any> {
|
||||
private buildAreaTypesConfig(theme: any, baseConfig: EditorColorConfig): Record<number, any> {
|
||||
const types: Record<number, any> = {};
|
||||
|
||||
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,
|
||||
stroke: theme[`stroke-${type}`] || baseConfig.area.types[type].stroke,
|
||||
strokeActive: theme.strokeActive || baseConfig.area.types[type].strokeActive,
|
||||
fill: theme[`fill-${type}`] || baseConfig.area.types[type].fill,
|
||||
borderColor: theme.border?.[`color-${type}`] || baseConfig.area.types[type].borderColor,
|
||||
borderWidth: theme.border?.width || baseConfig.area.types[type].borderWidth,
|
||||
borderOpacity: theme.border?.opacity || baseConfig.area.types[type].borderOpacity,
|
||||
};
|
||||
});
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user