diff --git a/src/views/pages/regulatory/customNode.vue b/src/views/pages/regulatory/customNode.vue new file mode 100644 index 0000000..139a6eb --- /dev/null +++ b/src/views/pages/regulatory/customNode.vue @@ -0,0 +1,46 @@ + + + + \ No newline at end of file diff --git a/src/views/pages/regulatory/index.vue b/src/views/pages/regulatory/index.vue index 3d1174d..850d657 100644 --- a/src/views/pages/regulatory/index.vue +++ b/src/views/pages/regulatory/index.vue @@ -11,27 +11,14 @@ - +
    -
  • +
  • - skadhjf + {{val.name}}
  • -
  • - - skadhjf -
  • -
  • - - skadhjf -
  • -
  • - - skadhjf -
  • -
  • - - skadhjf +
  • +
    该设备暂无任务链
@@ -40,34 +27,41 @@
-
+
+ +
-
请从左侧列表中选择组件.
- - + - + +
-
+
+ + + + 层级设置 + 提升 + 下降 + 是否 await + + + +
@@ -76,35 +70,37 @@ import '@vue-flow/core/dist/style.css'; /* import the default theme (optional) */ import '@vue-flow/core/dist/theme-default.css'; -import { Background, Panel, PanelPosition, Controls } from '@vue-flow/additional-components' -import { VueFlow, useVueFlow } from '@vue-flow/core' +import { Background, Panel, Controls } from '@vue-flow/additional-components' +import { VueFlow, useVueFlow } from '@vue-flow/core' import { onMounted, reactive, ref } from 'vue'; -import { Calendar, Grid } from '@element-plus/icons-vue' +import { Calendar, Grid, Aim } from '@element-plus/icons-vue' import { ElMessageBox, ElMessage } from 'element-plus'; -import { SysMenu } from '/@/api-services/models'; +import CustomNode from './customNode.vue' import { getEquipmentList, del } from '/@/api/equipment'; import { Session } from '/@/utils/storage'; + +const { nodes, addNodes, updateEdge, removeEdges, getElements, getNode, addEdges, fitView, updateNode, edges } = useVueFlow() const data = [ - { id: '1', type: 'process', label: 'Node 1', position: { x: 250, y: 5 }, background: '#42B983' }, - { id: '2', label: 'Node 2', position: { x: 100, y: 100 } }, - { id: '3', label: 'Node 3', position: { x: 400, y: 100 } }, - { id: '4', label: 'Node 4', position: { x: 400, y: 200 } }, - { id: '5', label: 'Node 5', position: { x: 100, y: 200 } }, - { id: '6', label: 'Node 6', position: { x: 400, y: 200 } }, +// { id: '1', type: 'process', label: 'Node 1', position: { x: 250, y: 5 }, background: '#42B983' }, +// { id: '2', label: 'Node 2', position: { x: 100, y: 100 } }, +// { id: '3', label: 'Node 3', position: { x: 400, y: 100 } }, +// { id: '4', label: 'Node 4', position: { x: 400, y: 200 } }, +// { id: '5', label: 'Node 5', position: { x: 100, y: 200 } }, +// { id: '6', label: 'Node 6', position: { x: 400, y: 200 } }, - { id: 'e1-2', source: '1', target: '2', type: 'animation' }, - { id: 'e1-3', source: '1', target: '3', type: 'edgeType' }, - { id: 'e1-4', source: '5', target: '6', type: 'edgeType' }, +// { id: 'e1-2', source: '1', target: '2', type: 'animation' }, +// { id: 'e1-3', source: '1', target: '3', type: 'edgeType' }, +// { id: 'e1-4', source: '5', target: '6', type: 'edgeType' }, ] let elements = ref(data) -const isHidden = ref(false) const collapseActiveNames = ref(['1', '2', '3']); - +const isAwait = ref(false); // const addEquipmentRef = ref>(); const state = reactive({ loading: false, activeName: 'first', - equipmentData: [] as Array, + activeSet: 'first', + equipmentData: [] as Array, taskChainList: [ ] as any, orgData: [] as any, @@ -126,40 +122,174 @@ onMounted(async () => { state.queryParams.position = state.orgData[0]?.code || ''; handleQuery(); }); -// watch: { -// isHidden: { -// immediate: false, -// handler: function () { -// nodes.value.forEach((n) => (n.hidden = isHidden.value)) -// edges.value.forEach((e) => (e.hidden = isHidden.value)) -// } -// } -// } - -const onPaneReady = (({ fitView }) => { - fitView() -}) -// const onNodeDragStop((e) => console.log('drag stop', e)) -// const onConnect((params) => addEdges([params])) - -const updatePos = () => { - nodes.value.forEach((el) => { - el.position = { - x: Math.random() * 400, - y: Math.random() * 400, +const nodeClickHandler = () => { + console.log(nodes.value, edges.value) +} + +// 修改节点是否await +const changeSwitch = () => { + var node = nodes.value.find((el) => el.selected); + if (!node) { + ElMessage.warning('请先选择一个节点'); + return; } - }) -}; - -const logToObject = () => { - ElMessage.info(JSON.stringify(toObject())); -}; -const resetTransform = () => { - elements.value = data - setTransform({ x: 0, y: 0, zoom: 1 }) + var nexts = nodes.value.filter((el) => el.data.level === node.data.level + 1); + if (nexts?.length < 1 && isAwait.value) { + ElMessage.warning('已是最后一个节点,无需等待'); + isAwait.value = false; + return; + } + if (isAwait.value) { + nexts.forEach((next) => { + let edge = edges.value.find((el) => el.source === node.id && el.target === next.id); + const len = edges.value.length; + if (!edge) { + const newEdge = { + id: parseInt(edges.value[len - 1].id.split('_')[0]) + 1 + '_edge', + source: node.id, + label: 'await', + target: next.id, + labelStyle: { fill: 'red', fontSize: 12}, + } + addEdges([newEdge]); + } + }) + } else { + edges.value.forEach((el) => { + if (el.source === node.id) { + removeEdges(el.id); + } + }) + } +} + // 添加节点 +const chainClick = (i, j) => { + const len = nodes.value.length; + const nodeId = (len + 1).toString()+'_add'; + const equipment = state.equipmentData[i]; + const level = len > 0 ? nodes.value[len - 1].data.level + 1 : 1; + const newNode = { + id: nodeId, + label: equipment.taskChainList[j]?.name, + // name: equipment.equipmentName, + type:'custom', + position: { x: 250, y: 120 * level }, + data:{...JSON.parse(JSON.stringify(equipment.taskChainList[j])), level, ...{name: equipment.equipmentName,}} + } + + addNodes([newNode]) + if (len > 0) { + const newEdge = { + id: (len + 1).toString() + '_edge', + source: nodes.value[len - 1].id, + // type: img_params.value.edge.type, + label: 'await', + target: nodeId, + // updatable: img_params.value.edge.updatable, + // events: { click: clickadd }, + // labelBgPadding: [8, 4], + labelStyle: { fill: 'red', fontSize: 12}, + // labelBgBorderRadius: 4, + // labelBgStyle: { fill: '#10b981', color: '#fff', fillOpacity: 1 }, + } + addEdges([newEdge]); + + } + setTimeout(() => { + fitView() + }, 200) }; -const toggleclass = () => nodes.value.forEach((el) => (el.class = el.class === 'node-light' ? 'node-dark' : 'node-light')) +const leaveSet = (i) => { + var node = nodes.value.find((el) => el.selected); + if (!node) { + ElMessage.warning('请先选择一个节点'); + return; + } + if (node.data.level === 1 && i < 0) { + ElMessage.warning('已是第一个节点,无法上移'); + return; + } + if (nodes.value.length === node.data.level && i > 0) { + ElMessage.warning('已是最后一个节点,无法下移'); + return; + } + node.data.level += i; + // 重新排序 + nodes.value.sort((a, b) => a.data.level - b.data.level); + // 遍历数组,检查并调整断层 + // debugger; + for (let j = 0; j < nodes.value.length; j++) { + let item = nodes.value[j]; + // 上一个节点存在,且当前节点的层级与上一个节点的层级不相等,且当前节点的层级与上一个节点的层级不是相邻的 + if (j > 0 && item.data.level !== nodes.value[j - 1].data.level && item.data.level !== nodes.value[j-1].data.level + 1) { + // 发现断层,从当前元素开始,后面的所有数字减1 + for (let i = j; i < nodes.value.length; i++) { + nodes.value[i].data.level--; + } + } + // 后面的节点往后移动 + if (i > 0 &&node.id !==item.id && node.data.level <= item.data.level) { + item.data.level++; + } + } + updateNodes(); + updateEdges(i, node); +} + +const updateNodes = () => { + const width = 180; + var frequencyMap = {}; + const len = nodes.value.length; + // debugger; + for (let j = 0; j < len; j++) { + if (!frequencyMap[nodes.value[j].data.level]) { + frequencyMap[nodes.value[j].data.level] = 1 + } else { + frequencyMap[nodes.value[j].data.level]++; + } + } + // 找出出现次数最多的 value + let maxFrequency = 0; + for (const value in frequencyMap) { + if (frequencyMap[value] > maxFrequency) { + maxFrequency = frequencyMap[value]; + } + } + var centX = width * maxFrequency / 2 + 100; + var setMap = {}; + nodes.value.forEach((el) => { + if (!setMap[el.data.level]) { + setMap[el.data.level] = 0; + } + el.position = { x: centX - frequencyMap[el.data.level] * width / 2 + setMap[el.data.level] * width, y: 120 * el.data.level } + setMap[el.data.level]++; + updateNode(el.id, el); + }) + setTimeout(() => { + fitView() + }, 300) +} + +const updateEdges = (i, node) => { + const len = edges.value.length; + for (let i = 0; i < len; i++) { + if (edges.value[i]?.target === node.id) { + removeEdges(edges.value[i].id); + } + } + let index = nodes.value.findIndex((el) => el.id === node.id); + if (index > 0 && i > 0) { + const newEdge = { + id: parseInt(edges.value[len - 1].id.split('_')[0]) + 1 + '_edge', + source: nodes.value[index - 1].id, + label: 'await', + target: node.id, + labelStyle: { fill: 'red', fontSize: 12}, + } + addEdges([newEdge]); + } +} // 查询操作 const handleQuery = async () => { @@ -240,6 +370,9 @@ const delMenu = (row: any) => { overflow-y: auto; // padding: 0 20px; box-sizing: border-box; + text-align: right; + line-height: 40px; + padding: 0 40px; } ul.el-collapse { padding-left: 10px; @@ -266,71 +399,13 @@ ul.el-collapse { .left-content { padding-left: 20px; } -.img-box { - position: relative; - margin: 0 auto; - font-family: 'MiSans-Regular'; - color: #000; - width: 850.4px; - height: 472.8px; - background: url('../assets/bg.png') no-repeat; - background-size: 100% 100%; - padding-top: 140px; - padding-left: 80px; - box-sizing: border-box; - .text { - position: relative; - } - .name-box { - display: inline-block; - width: 45%; - vertical-align: middle; - .name { - font-size: 100px; - font-family: 'MiSans-Demibold'; - font-weight: bold; - } - .pinying { - font-size: 50px; - } - } - .aprt { - position: absolute; - top: 28px; - left: 45%; - font-size: 70px; - width: 52%; - &.width5 { - width: 50%; - } - &.topLine { - top: 9px; - padding-left: 20px; - } - } - &.left3 .aprt { - left: 47%; - } - &.break { - page-break-after:always - } - &.block { - padding-top: 100px; - .name-box { - width: 100%; - } - .aprt { - position: static; - width: 100%; - margin-top: 40px; - font-size: 56px; - padding-left: 0; - } - } -} \ No newline at end of file diff --git a/src/views/system/equipment/index.vue b/src/views/system/equipment/index.vue index 8e50ae7..cb56038 100644 --- a/src/views/system/equipment/index.vue +++ b/src/views/system/equipment/index.vue @@ -87,7 +87,7 @@ import { Session } from '/@/utils/storage'; const addEquipmentRef = ref>(); const state = reactive({ loading: false, - equipmentData: [] as Array, + equipmentData: [] as Array, equipmentType: [] as any, orgData: [] as any, queryParams: {