feat: 删除无用数据与冗余逻辑以提升性能
This commit is contained in:
parent
e38770a496
commit
78737f6839
|
@ -44,7 +44,11 @@
|
|||
}"
|
||||
>
|
||||
<!-- 渲染连线 -->
|
||||
<svg class="wires-layer absolute top-0 left-0 w-full h-full z-50" width="10000" height="10000">
|
||||
<svg
|
||||
class="wires-layer absolute top-0 left-0 w-full h-full z-50"
|
||||
width="10000"
|
||||
height="10000"
|
||||
>
|
||||
<!-- 已完成的连线 -->
|
||||
<WireComponent
|
||||
v-for="(wire, index) in wireItems"
|
||||
|
@ -94,7 +98,9 @@
|
|||
top: component.y + 'px',
|
||||
left: component.x + 'px',
|
||||
zIndex: component.index ?? 0,
|
||||
transform: component.rotate ? `rotate(${component.rotate}deg)` : 'none',
|
||||
transform: component.rotate
|
||||
? `rotate(${component.rotate}deg)`
|
||||
: 'none',
|
||||
opacity: component.isOn ? 1 : 0.6,
|
||||
display: 'block',
|
||||
}"
|
||||
|
@ -185,8 +191,6 @@ import {
|
|||
saveDiagramData,
|
||||
updatePartPosition,
|
||||
updatePartAttribute,
|
||||
deletePart,
|
||||
deleteConnection,
|
||||
parseConnectionPin,
|
||||
connectionArrayToWireItem,
|
||||
validateDiagramData,
|
||||
|
@ -208,10 +212,7 @@ function handleContextMenu(e: MouseEvent) {
|
|||
}
|
||||
|
||||
// 定义组件发出的事件
|
||||
const emit = defineEmits([
|
||||
"toggle-doc-panel",
|
||||
"open-components",
|
||||
]);
|
||||
const emit = defineEmits(["toggle-doc-panel", "open-components"]);
|
||||
|
||||
// 定义组件接受的属性
|
||||
const props = defineProps<{
|
||||
|
@ -367,7 +368,7 @@ const isWireCreationEventActive = ref(false);
|
|||
// 画布拖拽事件
|
||||
useEventListener(document, "mousemove", (e: MouseEvent) => {
|
||||
if (isDragEventActive.value) {
|
||||
onDrag(e);
|
||||
onCanvasDrag(e);
|
||||
}
|
||||
if (isComponentDragEventActive.value) {
|
||||
onComponentDrag(e);
|
||||
|
@ -469,7 +470,7 @@ function startMiddleDrag(e: MouseEvent) {
|
|||
}
|
||||
|
||||
// 拖拽画布过程
|
||||
function onDrag(e: MouseEvent) {
|
||||
function onCanvasDrag(e: MouseEvent) {
|
||||
if (!isDragging.value && !isMiddleDragging.value) return;
|
||||
|
||||
const newX = e.clientX - dragStart.x;
|
||||
|
@ -579,8 +580,7 @@ function onComponentDrag(e: MouseEvent) {
|
|||
const groupComponents = diagramParts.value.filter(
|
||||
(p) =>
|
||||
p.group === draggedComponent.group &&
|
||||
p.id !== draggingComponentId.value &&
|
||||
!p.positionlock,
|
||||
p.id !== draggingComponentId.value,
|
||||
);
|
||||
|
||||
// 更新这些组件的位置
|
||||
|
@ -608,16 +608,12 @@ function onComponentDrag(e: MouseEvent) {
|
|||
function stopComponentDrag() {
|
||||
// 如果有组件被拖拽,保存当前状态
|
||||
if (draggingComponentId.value) {
|
||||
// console.log(`组件拖拽结束: ${draggingComponentId.value}`);
|
||||
|
||||
// 保存图表数据
|
||||
saveDiagramData(diagramData.value);
|
||||
|
||||
// 清除拖动状态
|
||||
draggingComponentId.value = null;
|
||||
}
|
||||
|
||||
isComponentDragEventActive.value = false;
|
||||
|
||||
saveDiagramData(diagramData.value);
|
||||
}
|
||||
|
||||
// 更新组件属性
|
||||
|
@ -637,7 +633,6 @@ function updateComponentProp(
|
|||
propName,
|
||||
value,
|
||||
);
|
||||
saveDiagramData(diagramData.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -815,9 +810,6 @@ function handlePinClick(componentId: string, pinInfo: any, event: MouseEvent) {
|
|||
connections: [...diagramData.value.connections, newConnection],
|
||||
};
|
||||
|
||||
// 保存图表数据
|
||||
saveDiagramData(diagramData.value);
|
||||
|
||||
// 重置连线创建状态
|
||||
resetWireCreation();
|
||||
isWireCreationEventActive.value = false;
|
||||
|
@ -863,12 +855,10 @@ function onCreatingWireMouseMove(e: MouseEvent) {
|
|||
|
||||
// 删除组件
|
||||
function deleteComponent(componentId: string) {
|
||||
diagramData.value = deletePart(diagramData.value, componentId);
|
||||
// 直接通过componentManager删除组件
|
||||
if (componentManager) {
|
||||
componentManager.deleteComponent(componentId);
|
||||
}
|
||||
saveDiagramData(diagramData.value);
|
||||
|
||||
// 清除选中状态
|
||||
if (selectedComponentId.value === componentId) {
|
||||
|
@ -922,9 +912,6 @@ function handleFileSelected(event: Event) {
|
|||
// 更新画布数据
|
||||
diagramData.value = parsed as DiagramData;
|
||||
|
||||
// 保存到本地文件
|
||||
saveDiagramData(diagramData.value);
|
||||
|
||||
alertStore?.show(`成功导入diagram文件`, "success");
|
||||
} catch (error) {
|
||||
console.error("解析JSON文件出错:", error);
|
||||
|
@ -988,22 +975,6 @@ function exportDiagram() {
|
|||
|
||||
// --- 生命周期钩子 ---
|
||||
onMounted(async () => {
|
||||
// 设置componentManager的画布引用
|
||||
if (componentManager) {
|
||||
// 创建一个包含必要方法的画布API对象
|
||||
const canvasAPI = {
|
||||
getDiagramData: () => diagramData.value,
|
||||
updateDiagramDataDirectly: (data: DiagramData) => {
|
||||
diagramData.value = data;
|
||||
saveDiagramData(data);
|
||||
},
|
||||
getCanvasPosition: () => componentManager.getCanvasPosition(),
|
||||
getScale: () => componentManager.getCanvasScale(),
|
||||
$el: canvasContainer.value,
|
||||
};
|
||||
componentManager.setCanvasRef(canvasAPI);
|
||||
}
|
||||
|
||||
// 加载图表数据
|
||||
try {
|
||||
diagramData.value = await loadDiagramData();
|
||||
|
@ -1061,7 +1032,6 @@ function updateDiagramDataDirectly(data: DiagramData) {
|
|||
}
|
||||
|
||||
diagramData.value = data;
|
||||
saveDiagramData(data);
|
||||
}
|
||||
|
||||
// 暴露方法给父组件
|
||||
|
@ -1070,21 +1040,16 @@ defineExpose({
|
|||
getDiagramData: () => diagramData.value,
|
||||
updateDiagramDataDirectly,
|
||||
});
|
||||
|
||||
// 监视器 - 当图表数据更改时保存
|
||||
watch(
|
||||
diagramData,
|
||||
(newData) => {
|
||||
saveDiagramData(newData);
|
||||
},
|
||||
{ deep: true },
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 基础容器样式 - 使用 Tailwind 类替代 */
|
||||
.diagram-container {
|
||||
background-size: 20px 20px, 20px 20px, 100px 100px, 100px 100px;
|
||||
background-size:
|
||||
20px 20px,
|
||||
20px 20px,
|
||||
100px 100px,
|
||||
100px 100px;
|
||||
background-position: 0 0;
|
||||
}
|
||||
|
||||
|
@ -1130,7 +1095,13 @@ watch(
|
|||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.component-wrapper :deep(svg *:not([class*="interactive"]):not(rect.glow):not(circle[fill-opacity]):not([fill-opacity])) {
|
||||
.component-wrapper
|
||||
:deep(
|
||||
svg
|
||||
*:not([class*="interactive"]):not(rect.glow):not(
|
||||
circle[fill-opacity]
|
||||
):not([fill-opacity])
|
||||
) {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
import { ref, shallowRef, computed, reactive } from "vue";
|
||||
import { createInjectionState } from "@vueuse/core";
|
||||
import type { DiagramData, DiagramPart } from "./diagramManager";
|
||||
import {
|
||||
saveDiagramData,
|
||||
type DiagramData,
|
||||
type DiagramPart,
|
||||
} from "./diagramManager";
|
||||
import type { PropertyConfig } from "@/components/equipments/componentConfig";
|
||||
import {
|
||||
generatePropertyConfigs,
|
||||
|
@ -24,10 +28,12 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
// --- 状态管理 ---
|
||||
const componentModules = ref<Record<string, ComponentModule>>({});
|
||||
const selectedComponentId = ref<string | null>(null);
|
||||
const selectedComponentConfig = shallowRef<{ props: PropertyConfig[] } | null>(null);
|
||||
const selectedComponentConfig = shallowRef<{
|
||||
props: PropertyConfig[];
|
||||
} | null>(null);
|
||||
const diagramCanvas = ref<any>(null);
|
||||
const componentRefs = ref<Record<string, any>>({});
|
||||
|
||||
|
||||
// 新增:直接管理canvas的位置和缩放
|
||||
const canvasPosition = reactive({ x: 0, y: 0 });
|
||||
const canvasScale = ref(1);
|
||||
|
@ -35,17 +41,21 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
// 计算当前选中的组件数据
|
||||
const selectedComponentData = computed(() => {
|
||||
if (!diagramCanvas.value || !selectedComponentId.value) return null;
|
||||
|
||||
|
||||
const canvasInstance = diagramCanvas.value as any;
|
||||
if (canvasInstance && canvasInstance.getDiagramData) {
|
||||
const data = canvasInstance.getDiagramData();
|
||||
return data.parts.find((p: DiagramPart) => p.id === selectedComponentId.value) || null;
|
||||
return (
|
||||
data.parts.find(
|
||||
(p: DiagramPart) => p.id === selectedComponentId.value,
|
||||
) || null
|
||||
);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
// --- Canvas 控制方法 ---
|
||||
|
||||
|
||||
/**
|
||||
* 设置canvas位置
|
||||
*/
|
||||
|
@ -86,20 +96,30 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
/**
|
||||
* 缩放到指定位置(以鼠标位置为中心)
|
||||
*/
|
||||
function zoomAtPosition(mouseX: number, mouseY: number, zoomFactor: number) {
|
||||
function zoomAtPosition(
|
||||
mouseX: number,
|
||||
mouseY: number,
|
||||
zoomFactor: number,
|
||||
) {
|
||||
// 计算鼠标在画布坐标系中的位置
|
||||
const mouseXCanvas = (mouseX - canvasPosition.x) / canvasScale.value;
|
||||
const mouseYCanvas = (mouseY - canvasPosition.y) / canvasScale.value;
|
||||
|
||||
// 计算新的缩放值
|
||||
const newScale = Math.max(0.2, Math.min(canvasScale.value * zoomFactor, 10.0));
|
||||
const newScale = Math.max(
|
||||
0.2,
|
||||
Math.min(canvasScale.value * zoomFactor, 10.0),
|
||||
);
|
||||
|
||||
// 计算新的位置,使鼠标指针位置在缩放前后保持不变
|
||||
canvasPosition.x = mouseX - mouseXCanvas * newScale;
|
||||
canvasPosition.y = mouseY - mouseYCanvas * newScale;
|
||||
canvasScale.value = newScale;
|
||||
|
||||
return { scale: newScale, position: { x: canvasPosition.x, y: canvasPosition.y } };
|
||||
return {
|
||||
scale: newScale,
|
||||
position: { x: canvasPosition.x, y: canvasPosition.y },
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -108,7 +128,7 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
function screenToCanvas(screenX: number, screenY: number) {
|
||||
return {
|
||||
x: (screenX - canvasPosition.x) / canvasScale.value,
|
||||
y: (screenY - canvasPosition.y) / canvasScale.value
|
||||
y: (screenY - canvasPosition.y) / canvasScale.value,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -118,14 +138,18 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
function canvasToScreen(canvasX: number, canvasY: number) {
|
||||
return {
|
||||
x: canvasX * canvasScale.value + canvasPosition.x,
|
||||
y: canvasY * canvasScale.value + canvasPosition.y
|
||||
y: canvasY * canvasScale.value + canvasPosition.y,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 居中显示指定区域
|
||||
*/
|
||||
function centerView(bounds: { x: number, y: number, width: number, height: number }, containerWidth: number, containerHeight: number) {
|
||||
function centerView(
|
||||
bounds: { x: number; y: number; width: number; height: number },
|
||||
containerWidth: number,
|
||||
containerHeight: number,
|
||||
) {
|
||||
// 计算合适的缩放比例
|
||||
const scaleX = containerWidth / bounds.width;
|
||||
const scaleY = containerHeight / bounds.height;
|
||||
|
@ -139,24 +163,27 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
canvasPosition.x = containerWidth / 2 - centerX * newScale;
|
||||
canvasPosition.y = containerHeight / 2 - centerY * newScale;
|
||||
|
||||
return { scale: newScale, position: { x: canvasPosition.x, y: canvasPosition.y } };
|
||||
return {
|
||||
scale: newScale,
|
||||
position: { x: canvasPosition.x, y: canvasPosition.y },
|
||||
};
|
||||
}
|
||||
|
||||
// --- 组件模块管理 ---
|
||||
|
||||
|
||||
/**
|
||||
* 动态加载组件模块
|
||||
*/
|
||||
async function loadComponentModule(type: string) {
|
||||
console.log(`尝试加载组件模块: ${type}`);
|
||||
console.log(`当前已加载的模块:`, Object.keys(componentModules.value));
|
||||
|
||||
|
||||
if (!componentModules.value[type]) {
|
||||
try {
|
||||
console.log(`正在动态导入模块: @/components/equipments/${type}.vue`);
|
||||
const module = await import(`@/components/equipments/${type}.vue`);
|
||||
console.log(`成功导入模块 ${type}:`, module);
|
||||
|
||||
|
||||
// 直接设置新的对象引用以触发响应性
|
||||
componentModules.value = {
|
||||
...componentModules.value,
|
||||
|
@ -180,7 +207,7 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
async function preloadComponentModules(componentTypes: string[]) {
|
||||
console.log("Preloading component modules:", componentTypes);
|
||||
await Promise.all(
|
||||
componentTypes.map((type) => loadComponentModule(type))
|
||||
componentTypes.map((type) => loadComponentModule(type)),
|
||||
);
|
||||
console.log("All component modules loaded");
|
||||
}
|
||||
|
@ -197,7 +224,7 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
}) {
|
||||
console.log("=== 开始添加组件 ===");
|
||||
console.log("组件数据:", componentData);
|
||||
|
||||
|
||||
const canvasInstance = diagramCanvas.value as any;
|
||||
if (!canvasInstance) {
|
||||
console.error("没有可用的画布实例");
|
||||
|
@ -222,8 +249,10 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
const viewportWidth = canvasContainer.clientWidth;
|
||||
const viewportHeight = canvasContainer.clientHeight;
|
||||
|
||||
position.x = (viewportWidth / 2 - canvasPosition.x) / canvasScale.value;
|
||||
position.y = (viewportHeight / 2 - canvasPosition.y) / canvasScale.value;
|
||||
position.x =
|
||||
(viewportWidth / 2 - canvasPosition.x) / canvasScale.value;
|
||||
position.y =
|
||||
(viewportHeight / 2 - canvasPosition.y) / canvasScale.value;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取画布位置时出错:", error);
|
||||
|
@ -264,17 +293,21 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
};
|
||||
|
||||
// 通过画布实例添加组件
|
||||
if (canvasInstance.getDiagramData && canvasInstance.updateDiagramDataDirectly) {
|
||||
if (
|
||||
canvasInstance.getDiagramData &&
|
||||
canvasInstance.updateDiagramDataDirectly
|
||||
) {
|
||||
const currentData = canvasInstance.getDiagramData();
|
||||
currentData.parts.push(newComponent);
|
||||
|
||||
|
||||
// 使用 updateDiagramDataDirectly 避免触发加载状态
|
||||
canvasInstance.updateDiagramDataDirectly(currentData);
|
||||
|
||||
saveDiagramData(currentData);
|
||||
|
||||
console.log("组件添加完成:", newComponent);
|
||||
|
||||
|
||||
// 等待Vue的下一个tick,确保组件模块已经更新
|
||||
await new Promise(resolve => setTimeout(resolve, 50));
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -287,9 +320,12 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
template: any;
|
||||
}) {
|
||||
console.log("添加模板:", templateData);
|
||||
|
||||
|
||||
const canvasInstance = diagramCanvas.value as any;
|
||||
if (!canvasInstance?.getDiagramData || !canvasInstance?.updateDiagramDataDirectly) {
|
||||
if (
|
||||
!canvasInstance?.getDiagramData ||
|
||||
!canvasInstance?.updateDiagramDataDirectly
|
||||
) {
|
||||
console.error("没有可用的画布实例添加模板");
|
||||
return;
|
||||
}
|
||||
|
@ -305,12 +341,14 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
let viewportCenter = { x: 300, y: 200 };
|
||||
try {
|
||||
const canvasContainer = canvasInstance.$el as HTMLElement;
|
||||
|
||||
|
||||
if (canvasContainer) {
|
||||
const viewportWidth = canvasContainer.clientWidth;
|
||||
const viewportHeight = canvasContainer.clientHeight;
|
||||
viewportCenter.x = (viewportWidth / 2 - canvasPosition.x) / canvasScale.value;
|
||||
viewportCenter.y = (viewportHeight / 2 - canvasPosition.y) / canvasScale.value;
|
||||
viewportCenter.x =
|
||||
(viewportWidth / 2 - canvasPosition.x) / canvasScale.value;
|
||||
viewportCenter.y =
|
||||
(viewportHeight / 2 - canvasPosition.y) / canvasScale.value;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取视口中心位置时出错:", error);
|
||||
|
@ -339,7 +377,10 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
}
|
||||
|
||||
// 计算新位置
|
||||
if (typeof newPart.x === "number" && typeof newPart.y === "number") {
|
||||
if (
|
||||
typeof newPart.x === "number" &&
|
||||
typeof newPart.y === "number"
|
||||
) {
|
||||
const relativeX = part.x - mainPart.x;
|
||||
const relativeY = part.y - mainPart.y;
|
||||
newPart.x = viewportCenter.x + relativeX;
|
||||
|
@ -347,7 +388,7 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
}
|
||||
|
||||
return newPart;
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
currentData.parts.push(...newParts);
|
||||
|
@ -359,32 +400,38 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
idMap[part.id] = `${idPrefix}${part.id}`;
|
||||
});
|
||||
|
||||
const newConnections = templateData.template.connections.map((conn: any) => {
|
||||
if (Array.isArray(conn)) {
|
||||
const [from, to, type, path] = conn;
|
||||
const fromParts = from.split(":");
|
||||
const toParts = to.split(":");
|
||||
const newConnections = templateData.template.connections.map(
|
||||
(conn: any) => {
|
||||
if (Array.isArray(conn)) {
|
||||
const [from, to, type, path] = conn;
|
||||
const fromParts = from.split(":");
|
||||
const toParts = to.split(":");
|
||||
|
||||
if (fromParts.length === 2 && toParts.length === 2) {
|
||||
const fromComponentId = fromParts[0];
|
||||
const fromPinId = fromParts[1];
|
||||
const toComponentId = toParts[0];
|
||||
const toPinId = toParts[1];
|
||||
if (fromParts.length === 2 && toParts.length === 2) {
|
||||
const fromComponentId = fromParts[0];
|
||||
const fromPinId = fromParts[1];
|
||||
const toComponentId = toParts[0];
|
||||
const toPinId = toParts[1];
|
||||
|
||||
const newFrom = `${idMap[fromComponentId] || fromComponentId}:${fromPinId}`;
|
||||
const newTo = `${idMap[toComponentId] || toComponentId}:${toPinId}`;
|
||||
const newFrom = `${idMap[fromComponentId] || fromComponentId}:${fromPinId}`;
|
||||
const newTo = `${idMap[toComponentId] || toComponentId}:${toPinId}`;
|
||||
|
||||
return [newFrom, newTo, type, path];
|
||||
return [newFrom, newTo, type, path];
|
||||
}
|
||||
}
|
||||
}
|
||||
return conn;
|
||||
});
|
||||
return conn;
|
||||
},
|
||||
);
|
||||
|
||||
currentData.connections.push(...newConnections);
|
||||
}
|
||||
|
||||
canvasInstance.updateDiagramDataDirectly(currentData);
|
||||
console.log("=== 更新图表数据完成,新组件数量:", currentData.parts.length);
|
||||
console.log(
|
||||
"=== 更新图表数据完成,新组件数量:",
|
||||
currentData.parts.length,
|
||||
);
|
||||
saveDiagramData(currentData);
|
||||
|
||||
return { success: true, message: `已添加 ${templateData.name} 模板` };
|
||||
} else {
|
||||
|
@ -398,13 +445,18 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
*/
|
||||
function deleteComponent(componentId: string) {
|
||||
const canvasInstance = diagramCanvas.value as any;
|
||||
if (!canvasInstance?.getDiagramData || !canvasInstance?.updateDiagramDataDirectly) {
|
||||
if (
|
||||
!canvasInstance?.getDiagramData ||
|
||||
!canvasInstance?.updateDiagramDataDirectly
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentData = canvasInstance.getDiagramData();
|
||||
const component = currentData.parts.find((p: DiagramPart) => p.id === componentId);
|
||||
|
||||
const component = currentData.parts.find(
|
||||
(p: DiagramPart) => p.id === componentId,
|
||||
);
|
||||
|
||||
if (!component) return;
|
||||
|
||||
const componentsToDelete: string[] = [componentId];
|
||||
|
@ -412,34 +464,47 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
// 处理组件组
|
||||
if (component.group && component.group !== "") {
|
||||
const groupMembers = currentData.parts.filter(
|
||||
(p: DiagramPart) => p.group === component.group && p.id !== componentId
|
||||
(p: DiagramPart) =>
|
||||
p.group === component.group && p.id !== componentId,
|
||||
);
|
||||
componentsToDelete.push(...groupMembers.map((p: DiagramPart) => p.id));
|
||||
console.log(`删除组件 ${componentId} 及其组 ${component.group} 中的 ${groupMembers.length} 个组件`);
|
||||
console.log(
|
||||
`删除组件 ${componentId} 及其组 ${component.group} 中的 ${groupMembers.length} 个组件`,
|
||||
);
|
||||
}
|
||||
|
||||
// 删除组件
|
||||
currentData.parts = currentData.parts.filter(
|
||||
(p: DiagramPart) => !componentsToDelete.includes(p.id)
|
||||
(p: DiagramPart) => !componentsToDelete.includes(p.id),
|
||||
);
|
||||
|
||||
// 删除相关连接
|
||||
currentData.connections = currentData.connections.filter((connection: any) => {
|
||||
for (const id of componentsToDelete) {
|
||||
if (connection[0].startsWith(`${id}:`) || connection[1].startsWith(`${id}:`)) {
|
||||
return false;
|
||||
currentData.connections = currentData.connections.filter(
|
||||
(connection: any) => {
|
||||
for (const id of componentsToDelete) {
|
||||
if (
|
||||
connection[0].startsWith(`${id}:`) ||
|
||||
connection[1].startsWith(`${id}:`)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return true;
|
||||
},
|
||||
);
|
||||
|
||||
// 清除选中状态
|
||||
if (selectedComponentId.value && componentsToDelete.includes(selectedComponentId.value)) {
|
||||
if (
|
||||
selectedComponentId.value &&
|
||||
componentsToDelete.includes(selectedComponentId.value)
|
||||
) {
|
||||
selectedComponentId.value = null;
|
||||
selectedComponentConfig.value = null;
|
||||
}
|
||||
|
||||
canvasInstance.updateDiagramDataDirectly(currentData);
|
||||
|
||||
saveDiagramData(currentData);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -470,16 +535,18 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
// 添加组件直接属性
|
||||
const directPropConfigs = generatePropertyConfigs(componentData);
|
||||
const newDirectProps = directPropConfigs.filter(
|
||||
(config) => !addedProps.has(config.name)
|
||||
(config) => !addedProps.has(config.name),
|
||||
);
|
||||
propConfigs.push(...newDirectProps);
|
||||
|
||||
// 添加 attrs 中的属性
|
||||
if (componentData.attrs) {
|
||||
const attrPropConfigs = generatePropsFromAttrs(componentData.attrs);
|
||||
const attrPropConfigs = generatePropsFromAttrs(
|
||||
componentData.attrs,
|
||||
);
|
||||
attrPropConfigs.forEach((attrConfig) => {
|
||||
const existingIndex = propConfigs.findIndex(
|
||||
(p) => p.name === attrConfig.name
|
||||
(p) => p.name === attrConfig.name,
|
||||
);
|
||||
if (existingIndex >= 0) {
|
||||
propConfigs[existingIndex] = attrConfig;
|
||||
|
@ -490,9 +557,15 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
}
|
||||
|
||||
selectedComponentConfig.value = { props: propConfigs };
|
||||
console.log(`Built config for ${componentData.type}:`, selectedComponentConfig.value);
|
||||
console.log(
|
||||
`Built config for ${componentData.type}:`,
|
||||
selectedComponentConfig.value,
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(`Error building config for ${componentData.type}:`, error);
|
||||
console.error(
|
||||
`Error building config for ${componentData.type}:`,
|
||||
error,
|
||||
);
|
||||
selectedComponentConfig.value = { props: [] };
|
||||
}
|
||||
} else {
|
||||
|
@ -505,9 +578,16 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
/**
|
||||
* 更新组件属性
|
||||
*/
|
||||
function updateComponentProp(componentId: string, propName: string, value: any) {
|
||||
function updateComponentProp(
|
||||
componentId: string,
|
||||
propName: string,
|
||||
value: any,
|
||||
) {
|
||||
const canvasInstance = diagramCanvas.value as any;
|
||||
if (!canvasInstance?.getDiagramData || !canvasInstance?.updateDiagramDataDirectly) {
|
||||
if (
|
||||
!canvasInstance?.getDiagramData ||
|
||||
!canvasInstance?.updateDiagramDataDirectly
|
||||
) {
|
||||
console.error("没有可用的画布实例进行属性更新");
|
||||
return;
|
||||
}
|
||||
|
@ -518,7 +598,9 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
}
|
||||
|
||||
const currentData = canvasInstance.getDiagramData();
|
||||
const part = currentData.parts.find((p: DiagramPart) => p.id === componentId);
|
||||
const part = currentData.parts.find(
|
||||
(p: DiagramPart) => p.id === componentId,
|
||||
);
|
||||
|
||||
if (part) {
|
||||
if (propName in part) {
|
||||
|
@ -531,27 +613,44 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
}
|
||||
|
||||
canvasInstance.updateDiagramDataDirectly(currentData);
|
||||
console.log(`更新组件${componentId}的属性${propName}为:`, value, typeof value);
|
||||
console.log(
|
||||
`更新组件${componentId}的属性${propName}为:`,
|
||||
value,
|
||||
typeof value,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新组件直接属性
|
||||
*/
|
||||
function updateComponentDirectProp(componentId: string, propName: string, value: any) {
|
||||
function updateComponentDirectProp(
|
||||
componentId: string,
|
||||
propName: string,
|
||||
value: any,
|
||||
) {
|
||||
const canvasInstance = diagramCanvas.value as any;
|
||||
if (!canvasInstance?.getDiagramData || !canvasInstance?.updateDiagramDataDirectly) {
|
||||
if (
|
||||
!canvasInstance?.getDiagramData ||
|
||||
!canvasInstance?.updateDiagramDataDirectly
|
||||
) {
|
||||
console.error("没有可用的画布实例进行属性更新");
|
||||
return;
|
||||
}
|
||||
|
||||
const currentData = canvasInstance.getDiagramData();
|
||||
const part = currentData.parts.find((p: DiagramPart) => p.id === componentId);
|
||||
const part = currentData.parts.find(
|
||||
(p: DiagramPart) => p.id === componentId,
|
||||
);
|
||||
|
||||
if (part) {
|
||||
(part as any)[propName] = value;
|
||||
canvasInstance.updateDiagramDataDirectly(currentData);
|
||||
console.log(`更新组件${componentId}的直接属性${propName}为:`, value, typeof value);
|
||||
console.log(
|
||||
`更新组件${componentId}的直接属性${propName}为:`,
|
||||
value,
|
||||
typeof value,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -560,12 +659,17 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
*/
|
||||
function moveComponent(moveData: { id: string; x: number; y: number }) {
|
||||
const canvasInstance = diagramCanvas.value as any;
|
||||
if (!canvasInstance?.getDiagramData || !canvasInstance?.updateDiagramDataDirectly) {
|
||||
if (
|
||||
!canvasInstance?.getDiagramData ||
|
||||
!canvasInstance?.updateDiagramDataDirectly
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentData = canvasInstance.getDiagramData();
|
||||
const part = currentData.parts.find((p: DiagramPart) => p.id === moveData.id);
|
||||
const part = currentData.parts.find(
|
||||
(p: DiagramPart) => p.id === moveData.id,
|
||||
);
|
||||
if (part) {
|
||||
part.x = moveData.x;
|
||||
part.y = moveData.y;
|
||||
|
@ -606,7 +710,13 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
if (canvasInstance && canvasInstance.getDiagramData) {
|
||||
return canvasInstance.getDiagramData();
|
||||
}
|
||||
return { parts: [], connections: [], version: 1, author: "admin", editor: "me" };
|
||||
return {
|
||||
parts: [],
|
||||
connections: [],
|
||||
version: 1,
|
||||
author: "admin",
|
||||
editor: "me",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -624,7 +734,7 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
*/
|
||||
function getComponentDefinition(type: string) {
|
||||
const module = componentModules.value[type];
|
||||
|
||||
|
||||
if (!module) {
|
||||
console.warn(`No module found for component type: ${type}`);
|
||||
// 尝试异步加载组件模块
|
||||
|
@ -668,7 +778,7 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
const canvasInstance = diagramCanvas.value as any;
|
||||
if (canvasInstance?.getDiagramData) {
|
||||
const diagramData = canvasInstance.getDiagramData();
|
||||
|
||||
|
||||
// 收集所有组件类型
|
||||
const componentTypes = new Set<string>();
|
||||
diagramData.parts.forEach((part: DiagramPart) => {
|
||||
|
@ -687,11 +797,11 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
selectedComponentData,
|
||||
selectedComponentConfig,
|
||||
componentRefs,
|
||||
|
||||
|
||||
// Canvas控制状态
|
||||
canvasPosition,
|
||||
canvasScale,
|
||||
|
||||
|
||||
// 方法
|
||||
loadComponentModule,
|
||||
preloadComponentModules,
|
||||
|
@ -710,7 +820,7 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
getComponentDefinition,
|
||||
prepareComponentProps,
|
||||
initialize,
|
||||
|
||||
|
||||
// Canvas控制方法
|
||||
setCanvasPosition,
|
||||
updateCanvasPosition,
|
||||
|
@ -722,7 +832,7 @@ const [useProvideComponentManager, useComponentManager] = createInjectionState(
|
|||
canvasToScreen,
|
||||
centerView,
|
||||
};
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
export { useProvideComponentManager, useComponentManager };
|
||||
|
|
|
@ -123,14 +123,6 @@ export function saveDiagramData(data: DiagramData): void {
|
|||
}
|
||||
}
|
||||
|
||||
// 添加新组件到图表数据
|
||||
export function addPart(data: DiagramData, part: DiagramPart): DiagramData {
|
||||
return {
|
||||
...data,
|
||||
parts: [...data.parts, part]
|
||||
};
|
||||
}
|
||||
|
||||
// 更新组件位置
|
||||
export function updatePartPosition(
|
||||
data: DiagramData,
|
||||
|
@ -171,42 +163,6 @@ export function updatePartAttribute(
|
|||
};
|
||||
}
|
||||
|
||||
// 删除组件及同组组件
|
||||
export function deletePart(data: DiagramData, partId: string): DiagramData {
|
||||
// 首先找到要删除的组件
|
||||
const component = data.parts.find(part => part.id === partId);
|
||||
if (!component) return data;
|
||||
|
||||
// 收集需要删除的组件ID列表
|
||||
const componentsToDelete: string[] = [partId];
|
||||
|
||||
// 如果组件属于一个组,则找出所有同组的组件
|
||||
if (component.group && component.group !== '') {
|
||||
const groupMembers = data.parts.filter(
|
||||
p => p.group === component.group && p.id !== partId
|
||||
);
|
||||
|
||||
// 将同组组件ID添加到删除列表
|
||||
componentsToDelete.push(...groupMembers.map(p => p.id));
|
||||
console.log(`删除组件 ${partId} 及其组 ${component.group} 中的 ${groupMembers.length} 个组件`);
|
||||
}
|
||||
|
||||
return {
|
||||
...data,
|
||||
// 删除所有标记的组件
|
||||
parts: data.parts.filter(part => !componentsToDelete.includes(part.id)),
|
||||
// 删除与这些组件相关的所有连接
|
||||
connections: data.connections.filter(conn => {
|
||||
const [startPin, endPin] = conn;
|
||||
const startCompId = startPin.split(':')[0];
|
||||
const endCompId = endPin.split(':')[0];
|
||||
|
||||
// 检查连接两端的组件是否在删除列表中
|
||||
return !componentsToDelete.includes(startCompId) && !componentsToDelete.includes(endCompId);
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
// 添加连接
|
||||
export function addConnection(
|
||||
data: DiagramData,
|
||||
|
@ -256,25 +212,6 @@ export function findConnectionsByPart(
|
|||
});
|
||||
}
|
||||
|
||||
// 基于组的移动相关组件
|
||||
export function moveGroupComponents(
|
||||
data: DiagramData,
|
||||
groupId: string,
|
||||
deltaX: number,
|
||||
deltaY: number
|
||||
): DiagramData {
|
||||
if (!groupId) return data;
|
||||
|
||||
return {
|
||||
...data,
|
||||
parts: data.parts.map(part =>
|
||||
part.group === groupId
|
||||
? { ...part, x: part.x + deltaX, y: part.y + deltaY }
|
||||
: part
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
// 添加验证diagram.json文件的函数
|
||||
export function validateDiagramData(data: any): { isValid: boolean; errors: string[] } {
|
||||
const errors: string[] = [];
|
||||
|
|
|
@ -98,7 +98,6 @@ const props = defineProps<{
|
|||
const propertySectionExpanded = ref(false); // 基本属性区域默认展开
|
||||
const pinsSectionExpanded = ref(false); // 引脚配置区域默认折叠
|
||||
const componentCapsExpanded = ref(true); // 组件功能区域默认展开
|
||||
const wireSectionExpanded = ref(false); // 连线管理区域默认折叠
|
||||
|
||||
const componentCaps = useTemplateRef("ComponentCapabilities");
|
||||
|
||||
|
|
Loading…
Reference in New Issue