1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387 |
- <template>
- <VueFlow ref="vueFlowRef" v-model:nodes="nodes" v-model:edges="edges" :class="{ dark }"
- class="basic-flow"
- style="background-image: url('src/assets/flowimg/surromdao.png'); background-position: center; background-repeat: no-repeat;"
- :default-viewport="{ zoom: 1.5 }" :min-zoom="0.2" :max-zoom="2.5" @drop="onDrop1"
- @node-contextmenu="onNodeContextMenu"
- @dragover="onDragOver" @dragleave="onDragLeave" @edge-click="onEdgeClick" @node-double-click="onNodeDoubleClick"
- @node-click="onNodeClick" @edge-double-click="onEdgeDoubleClick">
- <template #node-default="props">
- <eltree :node="props" />
- </template>
-
- <Background pattern-color="#aaa" :gap="16"
- />
- <!-- <MiniMap /> @input="handleUpdate"-->
- <Panel :position="'right'" style="display: none;">
- <div class="field">
- <div>
- <label for="label">Label:</label>
- <input id="label" v-model.lazy="labelname" /></div>
- <button @click="handleUpdate" class="lableaniu">确定</button>
- </div>
- <!-- <div> -->
- <!-- <button class="remove" @click="removeNode(event)">N</button>
- <button class="remove" @click="removeEdge(event)">E</button>
- <button class="remove" @click="removeall(event)">all</button>
-
- </div> -->
- <!-- <button @click="onSelection()" class="lableaniu">获取</button> -->
- </Panel>
- <Controls position="top-left">
- <ControlButton title="重置" @click="resetTransform">
- <Icon name="reset" />
- </ControlButton>
- <ControlButton title="背景切换" @click="toggleDarkMode">
- <Icon v-if="dark" name="sun" />
- <Icon v-else name="moon" />
- </ControlButton>
- <ControlButton title="保存" @click="logToObject1">
- <!-- <Icon name="log" /> -->
- <el-icon :color="iconcolor"><UploadFilled /></el-icon>
- </ControlButton>
- <ControlButton title="删除节点" @click="removeNode()">
- <el-icon :color="iconcolor"><DocumentDelete /></el-icon>
- </ControlButton>
- <ControlButton title="删除线" @click="removeEdge()">
- <el-icon :color="iconcolor"><Crop /></el-icon>
- </ControlButton>
- <ControlButton title="清空全部" @click="confirmDelete()">
- <el-icon :color="iconcolor"><DeleteFilled /></el-icon>
- </ControlButton>
-
-
- </Controls>
- <el-dialog v-model="changeNameshow" align-center :modal="false" :close-on-click-modal="false"
- :append-to-body="true" draggable :fullscreen="false" :modal-append-to-body="false" modal-class="summary-dlg"
- width="400" class="dialog_class bgcolor colortext tianjia sel">
- <template #header="{ titleId, titleClass }">
- <div class="my-header ">
- <h4 :id="titleId" :class="titleClass">修改名称</h4>
- </div>
- </template>
- <div style="margin-top: 20px;padding: 20px;">
- <el-form :model="changeName" label-width="100px" class="demo-ruleForm">
- <el-form-item label="新名称:" prop="name">
- <el-input v-model="changeName.name" placeholder="请输入名称" maxlength="20"></el-input>
- </el-form-item>
-
- </el-form>
- </div>
-
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="changeNameshow = false">取 消</el-button>
- <el-button type="primary" @click="handleUpdate">确 定</el-button>
- </div>
- </template>
- </el-dialog>
- <!-- 双击线段 -->
- <el-dialog v-model="dataflowshow" align-center :modal="false" :close-on-click-modal="false"
- :append-to-body="true" draggable :fullscreen="false" :modal-append-to-body="false" modal-class="summary-dlg"
- width="500" class="dialog_style bgcolor colortext tianjia sel">
- <template #header="{ titleId, titleClass }">
- <div class="my-header ">
- <h4 :id="titleId" :class="titleClass">数据流</h4>
- </div>
- </template>
- <div style="margin-top: 5px;padding: 10px 35px;">
- <div v-if="datacontent === '1'">
- <el-card :shadow="none" style="min-height: 240px; max-height: 480px;">
- <el-checkbox v-model="checkAll"
- :indeterminate="isIndeterminate"
- @change="handlecheckAllchange">全选</el-checkbox>
- <div class="eldesign classtable">
- <el-table :data="youhuaFFDtable" border :show-header="false">
- <el-table-column
- type="index"
- label=""
- ></el-table-column>
- <el-table-column prop="steamflag" width="55">
- <template #default="{ row }">
- <el-checkbox
- :false-label="0"
- :true-label="1"
- v-model="row.steamflag"
- @change="handlecheckFlagchange"></el-checkbox>
- </template>
- </el-table-column>
- <el-table-column prop="name" label="" ></el-table-column>
- </el-table>
- </div>
- </el-card>
- </div>
- <div v-if="datacontent === '2'">
- <el-card :shadow="none" style="min-height: 240px; max-height: 480px;">
- <el-checkbox v-model="checkAll"
- :indeterminate="isIndeterminate"
- @change="handlecheckAllchange">全选</el-checkbox>
- <div class="eldesign classtable">
- <el-table :data="youhuaCSTtable" border :show-header="false">
- <el-table-column
- type="index"
- label=""
- ></el-table-column>
- <el-table-column prop="steamflag" width="55">
- <template #default="{ row }">
- <el-checkbox
- :false-label="0"
- :true-label="1"
- v-model="row.steamflag"
- @change="handlecheckFlagchange"></el-checkbox>
- </template>
- </el-table-column>
- <el-table-column prop="name" label="" ></el-table-column>
- </el-table>
- </div>
- </el-card>
- </div>
- <div v-if="datacontent === '3'">
- <el-card :shadow="none" style="min-height: 240px; max-height: 480px;">
- <el-checkbox v-model="checkAll"
- :indeterminate="isIndeterminate"
- @change="handlecheckAllchange">全选</el-checkbox>
- <div class="eldesign classtable">
- <el-table :data="ADflowyouhuatable" border :show-header="false">
- <el-table-column
- type="index"
- label=""
- ></el-table-column>
- <el-table-column prop="steamflag" width="55">
- <template #default="{ row }">
- <el-checkbox
- :false-label="0"
- :true-label="1"
- v-model="row.steamflag"
- @change="handlecheckFlagchange"></el-checkbox>
- </template>
- </el-table-column>
- <el-table-column prop="name" label="" ></el-table-column>
- <el-table-column prop="steamtype">
- <template #default="{ row }">
- <el-select v-model="row.steamtype">
- <el-option
- v-for="item in steamtypeoptions"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
- </template>
- </el-table-column>
- </el-table>
- </div>
- </el-card>
- </div>
- <div v-if="datacontent === '4'">
- <el-card :shadow="none" style="min-height: 240px; max-height: 480px;">
- <el-checkbox v-model="checkAll"
- :indeterminate="isIndeterminate"
- @change="handlecheckAllchange">全选</el-checkbox>
- <div class="eldesign classtable">
- <el-table :data="Xfoilyouhuatable" border :show-header="false">
- <el-table-column
- type="index"
- label=""
- ></el-table-column>
- <el-table-column prop="steamflag" width="55">
- <template #default="{ row }">
- <el-checkbox
- :false-label="0"
- :true-label="1"
- v-model="row.steamflag"
- @change="handlecheckFlagchange"></el-checkbox>
- </template>
- </el-table-column>
- <el-table-column prop="name" label="" show-overflow-tooltip></el-table-column>
- <el-table-column prop="steamtype">
- <template #default="{ row }">
- <el-select v-model="row.steamtype">
- <el-option
- v-for="item in steamtypeoptions"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
- </template>
- </el-table-column>
- </el-table>
- </div>
- </el-card>
- </div>
-
- </div>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="dataflowshow = false">取 消</el-button>
- <el-button type="primary" @click="confirmselection();dataflowshow = false ">确 定</el-button>
- </div>
- </template>
- </el-dialog>
- </VueFlow>
- <div class="dnd-flow">
- <!-- <div id="contextMenu" @click="deleteItemConfirm">删除</div> -->
- </div>
- </template>
- <script setup>
- import { ref, markRaw,inject } from 'vue'
- import { VueFlow,Panel, useVueFlow, MarkerType} from '@vue-flow/core'
- import { ElMessage, ElButton, ElDialog, ElSelect, ElMessageBox} from 'element-plus'
- import {
- DocumentDelete,
- Delete,
- UploadFilled,
- Histogram,
- DeleteFilled,
- Crop,
- } from '@element-plus/icons-vue'
- import { useRoute } from 'vue-router';
- import { request, uploadFile } from "@/utils/request";
- import { Background } from '@vue-flow/background'
- import { ControlButton, Controls } from '@vue-flow/controls'
- import { initialEdges, initialNodes } from './modeljs.js'
- import { MiniMap } from '@vue-flow/minimap'
- import "./main.css";//重置样式
- import DropzoneBackground from './DropzoneBackground.vue'
- import eltree from './eltree.vue'
- import CustomEdge from './CustomEdge.vue';
- import useDragAndDrop from './useDnD';
- import f11 from '@/assets/img/f11.png'
- import r2 from '@/assets/img/r2.png'
- import html2canvas from 'html2canvas';
- import Icon from './Icon.vue'
- import { formatTime } from '@/js/lindex.js';
- import emitter from "@/utils/emitter";
- // import func from 'vue-temp/vue-editor-bridge.js';
- const dark = ref(false)
- let datatree=ref();
- const route = useRoute();
- const { onInit, onNodeDragStop, onNodeContextMenu, onConnect, addEdges, setViewport, toObject,addNodes,updateEdgeData,onConnectStart} = useVueFlow()
- let vueFlowRef = ref();
- let emit = defineEmits(['optimizerfalse']);
- let mergedObj=ref();
- let labelname=ref();
- let iconcolor=ref('#000')
- const props = defineProps({
- optimizer: {
- type: Boolean,
- },
- jboptimizer: {
- type: Boolean,
- },
- Xfoil: {
- type: Boolean,
- },
- // color1: {
- // type: String,
- // },
- })
- let newobj=ref({
- name:'',
- description:'',
- })
- let nodesitem=ref([]);
- let linenum=ref(1);
- let bgcolor=ref();
- let linecolor=ref('#b1b1b7')
- let pid=ref('');
- let newroter=ref();
- let vueflowimg=ref('');
- const shopShow = ref(false);
- // 选中节点
- let noid = ref([]);
- let Edgeid = ref();
- let seledge=ref(null);
- let djshow=ref(false);
- let node = ref();
- let contextMenu = ref({
- position: { x: 0, y: 0 },
- target: 'kong',
- })
- let Nested=ref([]);
- let Nested2=ref([]);
- let nnum=ref(0);
- const { onDragOver, onDrop, onDragLeave, isDragOver } = useDragAndDrop();
- const edges = ref([]);
- const nodes = ref([]);
- const changeNameshow = ref(false);
- const changeName = ref({
- name: '',
-
- })
- // 旧数据存储
- let prevNodes = [...nodes.value];
- let prevEdges = [...edges.value];
- // 监听节点变化
- watch(nodes, (newNodes) => {
- const deletedNodes = prevNodes.filter((node) => !newNodes.some((n) => n.id === node.id));
- if (deletedNodes.length > 0) {
- console.log("Deleted Nodes:", deletedNodes);
- // 处理节点删除逻辑
- }
- prevNodes = [...newNodes];
- }, { deep: true });
- // 监听连线变化
- watch(edges, (newEdges) => {
- const deletedEdges = prevEdges.filter((edge) => !newEdges.some((e) => e.id === edge.id));
- if (deletedEdges.length > 0) {
- console.log("Deleted Edges:", deletedEdges);
- // 处理连线删除逻辑
- }
- prevEdges = [...newEdges];
- }, { deep: true });
- onNodeContextMenu((e) => {
- noid.value = e.node;
- changeName.value.name = e.node.data.label;
- changeNameshow.value = true;
- })
- // 监听连接开始,提前取消选中的线段
- onConnectStart(() => {
- cleanEdgeselect();
- });
- // 线的类型 process-逻辑线 data-数据线
- let lineType = ref('process');
- // 线序号
- let linecount = ref(0);
- onConnect((connection) => {
- console.log('线连接',connection);
- // 创建唯一的边ID(由源节点和目标节点组成)
- const edgeId = `${lineType.value}-${connection.source}-${connection.sourceHandle}-${connection.target}-${connection.targetHandle}`;
- connection.id = edgeId; // 自定义 ID
- connection.type = 'smoothstep';// smoothstep straight
- connection.markerEnd = lineType.value === "data" ? "" : MarkerType.ArrowClosed;
- connection.color=linecolor.value;
- // connection.label = '这是一条注释';
- connection.style = { strokeWidth:linenum.value ,stroke:linecolor.value};
- // 连接数据流线前应先连接逻辑流
- if(lineType.value === 'data'){
- const processEdgeId = `process-${connection.source}-${connection.sourceHandle}-${connection.target}-${connection.targetHandle}`;
- const hasProcessEdge = edges.value.some(edge => edge.id === processEdgeId);
- if(!hasProcessEdge){
- ElMessage({
- message:'请先连接逻辑流连线!',
- type:'error'
- })
- return;
- }
- }
- //
- const sameEdge = edges.value.find(edge => edge.id === edgeId);
- if(sameEdge){
- deleteflow(sameEdge.data.wid);
- }
- addEdges(connection);
- seledge.value=null;
-
- linecount.value++;
- const newName = `Seg${linecount.value}`;
- const sourceNode = vueFlowRef.value.getNode(connection.source);
- const targetNode = vueFlowRef.value.getNode(connection.target);
- // 调用 saveflow 保存数据并获取 wid
- saveflow(pid.value, '', newName, lineType.value, sourceNode.data.uid, targetNode.data.uid)
- .then((wid) => {
- // 更新连接线的数据
- const updatedData = {
- wid: wid,
- uid: newName,
- type: lineType.value,
- fromuid: sourceNode.data.uid,
- touid: targetNode.data.uid,
- };
- updateEdgeData(connection.id, updatedData);
- })
- .catch((error) => {
- console.error('保存流程失败:', error);
- });
- })
- //修改名称
- const handleUpdate = () => {
- if (noid.value && noid.value.data) {
- noid.value.data.label = changeName.value.name; // 更新名称
- console.log(noid.value.data.label); // 打印更新后的值
- } else {
- console.error("noid.value 或 noid.value.data 未定义"); // 错误日志
- }
- changeNameshow.value = false; // 更新后关闭对话框
- // noid.value.data.label = labelname;
- };
- emitter.on('child2Data', data => {
- datatree.value = data;
- console.log("datatree的值:",datatree.value);
- })
- function onNodeClick(e) {
- noid.value = e.node;
- changeName.value.name=e.node.data.label;
- console.log("shuju:",e.node.data);
- console.log("noid.value:",noid.value);
- console.log("changeName.value:",changeName.value.name);
- djshow.value = !djshow.value;
- // if(djshow.value){
- // console.log('选中');
- // }else{
- // console.log('取消选中');
- // }
- }
- //模块化
- const bgcolorfunc= (color)=>{
- bgcolor.value=color;
- if(noid.value.style!=undefined){
- console.log(noid.value.style);
- noid.value.style.backgroundColor=color;
- }
- }
- function onSelection(){
- let positionX=[];
- let positiony=[];
- for(let i=0;i<Nested.value.length;i++){
- // Nested2.value.push(Nested.value[i]);
- positionX.push(Nested.value[i].position.x)
- positiony.push(Nested.value[i].position.y)
- }
- let xmin=Math.min(...positionX);
- let ymax=Math.max(...positiony);
- console.log(positionX);
- // console.log( positionX)
- // console.log(44444)
- // console.log( positiony)
- nnum.value++;
- // let x=Math.floor(Math.random() * 91) + 10;
- // let y=Math.floor(Math.random() * 91) + 10;
- let name='模块'+nnum.value
- let item= {
- id:nnum.value.toString(),
- data: { label:name },
- position: { x:xmin , y:ymax},
- style: { backgroundColor: bgcolor.value, width: '200px',height: '200px' },
- //children: [],
- }
-
- if(Nested.value.length!=0){
- Nested2.value=[];
- for(let i=0;i<Nested.value.length;i++){
- Nested2.value.push(Nested.value[i]);
- }
- console.log(Nested2.value);
- nodesitem.value= Nested2.value.map(node => {
- if(node.parentNode==undefined){
-
- node.isParent=false;
- node.parentNode=item.id;
- console.log( node.parentNode)
- node.position.x= node.position.x /2;
- node.position.y= node.position.y/2;
- node.expandParent=true;
- //positionxy=node.position;
- // node.extent='parent';
- // return node;
- }
- return node;
- })
-
- }
- nodes.value.push(item)
- for(let i=0;i<nodesitem.value.length;i++){
- console.log(nodesitem.value[i]);
- nodes.value.push(nodesitem.value[i])
- }
- console.log( nodes.value);
- }
- function onNodeDoubleClick(e) {
- noid.value = e.node;
- const nowid = e.node.data.wid;
- console.log( e.node.data.name);
- if (e.node.data.name == 'optimizer') {
- emit('optimizerfalse',{name:'优化器',wid:nowid});
- }else if(e.node.data.name=="optimizer1"){
- emit('optimizerfalse',{name:'进化优化器',wid:nowid});
- }else if(e.node.data.name=="optimizer3"){
- emit('optimizerfalse',{name:'代理优化器',wid:nowid});
- }else if(e.node.data.name=="Xfoil"){
- emit('optimizerfalse',{name:'Xfoil',wid:nowid});
- }else if(e.node.data.name=="optimizer2"){
- emit('optimizerfalse',{name:'梯度优化器',wid:nowid});
- }else if(e.node.data.name=="CST"){
- emit('optimizerfalse',{name:'CST',wid:nowid});
- }else if(e.node.data.name=="ADflow"|| e.node.data.name=="RAE2822"){
- emit('optimizerfalse',{name:'ADflow',wid:nowid});
- }else if(e.node.data.name=="FFD"){
- emit('optimizerfalse',{name:'FFD',wid:nowid});
- }else if(e.node.data.name=="TACS"){
- emit('optimizerfalse',{name:'TACS',wid:nowid});
- }else if(e.node.data.name=="参数化"){
- emit('optimizerfalse',{name:'参数化',wid:nowid});
- }else if(e.node.data.name=="气动分析"){
- emit('optimizerfalse',{name:'气动分析',wid:nowid});
- }else if(onPythonlist.value.some(item => e.node.data.name.includes(item))){
- emit('optimizerfalse',{name:e.node.data.name,wid:nowid});
- }else if(e.node.data.name=="CATIA"){
- emit('optimizerfalse',{name:'CATIA',wid:nowid});
- }else if(e.node.data.name=="FSI"){
- emit('optimizerfalse',{name:'FSI',wid:nowid});
- }else if(e.node.data.name=="Flight"){
- emit('optimizerfalse',{name:'Flight',wid:nowid});
- }
- }
- let onPythonlist=ref(['Python','Branin','Rosenbrock','Rastrigin','G9','Forrester']);
- let previousEdge = null; // 用于保存上一个选中的边缘
- // 监听线
- function onEdgeClick(e) {
- console.log('Edge Click', e.edge);
- console.log('所有线段:',edges.value);
- // 如果已经有选中的边缘
- if (seledge.value) {
- // 恢复上一个选中边缘的样式
- if (previousEdge) {
- previousEdge.style = {
- ...previousEdge.style,
- stroke: previousEdge.originalColor, // 恢复原始颜色
- strokeWidth: previousEdge.originalWidth,// 恢复原始宽度
- };
- }
- }
- // 保存当前点击的边缘为选中边缘
- Edgeid.value = e.edge.id;
- seledge.value = e.edge;
- // 暂时更改当前选中边缘的样式
- seledge.value.originalColor = seledge.value.style.stroke; // 保存当前边缘的原始颜色
- seledge.value.originalWidth = seledge.value.style.strokeWidth; // 保存当前边缘的原始宽度
- const isProcess = e.edge.data.type === 'process';
- seledge.value.style = {
- ...seledge.value.style,
- stroke: isProcess ? '#2267B1' : 'rgba(255, 255, 0, 0.3)',// 设置选中边缘的颜色
- strokeWidth: isProcess ? 2 : 6,// 设置选中边缘的宽度
- };
- // 保存当前选中的边缘作为上一个选中边缘
- previousEdge = seledge.value;
- }
- let dataflowshow=ref(false);
- let youhuaFFDtable = ref([
- { name:'FFD参数(sample)', steamflag:1 }
- ])
- let youhuaCSTtable = ref([
- { name:"上表面CST参数(upper)", steamflag:1 },
- { name:'下表面CST参数(lower)', steamflag:1 }
- ])
- let steamtypeoptions = ref([
- { label:'约束条件', value:1 },
- { label:'优化目标', value:2 }
- ])
- let ADflowyouhuatable = ref([
- { code: "cl", name:'升力系数Cl', comtype:2 , steamflag:1, steamtype:1 },
- { code: "cd", name:'阻力系数Cd', comtype:2 , steamflag:1, steamtype:1 },
- { code: "cm", name:'力矩系数Cm', comtype:2 , steamflag:1, steamtype:1 },
-
- ])
- let Xfoilyouhuatable = ref([
- // { code:'', name:'升力系数Cl', comtype:2 , steamflag:1, steamtype:1 },
- // { code:'', name:'阻力系数Cd', comtype:2 , steamflag:1, steamtype:1 },
- // { code:'', name:'压阻力系数Cdp', comtype:2 , steamflag:1, steamtype:1 },
- // { code:'', name:'力矩系数Cm', comtype:2 , steamflag:1, steamtype:1 },
- // { code:'', name:'上表面转换点位置xtr-upper', comtype:2 , steamflag:1, steamtype:1 },
- // { code:'', name:'下表面转换点位置xtr-lower', comtype:2 , steamflag:1, steamtype:1 },
- ])
- let checkAll = ref(false);
- let isIndeterminate = ref(false);
- const dataTables = {
- '1': youhuaFFDtable,
- '2': youhuaCSTtable,
- '3': ADflowyouhuatable,
- '4': Xfoilyouhuatable
- };
- const handlecheckFlagchange = () => {
- const table = dataTables[datacontent.value];
- if (!table) return;
- let checkedCount = table.value.filter(item => Boolean(item.steamflag)).length;
- checkAll.value = checkedCount === table.value.length;
- isIndeterminate.value = checkedCount > 0 && checkedCount < table.value.length;
- };
- const handlecheckAllchange = (val) => {
- const table = dataTables[datacontent.value];
- if (!table) return;
- table.value.forEach(item => item.steamflag = val ? 1 : 0);
- isIndeterminate.value = false;
- };
- // 双击线段弹窗确认
- const confirmselection=()=>{
- const table = dataTables[datacontent.value];
- let checkedData = table.value.filter((item) => item.steamflag).map((item) => item.name);
- console.log('xuanzhongshuju:',checkedData);
- console.log('seledge:',seledge.value);
- seledge.value.label=checkedData.join('\n');
- // 保存数据流
- dataFlowsave();
-
- dataflowshow.value = false;
- }
- const xfid = ref('')
- const adid = ref('')
- // 监听组件xfoil返回的xfid
- const handleXfid = (xfidFromB) => {
- xfid.value = xfidFromB.value;
- noid.value.data.xfid = xfid.value;
- };
- const handleAdid = (adidFromB) => {
- adid.value = adidFromB.value;
- noid.value.data.adid = adid.value;
- }
- let datacontent = ref('')
- // 判定是哪种线段
- function onEdgeDoubleClick(e) {
-
- console.log('Edge Double Click', e)
- if(e.edge.data.type==='process'){
- console.log('逻辑流不打开弹窗');
- return ;
- }
- seledge.value = e.edge;
- // dataflowshow.value = true
- console.log('qidian:',e.edge.sourceNode.data.name);
- console.log('zhongdian:',e.edge.targetNode.data.name);
- let qidian = e.edge.sourceNode.data.name;
- let zhongdian = e.edge.targetNode.data.name;
- let youhualist = ['optimizer','optimizer3','optimizer1','optimizer2'];
- if( youhualist.includes(qidian) && zhongdian ==='FFD' ){
- datacontent.value = '1';
- dataflowshow.value = true;
- }else if( youhualist.includes(qidian) && zhongdian ==='CST') {
- datacontent.value = '2';
- dataflowshow.value = true;
- }else if( qidian === 'ADflow' && youhualist.includes(zhongdian) ) {
- datacontent.value = '3';
- // emitter.emit('requestGetadid',pid.value);
- adid.value = e.edge.sourceNode.data.adid;
- // console.log('adid:',adid.value)
- if(adid.value) {
- querydataFlow(adid);
- dataflowshow.value = true;
- }else{
- ElMessage.error('ADflow未初始化!')
- }
- }else if ( qidian === 'Xfoil' && youhualist.includes(zhongdian) ) {
- datacontent.value = '4';
- // emitter.emit('requestGetxfid',pid.value);
- xfid.value = e.edge.sourceNode.data.xfid;
- // console.log('xfid:',xfid.value)
- if(xfid.value) {
- querydataFlow(xfid);
- dataflowshow.value = true;
- }else{
- ElMessage.error('Xfoil未初始化!')
- }
- }
- console.log('leixing:',datacontent.value);
- nextTick(() => {
- handlecheckFlagchange();
- });
- }
- const querydataFlow = (comid) => {
- const params = {
- transCode: "MDO0052",
- pid: pid.value,
- comid: comid.value
- }
- request(params).then((res) => {
- if(datacontent.value === '3'){
- ADflowyouhuatable.value = res.params;
- handlecheckFlagchange();
- }
- if(datacontent.value === '4'){
- Xfoilyouhuatable.value = res.params;
- handlecheckFlagchange();
- }
-
- })
- .catch((err) => {
- ElMessage.error(err.returnMsg)
- })
- }
- const dataFlowsave = () => {
- let stringArray = '';
- if(datacontent.value === '3'){
- stringArray = convertToStringArray([],ADflowyouhuatable.value);
- }else if(datacontent.value === '4'){
- stringArray = convertToStringArray([],Xfoilyouhuatable.value);
- }
- const params = {
- transCode: "MDO0053",
- paramstr: stringArray,
- };
- request(params).then((res) => {
- ElMessage({
- message: '数据流保存成功',
- type: 'success',
- })
- })
- .catch((err) => {
- ElMessage.error('数据流保存失败')
- })
- }
- const convertToStringArray = (result, Data) => {
- console.log('Data:', Data);
- // 安全检查 Data,确保它是一个数组
- if (!Array.isArray(Data)) {
- console.error('Data should be an array');
- return result; // 返回原 result 或者根据需要返回其他默认值
- }
- result = Data.map(row => {
- // 获取每一行的 `code`, `name`, `value` 和 `flag`
- const paramid = row.paramid ?? ' ';
- const steamflag = row.steamflag ?? '';
- const steamtype = row.steamtype ?? ' ';
- // 将字段连接为一个以逗号分隔的字符串
- return `${paramid},${steamflag},${steamtype}`;
- }).join(';'); // 每行之间用分号分隔
- return result;
- }
- // 右键更改名字
- // const onContextMenu = (e) => {
- // e.preventDefault(); // 阻止浏览器默认的右键菜单
- // const node = e.target.closest(".vue-flow__node");
- // console.log("nodes:",nodes);
- // console.log("node:",node);
- // if (node) {
- // // 获取当前右键点击的节点
- // const nodeId = node.getAttribute("data-id");
- // const clickedNode = nodes.value.find((n) => n.id === nodeId);
- // console.log("clickedNode:",clickedNode);
-
- // if (clickedNode) {
- // noid.value = clickedNode;
- // changeName.value.name = clickedNode.label; // 将当前节点的label放入弹窗中
- // changeNameshow.value = true; // 显示弹窗
- // }
- // }
- // };
- onInit((vueFlowInstance) => {
- vueFlowInstance.fitView()
- })
- onNodeDragStop(({ event, nodes, node }) => {
- console.log(nodes)
- Nested.value=nodes;
- console.log('Node Drag Stop', { event, nodes, node })
- })
- // onConnect((connection) => {
- // addEdges(connection)
- // console.log('Connection', connection)
- // })
- function updatePos() {
- nodes.value = nodes.value.map((node) => {
- return {
- ...node,
- position: {
- x: Math.random() * 400,
- y: Math.random() * 400,
- },
- }
- })
- }
- function removeEdge(id) {
- if(!seledge.value){
- return;
- }
- id = Edgeid.value;
- const wid = seledge.value.data.wid;
- vueFlowRef.value.removeEdges(id);
- deleteflow(wid);
- seledge.value=null;
- console.log('msg:',datatree.value);
- }
- // 触摸
- const onDrop1=(event)=>{
- onDrop(event);
- emitter.emit('doSomethingEvent');
- }
- function removeNode(id) {
- id = noid.value.id;
- const wid = noid.value.data.wid;
- console.log('removeNodewid:',wid);
- if(datatree.value==undefined){
- if(nodes.value.length>0){
- for (let i = 0; i <nodes.value.length; i++) {
- if(id==nodes.value[i].id){
- console.log(44444)
- console.log( nodes.value[i]);
- nodes.value.splice(i, 1)
- deleteflow(wid);
- }
- }
- console.log( nodes.value);
- }
- }else{
- if(nodes.value.length>0){
- for (let i = 0; i <nodes.value.length; i++) {
- if(id==nodes.value[i].id){
- console.log( nodes.value[i]);
- nodes.value.splice(i, 1)
- }
- }
- }
- for (let i = 0; i <datatree.value[0].children.length; i++) {
- if(id.includes(datatree.value[0].children[i].Text)){
- for (let j = 0; j <datatree.value[0].children[i].children.length; j++) {
- if(id==datatree.value[0].children[i].children[j].id){
- //datatree.value[0].children.splice(datatree.value[0].children[i].children[j], 1);
- datatree.value[0].children[i].children.splice(j, 1);
- deleteflow(wid);
- vueFlowRef.value.removeNodes(id);
- removeRelatedEdges(id);
- }
-
- }
- }
- }
- }
- }
- function removeRelatedEdges(nodeId) {
- //过滤出与该节点相关的连线
- const relatedEdges = edges.value.filter(
- (edge) => edge.source === nodeId || edge.target === nodeId
- );
-
- // 遍历删除关联的连线
- relatedEdges.forEach((edge) => {
- if (edge.data && edge.data.wid) {
- deleteflow(edge.data.wid);
- }
- });
- }
- // 删除提示
- const confirmDelete = () => {
- ElMessageBox.confirm(
- '确定要删除全部吗?删除后不可恢复!',
- '删除确认',
- {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning',
- }
- )
- .then(() => {
- removeall();
- })
- .catch(() => {
- ElMessage({
- type: 'info',
- message: '已取消删除',
- })
- })
- }
- function removeall() {
- try {
- const allnodes = nodes.value;
- const allEdges = edges.value;
- for (let i = 0; i < allnodes.length; i++) {
- if (allnodes[i].data.wid) {
- deleteflow(allnodes[i].data.wid);
- }
- }
- for (let i = 0; i < allEdges.length; i++) {
- if (allEdges[i].data.wid) {
- deleteflow(allEdges[i].data.wid);
- }
- }
- nodes.value = []
- edges.value = []
- Nested2.value = []
- Nested.value = []
- // 判断 datatree 是否为空或未定义
- if (!datatree.value || datatree.value.length === 0 || !datatree.value[0]?.children) {
- console.warn('datatree 数据为空或未定义')
- ElMessage({
- type: 'warning',
- message: '没有数据可以删除'
- })
- return
- }
- // 清空 datatree 的 children
- for (let i = 0; i < datatree.value[0].children.length; i++) {
- if (datatree.value[0]?.children[i]?.children) {
- datatree.value[0].children[i].children = []
- }
- }
-
- } catch (error) {
- console.error('删除失败:', error)
- ElMessage({
- type: 'error',
- message: '删除过程中出错'
- })
- }
- }
- // 流查询
- const queryflow = () => {
- const params = {
- transCode: 'MDO0057',
- pid: pid.value,
- }
- request(params)
- .then((res) => {
- console.log(res);
-
- })
- .catch((err) => {
- ElMessage.error(err.returnMsg)
- })
- }
- // 保存流
- const saveflow = async (pid,wid, uid, type, fromuid, touid) => {
- const params = {
- transCode: 'MDO0058',
- pid: pid || '',
- wid: wid || '', // 流ID
- uid: uid || '',
- type: type || '',
- fromuid: fromuid || '',
- touid: touid || '',
- };
- try {
- // 直接使用 await 等待 request 返回
- const res = await request(params);
- return res.wid; // 返回 wid
- } catch (err) {
- // 处理错误
- ElMessage.error(err.returnMsg || '保存流程失败');
- }
- };
- // async function saveFlowExample() {
- // try {
- // const wid = await saveflow('flow123', 'user001', 'process', 'fromA', 'toB');
- // console.log('返回的 wid:', wid);
- // } catch (err) {
- // console.error('保存流程失败:', err.message);
- // }
- // }
- // saveFlowExample();
- // 删除流
- const deleteflow = (nowid) => {
- const params = {
- transCode: 'MDO0059',
- wid: nowid,
- }
- request(params)
- .then((res) => {
- console.log(res);
- })
- .catch((err) => {
- ElMessage.error('删除流程失败')
- })
- }
- async function logToObject1() {
- let obj = { nodes: toObject().nodes,edges:toObject().edges };
- mergedObj.value=JSON.stringify(obj);
- try {
- const container = vueFlowRef.value.$el;
- const canvas = await html2canvas(container);
- const img = canvas.toDataURL('image/png');
-
- // 创建一个图片元素并设置src属性为转换后的图片数据
- vueflowimg.value=img
- if(vueflowimg.value!=''){
- console.log("进入了")
- addflow();
- }
- // 添加到DOM中或者做其他操作
- } catch (error) {
- console.error('转换出错:', error);
- }
- }
- //添加接口
- const addflow = () => {
- const savedObj = JSON.parse(sessionStorage.getItem("objlist"));
- const stypeValue = savedObj ? savedObj.stype : '';
- // 用于首页主界面切换数据一致
- const updateobjlist = {
- pid: pid.value,
- name: newobj.value.name,
- remark: newobj.value.description,
- image: vueflowimg.value,
- isshare: '1',
- flow: mergedObj.value,
- stype: stypeValue,
- }
- sessionStorage.setItem("objlist",JSON.stringify(updateobjlist));
-
- console.log("打印stypeValue:",stypeValue);
- const params = {
- transCode: 'MDO0002',
- pid: pid.value,
- name: newobj.value.name,
- remark:newobj.value.description,
- image:vueflowimg.value,
- isshare:'1',
- flow:mergedObj.value ,
- stype:stypeValue,
- }
- console.log(params);
- request(params)
- .then((res) => {
- console.log(res);
- ElMessage({
- message: '工程保存成功',
- type: 'success',
- })
- })
- .catch((err) => {
- ElMessage.error(err.returnMsg)
- })
- }
- /**
- * Resets the current viewport transformation (zoom & pan)
- */
- function resetTransform() {
- setViewport({ x: 0, y: 0, zoom: 1 })
- }
- function toggleDarkMode() {
- dark.value = !dark.value;
- if(dark.value){
- iconcolor.value='#fff'
- }else{
- iconcolor.value='#000'
- }
- }
- // 禁用右键菜单的函数
- const onNodeContextMenu1 = (event) => {
- event.preventDefault();
- };
- onMounted(() => {
- setTimeout(function() {
- getroter();
- }, 1500);
- // childfun();
-
- // 点击其他区域取消线段选中
- if (vueFlowRef.value) {
- vueFlowRef.value.$el.addEventListener('click', (event) => {
- // 确保点击的不是边缘
- if (seledge.value && !event.target.closest('.vue-flow__edge')) {
- cleanEdgeselect();
- }
- });
- }
- document.addEventListener('contextmenu', onNodeContextMenu1);
- emitter.on("xfidFromxfoil", handleXfid);
- emitter.on("adidFromadflow", handleAdid);
- });
- const cleanEdgeselect = () => {
- if(seledge.value) {
- // 恢复选中边缘的原始样式
- seledge.value.style = {
- ...seledge.value.style,
- stroke: seledge.value.originalColor,
- strokeWidth: previousEdge?.originalWidth || 1, // 恢复原始宽度
- };
- // 清空选中的边缘
- seledge.value = null;
- Edgeid.value = null;
- previousEdge = null;
- }
-
- }
- // 在组件销毁前移除右键菜单禁用
- onBeforeUnmount(() => {
- document.removeEventListener('contextmenu', onNodeContextMenu1);
- });
- onUnmounted(() => {
- emitter.off('child2Data');
- emitter.off("xfidFromxfoil", handleXfid);
- emitter.off("adidFromadflow", handleAdid);
- });
- // 获取链接
- const getroter=()=>{
- //datatree.value[0].children=[];
- let objlist=JSON.parse(sessionStorage.getItem("objlist"));
- if(objlist.flow!=''){
- let nodesflow=JSON.parse(objlist.flow)
- nodes.value=nodesflow.nodes;
- edges.value=nodesflow.edges;
- }
- newobj.value.name=objlist.name;
- newobj.value.description=objlist.remark;
- pid.value=objlist.pid;
- // let item={
- // id:'1-0',
- // label: objlist.name,
- // img:r2,
- // }
- // console.log( datatree.value[0].children);
- // datatree.value[0].children.push(item);
- }
- //改变线的粗
- const linestrokeWidth=(type)=>{
- if(type=='process'){
- linenum.value=1;
- linecolor.value = '#b1b1b7';
- lineType.value = 'process';
- }else if(type=='data'){
- linenum.value=6;
- linecolor.value = "rgba(150, 150, 150, 0.2)";
- lineType.value = 'data';
- }
- }
- //改变线的颜色
- const changeAllEdgesColor = (color1) => {
- console.log('yanse:', color1);
- linecolor.value = color1;
- // 找到当前选中的边缘
- if (seledge.value) {
- // 更新该边缘的颜色
- let newColor = linecolor.value;
- // 如果选中的线 `linetype` 是 `data`,则增加透明度 0.3
- if (seledge.value.data.type === 'data') {
- newColor = convertToRGBA(linecolor.value, 0.3);
- }
- const updatedEdge = {
- ...seledge.value,
- style: {
- ...seledge.value.style,
- stroke: newColor, // 只修改颜色
- }
- };
- // 更新 edges 数组
- const updatedEdges = edges.value.map(edge =>
- edge.id === seledge.value.id ? updatedEdge : edge
- );
- edges.value = updatedEdges; // 持久化修改后的边缘
- }
- };
- // 颜色转换函数:将 Hex / RGB 转换为 RGBA
- const convertToRGBA = (color, alpha) => {
- if (color.startsWith('#')) {
- // 处理 Hex 颜色(例如 #ff0000 转换为 rgba(255, 0, 0, 0.3))
- const r = parseInt(color.substring(1, 3), 16);
- const g = parseInt(color.substring(3, 5), 16);
- const b = parseInt(color.substring(5, 7), 16);
- return `rgba(${r}, ${g}, ${b}, ${alpha})`;
- } else if (color.startsWith('rgb')) {
- // 处理 RGB 颜色,替换透明度
- return color.replace(/rgb(a?)\(([^)]+)\)/, `rgba($2, ${alpha})`);
- }
- return color; // 默认返回原始颜色(避免报错)
- };
- watch(() => seledge.value, (newItems, oldItems) => {
- if(seledge.value!=null){
- // seledge.value.style.stroke = linecolor.value;
- }
- });
- defineExpose({changeAllEdgesColor,linestrokeWidth,getroter,onSelection,bgcolorfunc,logToObject1});
- </script>
- <style>
- /* .vue-flow__edge.selected .vue-flow__edge-path, .vue-flow__edge:focus .vue-flow__edge-path, .vue-flow__edge:focus-visible .vue-flow__edge-path {
- stroke: #555 !important;
- } */
- .vue-flow__edge:focus .vue-flow__edge-path, .vue-flow__edge:focus-visible .vue-flow__edge-path {
- stroke: #555 !important;
- }
- .vue-flow__edge {
- text-align: left;
- /* 设置edges的左对齐 */
- }
- .vue-flow__edge-text {
- transform: translateY(-10px); /* 将 label 向上偏移 */
- background: transparent !important;
- font-size: 8px;
- font-family: 'Microsoft YaHei';
- color: #333333;
- }
- .vue-flow__edge-textbg {
- fill: transparent !important; /* 将背景设置为透明 */
- }
- #contextMenu {
- display: none;
- position: absolute;
- background-color: #fff;
- border-radius: 5px;
- padding: 10px;
- text-align: center;
- color: black;
- font-size: 14px;
- font-weight: 400;
- cursor: pointer;
- z-index: 99999;
- }
- .vue-flow__node-default.selectable:hover,
- .vue-flow__node-input.selectable:hover,
- .vue-flow__node-output.selectable:hover {
- box-shadow: none;
- }
- panel {
- cursor: pointer;
- position: absolute;
- z-index: 100000;
- }
- .remove {
- background: #fff;
- color: #666;
- margin: 0 10px;
- font-size: 12px;
- }
- .vue-flow__node-default, .vue-flow__node-input, .vue-flow__node-output{
- /* width: auto !important; */
- border: none;
- background-color: rgba(0,0,0,0);
- }
- .node-content {
- cursor: move; /* 更改鼠标光标表示可拖动 */
- }
- .vue-flow__node {
- cursor: move;
- }
- /* 禁用文本选中效果 */
- .left_main * {
- -webkit-user-select: none; /* Safari */
- -moz-user-select: none; /* Firefox */
- -ms-user-select: none; /* IE10+/Edge */
- user-select: none; /* Standard syntax */
- }
- .lableaniu{
- font-size: 12px;
- background-color: #ddd;
- padding: 4px 16px;
- /* margin-top: -17px; */
- margin-left: 5px;
- margin-top: 0px;
- border-radius: 1px;
- }
- .vue-flow__controls-button svg{
- max-width: 16px;
- max-height: 16px;
- }
- .field{
- display: flex;
- }
- </style>
|