修改组态化

master
夜笙歌 2 months ago
parent ea59268910
commit c1347b14d3

@ -20,6 +20,8 @@
"dependencies": { "dependencies": {
"@element-plus/icons-vue": "2.3.1", "@element-plus/icons-vue": "2.3.1",
"@highlightjs/vue-plugin": "2.1.0", "@highlightjs/vue-plugin": "2.1.0",
"@vue-flow/background": "^1.3.2",
"@vue-flow/core": "^1.43.1",
"@vueup/vue-quill": "1.2.0", "@vueup/vue-quill": "1.2.0",
"@vueuse/core": "10.9.0", "@vueuse/core": "10.9.0",
"animate.css": "4.1.1", "animate.css": "4.1.1",

@ -3,6 +3,8 @@ import { createApp, provide } from 'vue';
import 'virtual:uno.css'; import 'virtual:uno.css';
import '@/assets/styles/index.scss'; import '@/assets/styles/index.scss';
import 'element-plus/theme-chalk/dark/css-vars.css'; import 'element-plus/theme-chalk/dark/css-vars.css';
import '@vue-flow/core/dist/style.css'
import '@vue-flow/core/dist/theme-default.css'
// App、router、store // App、router、store
import App from './App.vue'; import App from './App.vue';

@ -10,7 +10,7 @@ import useSettingsStore from '@/store/modules/settings';
import usePermissionStore from '@/store/modules/permission'; import usePermissionStore from '@/store/modules/permission';
NProgress.configure({ showSpinner: false }); NProgress.configure({ showSpinner: false });
const whiteList = ['/board1','/board2','/login', '/register', '/social-callback']; const whiteList = ['/boardGenerate','/board1','/board2','/login', '/register', '/social-callback'];
router.beforeEach(async (to, from, next) => { router.beforeEach(async (to, from, next) => {
NProgress.start(); NProgress.start();

@ -26,6 +26,11 @@ import Layout from '@/layout/index.vue';
// 公共路由 // 公共路由
export const constantRoutes: RouteRecordRaw[] = [ export const constantRoutes: RouteRecordRaw[] = [
{
path: '/boardGenerate',
hidden: true,
component: () => import('@/views/boardGenerate/index.vue')
},
{ {
path: '/board1', path: '/board1',
hidden: true, hidden: true,

@ -0,0 +1,80 @@
<template>
<div class="leftPanel">
<el-tabs v-model="leftPanelState" class="demo-tabs" type="border-card">
<el-tab-pane label="图表组件" name="1">
<el-card style="width: 80px" shadow="never" :draggable="true"
@dragstart="onDragStart($event, 'line')" :style="{display:'inline-block',margin:'0 4px 4px 0'}"
:body-style="{padding:'4px 0'}">
<template #header>
<StarFilled />
</template>
图表
</el-card>
</el-tab-pane>
<el-tab-pane label="数据源" name="2">Config</el-tab-pane>
<el-tab-pane label="表单组件" name="3">Role</el-tab-pane>
<el-tab-pane label="Task" name="4">Task</el-tab-pane>
</el-tabs>
</div>
<div class="content" @drop="onDrop">
<VueFlow :min-zoom="0.01" ref="flowRef" v-model:nodes="nodes" v-model:edges="edges" fit-view-on-init
default-marker-color="#409EFF"
@node-click="logEvent('click', $event)"
@node-contextMenu="logEvent('contextmenu', $event)"
@dragover="onDragOver"
>
<Background :size="1" :gap="20" pattern-color="#BDBDBD" />
<template #node-line="lineNodeProps">
<LineNdoe v-bind="lineNodeProps"
@resize="resize"></LineNdoe>
</template>
</VueFlow>
</div>
<div class="rightPanel"></div>
</template>
<script setup lang="ts">
import { VueFlow, useVueFlow } from '@vue-flow/core';
import { Background } from '@vue-flow/background';
import { StarFilled } from '@element-plus/icons-vue';
import { onDragStart, onDrop, onDragOver } from './tool';
const leftPanelState = ref('1');
const nodes = ref([]);
const edges = ref([]);
const logEvent = async (eventname, event) => {
switch (eventname) {
case 'click':
console.log('click', event);
break;
case 'contextmenu':
console.log('contextmenu', event);
}
};
</script>
<style>
.leftPanel {
position: absolute;
top: 0;
left: 0;
width: 300px;
height: 100%;
border-right: 1px solid #409EFF;
}
.content {
position: absolute;
top: 0;
left: 320px;
width: calc(100% - 320px - 320px);
height: 100%;
}
.rightPanel {
position: absolute;
top: 0;
right: 0;
width: 300px;
height: 100%;
border-left: 1px solid #409EFF;
}
</style>

@ -0,0 +1,151 @@
<template>
<div :style="`transform: rotate(${props.data.options?.rotate || 0}deg);cursor: progress;`">
<div class="custom-node" :style="{width:props.width}">
</div>
<NodeResizer :color="color || '#000' " v-if="!props.isHideHandle && props.selected" @resize="resize" />
</div>
</template>
<script setup>
import { defineEmits, defineProps, ref, watch } from 'vue';
import { Handle, Position } from '@vue-flow/core';
import { NodeResizer } from '@vue-flow/node-resizer';
const props = defineProps({
color: {
type: String,
required: false
},
id: {
type: String,
required: true
},
isAlm: {
type: Boolean,
required: false
},
isHideHandle: {
type: Boolean,
required: false
},
selected: {
type: Boolean,
required: false
},
data: {
type: Object,
required: true
},
dimensions: {
type: Object,
required: true
},
deviceData: {
type: Object,
required: false
}
});
const emit = defineEmits(['resize']);
const resize = (e) => {
emit('resize', e, props.id);
};
</script>
<style scoped>
.custom-node {
width: 100%;
height: 100%;
}
.counter {
position: relative;
width: 100%;
height: 100%;
}
.tsj-div {
width: 100%;
display: flex;
position: relative;
align-items: center;
justify-self: center;
overflow: hidden;
}
.tsj {
height: 300px;
}
.icon-tishengji1 {
position: absolute;
left: 50%;
top: 0;
transform: translateX(-50%);
}
.deviceIdAndName {
color: #fff;
position: absolute;
left: 100%;
width: 50%;
top: 0%;
white-space: pre-wrap;
text-align: left;
}
.info {
position: absolute;
top: 50%;
right: 100%;
transform: translateY(-50%);
color: #000;
}
.value {
display: inline-block;
width: 2vw;
height: 0.4vw;
line-height: 0.4vw;
font-size: 0.4vw;
text-align: center;
vertical-align: top;
background-color: #00ff02;
}
.unit {
display: inline-block;
width: 0.6vw;
height: 0.4vw;
line-height: 0.4vw;
font-size: 0.4vw;
text-align: center;
vertical-align: top;
background-color: #01a098;
}
.alarmInfo {
position: absolute;
top: 50%;
left: 50%;
width: 100%;
transform: translate(-50%, -50%);
text-align: center;
font-size: 0.4vw;
line-height: 0.6vw;
white-space: nowrap;
animation: colourSwitching 0.5s infinite;
pointer-events: none;
}
@keyframes colourSwitching {
0% {
color: #ffff00;
}
50% {
color: #ff0000;
}
100% {
color: #ffff00;
}
}
</style>

@ -0,0 +1,72 @@
import { useVueFlow } from '@vue-flow/core';
import { ref, watch } from 'vue';
import { v4 as uuidv4 } from 'uuid';
const nodeType = ref('');
const { addNodes, screenToFlowCoordinate, onNodesInitialized, updateNode } = useVueFlow();
const getId = (type) => {
return `${type}_${uuidv4().replaceAll('-', '_')}`;
};
const onDragStart = (event, type) => {
if (event.dataTransfer) {
event.dataTransfer.setData('application/vueflow', type);
event.dataTransfer.effectAllowed = 'move';
}
nodeType.value = type;
document.addEventListener('drop', onDragEnd);
};
const onDragEnd = () => {
nodeType.value = null;
document.removeEventListener('drop', onDragEnd);
};
const getOption = (e) => {
return {
deviceType: e, deviceName: ''
};
};
const onDragOver = (event) => {
event.preventDefault();
if (nodeType.value) {
if (event.dataTransfer) {
event.dataTransfer.dropEffect = 'move';
}
}
};
const onDrop = (event) => {
console.log('onDrop', event);
const position = screenToFlowCoordinate({
x: event.clientX, y: event.clientY
});
const nodeId = getId(nodeType.value);
const newNode = {
id: nodeId, name: nodeType.value, type: nodeType.value, dimensions: {
width: 100, height: 60
}, position, data: { label: nodeId, options: getOption(nodeType.value), deviceData: {} }
};
const { off } = onNodesInitialized(() => {
updateNode(nodeId, (node) => ({
position: { x: node.position.x - node.dimensions.width / 2, y: node.position.y - node.dimensions.height / 2 }
}));
off();
});
addNodes(newNode);
};
export {
onDragStart, onDragEnd, onDrop, onDragOver
};

@ -190,7 +190,7 @@ const aaDel = () => {
const aaAddSubmit = async () => { const aaAddSubmit = async () => {
let formData = aaOperationForm.value; let formData = aaOperationForm.value;
let localData = pageData.value; let localData = pageData.value;
console.log(formData);
aaOperationFormVisible.value = false; aaOperationFormVisible.value = false;
}; };

@ -28,7 +28,7 @@ const exportConfig = (e) => {
let codeStr = template + script; let codeStr = template + script;
console.log(codeStr); console.log(codeStr);
const blob = new Blob([codeStr], { type: 'text/plain;charset=utf-8' }); const blob = new Blob([codeStr], { type: 'text/plain;charset=utf-8' });
// Download.saveAs(blob, Date.now() + '.vue'); Download.saveAs(blob, Date.now() + '.vue');
}; };

Loading…
Cancel
Save