187 lines
5.3 KiB
TypeScript
187 lines
5.3 KiB
TypeScript
// 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];
|
||
}
|