Refactor component configuration and diagram management

- Removed the component configuration from `componentConfig.ts` to streamline the codebase.
- Introduced a new `diagram.json` file to define the initial structure for diagrams.
- Created a `diagramManager.ts` to handle diagram data, including loading, saving, and validating diagram structures.
- Updated `ProjectView.vue` to integrate the new diagram management system, including handling component selection and property updates.
- Enhanced the component property management to support dynamic attributes and improved error handling.
- Added functions for managing connections between components within the diagram.
This commit is contained in:
alivender
2025-05-07 15:42:35 +08:00
parent 1c75aa621a
commit 47cfe17d16
10 changed files with 1457 additions and 890 deletions

View File

@@ -17,11 +17,11 @@
<rect
width="70"
height="30"
x="15"
y="15"
x="15"
y="15"
:fill="ledColor"
:style="{ opacity: isOn ? 1 : 0.2 }"
rx="15"
rx="15"
ry="15"
class="interactive"
/>
@@ -39,13 +39,19 @@
ry="18"
filter="blur(5px)"
class="glow"
/>
</svg>
<!-- 新增数字输入引脚Pin放在LED左侧居中 -->
<div style="position:absolute;left:-18px;top:50%;transform:translateY(-50%);">
<Pin
ref="pinRef"
v-bind="props"
/> </svg>
<!-- 渲染自定义引脚数组 -->
<div v-for="pin in props.pins" :key="pin.pinId"
:style="{
position: 'absolute',
left: `${pin.x}px`,
top: `${pin.y}px`,
transform: 'translate(-50%, -50%)'
}"> <Pin
:ref="el => { if(el) pinRefs[pin.pinId] = el }"
:label="pin.pinId"
:constraint="pin.constraint"
:pinId="pin.pinId"
@pin-click="$emit('pin-click', $event)"
/>
</div>
@@ -57,34 +63,36 @@ import { ref, computed, watch, onMounted, onUnmounted } from 'vue';
import { getConstraintState, onConstraintStateChange } from '../../stores/constraints';
import Pin from './Pin.vue';
// --- 关键暴露getPinPosition代理到内部Pin ---
const pinRef = ref<any>(null);
// 从Pin组件继承属性
interface PinProps {
label?: string;
constraint?: string;
componentId?: string; // 添加componentId属性
// 这些属性被预设为固定值,但仍然包含在类型中以便完整继承
direction?: 'input' | 'output' | 'inout';
type?: 'digital' | 'analog';
}
// 存储多个Pin引用
const pinRefs = ref<Record<string, any>>({});
// LED特有属性
interface LEDProps {
size?: number;
color?: string;
initialOn?: boolean;
brightness?: number;
pins?: {
pinId: string;
constraint: string;
x: number;
y: number;
}[];
}
// 组合两个接口
interface Props extends PinProps, LEDProps {}
const props = withDefaults(defineProps<Props>(), {
const props = withDefaults(defineProps<LEDProps>(), {
size: 1,
color: 'red',
constraint: '',
label: 'LED',
componentId: ''
initialOn: false,
brightness: 80,
pins: () => [
{
pinId: 'LED',
constraint: '',
x: 50,
y: 30
}
]
});
const width = computed(() => 100 * props.size);
@@ -106,18 +114,26 @@ const ledColor = computed(() => {
return colorMap[props.color.toLowerCase()] || props.color;
});
// 获取LED的constraint值
const ledConstraint = computed(() => {
if (props.pins && props.pins.length > 0) {
return props.pins[0].constraint;
}
return '';
});
// 监听约束状态变化
let unsubscribe: (() => void) | null = null;
onMounted(() => {
if (props.constraint) {
if (ledConstraint.value) {
unsubscribe = onConstraintStateChange((constraint, level) => {
if (constraint === props.constraint) {
if (constraint === ledConstraint.value) {
isOn.value = (level === 'high');
}
});
// 初始化LED状态
const currentState = getConstraintState(props.constraint);
const currentState = getConstraintState(ledConstraint.value);
isOn.value = (currentState === 'high');
}
});
@@ -128,7 +144,7 @@ onUnmounted(() => {
}
});
watch(() => props.constraint, (newConstraint) => {
watch(() => ledConstraint.value, (newConstraint) => {
if (unsubscribe) {
unsubscribe();
unsubscribe = null;
@@ -149,20 +165,49 @@ defineExpose({
getInfo: () => ({
color: props.color,
isOn: isOn.value,
constraint: props.constraint,
componentId: props.componentId,
constraint: ledConstraint.value,
direction: 'input',
type: 'digital'
}),
getPinPosition: (componentId: string) => {
if (pinRef.value && pinRef.value.getPinPosition) {
return pinRef.value.getPinPosition(componentId);
}
return null;
type: 'digital',
pins: props.pins
}), getPinPosition: (pinId: string) => {
// 如果是自定义的引脚ID
if (props.pins && props.pins.length > 0) {
console.log('Pin ID:', pinId);
const customPin = props.pins.find(p => p.pinId === pinId);
console.log('Custom Pin:', customPin);
console.log('Pin Refs:', pinRefs.value[pinId]);
if (customPin) {
// 调用对应Pin组件的getPinPosition方法
return {
x: customPin.x,
y: customPin.y
}
} return null;
} return null;
}
});
</script>
<script lang="ts">
// 添加一个静态方法来获取默认props
export function getDefaultProps() {
return {
size: 1,
color: 'red',
initialOn: false,
brightness: 80,
pins: [
{
pinId: 'LED',
constraint: '',
x: 50,
y: 30
}
]
};
}
</script>
<style scoped>
.led-container {
display: flex;