Commit e3663aab authored by fenghen777's avatar fenghen777

feat: Implement core diagram editor functionality including a component...

feat: Implement core diagram editor functionality including a component library, React Flow state management, and property editing.
parent 5ef2e19f
......@@ -383,8 +383,7 @@
background: #1a1a28;
}
.portTypeSelect,
.portSideSelect {
.portTypeSelect {
width: 52px;
padding: 3px 2px;
border: 1px solid #2a2a3a;
......@@ -395,8 +394,26 @@
cursor: pointer;
}
.portSideSelect {
width: 48px;
.portConnectorInput {
width: 60px;
padding: 3px 5px;
border: 1px solid transparent;
border-radius: 3px;
background: transparent;
color: #6366f1;
font-size: 10px;
font-family: 'Consolas', monospace;
flex-shrink: 0;
}
.portConnectorInput:focus {
outline: none;
border-color: #6366f1;
background: #1a1a28;
}
.portConnectorInput::placeholder {
color: #444;
}
.portDeleteBtn {
......
......@@ -6,12 +6,6 @@ import { PORT_TYPES } from '../../utils/constants';
import useComponentLibrary from '../../hooks/useComponentLibrary';
import styles from './ComponentEditor.module.css';
const SIDES = [
{ value: 'top', label: '上' },
{ value: 'bottom', label: '下' },
{ value: 'left', label: '左' },
{ value: 'right', label: '右' },
];
export default function PortEditor() {
const { editingTemplate, updatePort, removePort, addPort } = useComponentLibrary();
......@@ -76,6 +70,15 @@ export default function PortEditor() {
placeholder="端点描述"
/>
{/* Connector 参数 */}
<input
className={styles.portConnectorInput}
value={port.connector || ''}
onChange={(e) => updatePort(port.id, { connector: e.target.value })}
placeholder="connector"
title="Modelica 端口标识"
/>
{/* 类型选择 */}
<select
className={styles.portTypeSelect}
......@@ -87,17 +90,6 @@ export default function PortEditor() {
))}
</select>
{/* 位置选择 */}
<select
className={styles.portSideSelect}
value={port.side}
onChange={(e) => updatePort(port.id, { side: e.target.value })}
>
{SIDES.map(s => (
<option key={s.value} value={s.value}>{s.label}</option>
))}
</select>
{/* 删除 */}
<button
className={styles.portDeleteBtn}
......
......@@ -97,7 +97,7 @@ export default function PropertiesPanel() {
<div className={styles.portList}>
{(selectedNode.data?.ports || selectedNode.data?.templateData?.ports || []).map(p => (
<span key={typeof p === 'string' ? p : p.id || p} className={styles.portTag}>
{typeof p === 'string' ? p : (p.portId != null ? p.portId : p.name)}
{typeof p === 'string' ? p : (p.connector || p.name)}
</span>
))}
</div>
......
......@@ -68,12 +68,24 @@ export function createBlankTemplate() {
shapes: [],
params: [],
ports: [
{ id: 'in1', portId: 1, name: '1', description: '端点描述', type: 'generic', side: 'left', position: 0.5 },
{ id: 'out1', portId: 2, name: '2', description: '端点描述', type: 'generic', side: 'right', position: 0.5 },
{ id: 'in1', portId: 1, name: '1', description: '', type: 'generic', side: 'left', position: 0.5, connector: 'in1' },
{ id: 'out1', portId: 2, name: '2', description: '', type: 'generic', side: 'right', position: 0.5, connector: 'out1' },
],
};
}
/**
* 根据已有端口列表生成默认 connector 名称和端口编号
* connector 使用 p 前缀:p1, p2, p3...
* 返回 { connector, portNum } 以便同步生成名称 portN
*/
function generateDefaultPortInfo(existingPorts) {
let n = 1;
const usedConnectors = new Set(existingPorts.map(p => p.connector));
while (usedConnectors.has(`p${n}`)) n++;
return { connector: `p${n}`, portNum: n };
}
const useComponentLibrary = create((set, get) => ({
templates: loadFromStorage(),
customCategories: loadCategories(),
......@@ -161,14 +173,18 @@ const useComponentLibrary = create((set, get) => ({
if (!current) return;
get().pushHistory();
const maxPortId = current.ports.reduce((max, p) => Math.max(max, p.portId || 0), 0);
const side = port.side || 'left';
const { connector: defaultConnector, portNum } = generateDefaultPortInfo(current.ports);
const connector = port.connector || defaultConnector;
const newPort = {
id: `port-${Date.now()}`,
portId: maxPortId + 1,
name: `${maxPortId + 1}`,
description: '端点描述',
name: port.name || `port${portNum}`,
description: '',
type: 'generic',
side: 'left',
side,
position: 0.5,
connector,
...port,
};
set({ editingTemplate: { ...current, ports: [...current.ports, newPort] } });
......
......@@ -90,10 +90,11 @@ const useFlowStore = create((set, get) => ({
id: `${p.id}-${counter}`, // 确保端口 id 全局唯一
portId: p.id,
description: '',
connector: p.connector || p.name,
}))
: [
{ id: `p-in-1-${counter}`, name: '输入1', portId: 1, description: '', type: 'generic', side: 'left', position: 0.5 },
{ id: `p-out-1-${counter}`, name: '输出1', portId: 2, description: '', type: 'generic', side: 'right', position: 0.5 },
{ id: `p-in-1-${counter}`, name: '输入1', portId: 1, description: '', type: 'generic', side: 'left', position: 0.5, connector: 'in1' },
{ id: `p-out-1-${counter}`, name: '输出1', portId: 2, description: '', type: 'generic', side: 'right', position: 0.5, connector: 'out1' },
];
const templateData = {
......
......@@ -17,8 +17,8 @@ export const DEVICE_CATEGORIES = [
code: 1001, type: 'resistor', label: '电阻', color: '#FF9800', icon: 'R',
width: 120, height: 60,
ports: [
{ id: 'p1', name: '1', side: 'left', position: 0.5, type: 'power' },
{ id: 'p2', name: '2', side: 'right', position: 0.5, type: 'power' },
{ id: 'p1', name: '1', side: 'left', position: 0.5, type: 'power', connector: 'p' },
{ id: 'p2', name: '2', side: 'right', position: 0.5, type: 'power', connector: 'n' },
],
params: [
{ key: 'R', label: '阻值', unit: 'Ω', defaultValue: '10k' },
......@@ -29,8 +29,8 @@ export const DEVICE_CATEGORIES = [
code: 1002, type: 'capacitor', label: '电容', color: '#2196F3', icon: 'C',
width: 120, height: 60,
ports: [
{ id: 'p-pos', name: '+', side: 'left', position: 0.5, type: 'power' },
{ id: 'p-neg', name: '-', side: 'right', position: 0.5, type: 'power' },
{ id: 'p-pos', name: '+', side: 'left', position: 0.5, type: 'power', connector: 'p' },
{ id: 'p-neg', name: '-', side: 'right', position: 0.5, type: 'power', connector: 'n' },
],
params: [
{ key: 'C', label: '容值', unit: 'F', defaultValue: '100u' },
......@@ -41,8 +41,8 @@ export const DEVICE_CATEGORIES = [
code: 1003, type: 'inductor', label: '电感', color: '#9C27B0', icon: 'L',
width: 120, height: 60,
ports: [
{ id: 'p1', name: '1', side: 'left', position: 0.5, type: 'power' },
{ id: 'p2', name: '2', side: 'right', position: 0.5, type: 'power' },
{ id: 'p1', name: '1', side: 'left', position: 0.5, type: 'power', connector: 'p' },
{ id: 'p2', name: '2', side: 'right', position: 0.5, type: 'power', connector: 'n' },
],
params: [
{ key: 'L', label: '感值', unit: 'H', defaultValue: '10m' },
......@@ -52,16 +52,16 @@ export const DEVICE_CATEGORIES = [
code: 1004, type: 'diode', label: '二极管', color: '#E91E63', icon: 'D',
width: 120, height: 60,
ports: [
{ id: 'p-a', name: 'A', side: 'left', position: 0.5, type: 'power' },
{ id: 'p-k', name: 'K', side: 'right', position: 0.5, type: 'power' },
{ id: 'p-a', name: 'A', side: 'left', position: 0.5, type: 'power', connector: 'p' },
{ id: 'p-k', name: 'K', side: 'right', position: 0.5, type: 'power', connector: 'n' },
],
},
{
code: 1005, type: 'voltage_source', label: '电压源', color: '#4CAF50', icon: 'V',
width: 120, height: 80,
ports: [
{ id: 'p-pos', name: 'V+', side: 'left', position: 0.5, type: 'power' },
{ id: 'p-neg', name: 'V-', side: 'right', position: 0.5, type: 'power' },
{ id: 'p-pos', name: 'V+', side: 'left', position: 0.5, type: 'power', connector: 'p' },
{ id: 'p-neg', name: 'V-', side: 'right', position: 0.5, type: 'power', connector: 'n' },
],
params: [
{ key: 'V', label: '电压', unit: 'V', defaultValue: '24' },
......@@ -71,7 +71,7 @@ export const DEVICE_CATEGORIES = [
code: 1006, type: 'ground', label: '接地', color: '#607D8B', icon: 'GND',
width: 80, height: 60,
ports: [
{ id: 'p-gnd', name: 'GND', side: 'top', position: 0.5, type: 'power' },
{ id: 'p-gnd', name: 'GND', side: 'top', position: 0.5, type: 'power', connector: 'p' },
],
},
],
......@@ -83,40 +83,40 @@ export const DEVICE_CATEGORIES = [
code: 100, type: 'terminal', label: '端子排', color: '#4CAF50', icon: '⊞',
width: 180, height: 80,
ports: [
{ id: 'p-in-1', name: '输入1', side: 'left', position: 0.5, type: 'generic' },
{ id: 'p-out-1', name: '输出1', side: 'right', position: 0.5, type: 'generic' },
{ id: 'p-in-1', name: '输入1', side: 'left', position: 0.5, type: 'generic', connector: 'pIn' },
{ id: 'p-out-1', name: '输出1', side: 'right', position: 0.5, type: 'generic', connector: 'pOut' },
],
},
{
code: 200, type: 'contactor', label: '接触器', color: '#2196F3', icon: '◈',
width: 180, height: 100,
ports: [
{ id: 'p-l1', name: 'L1', side: 'top', position: 0.25, type: 'power' },
{ id: 'p-l2', name: 'L2', side: 'top', position: 0.5, type: 'power' },
{ id: 'p-l3', name: 'L3', side: 'top', position: 0.75, type: 'power' },
{ id: 'p-t1', name: 'T1', side: 'bottom', position: 0.25, type: 'power' },
{ id: 'p-t2', name: 'T2', side: 'bottom', position: 0.5, type: 'power' },
{ id: 'p-t3', name: 'T3', side: 'bottom', position: 0.75, type: 'power' },
{ id: 'p-a1', name: 'A1', side: 'left', position: 0.5, type: 'digital' },
{ id: 'p-a2', name: 'A2', side: 'right', position: 0.5, type: 'digital' },
{ id: 'p-l1', name: 'L1', side: 'top', position: 0.25, type: 'power', connector: 'l1' },
{ id: 'p-l2', name: 'L2', side: 'top', position: 0.5, type: 'power', connector: 'l2' },
{ id: 'p-l3', name: 'L3', side: 'top', position: 0.75, type: 'power', connector: 'l3' },
{ id: 'p-t1', name: 'T1', side: 'bottom', position: 0.25, type: 'power', connector: 't1' },
{ id: 'p-t2', name: 'T2', side: 'bottom', position: 0.5, type: 'power', connector: 't2' },
{ id: 'p-t3', name: 'T3', side: 'bottom', position: 0.75, type: 'power', connector: 't3' },
{ id: 'p-a1', name: 'A1', side: 'left', position: 0.5, type: 'digital', connector: 'a1' },
{ id: 'p-a2', name: 'A2', side: 'right', position: 0.5, type: 'digital', connector: 'a2' },
],
},
{
code: 300, type: 'relay', label: '继电器', color: '#9C27B0', icon: '◇',
width: 160, height: 80,
ports: [
{ id: 'p-a1', name: 'A1', side: 'left', position: 0.3, type: 'digital' },
{ id: 'p-a2', name: 'A2', side: 'left', position: 0.7, type: 'digital' },
{ id: 'p-11', name: '11', side: 'right', position: 0.3, type: 'digital' },
{ id: 'p-14', name: '14', side: 'right', position: 0.7, type: 'digital' },
{ id: 'p-a1', name: 'A1', side: 'left', position: 0.3, type: 'digital', connector: 'a1' },
{ id: 'p-a2', name: 'A2', side: 'left', position: 0.7, type: 'digital', connector: 'a2' },
{ id: 'p-11', name: '11', side: 'right', position: 0.3, type: 'digital', connector: 'p11' },
{ id: 'p-14', name: '14', side: 'right', position: 0.7, type: 'digital', connector: 'p14' },
],
},
{
code: 501, type: 'breaker', label: '断路器', color: '#F44336', icon: '⊗',
width: 140, height: 80,
ports: [
{ id: 'p-in', name: '进线', side: 'top', position: 0.5, type: 'power' },
{ id: 'p-out', name: '出线', side: 'bottom', position: 0.5, type: 'power' },
{ id: 'p-in', name: '进线', side: 'top', position: 0.5, type: 'power', connector: 'pIn' },
{ id: 'p-out', name: '出线', side: 'bottom', position: 0.5, type: 'power', connector: 'pOut' },
],
params: [
{ key: 'In', label: '额定电流', unit: 'A', defaultValue: '16' },
......@@ -126,19 +126,19 @@ export const DEVICE_CATEGORIES = [
code: 600, type: 'switch', label: '开关', color: '#00BCD4', icon: '⊘',
width: 120, height: 60,
ports: [
{ id: 'p-com', name: 'COM', side: 'left', position: 0.5, type: 'power' },
{ id: 'p-no', name: 'NO', side: 'right', position: 0.3, type: 'power' },
{ id: 'p-nc', name: 'NC', side: 'right', position: 0.7, type: 'power' },
{ id: 'p-com', name: 'COM', side: 'left', position: 0.5, type: 'power', connector: 'com' },
{ id: 'p-no', name: 'NO', side: 'right', position: 0.3, type: 'power', connector: 'no' },
{ id: 'p-nc', name: 'NC', side: 'right', position: 0.7, type: 'power', connector: 'nc' },
],
},
{
code: 400, type: 'motor', label: '电动机', color: '#FF9800', icon: '◎',
width: 160, height: 100,
ports: [
{ id: 'p-u', name: 'U', side: 'top', position: 0.25, type: 'power' },
{ id: 'p-v', name: 'V', side: 'top', position: 0.5, type: 'power' },
{ id: 'p-w', name: 'W', side: 'top', position: 0.75, type: 'power' },
{ id: 'p-pe',name: 'PE', side: 'bottom', position: 0.5, type: 'power' },
{ id: 'p-u', name: 'U', side: 'top', position: 0.25, type: 'power', connector: 'u' },
{ id: 'p-v', name: 'V', side: 'top', position: 0.5, type: 'power', connector: 'v' },
{ id: 'p-w', name: 'W', side: 'top', position: 0.75, type: 'power', connector: 'w' },
{ id: 'p-pe',name: 'PE', side: 'bottom', position: 0.5, type: 'power', connector: 'pe' },
],
params: [
{ key: 'Pw', label: '功率', unit: 'kW', defaultValue: '2.2' },
......@@ -149,27 +149,27 @@ export const DEVICE_CATEGORIES = [
code: 802, type: 'transformer', label: '变压器', color: '#FF5722', icon: '⊜',
width: 160, height: 100,
ports: [
{ id: 'p-pri1', name: '初级1', side: 'left', position: 0.3, type: 'power' },
{ id: 'p-pri2', name: '初级2', side: 'left', position: 0.7, type: 'power' },
{ id: 'p-sec1', name: '次级1', side: 'right', position: 0.3, type: 'power' },
{ id: 'p-sec2', name: '次级2', side: 'right', position: 0.7, type: 'power' },
{ id: 'p-pri1', name: '初级1', side: 'left', position: 0.3, type: 'power', connector: 'pri1' },
{ id: 'p-pri2', name: '初级2', side: 'left', position: 0.7, type: 'power', connector: 'pri2' },
{ id: 'p-sec1', name: '次级1', side: 'right', position: 0.3, type: 'power', connector: 'sec1' },
{ id: 'p-sec2', name: '次级2', side: 'right', position: 0.7, type: 'power', connector: 'sec2' },
],
},
{
code: 700, type: 'sensor', label: '传感器', color: '#795548', icon: '◉',
width: 140, height: 80,
ports: [
{ id: 'p-vcc', name: 'VCC', side: 'top', position: 0.5, type: 'power' },
{ id: 'p-gnd', name: 'GND', side: 'bottom',position: 0.5, type: 'power' },
{ id: 'p-sig', name: 'SIG', side: 'right', position: 0.5, type: 'analog' },
{ id: 'p-vcc', name: 'VCC', side: 'top', position: 0.5, type: 'power', connector: 'vcc' },
{ id: 'p-gnd', name: 'GND', side: 'bottom',position: 0.5, type: 'power', connector: 'gnd' },
{ id: 'p-sig', name: 'SIG', side: 'right', position: 0.5, type: 'analog', connector: 'sig' },
],
},
{
code: 900, type: 'cable', label: '电缆/线缆', color: '#607D8B', icon: '⊟',
width: 160, height: 60,
ports: [
{ id: 'p-in', name: '输入', side: 'left', position: 0.5, type: 'generic' },
{ id: 'p-out', name: '输出', side: 'right', position: 0.5, type: 'generic' },
{ id: 'p-in', name: '输入', side: 'left', position: 0.5, type: 'generic', connector: 'pIn' },
{ id: 'p-out', name: '输出', side: 'right', position: 0.5, type: 'generic', connector: 'pOut' },
],
},
],
......@@ -181,56 +181,56 @@ export const DEVICE_CATEGORIES = [
code: 2001, type: 'plc_cpu', label: 'PLC CPU', color: '#3F51B5', icon: 'CPU',
width: 200, height: 120,
ports: [
{ id: 'p-24v', name: '24V', side: 'top', position: 0.25, type: 'power' },
{ id: 'p-0v', name: '0V', side: 'top', position: 0.75, type: 'power' },
{ id: 'p-di1', name: 'DI1', side: 'left', position: 0.25, type: 'digital' },
{ id: 'p-di2', name: 'DI2', side: 'left', position: 0.5, type: 'digital' },
{ id: 'p-di3', name: 'DI3', side: 'left', position: 0.75, type: 'digital' },
{ id: 'p-do1', name: 'DO1', side: 'right', position: 0.25, type: 'digital' },
{ id: 'p-do2', name: 'DO2', side: 'right', position: 0.5, type: 'digital' },
{ id: 'p-do3', name: 'DO3', side: 'right', position: 0.75, type: 'digital' },
{ id: 'p-24v', name: '24V', side: 'top', position: 0.25, type: 'power', connector: 'v24' },
{ id: 'p-0v', name: '0V', side: 'top', position: 0.75, type: 'power', connector: 'v0' },
{ id: 'p-di1', name: 'DI1', side: 'left', position: 0.25, type: 'digital', connector: 'di1' },
{ id: 'p-di2', name: 'DI2', side: 'left', position: 0.5, type: 'digital', connector: 'di2' },
{ id: 'p-di3', name: 'DI3', side: 'left', position: 0.75, type: 'digital', connector: 'di3' },
{ id: 'p-do1', name: 'DO1', side: 'right', position: 0.25, type: 'digital', connector: 'do1' },
{ id: 'p-do2', name: 'DO2', side: 'right', position: 0.5, type: 'digital', connector: 'do2' },
{ id: 'p-do3', name: 'DO3', side: 'right', position: 0.75, type: 'digital', connector: 'do3' },
],
},
{
code: 2002, type: 'plc_di', label: 'PLC 数字输入', color: '#2196F3', icon: 'DI',
width: 180, height: 120,
ports: [
{ id: 'p-di1', name: 'DI1', side: 'left', position: 0.15, type: 'digital' },
{ id: 'p-di2', name: 'DI2', side: 'left', position: 0.35, type: 'digital' },
{ id: 'p-di3', name: 'DI3', side: 'left', position: 0.55, type: 'digital' },
{ id: 'p-di4', name: 'DI4', side: 'left', position: 0.75, type: 'digital' },
{ id: 'p-com', name: 'COM', side: 'right',position: 0.5, type: 'power' },
{ id: 'p-di1', name: 'DI1', side: 'left', position: 0.15, type: 'digital', connector: 'di1' },
{ id: 'p-di2', name: 'DI2', side: 'left', position: 0.35, type: 'digital', connector: 'di2' },
{ id: 'p-di3', name: 'DI3', side: 'left', position: 0.55, type: 'digital', connector: 'di3' },
{ id: 'p-di4', name: 'DI4', side: 'left', position: 0.75, type: 'digital', connector: 'di4' },
{ id: 'p-com', name: 'COM', side: 'right',position: 0.5, type: 'power', connector: 'com' },
],
},
{
code: 2003, type: 'plc_do', label: 'PLC 数字输出', color: '#4CAF50', icon: 'DO',
width: 180, height: 120,
ports: [
{ id: 'p-do1', name: 'DO1', side: 'right', position: 0.15, type: 'digital' },
{ id: 'p-do2', name: 'DO2', side: 'right', position: 0.35, type: 'digital' },
{ id: 'p-do3', name: 'DO3', side: 'right', position: 0.55, type: 'digital' },
{ id: 'p-do4', name: 'DO4', side: 'right', position: 0.75, type: 'digital' },
{ id: 'p-com', name: 'COM', side: 'left', position: 0.5, type: 'power' },
{ id: 'p-do1', name: 'DO1', side: 'right', position: 0.15, type: 'digital', connector: 'do1' },
{ id: 'p-do2', name: 'DO2', side: 'right', position: 0.35, type: 'digital', connector: 'do2' },
{ id: 'p-do3', name: 'DO3', side: 'right', position: 0.55, type: 'digital', connector: 'do3' },
{ id: 'p-do4', name: 'DO4', side: 'right', position: 0.75, type: 'digital', connector: 'do4' },
{ id: 'p-com', name: 'COM', side: 'left', position: 0.5, type: 'power', connector: 'com' },
],
},
{
code: 2004, type: 'plc_ai', label: 'PLC 模拟输入', color: '#E91E63', icon: 'AI',
width: 180, height: 100,
ports: [
{ id: 'p-ai1', name: 'AI1', side: 'left', position: 0.3, type: 'analog' },
{ id: 'p-ai2', name: 'AI2', side: 'left', position: 0.7, type: 'analog' },
{ id: 'p-vcc', name: 'VCC', side: 'top', position: 0.5, type: 'power' },
{ id: 'p-gnd', name: 'GND', side: 'bottom',position: 0.5, type: 'power' },
{ id: 'p-ai1', name: 'AI1', side: 'left', position: 0.3, type: 'analog', connector: 'ai1' },
{ id: 'p-ai2', name: 'AI2', side: 'left', position: 0.7, type: 'analog', connector: 'ai2' },
{ id: 'p-vcc', name: 'VCC', side: 'top', position: 0.5, type: 'power', connector: 'vcc' },
{ id: 'p-gnd', name: 'GND', side: 'bottom',position: 0.5, type: 'power', connector: 'gnd' },
],
},
{
code: 2005, type: 'plc_ao', label: 'PLC 模拟输出', color: '#FF5722', icon: 'AO',
width: 180, height: 100,
ports: [
{ id: 'p-ao1', name: 'AO1', side: 'right', position: 0.3, type: 'analog' },
{ id: 'p-ao2', name: 'AO2', side: 'right', position: 0.7, type: 'analog' },
{ id: 'p-vcc', name: 'VCC', side: 'top', position: 0.5, type: 'power' },
{ id: 'p-gnd', name: 'GND', side: 'bottom',position: 0.5, type: 'power' },
{ id: 'p-ao1', name: 'AO1', side: 'right', position: 0.3, type: 'analog', connector: 'ao1' },
{ id: 'p-ao2', name: 'AO2', side: 'right', position: 0.7, type: 'analog', connector: 'ao2' },
{ id: 'p-vcc', name: 'VCC', side: 'top', position: 0.5, type: 'power', connector: 'vcc' },
{ id: 'p-gnd', name: 'GND', side: 'bottom',position: 0.5, type: 'power', connector: 'gnd' },
],
},
],
......@@ -242,37 +242,37 @@ export const DEVICE_CATEGORIES = [
code: 3001, type: 'pump', label: '水泵', color: '#00BCD4', icon: 'P',
width: 160, height: 100,
ports: [
{ id: 'p-in', name: '进水', side: 'left', position: 0.5, type: 'water' },
{ id: 'p-out', name: '出水', side: 'right', position: 0.5, type: 'water' },
{ id: 'p-pwr1', name: 'L', side: 'top', position: 0.3, type: 'power' },
{ id: 'p-pwr2', name: 'N', side: 'top', position: 0.7, type: 'power' },
{ id: 'p-in', name: '进水', side: 'left', position: 0.5, type: 'water', connector: 'waterIn' },
{ id: 'p-out', name: '出水', side: 'right', position: 0.5, type: 'water', connector: 'waterOut' },
{ id: 'p-pwr1', name: 'L', side: 'top', position: 0.3, type: 'power', connector: 'l' },
{ id: 'p-pwr2', name: 'N', side: 'top', position: 0.7, type: 'power', connector: 'n' },
],
},
{
code: 3002, type: 'valve', label: '阀门', color: '#009688', icon: 'V',
width: 120, height: 80,
ports: [
{ id: 'p-in', name: '进口', side: 'left', position: 0.5, type: 'water' },
{ id: 'p-out', name: '出口', side: 'right', position: 0.5, type: 'water' },
{ id: 'p-ctl', name: '控制', side: 'top', position: 0.5, type: 'digital' },
{ id: 'p-in', name: '进口', side: 'left', position: 0.5, type: 'water', connector: 'inlet' },
{ id: 'p-out', name: '出口', side: 'right', position: 0.5, type: 'water', connector: 'outlet' },
{ id: 'p-ctl', name: '控制', side: 'top', position: 0.5, type: 'digital', connector: 'ctrl' },
],
},
{
code: 3003, type: 'flow_meter', label: '流量计', color: '#00ACC1', icon: 'FM',
width: 140, height: 80,
ports: [
{ id: 'p-in', name: '进口', side: 'left', position: 0.5, type: 'water' },
{ id: 'p-out', name: '出口', side: 'right', position: 0.5, type: 'water' },
{ id: 'p-sig', name: '信号', side: 'bottom',position: 0.5, type: 'analog' },
{ id: 'p-in', name: '进口', side: 'left', position: 0.5, type: 'water', connector: 'inlet' },
{ id: 'p-out', name: '出口', side: 'right', position: 0.5, type: 'water', connector: 'outlet' },
{ id: 'p-sig', name: '信号', side: 'bottom',position: 0.5, type: 'analog', connector: 'sig' },
],
},
{
code: 3004, type: 'tank', label: '水箱', color: '#0288D1', icon: 'TK',
width: 180, height: 120,
ports: [
{ id: 'p-in', name: '进水', side: 'top', position: 0.5, type: 'water' },
{ id: 'p-out', name: '出水', side: 'bottom', position: 0.5, type: 'water' },
{ id: 'p-level', name: '液位信号', side: 'right', position: 0.5, type: 'analog' },
{ id: 'p-in', name: '进水', side: 'top', position: 0.5, type: 'water', connector: 'waterIn' },
{ id: 'p-out', name: '出水', side: 'bottom', position: 0.5, type: 'water', connector: 'waterOut' },
{ id: 'p-level', name: '液位信号', side: 'right', position: 0.5, type: 'analog', connector: 'levelSig' },
],
},
],
......@@ -284,45 +284,45 @@ export const DEVICE_CATEGORIES = [
code: 4001, type: 'cylinder', label: '气缸', color: '#8BC34A', icon: 'CY',
width: 160, height: 80,
ports: [
{ id: 'p-a', name: 'A腔', side: 'left', position: 0.5, type: 'air' },
{ id: 'p-b', name: 'B腔', side: 'right', position: 0.5, type: 'air' },
{ id: 'p-fb',name: '反馈', side: 'bottom',position: 0.5, type: 'digital' },
{ id: 'p-a', name: 'A腔', side: 'left', position: 0.5, type: 'air', connector: 'portA' },
{ id: 'p-b', name: 'B腔', side: 'right', position: 0.5, type: 'air', connector: 'portB' },
{ id: 'p-fb',name: '反馈', side: 'bottom',position: 0.5, type: 'digital', connector: 'fb' },
],
},
{
code: 4002, type: 'solenoid_valve', label: '电磁阀', color: '#689F38', icon: 'SV',
width: 140, height: 80,
ports: [
{ id: 'p-in', name: 'P', side: 'left', position: 0.5, type: 'air' },
{ id: 'p-a', name: 'A', side: 'right', position: 0.3, type: 'air' },
{ id: 'p-b', name: 'B', side: 'right', position: 0.7, type: 'air' },
{ id: 'p-ctl', name: '线圈', side: 'top', position: 0.5, type: 'digital' },
{ id: 'p-in', name: 'P', side: 'left', position: 0.5, type: 'air', connector: 'supply' },
{ id: 'p-a', name: 'A', side: 'right', position: 0.3, type: 'air', connector: 'portA' },
{ id: 'p-b', name: 'B', side: 'right', position: 0.7, type: 'air', connector: 'portB' },
{ id: 'p-ctl', name: '线圈', side: 'top', position: 0.5, type: 'digital', connector: 'coil' },
],
},
{
code: 4003, type: 'servo', label: '伺服电机', color: '#FF9800', icon: 'SV',
width: 180, height: 100,
ports: [
{ id: 'p-u', name: 'U', side: 'top', position: 0.2, type: 'power' },
{ id: 'p-v', name: 'V', side: 'top', position: 0.5, type: 'power' },
{ id: 'p-w', name: 'W', side: 'top', position: 0.8, type: 'power' },
{ id: 'p-enc',name: '编码器', side: 'right',position: 0.5, type: 'analog' },
{ id: 'p-pe', name: 'PE', side: 'bottom',position: 0.5, type: 'power' },
{ id: 'p-u', name: 'U', side: 'top', position: 0.2, type: 'power', connector: 'u' },
{ id: 'p-v', name: 'V', side: 'top', position: 0.5, type: 'power', connector: 'v' },
{ id: 'p-w', name: 'W', side: 'top', position: 0.8, type: 'power', connector: 'w' },
{ id: 'p-enc',name: '编码器', side: 'right',position: 0.5, type: 'analog', connector: 'encoder' },
{ id: 'p-pe', name: 'PE', side: 'bottom',position: 0.5, type: 'power', connector: 'pe' },
],
},
{
code: 4004, type: 'vfd', label: '变频器', color: '#673AB7', icon: 'VFD',
width: 180, height: 120,
ports: [
{ id: 'p-r', name: 'R', side: 'top', position: 0.2, type: 'power' },
{ id: 'p-s', name: 'S', side: 'top', position: 0.5, type: 'power' },
{ id: 'p-t', name: 'T', side: 'top', position: 0.8, type: 'power' },
{ id: 'p-u', name: 'U', side: 'bottom', position: 0.2, type: 'power' },
{ id: 'p-v', name: 'V', side: 'bottom', position: 0.5, type: 'power' },
{ id: 'p-w', name: 'W', side: 'bottom', position: 0.8, type: 'power' },
{ id: 'p-fi', name: 'FWD', side: 'left', position: 0.3, type: 'digital' },
{ id: 'p-ri', name: 'REV', side: 'left', position: 0.7, type: 'digital' },
{ id: 'p-fb', name: 'FB', side: 'right',position: 0.5, type: 'analog' },
{ id: 'p-r', name: 'R', side: 'top', position: 0.2, type: 'power', connector: 'r' },
{ id: 'p-s', name: 'S', side: 'top', position: 0.5, type: 'power', connector: 's' },
{ id: 'p-t', name: 'T', side: 'top', position: 0.8, type: 'power', connector: 't' },
{ id: 'p-u', name: 'U', side: 'bottom', position: 0.2, type: 'power', connector: 'u' },
{ id: 'p-v', name: 'V', side: 'bottom', position: 0.5, type: 'power', connector: 'v' },
{ id: 'p-w', name: 'W', side: 'bottom', position: 0.8, type: 'power', connector: 'w' },
{ id: 'p-fi', name: 'FWD', side: 'left', position: 0.3, type: 'digital', connector: 'fwd' },
{ id: 'p-ri', name: 'REV', side: 'left', position: 0.7, type: 'digital', connector: 'rev' },
{ id: 'p-fb', name: 'FB', side: 'right',position: 0.5, type: 'analog', connector: 'fb' },
],
},
],
......
......@@ -152,6 +152,8 @@ export function resolvePortName(handleId, type, ports) {
if (ports && ports.length > 0) {
const port = ports.find(p => p.id === handleId);
if (port) {
// 优先使用 connector 字段
if (port.connector) return port.connector;
const originalId = port.portId || port.id;
// 查映射表
if (mapping && mapping.portMap[originalId]) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment