feat: Refactor code structure for improved readability and maintainability
This commit is contained in:
@@ -0,0 +1,186 @@
|
||||
// componentConfig.ts 提供通用的组件配置功能
|
||||
import type { DiagramPart } from '../diagramManager';
|
||||
|
||||
// 属性配置接口
|
||||
export interface PropertyConfig {
|
||||
name: string;
|
||||
type: string;
|
||||
label: string;
|
||||
default: any;
|
||||
options?: Array<{ value: any; label: string }>; // 添加 options 字段用于 select 类型
|
||||
isDirectProp?: boolean; // 标记是否为直接属性
|
||||
isReadOnly?: boolean; // 标记是否为只读属性
|
||||
min?: number; // 用于数值类型的最小值
|
||||
max?: number; // 用于数值类型的最大值
|
||||
step?: number; // 用于数值类型的步长
|
||||
isArrayType?: boolean; // 标记数组类型属性
|
||||
}
|
||||
|
||||
// 所有基础属性的标签映射
|
||||
const basePropertyLabels: Record<number, string> = {
|
||||
0: 'ID',
|
||||
1: '组件类型',
|
||||
2: '水平坐标',
|
||||
3: '垂直坐标',
|
||||
4: '角度',
|
||||
5: '分组',
|
||||
6: '锁定位置',
|
||||
7: '隐藏引脚',
|
||||
8: '激活状态',
|
||||
9: '层级'
|
||||
};
|
||||
|
||||
// 只读属性索引列表
|
||||
const readOnlyPropertyIndexes = [0, 1]; // 移除了isOn对应的索引8
|
||||
|
||||
/**
|
||||
* 从组件数据中自动生成属性配置
|
||||
* @param componentData 组件数据
|
||||
* @returns 属性配置数组
|
||||
*/
|
||||
export function generatePropertyConfigs(componentData: DiagramPart): PropertyConfig[] {
|
||||
const configs: PropertyConfig[] = [];
|
||||
|
||||
// 获取基础属性(排除attrs)
|
||||
const directPropKeys = Object.keys(componentData).filter(key => key !== 'attrs');
|
||||
|
||||
// 为每个直接属性创建配置
|
||||
directPropKeys.forEach((propName, index) => {
|
||||
let propValue: any = (componentData as any)[propName];
|
||||
let propType = typeof propValue;
|
||||
|
||||
// 对于undefined的属性,提供默认值
|
||||
if (propValue === undefined) {
|
||||
if (propType === 'boolean') propValue = false;
|
||||
else if (propType === 'number') propValue = 0;
|
||||
else propValue = '';
|
||||
}
|
||||
|
||||
// 创建配置对象
|
||||
const propConfig: PropertyConfig = {
|
||||
name: propName,
|
||||
label: basePropertyLabels[index] || propName,
|
||||
type: propType as 'string' | 'number' | 'boolean' | 'select',
|
||||
default: propValue,
|
||||
isDirectProp: true,
|
||||
isReadOnly: readOnlyPropertyIndexes.includes(index)
|
||||
};
|
||||
|
||||
// 数值类型的特殊设置
|
||||
if (propType === 'number') {
|
||||
if (index === 9) { // 层级
|
||||
propConfig.min = 0;
|
||||
propConfig.max = 100;
|
||||
} else if (index === 4) { // 角度
|
||||
propConfig.min = 0;
|
||||
propConfig.max = 360;
|
||||
}
|
||||
propConfig.step = 1;
|
||||
}
|
||||
|
||||
configs.push(propConfig);
|
||||
});
|
||||
|
||||
return configs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从组件模块的getDefaultProps方法生成属性配置
|
||||
* @param defaultProps 默认属性对象
|
||||
* @returns 属性配置数组
|
||||
*/
|
||||
export function generatePropsFromDefault(defaultProps: Record<string, any>): PropertyConfig[] {
|
||||
const configs: PropertyConfig[] = [];
|
||||
|
||||
for (const [propName, propValue] of Object.entries(defaultProps)) {
|
||||
// 特殊处理pins属性
|
||||
if (propName === 'pins') {
|
||||
const propConfig: PropertyConfig = {
|
||||
name: propName,
|
||||
label: 'Pins',
|
||||
default: propValue,
|
||||
type: 'array',
|
||||
isArrayType: true
|
||||
};
|
||||
configs.push(propConfig);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 根据属性类型创建配置
|
||||
let propType = typeof propValue;
|
||||
let propConfig: PropertyConfig = {
|
||||
name: propName,
|
||||
label: propName.charAt(0).toUpperCase() + propName.slice(1), // 首字母大写作为标签
|
||||
default: propValue,
|
||||
type: propType as 'string' | 'number' | 'boolean' | 'select'
|
||||
};
|
||||
|
||||
// 根据值类型设置表单控件类型
|
||||
if (propType === 'string') {
|
||||
propConfig.type = 'string';
|
||||
} else if (propType === 'number') {
|
||||
propConfig.type = 'number';
|
||||
propConfig.min = 0;
|
||||
propConfig.max = 100;
|
||||
propConfig.step = 0.1;
|
||||
} else if (propType === 'boolean') {
|
||||
propConfig.type = 'boolean';
|
||||
} else if (propType === 'object' && propValue !== null && propValue.hasOwnProperty('options')) {
|
||||
// 如果是含有options的对象,认为它是select类型
|
||||
propConfig.type = 'select';
|
||||
propConfig.options = (propValue as any).options;
|
||||
}
|
||||
|
||||
configs.push(propConfig);
|
||||
}
|
||||
|
||||
return configs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从属性对象生成配置
|
||||
* @param attrs 属性对象
|
||||
* @returns 属性配置数组
|
||||
*/
|
||||
export function generatePropsFromAttrs(attrs: Record<string, any>): PropertyConfig[] {
|
||||
const configs: PropertyConfig[] = [];
|
||||
|
||||
for (const [propName, propValue] of Object.entries(attrs)) {
|
||||
// 特殊处理pins属性
|
||||
if (propName === 'pins') {
|
||||
const propConfig: PropertyConfig = {
|
||||
name: propName,
|
||||
label: 'Pins',
|
||||
default: propValue,
|
||||
type: 'array',
|
||||
isArrayType: true
|
||||
};
|
||||
configs.push(propConfig);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 根据属性值类型创建配置
|
||||
let propType = typeof propValue;
|
||||
let propConfig: PropertyConfig = {
|
||||
name: propName,
|
||||
label: propName.charAt(0).toUpperCase() + propName.slice(1), // 首字母大写作为标签
|
||||
default: propValue || '',
|
||||
type: propType as 'string' | 'number' | 'boolean' | 'select'
|
||||
};
|
||||
|
||||
configs.push(propConfig);
|
||||
}
|
||||
|
||||
return configs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全地从组件对象获取属性值
|
||||
* @param component 组件对象
|
||||
* @param propName 属性名
|
||||
* @returns 属性值
|
||||
*/
|
||||
export function getPropValue(component: DiagramPart, propName: string): any {
|
||||
if (!component) return undefined;
|
||||
return (component as any)[propName];
|
||||
}
|
||||
Reference in New Issue
Block a user