|
|
@@ -1,68 +1,104 @@
|
|
|
<template>
|
|
|
- <div class="app-container">
|
|
|
- <el-row :gutter="20">
|
|
|
- <el-col :span="4" class="sidebar-wrapper">
|
|
|
- <el-input
|
|
|
- v-model="modelQueryParams.name"
|
|
|
- placeholder="请输入模型名称"
|
|
|
- clearable
|
|
|
- prefix-icon="Search"
|
|
|
- style="margin-bottom: 10px"
|
|
|
- @change="getModelList()"
|
|
|
- />
|
|
|
- <el-radio-group style="flex-wrap: nowrap;" v-model="modelQueryParams.isPublic" @change="getModelList">
|
|
|
- <el-radio-button label="已发布" value="1"/>
|
|
|
- <el-radio-button label="未发布" value="0"/>
|
|
|
- </el-radio-group>
|
|
|
- <div class="tool-container">
|
|
|
- <div :class="{'active': modelId === item.mdid}" v-for="(item, index) in modelOptions" :key="index"
|
|
|
- class="tool-item" @click="handleModelClick(item.mdid)">
|
|
|
- {{ item.name }}
|
|
|
- </div>
|
|
|
+ <div>
|
|
|
+ <el-button type="primary" @click="showData">测试</el-button>
|
|
|
+ <!-- <div style="margin-left: 1%;padding-top: 1%;position: absolute;z-index: 1000;cursor: pointer;" @click="back">
|
|
|
+ <el-icon size="large"><Back /></el-icon>
|
|
|
+ </div> -->
|
|
|
+ <div style="height: 85vh;width: 20vw;position: absolute;float: right;z-index: 1000;right: 1%;top: 1%;border: 0.1px solid #dedfe0;border-radius: 6px;background-color: white;">
|
|
|
+ <div style="display: flex;margin-left: 3%;margin-top: 3%;align-items: center;justify-content: space-between;width: 95%;">
|
|
|
+ <el-tag class="ml-2" style="" type="warning">服务</el-tag>
|
|
|
+ <div style="margin-left: 4%;">
|
|
|
+ 获取台风信息列表
|
|
|
</div>
|
|
|
- </el-col>
|
|
|
- <!-- v-loading="loading" -->
|
|
|
- <el-col :span="16" style="position: relative;">
|
|
|
- <el-button-group class="flow-button-group">
|
|
|
- <el-button type="primary" :icon="Promotion" @click="saveStep">保存</el-button>
|
|
|
- <!-- <el-button type="primary" :icon="Check">测试</el-button>-->
|
|
|
- </el-button-group>
|
|
|
- <VueFlow :nodes="nodes" :edges="edges" @drop="onDrop" @dragover="onDragOver" @dragleave="onDragLeave"
|
|
|
- @connect="onConnect" fit-view-on-init>
|
|
|
- <template #node-special="specialNodeProps">
|
|
|
- <SpecialNode :id="specialNodeProps.id" :position="specialNodeProps.position" :data="specialNodeProps.data"/>
|
|
|
+ <el-icon style="margin-left: auto;"><Close /></el-icon>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div style="display: flex;height: 85vh;width: 100%;padding-top: 1%;">
|
|
|
+ <div style="width: 20%;margin-left: 1%;overflow-y: auto;">
|
|
|
+ <el-tree :expand-on-click-node="false" ref="treeRef" :filter-node-method="filterNode" :current-node-key="currentNodeKey" class="treeLeft" :data="dataTree" @node-click="handleNodeClick" node-key="id" style="margin-left: 5%;margin-top: 5%;width: 90%;background-color: transparent;" default-expand-all :key="valueKet">
|
|
|
+ <template #default="{ node, data }">
|
|
|
+ <span style="justify-content: space-between;display: flex;width: 100%;align-items: center;">
|
|
|
+ <div class="custom-tree-node":draggable="true"
|
|
|
+ @dragstart="onDragStart($event,data)">
|
|
|
+ <!-- <el-tag v-if="data.nodeType=='MODEL'" class="ml-2" type="warning">模型</el-tag> -->
|
|
|
+ <svg-icon icon-class="model2" style="color: #eebe77;" v-if="data.nodeType=='MODEL'"/>
|
|
|
+ <!-- <el-tag class="ml-2">
|
|
|
+ 服务
|
|
|
+ </el-tag> -->
|
|
|
+ <svg-icon icon-class="model" dstyle="color: #13E03B;" v-if="data.nodeType=='SERVICE'"/>
|
|
|
+ <svg-icon svg-icon icon-class="cate" style="color: red;" v-if="data.nodeType=='TREE'"/>
|
|
|
+ <span>{{ node.label }}</span>
|
|
|
+ </div>
|
|
|
+ </span>
|
|
|
</template>
|
|
|
+ </el-tree>
|
|
|
+ </div>
|
|
|
+ <VueFlow :nodes="nodes" :edges="edges" @drop="onDrop" @dragover="onDragOver" @dragleave="onDragLeave"
|
|
|
+ @node-click="onNodeClick" @connect="onConnect" fit-view-on-init>
|
|
|
+ <template #node-special="specialNodeProps">
|
|
|
+ <div v-if="specialNodeProps.data.label=='开始'" class="vue-flow__node-default" style="border: 0.2px solid #c8c9cc;border-radius: 6px;min-height: 6vh;min-width: 11vw">
|
|
|
+ <div style='width:100%;font-size:10px;display:flex;align-items:flex-end;height: 10px;margin-top: 2%;'>
|
|
|
+ <img style="width: 15px;height:15px;border-radius: 12px;" src="@/assets/images/icon-Start-v2.jpg" alt="">
|
|
|
+ <div style="margin-left: 3%;font-weight: 500;">
|
|
|
+ 开始
|
|
|
+ </div>
|
|
|
+ <el-tag class="ml-2" style="width: 30px;height: 15px;font-size: 7px;margin-left: 6%;" type="info">触发器</el-tag>
|
|
|
+ </div>
|
|
|
+ <Handle type="source" :position="Position.Right"/>
|
|
|
+ </div>
|
|
|
+ <div v-if="specialNodeProps.data.label=='结束'" class="vue-flow__node-default" style="border: 0.2px solid #c8c9cc;border-radius: 6px;min-height: 6vh;min-width: 11vw">
|
|
|
+ <div style='width:100%;font-size:10px;display:flex;align-items:flex-end;height: 10px;margin-top: 2%;'>
|
|
|
+ <img style="width: 15px;height:15px;border-radius: 12px;" src="@/assets/images/icon-Start-v2.jpg" alt="">
|
|
|
+ <div style="margin-left: 3%;font-weight: 500;">
|
|
|
+ 结束
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <Handle type="target" :position="Position.Left"/>
|
|
|
+ </div>
|
|
|
+ <div v-if="specialNodeProps.data.label!=='结束'&&specialNodeProps.data.label!=='开始'" class="vue-flow__node-default"
|
|
|
+ style="border: 0.5px solid #c8c9cc;border-radius: 6px;border-radius: 6px;min-height: 8vh;min-width: 13vw">
|
|
|
+ <div style='width:100%;font-size:10px;display:flex;align-items:flex-end;height: 10px;margin-top: 2%;justify-content: space-between;'>
|
|
|
+ <img style="width: 15px;height:15px;border-radius: 12px;" src="@/assets/images/icon-HTTP.png" alt="">
|
|
|
+ <div style="margin-left:3%;font-weight: 500;width: 40%;">
|
|
|
+ {{ specialNodeProps.data.label }}
|
|
|
+ </div>
|
|
|
+ <el-icon style="cursor: pointer;margin-left: auto;"><CaretRight /></el-icon>
|
|
|
+ <el-icon style="cursor: pointer;color: #F56C6C;margin-left: 2%;"><Delete /></el-icon>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ <div style="display: flex;margin-top: 3%;">
|
|
|
+ <el-tag class="ml-2" style="width: 35px;height: 20px;font-size: 10px;" type="warning">服务</el-tag>
|
|
|
+ </div>
|
|
|
+ <div style="display: flex;margin-top: 3%;font-size: 9px;color: #b1b3b8;align-items: center;">
|
|
|
+ <div>
|
|
|
+ GET:
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ https://www.zhihu.com/
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div style="display: flex;margin-top: 3%;font-size: 9px;color: #b1b3b8;align-items: center;">
|
|
|
+ <div>
|
|
|
+ 输出:
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ https://www.zhihu.com/
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <Handle type="source" :position="Position.Right"/>
|
|
|
+ <Handle type="target" :position="Position.Left"/>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template #edge-custom="specialEdgeProps">
|
|
|
+ <div style="height: 1px;color: red;">
|
|
|
|
|
|
- <!-- bind your custom edge type to a component by using slots, slot names are always `edge-<type>` -->
|
|
|
- <template #edge-special="specialEdgeProps">
|
|
|
- <SpecialEdge v-bind="specialEdgeProps"/>
|
|
|
- </template>
|
|
|
- </VueFlow>
|
|
|
- </el-col>
|
|
|
- <el-col :span="4" class="sidebar-wrapper">
|
|
|
- <el-input
|
|
|
- v-model="toolQueryParams.name"
|
|
|
- placeholder="请输入工具名称"
|
|
|
- clearable
|
|
|
- prefix-icon="Search"
|
|
|
- style="margin-bottom: 10px"
|
|
|
- @change="getServiceList()"
|
|
|
- />
|
|
|
- <el-radio-group style="flex-wrap: nowrap;" v-model="toolType">
|
|
|
- <el-radio-button label="工具类" value="1"/>
|
|
|
- <el-radio-button label="服务" value="0"/>
|
|
|
- </el-radio-group>
|
|
|
- <div v-show="toolType === '1'" class="tool-container">
|
|
|
- <div></div>
|
|
|
- </div>
|
|
|
- <div v-show="toolType === '0'" class="tool-container">
|
|
|
- <div v-for="(item, index) in serviceList" :key="index" class="tool-item" :draggable="true"
|
|
|
- @dragstart="onDragStart($event, item)">
|
|
|
- {{ item.label }}
|
|
|
</div>
|
|
|
- </div>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
+ </template>
|
|
|
+ </VueFlow>
|
|
|
+ </div>
|
|
|
|
|
|
<!-- 添加或修改部门对话框 -->
|
|
|
<el-dialog :title="title" v-model="open" width="600px" append-to-body>
|
|
|
@@ -136,36 +172,34 @@
|
|
|
<script setup>
|
|
|
import DynamicMap from '@/components/DynamicMap/index.vue'
|
|
|
import {Promotion} from '@element-plus/icons-vue'
|
|
|
-import {ref} from 'vue'
|
|
|
-import {useVueFlow, VueFlow} from '@vue-flow/core'
|
|
|
+import { onMounted, ref } from 'vue'
|
|
|
+import {useVueFlow, VueFlow ,MarkerType } from '@vue-flow/core'
|
|
|
import SpecialNode from './components/SpecialNode.vue'
|
|
|
import SpecialEdge from './components/SpecialEdge.vue'
|
|
|
import {getPtServiceList} from "@/api/service/info.js";
|
|
|
import {getModelList2} from "@/api/register/regCom.js";
|
|
|
import {copyObject} from "@/utils/index.js";
|
|
|
import {getWorkflowByModelId, saveWorkflow} from "@/api/standardization/workflow.js";
|
|
|
-
|
|
|
+import { useStore } from 'vuex';
|
|
|
+import {Handle, Position} from '@vue-flow/core'
|
|
|
+import { computed } from 'vue';
|
|
|
+import { modelTreeSelect } from "@/api/service/info";
|
|
|
const {
|
|
|
- onInit,
|
|
|
- findNode,
|
|
|
- fitView,
|
|
|
snapToGrid,
|
|
|
addEdges,
|
|
|
+ onEdgeClick,
|
|
|
+ removeElements,
|
|
|
addNodes,
|
|
|
- toObject,
|
|
|
screenToFlowCoordinate,
|
|
|
onNodesInitialized,
|
|
|
updateNode,
|
|
|
onNodeClick,
|
|
|
- onEdgeClick,
|
|
|
getNodes,
|
|
|
getEdges,
|
|
|
removeNodes,
|
|
|
removeEdges,
|
|
|
} = useVueFlow()
|
|
|
-// to enable snapping to grid
|
|
|
snapToGrid.value = true
|
|
|
-
|
|
|
const {proxy} = getCurrentInstance();
|
|
|
const modelQueryParams = ref({
|
|
|
name: undefined,
|
|
|
@@ -174,22 +208,51 @@ const modelQueryParams = ref({
|
|
|
const toolQueryParams = ref({
|
|
|
name: undefined,
|
|
|
});
|
|
|
+const dataTree = ref([]);
|
|
|
const modelOptions = ref(undefined);
|
|
|
const modelId = ref(undefined);
|
|
|
const loading = ref(true);
|
|
|
const toolType = ref('0');
|
|
|
const serviceList = ref([]);
|
|
|
-
|
|
|
+const defaultEdgeStyle = {
|
|
|
+ style: {
|
|
|
+ stroke: '#6366f1',
|
|
|
+ strokeWidth: 2,
|
|
|
+ fill: 'none' // 避免截图时出现黑色背景 [4](@ref)
|
|
|
+ },
|
|
|
+ markerEnd: {
|
|
|
+ type: MarkerType.ArrowClosed,
|
|
|
+ color: '#ff0000', // 箭头颜色
|
|
|
+ width: 15, // 箭头宽度
|
|
|
+ height: 15 // 箭头高度
|
|
|
+ }
|
|
|
+};
|
|
|
const draggedData = ref(undefined);
|
|
|
const isDragging = ref(false);
|
|
|
const isDragOver = ref(false);
|
|
|
-const nodes = ref([]);
|
|
|
-const edges = ref([]);
|
|
|
+const nodes = ref([
|
|
|
+ { id: '1', position: { x: -600, y: -300 }, data: { label: '开始' }, type: 'special' },
|
|
|
+ { id: '2', position: { x: 150, y: 100 }, data: { label: '结束' }, type: 'special' },
|
|
|
+]);
|
|
|
+const edges = ref([]);
|
|
|
|
|
|
const title = ref('')
|
|
|
const open = ref(false)
|
|
|
+const store = useStore();
|
|
|
|
|
|
-
|
|
|
+onEdgeClick(({ edge }) => {
|
|
|
+ edges.value = edges.value.filter(edge => edge.id !== edgeId)
|
|
|
+});
|
|
|
+async function getTreeLeft(){
|
|
|
+ await modelTreeSelect().then(res=>{
|
|
|
+ dataTree.value = res.data
|
|
|
+ })
|
|
|
+ optionsMdid.value = filterModelNodes(par)
|
|
|
+ console.log(optionsMdid.value)
|
|
|
+}
|
|
|
+function showData(){
|
|
|
+ console.log(nodes.value,edges.value)
|
|
|
+}
|
|
|
function handleModelClick(mid) {
|
|
|
modelId.value = mid
|
|
|
removeNodes(getNodes.value)
|
|
|
@@ -197,25 +260,15 @@ function handleModelClick(mid) {
|
|
|
getWorkflow(mid)
|
|
|
}
|
|
|
|
|
|
-onInit((instance) => {
|
|
|
- fitView()
|
|
|
- const node = findNode('1')
|
|
|
- if (node) {
|
|
|
- node.position = {x: 100, y: 100}
|
|
|
- }
|
|
|
-})
|
|
|
|
|
|
onNodeClick(({event, node}) => {
|
|
|
- form.value = node.data
|
|
|
+ console.log(node)
|
|
|
+ // form.value = node.data
|
|
|
open.value = true
|
|
|
- title.value = node.data.label
|
|
|
- nodeId.value = node.id
|
|
|
+ // title.value = node.data.label
|
|
|
+ // nodeId.value = node.id
|
|
|
});
|
|
|
|
|
|
-// Edge click event handler
|
|
|
-onEdgeClick(({event, edge}) => {
|
|
|
- console.log('Edge clicked:', edge, event);
|
|
|
-});
|
|
|
|
|
|
const data = reactive({
|
|
|
form: {config: {}},
|
|
|
@@ -255,17 +308,21 @@ const nodeId = ref(null)
|
|
|
* @param data
|
|
|
*/
|
|
|
function onDragStart(event, data) {
|
|
|
+ console.log(data)
|
|
|
if (event.dataTransfer) {
|
|
|
event.dataTransfer.setData('application/vueflow', data)
|
|
|
event.dataTransfer.effectAllowed = 'move'
|
|
|
}
|
|
|
|
|
|
draggedData.value = data
|
|
|
+ console.log(draggedData.value)
|
|
|
isDragging.value = true
|
|
|
|
|
|
document.addEventListener('drop', onDragEnd)
|
|
|
}
|
|
|
-
|
|
|
+function back(){
|
|
|
+ proxy.$router.push({ path: '/standardization/modelUsing' });
|
|
|
+}
|
|
|
/**
|
|
|
* 拖拽到画布vueflow的事件
|
|
|
* @param event
|
|
|
@@ -293,7 +350,6 @@ function onDrop(event) {
|
|
|
})
|
|
|
|
|
|
const nodeId = Math.random() + "id";
|
|
|
-
|
|
|
const data = copyObject(draggedData.value)
|
|
|
const newNode = {
|
|
|
id: nodeId,
|
|
|
@@ -332,8 +388,7 @@ function onDragEnd() {
|
|
|
}
|
|
|
|
|
|
function onConnect(params) {
|
|
|
- console.log('on connect', params)
|
|
|
- addEdges(params)
|
|
|
+ addEdges({ ...params, ...defaultEdgeStyle })
|
|
|
}
|
|
|
|
|
|
/** 查询模型列表 */
|
|
|
@@ -351,9 +406,8 @@ const filterNode = (value, data) => {
|
|
|
};
|
|
|
|
|
|
/** 节点单击事件 */
|
|
|
-function handleNodeClick(data) {
|
|
|
- queryParams.value.modeId = 1 // data.id;
|
|
|
- handleQuery();
|
|
|
+function handleNodeClick(node,data,event) {
|
|
|
+ console.log(data)
|
|
|
}
|
|
|
|
|
|
/** 搜索按钮操作 */
|
|
|
@@ -452,87 +506,37 @@ function getWorkflow(modelId) {
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
+onMounted(() => {
|
|
|
+ getTreeLeft()
|
|
|
+ getModelList()
|
|
|
+ getServiceList()
|
|
|
+ const count = computed(() => store.getters.id)
|
|
|
+ console.log(count.value);
|
|
|
+})
|
|
|
|
|
|
|
|
|
-getModelList()
|
|
|
-getServiceList()
|
|
|
</script>
|
|
|
<style>
|
|
|
@import '@vue-flow/core/dist/style.css';
|
|
|
@import '@vue-flow/core/dist/theme-default.css';
|
|
|
</style>
|
|
|
<style scoped>
|
|
|
-.app-container {
|
|
|
- height: 100%;
|
|
|
-
|
|
|
- & > div {
|
|
|
- height: 100%;
|
|
|
-
|
|
|
- & > div {
|
|
|
- height: 100%;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .sidebar-wrapper {
|
|
|
- padding: 10px 0;
|
|
|
- border-radius: 8px;
|
|
|
- border: 1px solid var(--el-border-color);
|
|
|
- }
|
|
|
-
|
|
|
- .tool-container {
|
|
|
- overflow: auto;
|
|
|
- height: calc(100% - 74px);
|
|
|
-
|
|
|
- .tool-item {
|
|
|
- padding: 5px 10px;
|
|
|
- border-radius: 6px;
|
|
|
- cursor: pointer;
|
|
|
-
|
|
|
- &:hover, &.active {
|
|
|
- background-color: var(--el-color-primary);
|
|
|
- color: #fff;
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- .flow-button-group {
|
|
|
- position: absolute;
|
|
|
- top: 10px;
|
|
|
- left: 10px;
|
|
|
- z-index: 10;
|
|
|
- }
|
|
|
-
|
|
|
-}
|
|
|
|
|
|
-:deep(.el-radio-group) {
|
|
|
- display: flex;
|
|
|
- width: 100%;
|
|
|
- text-align: center;
|
|
|
+:deep(.treeLeft) .el-tree-node__content {
|
|
|
+ display: flex !important;
|
|
|
+ height: 28px; /* 按设计稿调整高度 */
|
|
|
+ align-items: center;
|
|
|
+ padding-top: 0 !important;
|
|
|
}
|
|
|
-
|
|
|
-:deep(.el-radio-button) {
|
|
|
- flex: 1;
|
|
|
- border: var(--el-border);
|
|
|
-}
|
|
|
-
|
|
|
-:deep(.el-radio-button.is-active) {
|
|
|
- background-color: var(--el-color-primary);
|
|
|
-}
|
|
|
-
|
|
|
-:deep(.el-radio-button:first-child) {
|
|
|
- border-top-left-radius: 5px;
|
|
|
- border-bottom-left-radius: 5px;
|
|
|
-}
|
|
|
-
|
|
|
-:deep(.el-radio-button:last-child) {
|
|
|
- border-top-right-radius: 5px;
|
|
|
- border-bottom-right-radius: 5px;
|
|
|
+:deep(.treeLeft) .el-tree-node__content:hover {
|
|
|
+ background-color: #e9e9eb;
|
|
|
}
|
|
|
+:deep(.treeLeft) .el-tree-node__content:active {
|
|
|
+ background-color: rgka(69,157,255,0.1) !important;
|
|
|
+ }
|
|
|
|
|
|
-:deep(.el-radio-button__inner) {
|
|
|
- transition: none;
|
|
|
- border: none !important;
|
|
|
-}
|
|
|
+ /* 选中态(Active) */
|
|
|
+:deep(.treeLeft) .el-tree-node.is-current > .el-tree-node__content {
|
|
|
+ background-color: #c6e2ff !important;
|
|
|
+ }
|
|
|
</style>
|