修改算法类型判断,调整链接桩大小,点击添加移动连接线功能
This commit is contained in:
parent
086d834788
commit
86c7d1c7a9
BIN
business-css/frontend/src/assets/del.png
Normal file
BIN
business-css/frontend/src/assets/del.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
@ -1,244 +0,0 @@
|
|||||||
<!-- components/GraphCanvas.vue -->
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { onMounted, ref, onBeforeUnmount } from 'vue';
|
|
||||||
import { Graph, registerNode, Brush } from '@antv/g6';
|
|
||||||
import { NodeItem, NodeType } from '@/types/graph';
|
|
||||||
|
|
||||||
// 定义图形映射名称
|
|
||||||
const NODE_LABEL_MAP: Record<NodeType, string> = {
|
|
||||||
cylinder_slot: '圆柱槽',
|
|
||||||
flat_slot: '扁平槽',
|
|
||||||
ring_slot: '环形槽',
|
|
||||||
tube_slot: '管形槽',
|
|
||||||
bar_stock: '棒料',
|
|
||||||
tapered_head: '锥形头',
|
|
||||||
monk_ring_slot: '僧帽环形槽',
|
|
||||||
};
|
|
||||||
|
|
||||||
// 自定义 G6 节点:根据 type 渲染不同形状和颜色
|
|
||||||
const registerCustomNode = () => {
|
|
||||||
registerNode(
|
|
||||||
'custom-mechanical-node',
|
|
||||||
{
|
|
||||||
draw: (cfg, group) => {
|
|
||||||
const type = cfg?.type as NodeType;
|
|
||||||
let shape, color;
|
|
||||||
|
|
||||||
// 根据类型设置外观
|
|
||||||
switch (type) {
|
|
||||||
case 'cylinder_slot':
|
|
||||||
shape = group!.addShape('ellipse', {
|
|
||||||
attrs: {
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
rx: 40,
|
|
||||||
ry: 20,
|
|
||||||
fill: '#ffeaa7',
|
|
||||||
stroke: '#fab1a0',
|
|
||||||
lineWidth: 1.5,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case 'flat_slot':
|
|
||||||
shape = group!.addShape('rect', {
|
|
||||||
attrs: {
|
|
||||||
x: -50,
|
|
||||||
y: -15,
|
|
||||||
width: 100,
|
|
||||||
height: 30,
|
|
||||||
fill: '#fdcb6e',
|
|
||||||
stroke: '#e17055',
|
|
||||||
radius: 4,
|
|
||||||
lineWidth: 1.5,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case 'ring_slot':
|
|
||||||
shape = group!.addShape('circle', {
|
|
||||||
attrs: {
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
r: 30,
|
|
||||||
fill: '#a29bfe',
|
|
||||||
stroke: '#6c5ce7',
|
|
||||||
lineWidth: 2,
|
|
||||||
shadowBlur: 4,
|
|
||||||
shadowColor: 'rgba(108, 92, 231, 0.3)',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case 'tube_slot':
|
|
||||||
shape = group!.addShape('path', {
|
|
||||||
attrs: {
|
|
||||||
path:
|
|
||||||
'M -40 -20 L 40 -20 C 50 -20 50 20 40 20 L -40 20 C -50 20 -50 -20 -40 -20 Z M -30 -10 L 30 -10 L 30 10 L -30 10 Z',
|
|
||||||
fill: '#7bed9f',
|
|
||||||
stroke: '#00b894',
|
|
||||||
lineWidth: 1,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case 'bar_stock':
|
|
||||||
shape = group!.addShape('rect', {
|
|
||||||
attrs: {
|
|
||||||
x: -45,
|
|
||||||
y: -10,
|
|
||||||
width: 90,
|
|
||||||
height: 20,
|
|
||||||
fill: '#fab1a0',
|
|
||||||
stroke: '#d63031',
|
|
||||||
lineWidth: 1.2,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case 'tapered_head':
|
|
||||||
shape = group!.addShape('path', {
|
|
||||||
attrs: {
|
|
||||||
path: 'M -40 20 L 0 -25 L 40 20 L 20 20 L 0 -5 L -20 20 Z',
|
|
||||||
fill: '#fd79a8',
|
|
||||||
stroke: '#e84393',
|
|
||||||
lineWidth: 1.5,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case 'monk_ring_slot':
|
|
||||||
shape = group!.addShape('path', {
|
|
||||||
attrs: {
|
|
||||||
path:
|
|
||||||
'M -35 20 C -35 10, -25 -25, 0 -25 C 25 -25, 35 10, 35 20 C 35 20, 25 -10, 0 -10 C -25 -10, -35 20, -35 20 Z',
|
|
||||||
fill: '#6c5ce7',
|
|
||||||
stroke: '#55efc4',
|
|
||||||
lineWidth: 2,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
shape = group!.addShape('circle', {
|
|
||||||
attrs: {
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
r: 20,
|
|
||||||
fill: '#ccc',
|
|
||||||
stroke: '#999',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加文字标签
|
|
||||||
group!.addShape('text', {
|
|
||||||
attrs: {
|
|
||||||
text: NODE_LABEL_MAP[type] || '未知',
|
|
||||||
x: 0,
|
|
||||||
y: 40,
|
|
||||||
fontSize: 12,
|
|
||||||
textAlign: 'center',
|
|
||||||
textBaseline: 'middle',
|
|
||||||
fill: '#555',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return shape!;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'single-shape'
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
let graph: Graph | null = null;
|
|
||||||
const container = ref<HTMLDivElement>();
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
if (!container.value) return;
|
|
||||||
|
|
||||||
// 注册自定义节点
|
|
||||||
registerCustomNode();
|
|
||||||
|
|
||||||
// 初始化 G6 图实例
|
|
||||||
graph = new Graph({
|
|
||||||
container: container.value!,
|
|
||||||
width: container.value.offsetWidth,
|
|
||||||
height: container.value.offsetHeight,
|
|
||||||
fitView: true,
|
|
||||||
fitViewPadding: 40,
|
|
||||||
|
|
||||||
// 默认节点配置
|
|
||||||
defaultNode: {
|
|
||||||
shape: 'custom-mechanical-node',
|
|
||||||
size: [80, 40],
|
|
||||||
},
|
|
||||||
|
|
||||||
// 交互模式
|
|
||||||
modes: {
|
|
||||||
default: [
|
|
||||||
'drag-canvas', // 拖动画布
|
|
||||||
'zoom-canvas', // 缩放
|
|
||||||
'drag-node', // 拖动节点
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
// 启用 Brush 插件实现框选
|
|
||||||
plugins: [
|
|
||||||
new Brush({
|
|
||||||
brushType: 'rect', // 矩形框选
|
|
||||||
onSelect: (items) => {
|
|
||||||
console.log('Selected items:', items.map((i) => i.getModel()));
|
|
||||||
},
|
|
||||||
onDeselect: () => {
|
|
||||||
console.log('Deselected all');
|
|
||||||
},
|
|
||||||
})
|
|
||||||
brushType: 'rect', // 矩形框选
|
|
||||||
onSelect: (items) => {
|
|
||||||
console.log('Selected items:', items.map((i) => i.getModel()));
|
|
||||||
},
|
|
||||||
onDeselect: () => {
|
|
||||||
console.log('Deselected all');
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
// 初始空图
|
|
||||||
graph.data({ nodes: [], edges: [] });
|
|
||||||
graph.render();
|
|
||||||
});
|
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
|
||||||
if (graph) {
|
|
||||||
graph.destroy();
|
|
||||||
graph = null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 接收拖入事件
|
|
||||||
defineExpose({
|
|
||||||
addNodeAtPosition(type: NodeType, x: number, y: number) {
|
|
||||||
if (!graph) return;
|
|
||||||
|
|
||||||
const modelId = `${type}_${Date.now()}`;
|
|
||||||
const nodeModel = {
|
|
||||||
id: modelId,
|
|
||||||
shape: 'custom-mechanical-node',
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
type: type,
|
|
||||||
};
|
|
||||||
|
|
||||||
graph.addItem('node', nodeModel);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="graph-container" ref="container"></div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.graph-container {
|
|
||||||
flex: 1;
|
|
||||||
height: 100vh;
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: #f0f2f5;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -1,101 +0,0 @@
|
|||||||
<!-- components/LeftPanel.vue -->
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { ref } from 'vue';
|
|
||||||
import { NodeItem, NodeType } from '@/types/graph';
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
|
||||||
(e: 'drag-start', nodeType: NodeType): void;
|
|
||||||
(e: 'drag-end'): void;
|
|
||||||
}>();
|
|
||||||
|
|
||||||
const nodes: NodeItem[] = [
|
|
||||||
{ type: 'cylinder_slot', label: '圆柱槽' },
|
|
||||||
{ type: 'flat_slot', label: '扁平槽' },
|
|
||||||
{ type: 'ring_slot', label: '环形槽' },
|
|
||||||
{ type: 'tube_slot', label: '管形槽' },
|
|
||||||
{ type: 'bar_stock', label: '棒料' },
|
|
||||||
{ type: 'tapered_head', label: '锥形头' },
|
|
||||||
{ type: 'monk_ring_slot', label: '僧帽环形槽' },
|
|
||||||
];
|
|
||||||
|
|
||||||
const handleDragStart = (e: DragEvent, type: NodeType) => {
|
|
||||||
if (!e.dataTransfer) return;
|
|
||||||
e.dataTransfer.setData('text/plain', type);
|
|
||||||
emit('drag-start', type);
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="left-panel">
|
|
||||||
<h3 class="panel-title">图形元件库</h3>
|
|
||||||
<div class="node-list">
|
|
||||||
<div
|
|
||||||
v-for="node in nodes"
|
|
||||||
:key="node.type"
|
|
||||||
class="node-item"
|
|
||||||
draggable
|
|
||||||
@dragstart="handleDragStart($event, node.type)"
|
|
||||||
>
|
|
||||||
<span class="icon">⚙️</span>
|
|
||||||
<span class="label">{{ node.label }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.left-panel {
|
|
||||||
width: 200px;
|
|
||||||
height: 100vh;
|
|
||||||
background-color: #f7f9fc;
|
|
||||||
border-right: 1px solid #ddd;
|
|
||||||
overflow-y: auto;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-title {
|
|
||||||
padding: 16px;
|
|
||||||
font-size: 18px;
|
|
||||||
color: #1a1a1a;
|
|
||||||
border-bottom: 1px solid #eee;
|
|
||||||
margin: 0;
|
|
||||||
background-color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.node-list {
|
|
||||||
padding: 8px;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.node-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 10px;
|
|
||||||
padding: 10px 12px;
|
|
||||||
margin-bottom: 6px;
|
|
||||||
background-color: white;
|
|
||||||
border: 1px solid #e0e0e0;
|
|
||||||
border-radius: 6px;
|
|
||||||
cursor: grab;
|
|
||||||
user-select: none;
|
|
||||||
transition: all 0.2s ease;
|
|
||||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.node-item:hover {
|
|
||||||
background-color: #e6f7ff;
|
|
||||||
border-color: #91d5ff;
|
|
||||||
transform: translateY(-1px);
|
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.label {
|
|
||||||
font-size: 14px;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -1,412 +0,0 @@
|
|||||||
<!-- AntV G6 Graph Component -->
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { ref, onMounted } from 'vue';
|
|
||||||
import { Graph,NodeEvent } from '@antv/g6';
|
|
||||||
|
|
||||||
const container = ref<HTMLElement | null>(null);
|
|
||||||
let graph: Graph | null = null;
|
|
||||||
// Device types data
|
|
||||||
const deviceTypes = [
|
|
||||||
{ id: 'device1', name: '圆柱槽', icon: '🟢',
|
|
||||||
img: 'http://localhost:3000/dev-api/avatar/1.png'
|
|
||||||
},
|
|
||||||
{ id: 'device2', name: '扁平槽', icon: '🔵',
|
|
||||||
img: 'http://localhost:3000/dev-api/avatar/2.png'
|
|
||||||
},
|
|
||||||
{ id: 'device3', name: '环形槽', icon: '🟢',
|
|
||||||
img: 'http://localhost:3000/dev-api/avatar/3.png'
|
|
||||||
},
|
|
||||||
{ id: 'device4', name: '管束槽', icon: '🟢',
|
|
||||||
img: 'http://localhost:3000/dev-api/avatar/4.png'
|
|
||||||
},
|
|
||||||
{ id: 'device5', name: '萃取柱', icon: '🟦',
|
|
||||||
img: 'http://localhost:3000/dev-api/avatar/5.png'
|
|
||||||
},
|
|
||||||
{ id: 'device6', name: '流化床', icon: '🟦',
|
|
||||||
img: 'http://localhost:3000/dev-api/avatar/6.png'
|
|
||||||
},
|
|
||||||
{ id: 'device7', name: '锥底环形槽', icon: '🟦',
|
|
||||||
img: 'http://localhost:3000/dev-api/avatar/7.png'
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const data = {
|
|
||||||
nodes: [
|
|
||||||
],
|
|
||||||
edges: [
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
// Drag and drop functions
|
|
||||||
const handleDragStart = (event: DragEvent, device: any) => {
|
|
||||||
if (event.dataTransfer) {
|
|
||||||
event.dataTransfer.setData('application/json', JSON.stringify(device));
|
|
||||||
event.dataTransfer.effectAllowed = 'copy';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDragOver = (event: DragEvent) => {
|
|
||||||
event.preventDefault();
|
|
||||||
if (event.dataTransfer) {
|
|
||||||
event.dataTransfer.dropEffect = 'copy';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDrop = (event: DragEvent) => {
|
|
||||||
event.preventDefault();
|
|
||||||
if (!graph || !event.dataTransfer || !container.value) return;
|
|
||||||
|
|
||||||
let newNode = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const deviceData = JSON.parse(event.dataTransfer.getData('application/json'));
|
|
||||||
let imgUrl = deviceData.img;
|
|
||||||
|
|
||||||
// Calculate coordinates relative to graph container
|
|
||||||
const rect = container.value.getBoundingClientRect();
|
|
||||||
const x = event.clientX - rect.left;
|
|
||||||
const y = event.clientY - rect.top;
|
|
||||||
// const point = graph.getPointByClient(event.clientX, event.clientY);
|
|
||||||
// const x = point.x;
|
|
||||||
// const y = point.y;
|
|
||||||
const nodeId = 'node1-' + Date.now();
|
|
||||||
graph.addNodeData([
|
|
||||||
{
|
|
||||||
type: 'image',
|
|
||||||
id: nodeId,
|
|
||||||
img: imgUrl, // 图片地址
|
|
||||||
data: { label: '自定义图片1', status: 'online' },
|
|
||||||
style: {
|
|
||||||
x: x,
|
|
||||||
y: y,
|
|
||||||
size: 60,
|
|
||||||
src: imgUrl, // 图片地址
|
|
||||||
labelText: '111111111111',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
graph.draw();
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error handling drop:', error);
|
|
||||||
console.error('Graph instance:', graph);
|
|
||||||
if (newNode) {
|
|
||||||
console.error('New node:', JSON.stringify(newNode, null, 2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const dragelement = ref('');
|
|
||||||
function setDragElement(type: string) {
|
|
||||||
dragelement.value = type;
|
|
||||||
}
|
|
||||||
const dragLineData = ref([{
|
|
||||||
stroke: '#333',
|
|
||||||
lineWidth: 2,
|
|
||||||
endArrow: false,
|
|
||||||
endArrowType: '',
|
|
||||||
endArrowSize: 10,
|
|
||||||
},{
|
|
||||||
stroke: '#333',
|
|
||||||
lineWidth: 2,
|
|
||||||
endArrow: true,
|
|
||||||
endArrowType: 'vee',
|
|
||||||
endArrowSize: 10,
|
|
||||||
},{
|
|
||||||
startArrow: true,
|
|
||||||
startArrowType: 'vee',
|
|
||||||
startArrowSize: 10,
|
|
||||||
endArrow: true,
|
|
||||||
endArrowType: 'vee',
|
|
||||||
endArrowSize: 10,
|
|
||||||
stroke: '#333',
|
|
||||||
lineWidth: 2
|
|
||||||
},{
|
|
||||||
stroke: '#333',
|
|
||||||
lineWidth: 2,
|
|
||||||
lineDash: [5, 5],
|
|
||||||
},{
|
|
||||||
stroke: '#333',
|
|
||||||
lineWidth: 2,
|
|
||||||
lineDash: [5, 5],
|
|
||||||
endArrow: true,
|
|
||||||
endArrowType: 'vee',
|
|
||||||
endArrowSize: 10,
|
|
||||||
},{
|
|
||||||
startArrow: true,
|
|
||||||
startArrowType: 'vee',
|
|
||||||
startArrowSize: 10,
|
|
||||||
lineDash: [5, 5],
|
|
||||||
endArrow: true,
|
|
||||||
endArrowType: 'vee',
|
|
||||||
endArrowSize: 10,
|
|
||||||
stroke: '#333',
|
|
||||||
lineWidth: 2
|
|
||||||
}]);
|
|
||||||
const dragLine:any = ref({
|
|
||||||
stroke: '#333',
|
|
||||||
lineWidth: 2,
|
|
||||||
lineDash: [5, 5],
|
|
||||||
});
|
|
||||||
const dragLineType = ref('实线');
|
|
||||||
function setDragLineStyle(index: any, type: string) {
|
|
||||||
dragLine.value = dragLineData.value[index];
|
|
||||||
dragLineType.value = type;
|
|
||||||
// graph.updateBehavior({
|
|
||||||
// key: 'create-edge',
|
|
||||||
// style: (edgeData:any) => {
|
|
||||||
// debugger
|
|
||||||
// return {
|
|
||||||
// ...dragLine.value
|
|
||||||
// };
|
|
||||||
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
onMounted(() => {
|
|
||||||
if (container.value) {
|
|
||||||
// Create G6 graph instance with data in constructor - G6 v4 compatible
|
|
||||||
graph = new Graph({
|
|
||||||
container: container.value,
|
|
||||||
width: container.value.offsetWidth,
|
|
||||||
height: container.value.offsetHeight,
|
|
||||||
node: {
|
|
||||||
type: 'image',
|
|
||||||
style: {
|
|
||||||
size: 80,
|
|
||||||
labelText: (d) => '',
|
|
||||||
src: (d: any) => d.img
|
|
||||||
},
|
|
||||||
},
|
|
||||||
edge: {
|
|
||||||
type: 'line',
|
|
||||||
style: (datum) => {
|
|
||||||
// 正确的动态样式配置方式
|
|
||||||
return dragLine.value
|
|
||||||
},
|
|
||||||
// style: {
|
|
||||||
// lineDash: function (datum) {
|
|
||||||
// if (dragLineType.value === '虚线' || dragLineType.value === '单箭头虚线' || dragLineType.value === '双箭头虚线') {
|
|
||||||
// return [5, 5];
|
|
||||||
// }
|
|
||||||
// return [];
|
|
||||||
// },
|
|
||||||
// }
|
|
||||||
},
|
|
||||||
behaviors: [
|
|
||||||
// 'drag-canvas', // 允许拖拽画布
|
|
||||||
// 'zoom-canvas', // 允许缩放画布
|
|
||||||
{
|
|
||||||
type: 'drag-element',
|
|
||||||
enable: (event:any) => {
|
|
||||||
// 只有当拖拽目标是节点且其id不为'fixedNode'时才允许拖拽
|
|
||||||
return dragelement.value === 'drag-element' ;
|
|
||||||
},
|
|
||||||
}, // 允许拖拽节点
|
|
||||||
{
|
|
||||||
type: 'create-edge',
|
|
||||||
trigger: 'drag',
|
|
||||||
enable: (event:any) => {
|
|
||||||
// 动态判断是否允许创建边
|
|
||||||
// 例如:只有按住 Shift 键时才允许连线
|
|
||||||
return dragelement.value === '' ;
|
|
||||||
},
|
|
||||||
// style: dragLine.value,
|
|
||||||
style: (edgeData:any) => {
|
|
||||||
// 动态设置虚线还是实线
|
|
||||||
const baseStyle = dragLine.value;
|
|
||||||
if (edgeData.data && edgeData.data.isDashed) {
|
|
||||||
return {
|
|
||||||
...baseStyle,
|
|
||||||
lineDash: [5, 5], // 虚线
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
...baseStyle,
|
|
||||||
lineDash: [], // 实线
|
|
||||||
};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
|
|
||||||
data: data // Pass data directly in constructor
|
|
||||||
});
|
|
||||||
|
|
||||||
graph.on(NodeEvent.CLICK, (evt) => {
|
|
||||||
const { target } = evt;
|
|
||||||
const nodeId = target.id;
|
|
||||||
|
|
||||||
// 在控制台输出点击的节点信息
|
|
||||||
console.log(`节点 ${nodeId} 被点击了`);
|
|
||||||
|
|
||||||
// 获取节点数据
|
|
||||||
const nodeData = graph.getNodeData(nodeId);
|
|
||||||
console.log('节点数据:', nodeData);
|
|
||||||
|
|
||||||
// 设置节点选中状态
|
|
||||||
graph.setElementState(nodeId, 'selected', true);
|
|
||||||
});
|
|
||||||
// Just render, no need for separate data() call
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="app-layout">
|
|
||||||
<!-- Left Sidebar -->
|
|
||||||
<div class="sidebar">
|
|
||||||
<div class="sidebar-section">
|
|
||||||
<h3>设备</h3>
|
|
||||||
<div
|
|
||||||
v-for="device in deviceTypes"
|
|
||||||
:key="device.id"
|
|
||||||
class="device-item"
|
|
||||||
draggable="true"
|
|
||||||
@dragstart="handleDragStart($event, device)"
|
|
||||||
>
|
|
||||||
<div class="device-icon">
|
|
||||||
<img :src="device.img" alt="设备图标" style="width: 40px; height: 40px;">
|
|
||||||
</div>
|
|
||||||
<div class="device-name">{{ device.name }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="sidebar-section">
|
|
||||||
<h3>链接</h3>
|
|
||||||
|
|
||||||
<div class="device-item" @click="setDragElement('drag-element')">
|
|
||||||
<div class="device-icon">↔️</div>
|
|
||||||
<div class="device-name">移动</div>
|
|
||||||
</div>
|
|
||||||
<div class="device-item" @click="setDragElement('')">
|
|
||||||
<div class="device-icon">↔️</div>
|
|
||||||
<div class="device-name">不移动</div>
|
|
||||||
</div>
|
|
||||||
<div class="device-item" @click="setDragLineStyle(0,'实线')">
|
|
||||||
<div class="device-icon">↔️</div>
|
|
||||||
<div class="device-name">实线</div>
|
|
||||||
</div>
|
|
||||||
<div class="device-item" @click="setDragLineStyle(1,'单箭头实线')">
|
|
||||||
<div class="device-icon">↔️</div>
|
|
||||||
<div class="device-name">单箭头实线</div>
|
|
||||||
</div>
|
|
||||||
<div class="device-item" @click="setDragLineStyle(2,'双箭头实线')">
|
|
||||||
<div class="device-icon">⇄</div>
|
|
||||||
<div class="device-name">双箭头实线</div>
|
|
||||||
</div>
|
|
||||||
<div class="device-item" @click="setDragLineStyle(3,'虚线')">
|
|
||||||
<div class="device-icon">↔️</div>
|
|
||||||
<div class="device-name">虚线</div>
|
|
||||||
</div>
|
|
||||||
<div class="device-item" @click="setDragLineStyle(4,'单箭头虚线')">
|
|
||||||
<div class="device-icon">↔️</div>
|
|
||||||
<div class="device-name">单箭头虚线</div>
|
|
||||||
</div>
|
|
||||||
<div class="device-item" @click="setDragLineStyle(5,'双箭头虚线')">
|
|
||||||
<div class="device-icon">⇄</div>
|
|
||||||
<div class="device-name">双箭头虚线</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Graph Container -->
|
|
||||||
<div
|
|
||||||
class="graph-container"
|
|
||||||
ref="container"
|
|
||||||
@dragover="handleDragOver"
|
|
||||||
@drop="handleDrop"
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
* {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-layout {
|
|
||||||
display: flex;
|
|
||||||
width: 100vw;
|
|
||||||
height: 100vh;
|
|
||||||
font-family: 'Segoe UI', sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sidebar Styles */
|
|
||||||
.sidebar {
|
|
||||||
width: 200px;
|
|
||||||
background-color: #ffffff;
|
|
||||||
border-right: 1px solid #e0e0e0;
|
|
||||||
overflow-y: auto;
|
|
||||||
padding: 16px;
|
|
||||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-section {
|
|
||||||
margin-bottom: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-section h3 {
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #333;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
padding-bottom: 8px;
|
|
||||||
border-bottom: 1px solid #f0f0f0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.device-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 10px;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
background-color: #fafafa;
|
|
||||||
border: 1px solid #e0e0e0;
|
|
||||||
border-radius: 4px;
|
|
||||||
cursor: grab;
|
|
||||||
transition: all 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.device-item:hover {
|
|
||||||
background-color: #f0f5ff;
|
|
||||||
border-color: #1890ff;
|
|
||||||
transform: translateY(-1px);
|
|
||||||
box-shadow: 0 2px 4px rgba(24, 144, 255, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.device-item:active {
|
|
||||||
cursor: grabbing;
|
|
||||||
}
|
|
||||||
|
|
||||||
.device-icon {
|
|
||||||
font-size: 24px;
|
|
||||||
margin-right: 12px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.device-name {
|
|
||||||
font-size: 13px;
|
|
||||||
color: #333;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Graph Container Styles */
|
|
||||||
.graph-container {
|
|
||||||
flex: 1;
|
|
||||||
position: relative;
|
|
||||||
background-color: #fafafa;
|
|
||||||
overflow: hidden;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Drag and drop visual feedback */
|
|
||||||
.graph-container.drag-over {
|
|
||||||
background-color: #e6f7ff;
|
|
||||||
border: 2px dashed #1890ff;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -84,7 +84,7 @@ onMounted(() => {
|
|||||||
connector: {
|
connector: {
|
||||||
name: 'rounded',
|
name: 'rounded',
|
||||||
args: {
|
args: {
|
||||||
radius: 8,
|
radius: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
anchor: 'center',
|
anchor: 'center',
|
||||||
@ -109,6 +109,13 @@ onMounted(() => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
zIndex: 0,
|
zIndex: 0,
|
||||||
|
interactive: {
|
||||||
|
vertexMovable: true,
|
||||||
|
vertexAddable: true,
|
||||||
|
vertexDeletable: true,
|
||||||
|
arrowheadMovable: true,
|
||||||
|
edgeMovable: true,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
validateConnection({ targetMagnet }) {
|
validateConnection({ targetMagnet }) {
|
||||||
@ -126,7 +133,8 @@ onMounted(() => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
interacting: function (cellView) {
|
|
||||||
|
interacting: function (cellView) {
|
||||||
// 获取当前节点的模型
|
// 获取当前节点的模型
|
||||||
const cell = cellView.cell
|
const cell = cellView.cell
|
||||||
// 判断节点是否为 'rect' 形状
|
// 判断节点是否为 'rect' 形状
|
||||||
@ -344,12 +352,12 @@ onMounted(() => {
|
|||||||
}else if(node.store.data.attrs.text.text == '扁平槽'){
|
}else if(node.store.data.attrs.text.text == '扁平槽'){
|
||||||
deviceTypetype.value = 'FlatTank'
|
deviceTypetype.value = 'FlatTank'
|
||||||
|
|
||||||
node.size(130, 80)
|
node.size(130, 60)
|
||||||
const width = node.size().width
|
const width = node.size().width
|
||||||
node.attr('image/xlink:href', '/assets/22.png')
|
node.attr('image/xlink:href', '/assets/22.png')
|
||||||
node.attr('image/width', 130)
|
node.attr('image/width', 130)
|
||||||
node.attr('image/height', 80)
|
node.attr('image/height', 60)
|
||||||
node.attr('label/refY', 85)
|
node.attr('label/refY', 65)
|
||||||
node.attr('label/refX', width/2)
|
node.attr('label/refX', width/2)
|
||||||
node.attr('label/textAnchor', 'middle')
|
node.attr('label/textAnchor', 'middle')
|
||||||
|
|
||||||
@ -357,10 +365,10 @@ onMounted(() => {
|
|||||||
}else if(node.store.data.attrs.text.text == '环形槽'){
|
}else if(node.store.data.attrs.text.text == '环形槽'){
|
||||||
deviceTypetype.value = 'AnnularTank'
|
deviceTypetype.value = 'AnnularTank'
|
||||||
|
|
||||||
node.size(110, 140)
|
node.size(90, 140)
|
||||||
const width = node.size().width
|
const width = node.size().width
|
||||||
node.attr('image/xlink:href', '/assets/33.png')
|
node.attr('image/xlink:href', '/assets/33.png')
|
||||||
node.attr('image/width', 105)
|
node.attr('image/width', 90)
|
||||||
node.attr('image/height', 135)
|
node.attr('image/height', 135)
|
||||||
node.attr('label/refY', 140)
|
node.attr('label/refY', 140)
|
||||||
node.attr('label/refX', width/2)
|
node.attr('label/refX', width/2)
|
||||||
@ -369,10 +377,10 @@ onMounted(() => {
|
|||||||
|
|
||||||
}else if(node.store.data.attrs.text.text == '管束槽'){
|
}else if(node.store.data.attrs.text.text == '管束槽'){
|
||||||
deviceTypetype.value = 'TubeBundleTank'
|
deviceTypetype.value = 'TubeBundleTank'
|
||||||
node.size(110, 140)
|
node.size(80, 140)
|
||||||
const width = node.size().width
|
const width = node.size().width
|
||||||
node.attr('image/xlink:href', '/assets/44.png')
|
node.attr('image/xlink:href', '/assets/44.png')
|
||||||
node.attr('image/width', 105)
|
node.attr('image/width', 80)
|
||||||
node.attr('image/height', 135)
|
node.attr('image/height', 135)
|
||||||
node.attr('label/refY', 140)
|
node.attr('label/refY', 140)
|
||||||
node.attr('label/refX', width/2)
|
node.attr('label/refX', width/2)
|
||||||
@ -392,20 +400,20 @@ onMounted(() => {
|
|||||||
|
|
||||||
}else if(node.store.data.attrs.text.text == '流化床'){
|
}else if(node.store.data.attrs.text.text == '流化床'){
|
||||||
deviceTypetype.value = 'FluidizedBed'
|
deviceTypetype.value = 'FluidizedBed'
|
||||||
node.size(80, 140)
|
node.size(60, 140)
|
||||||
const width = node.size().width
|
const width = node.size().width
|
||||||
node.attr('image/xlink:href', '/assets/66.png')
|
node.attr('image/xlink:href', '/assets/66.png')
|
||||||
node.attr('image/width', 80)
|
node.attr('image/width', 60)
|
||||||
node.attr('image/height', 135)
|
node.attr('image/height', 135)
|
||||||
node.attr('label/refY', 140)
|
node.attr('label/refY', 140)
|
||||||
node.attr('label/refX', width/2)
|
node.attr('label/refX', width/2)
|
||||||
node.attr('label/textAnchor', 'middle')
|
node.attr('label/textAnchor', 'middle')
|
||||||
}else if(node.store.data.attrs.text.text == '锥底环形槽'){
|
}else if(node.store.data.attrs.text.text == '锥底环形槽'){
|
||||||
deviceTypetype.value = 'ACFTank'
|
deviceTypetype.value = 'ACFTank'
|
||||||
node.size(80, 140)
|
node.size(40, 140)
|
||||||
const width = node.size().width
|
const width = node.size().width
|
||||||
node.attr('image/xlink:href', '/assets/77.png')
|
node.attr('image/xlink:href', '/assets/77.png')
|
||||||
node.attr('image/width', 80)
|
node.attr('image/width', 40)
|
||||||
node.attr('image/height', 135)
|
node.attr('image/height', 135)
|
||||||
node.attr('label/refY', 140)
|
node.attr('label/refY', 140)
|
||||||
node.attr('label/refX', width/2)
|
node.attr('label/refX', width/2)
|
||||||
@ -424,7 +432,7 @@ onMounted(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
graph.on('edge:selected', ({ edge }) => {
|
graph.on('edge:selected', ({ edge }) => {
|
||||||
|
let edgeTemp :any = edge
|
||||||
edge.addTools({
|
edge.addTools({
|
||||||
name: 'button-remove',
|
name: 'button-remove',
|
||||||
args: {
|
args: {
|
||||||
@ -433,8 +441,22 @@ onMounted(() => {
|
|||||||
offset: { x: 10, y: 10 },
|
offset: { x: 10, y: 10 },
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
edge.addTools({
|
||||||
|
name: 'vertices', // 指定使用 vertices 工具
|
||||||
|
args: {
|
||||||
|
// 可选配置参数
|
||||||
|
snapRadius: 20, // 移动时的吸附半径
|
||||||
|
addable: true, // 是否允许单击边添加顶点
|
||||||
|
removable: true, // 是否允许双击顶点删除
|
||||||
|
attrs: { // 自定义顶点的样式(小圆点)
|
||||||
|
r: 6,
|
||||||
|
fill: edgeTemp.store.data.attrs.line.stroke,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
graph.on('edge:unselected', ({ edge }) => {
|
graph.on('edge:unselected', ({ edge }) => {
|
||||||
edge.removeTools()
|
edge.removeTools()
|
||||||
@ -525,6 +547,10 @@ graph.on('blank:mouseup', (e) => {
|
|||||||
console.log('鼠标松开事件', e)
|
console.log('鼠标松开事件', e)
|
||||||
if (!startPoint) return
|
if (!startPoint) return
|
||||||
|
|
||||||
|
if(isBoundary.value == false){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const endPoint = { x: e.x, y: e.y }
|
const endPoint = { x: e.x, y: e.y }
|
||||||
if(Math.abs(endPoint.x - startPoint.x) <20 && Math.abs(endPoint.y - startPoint.y) <20){
|
if(Math.abs(endPoint.x - startPoint.x) <20 && Math.abs(endPoint.y - startPoint.y) <20){
|
||||||
@ -601,7 +627,7 @@ graph.on('blank:mouseup', (e) => {
|
|||||||
position: 'top',
|
position: 'top',
|
||||||
attrs: {
|
attrs: {
|
||||||
circle: {
|
circle: {
|
||||||
r: 4,
|
r: 8,
|
||||||
magnet: true,
|
magnet: true,
|
||||||
stroke: '#5F95FF',
|
stroke: '#5F95FF',
|
||||||
strokeWidth: 1,
|
strokeWidth: 1,
|
||||||
@ -616,7 +642,7 @@ graph.on('blank:mouseup', (e) => {
|
|||||||
position: 'right',
|
position: 'right',
|
||||||
attrs: {
|
attrs: {
|
||||||
circle: {
|
circle: {
|
||||||
r: 4,
|
r: 8,
|
||||||
magnet: true,
|
magnet: true,
|
||||||
stroke: '#5F95FF',
|
stroke: '#5F95FF',
|
||||||
strokeWidth: 1,
|
strokeWidth: 1,
|
||||||
@ -631,7 +657,7 @@ graph.on('blank:mouseup', (e) => {
|
|||||||
position: 'bottom',
|
position: 'bottom',
|
||||||
attrs: {
|
attrs: {
|
||||||
circle: {
|
circle: {
|
||||||
r: 4,
|
r: 8,
|
||||||
magnet: true,
|
magnet: true,
|
||||||
stroke: '#5F95FF',
|
stroke: '#5F95FF',
|
||||||
strokeWidth: 1,
|
strokeWidth: 1,
|
||||||
@ -646,7 +672,7 @@ graph.on('blank:mouseup', (e) => {
|
|||||||
position: 'left',
|
position: 'left',
|
||||||
attrs: {
|
attrs: {
|
||||||
circle: {
|
circle: {
|
||||||
r: 4,
|
r: 8,
|
||||||
magnet: true,
|
magnet: true,
|
||||||
stroke: '#5F95FF',
|
stroke: '#5F95FF',
|
||||||
strokeWidth: 1,
|
strokeWidth: 1,
|
||||||
@ -1406,6 +1432,10 @@ function saveDesign() { // 保存设计
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const isBoundary = ref(false)
|
||||||
|
const boundaryClick = () => {
|
||||||
|
isBoundary.value = !isBoundary.value
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -1440,14 +1470,20 @@ function saveDesign() { // 保存设计
|
|||||||
<img src="@/assets/x6/reduce.png">
|
<img src="@/assets/x6/reduce.png">
|
||||||
<div class="operation-icon-text">缩小</div>
|
<div class="operation-icon-text">缩小</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="operation-icon-box" @click="isDisplay = !isDisplay">
|
<div class="operation-icon-box" @click="isDisplay = !isDisplay">
|
||||||
<img v-if="isDisplay" src="@/assets/x6/display.png">
|
<img v-if="isDisplay" src="@/assets/x6/display.png">
|
||||||
<img v-else src="@/assets/x6/hide.png">
|
<img v-else src="@/assets/x6/hide.png">
|
||||||
<div class="operation-icon-text">显示</div>
|
<div class="operation-icon-text">显示</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="operation-icon-box" @click="ConnectingwireClick">
|
<div class="operation-icon-box" style="width: 60px;" @click="boundaryClick">
|
||||||
|
<img v-if="!isBoundary" src="@/assets/x6/display.png">
|
||||||
|
<img v-else src="@/assets/x6/hide.png">
|
||||||
|
<div v-if="!isBoundary" class="operation-icon-text">绘制边界</div>
|
||||||
|
<div v-else class="operation-icon-text">停止绘制</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="operation-icon-box" @click="ConnectingwireClick">
|
||||||
<img src="@/assets/x6/line.png" style="margin: 5px 0;">
|
<img src="@/assets/x6/line.png" style="margin: 5px 0;">
|
||||||
<div class="operation-icon-text">连接线</div>
|
<div class="operation-icon-text">连接线</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -137,7 +137,7 @@ function addAttrText(item:any,index:any){
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
debugger
|
||||||
graph.addNode({
|
graph.addNode({
|
||||||
shape: 'image-node',
|
shape: 'image-node',
|
||||||
x: item.position.x + 135 ,
|
x: item.position.x + 135 ,
|
||||||
|
|||||||
@ -133,21 +133,7 @@ function menuClick(index:any){ // 点击菜单切换
|
|||||||
getTimelineList()
|
getTimelineList()
|
||||||
}
|
}
|
||||||
function addMenu(){ //添加导菜单
|
function addMenu(){ //添加导菜单
|
||||||
// menuList.value.unshift({
|
|
||||||
// label: '条件' + (menuList.value.length + 1),
|
|
||||||
// target:{
|
|
||||||
// entityType: '',
|
|
||||||
// entityId: '',
|
|
||||||
// property: '',
|
|
||||||
// },
|
|
||||||
// unit: 'cm',
|
|
||||||
// segments: [{
|
|
||||||
// segmentId: '分段-1',
|
|
||||||
// start:null,
|
|
||||||
// end:null,
|
|
||||||
// timeline:[]
|
|
||||||
// }]
|
|
||||||
// })
|
|
||||||
menuList.value.push({
|
menuList.value.push({
|
||||||
label: '条件' + (menuList.value.length + 1),
|
label: '条件' + (menuList.value.length + 1),
|
||||||
target:{
|
target:{
|
||||||
@ -163,9 +149,13 @@ function addMenu(){ //添加导菜单
|
|||||||
timeline:[]
|
timeline:[]
|
||||||
}]
|
}]
|
||||||
})
|
})
|
||||||
// menuIndex.value = 0
|
menuClick(menuList.value.length - 1)
|
||||||
|
}
|
||||||
|
function delMenu(){ // 删除导菜单
|
||||||
|
menuList.value.splice(menuIndex.value, 1);
|
||||||
|
menuIndex.value = 0
|
||||||
|
menuClick(menuList.value.length - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 查询字典项
|
// 查询字典项
|
||||||
function DicInit() {
|
function DicInit() {
|
||||||
@ -302,6 +292,7 @@ function handleSuccess(file: any) {
|
|||||||
{{ item.label }}
|
{{ item.label }}
|
||||||
</div>
|
</div>
|
||||||
<img src="@/assets/add.png" v-if="isEdit == true" alt="" class="condition-img" style="cursor: pointer;" @click="addMenu">
|
<img src="@/assets/add.png" v-if="isEdit == true" alt="" class="condition-img" style="cursor: pointer;" @click="addMenu">
|
||||||
|
<img src="@/assets/del.png" v-if="isEdit == true && menuList.length > 1" alt="" class="condition-img" style="cursor: pointer;" @click="delMenu">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-form ref="infoForm" label-width="120px">
|
<el-form ref="infoForm" label-width="120px">
|
||||||
|
|||||||
@ -52,7 +52,31 @@ function confirmClick(formEl: any) {
|
|||||||
console.log(info.value)
|
console.log(info.value)
|
||||||
formEl.validate((valid: any) => {
|
formEl.validate((valid: any) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
|
let isAlgorithmType = false
|
||||||
|
let isSonAlgorithmType = 0
|
||||||
|
for(let i = 0;i<deviceData.value.length;i++){
|
||||||
|
if(deviceData.value[i].algorithmType != null && deviceData.value[i].algorithmType != ''){
|
||||||
|
isSonAlgorithmType = isSonAlgorithmType + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(info.value.algorithmType == null || info.value.algorithmType == ''){
|
||||||
|
isAlgorithmType = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if( isAlgorithmType == true && isSonAlgorithmType == 0){
|
||||||
|
ElMessage({
|
||||||
|
type: "error",
|
||||||
|
message: "请选择算法类型",
|
||||||
|
});
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if( isSonAlgorithmType != deviceData.value.length){
|
||||||
|
ElMessage({
|
||||||
|
type: "error",
|
||||||
|
message: "设备算法配置映射没有填写完全",
|
||||||
|
});
|
||||||
|
return
|
||||||
|
}
|
||||||
if (!info.value.scenarioId) {
|
if (!info.value.scenarioId) {
|
||||||
const params:any = {
|
const params:any = {
|
||||||
projectId: props.projectInfo.projectId,
|
projectId: props.projectInfo.projectId,
|
||||||
@ -127,6 +151,7 @@ function confirmClick(formEl: any) {
|
|||||||
}
|
}
|
||||||
const conditionModel = ref()
|
const conditionModel = ref()
|
||||||
function submitClick(){
|
function submitClick(){
|
||||||
|
|
||||||
const tempData = conditionModel.value?.submitClick()
|
const tempData = conditionModel.value?.submitClick()
|
||||||
let data:any = []
|
let data:any = []
|
||||||
tempData.forEach((item: any) => {
|
tempData.forEach((item: any) => {
|
||||||
@ -170,6 +195,15 @@ onMounted(() => {
|
|||||||
initDeviceData()
|
initDeviceData()
|
||||||
getAlgorithmType()
|
getAlgorithmType()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function changeAlgorithmType(){
|
||||||
|
deviceData.value.forEach((item: any) => {
|
||||||
|
item.algorithmType = ""
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function changeSonAlgorithmType(){
|
||||||
|
info.value.algorithmType = ""
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<el-dialog v-model="dialogVisible" :close-on-click-modal="false"
|
<el-dialog v-model="dialogVisible" :close-on-click-modal="false"
|
||||||
@ -189,7 +223,7 @@ onMounted(() => {
|
|||||||
<el-input v-model="info.name" style="width: 100%" placeholder="输入事故情景名称" ></el-input>
|
<el-input v-model="info.name" style="width: 100%" placeholder="输入事故情景名称" ></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="算法类型:">
|
<el-form-item label="算法类型:">
|
||||||
<el-select v-model="info.algorithmType" placeholder="请选择" style="width:100%;" clearable>
|
<el-select v-model="info.algorithmType" placeholder="请选择" style="width:100%;" clearable @change="changeAlgorithmType">
|
||||||
<el-option v-for="item in algorithmTypeData" :key="item.algorithmType" :label="item.name" :value="item.algorithmType" />
|
<el-option v-for="item in algorithmTypeData" :key="item.algorithmType" :label="item.name" :value="item.algorithmType" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -198,7 +232,7 @@ onMounted(() => {
|
|||||||
<div style="width: 100%;padding-top: 40px;">
|
<div style="width: 100%;padding-top: 40px;">
|
||||||
<div v-for="item in deviceData" :key="item.deviceId" style="display: flex;align-items: center;margin-bottom: 10px;">
|
<div v-for="item in deviceData" :key="item.deviceId" style="display: flex;align-items: center;margin-bottom: 10px;">
|
||||||
<div style="width: 150px;text-align: right;padding-right: 10px;">{{item.deviceName}}</div>
|
<div style="width: 150px;text-align: right;padding-right: 10px;">{{item.deviceName}}</div>
|
||||||
<el-select v-model="item.algorithmType" placeholder="请选择" style="width:100%;" clearable>
|
<el-select v-model="item.algorithmType" placeholder="请选择" style="width:100%;" clearable @change="changeSonAlgorithmType">
|
||||||
<el-option v-for="item in algorithmTypeData" :key="item.algorithmType" :label="item.name" :value="item.algorithmType" />
|
<el-option v-for="item in algorithmTypeData" :key="item.algorithmType" :label="item.name" :value="item.algorithmType" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -216,6 +216,31 @@ const getAlgorithmType = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
function submitClick(){
|
function submitClick(){
|
||||||
|
let isAlgorithmType = false
|
||||||
|
let isSonAlgorithmType = 0
|
||||||
|
for(let i = 0;i<deviceData.value.length;i++){
|
||||||
|
if(deviceData.value[i].algorithmType != null && deviceData.value[i].algorithmType != ''){
|
||||||
|
isSonAlgorithmType = isSonAlgorithmType + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(info.value.algorithmType == null || info.value.algorithmType == ''){
|
||||||
|
isAlgorithmType = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if( isAlgorithmType == true && isSonAlgorithmType == 0){
|
||||||
|
ElMessage({
|
||||||
|
type: "error",
|
||||||
|
message: "请选择算法类型",
|
||||||
|
});
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if( isSonAlgorithmType != deviceData.value.length){
|
||||||
|
ElMessage({
|
||||||
|
type: "error",
|
||||||
|
message: "设备算法配置映射没有填写完全",
|
||||||
|
});
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
let data:any = {
|
let data:any = {
|
||||||
scenarioId: info.value.scenarioId,
|
scenarioId: info.value.scenarioId,
|
||||||
@ -385,6 +410,15 @@ function initDeviceData(){
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function changeAlgorithmType(){
|
||||||
|
deviceData.value.forEach((item: any) => {
|
||||||
|
item.algorithmType = ""
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function changeSonAlgorithmType(){
|
||||||
|
info.value.algorithmType = ""
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -468,7 +502,8 @@ function initDeviceData(){
|
|||||||
<el-input v-model="info.name" style="width: 100%" placeholder="输入事故情景名称" :disabled="title == '查看事故情景'"></el-input>
|
<el-input v-model="info.name" style="width: 100%" placeholder="输入事故情景名称" :disabled="title == '查看事故情景'"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="算法类型:" :disabled="title == '查看事故情景'">
|
<el-form-item label="算法类型:" :disabled="title == '查看事故情景'">
|
||||||
<el-select v-model="info.algorithmType" placeholder="请选择" style="width:100%;" clearable :disabled="title == '查看事故情景'">
|
<el-select v-model="info.algorithmType" placeholder="请选择" style="width:100%;" clearable
|
||||||
|
:disabled="title == '查看事故情景'" @change="changeAlgorithmType">
|
||||||
<el-option v-for="item in algorithmTypeData" :key="item.algorithmType" :label="item.name + '(' + item.algorithmType + ')' " :value="item.algorithmType" />
|
<el-option v-for="item in algorithmTypeData" :key="item.algorithmType" :label="item.name + '(' + item.algorithmType + ')' " :value="item.algorithmType" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -476,7 +511,8 @@ function initDeviceData(){
|
|||||||
<div style="width: 100%;padding-top: 40px;">
|
<div style="width: 100%;padding-top: 40px;">
|
||||||
<div v-for="item in deviceData" :key="item.deviceType" style="display: flex;align-items: center;margin-bottom: 10px;">
|
<div v-for="item in deviceData" :key="item.deviceType" style="display: flex;align-items: center;margin-bottom: 10px;">
|
||||||
<div style="width: 150px;text-align: right;padding-right: 10px;">{{item.deviceName}}</div>
|
<div style="width: 150px;text-align: right;padding-right: 10px;">{{item.deviceName}}</div>
|
||||||
<el-select v-model="item.algorithmType" placeholder="请选择" style="width:100%;" clearable :disabled="title == '查看事故情景'">
|
<el-select v-model="item.algorithmType" placeholder="请选择" style="width:100%;"
|
||||||
|
clearable :disabled="title == '查看事故情景'" @change="changeSonAlgorithmType">
|
||||||
<el-option v-for="item in algorithmTypeData" :key="item.algorithmType" :label="item.name" :value="item.algorithmType" />
|
<el-option v-for="item in algorithmTypeData" :key="item.algorithmType" :label="item.name" :value="item.algorithmType" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
@ -511,10 +547,11 @@ function initDeviceData(){
|
|||||||
<el-dialog v-model="isShowResult" :close-on-click-modal="false"
|
<el-dialog v-model="isShowResult" :close-on-click-modal="false"
|
||||||
:modal="false" draggable :before-close="handleResultClose" :title="title"
|
:modal="false" draggable :before-close="handleResultClose" :title="title"
|
||||||
append-to-body width="calc(100% - 100px)" class="resultmodel-dialog-box">
|
append-to-body width="calc(100% - 100px)" class="resultmodel-dialog-box">
|
||||||
<div style="display: flex; margin-bottom: 0px; border-bottom: 1px solid #e5e5e5;padding-bottom: 5px;padding-top: 10px;padding-left: 10px;">
|
<div style="position: relative; display: flex; margin-bottom: 0px; border-bottom: 1px solid #e5e5e5;padding-bottom: 5px;padding-top: 10px;padding-left: 10px;">
|
||||||
<div @click="changeShowResult(0)" class="adddevice_navigation_left" :class="{'adddevice_navigation_activeleft':isEchartsModel == 0}">图形化</div>
|
<div @click="changeShowResult(0)" class="adddevice_navigation_left" :class="{'adddevice_navigation_activeleft':isEchartsModel == 0}">图形化</div>
|
||||||
<div @click="changeShowResult(1)" class="adddevice_navigation_right" :class="{'adddevice_navigation_activeright':isEchartsModel == 1}">列表</div>
|
<div @click="changeShowResult(1)" class="adddevice_navigation_right" :class="{'adddevice_navigation_activeright':isEchartsModel == 1}">列表</div>
|
||||||
<div @click="changeShowResult(2)" class="adddevice_navigation_right" :class="{'adddevice_navigation_activeright':isEchartsModel == 2}">图形</div>
|
<div @click="changeShowResult(2)" class="adddevice_navigation_right" :class="{'adddevice_navigation_activeright':isEchartsModel == 2}">图形</div>
|
||||||
|
<el-button v-if="isEchartsModel == 1" style="position: absolute;right: 50px;top: 5px;" type="primary">导出全部</el-button>
|
||||||
</div>
|
</div>
|
||||||
<Viewx6 v-if="isShowResult && isEchartsModel == 0 " :projectId="projectInfo.projectId"
|
<Viewx6 v-if="isShowResult && isEchartsModel == 0 " :projectId="projectInfo.projectId"
|
||||||
:scenarioId="scenarioId"
|
:scenarioId="scenarioId"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user