update code

main
haha 2024-07-09 00:40:30 +08:00
parent 4bcf5f9fef
commit 7ddabba1e0
7 changed files with 246 additions and 78 deletions

View File

@ -1,12 +1,8 @@
<template>
<el-config-provider :locale="locale" :size="size">
<!-- 开启水印 -->
<el-watermark
v-if="watermarkEnabled"
:font="{ color: fontColor }"
:content="defaultSettings.watermarkContent"
class="wh-full"
>
<el-watermark v-if="watermarkEnabled" :font="{ color: fontColor }" :content="defaultSettings.watermarkContent"
class="wh-full">
<router-view />
</el-watermark>
<!-- 关闭水印 -->
@ -35,19 +31,32 @@ const fontColor = computed(() => {
});
</script>
<style lang="scss">
.router-link-active .el-menu-item{
.router-link-active .el-menu-item {
background-color: #EEF3FB;
border-right: solid 3px var(--el-color-primary);
}
.table-container .el-form-item--default {
margin-bottom: 0px !important;
}
.el-table__header{
th{
.el-table__header {
th {
background-color: #edebeb6e !important;
}
}
.el-pagination{
.el-pagination {
justify-content: end;
}
.scroll::-webkit-scrollbar {
width: 8px;
height: 8px;
}
.scroll::-webkit-scrollbar-thumb {
background-color: rgb(1, 169, 255);
border-radius: 4px;
}
</style>

View File

@ -1,27 +1,34 @@
import { RectNode, RectNodeModel, h } from "@logicflow/core"
import { getBytesLength } from '../util'
import { RectNode, RectNodeModel, h } from "@logicflow/core";
import { getBytesLength } from "../util";
class RedNodeModel extends RectNodeModel {
/**
* 初始化
*/
initNodeData(data) {
super.initNodeData(data)
super.initNodeData(data);
this.width = 200;
this.height = 30;
this.radius = 5;
this.text.x = this.x + 10;
this.defaultFill = data.fill||'rgb(253, 208, 162)'
this.defaultFill = data.fill || "rgb(253, 208, 162)";
const startOnlyAsTarget={
message:"开始结点只能连接结束节点",
validate: (sourceNode, targetNode, sourceAnchor, targetAnchor) => {
return sourceAnchor.type !== targetAnchor.type;
},
};
this.sourceRules.push(startOnlyAsTarget);
}
getData () {
const data = super.getData()
data.properties.ui = 'node-ai'
return data
getData() {
const data = super.getData();
data.properties.ui = "node-ai";
return data;
}
updateText(val) {
super.updateText(val)
super.updateText(val);
this.setAttributes();
}
/**
@ -32,10 +39,10 @@ class RedNodeModel extends RectNodeModel {
const dataStyle = this.properties.style || {};
if (this.isSelected) {
style.strokeWidth = Number(dataStyle.borderWidth) || 2;
style.stroke = dataStyle.borderColor || '#ff7f0e';
style.stroke = dataStyle.borderColor || "#ff7f0e";
} else {
style.strokeWidth = Number(dataStyle.borderWidth) || 1;
style.stroke = dataStyle.borderColor || '#999';
style.stroke = dataStyle.borderColor || "#999";
}
style.fill = dataStyle.backgroundColor || this.defaultFill;
return style;
@ -47,17 +54,19 @@ class RedNodeModel extends RectNodeModel {
const { x, y, id, width, height } = this;
const anchors = [
{
x: x ,
y: y+ height / 2,
x: x,
y: y - height / 2,
id: `${id}_right`,
type: "right"
type: "start",
className: "anchors-start",
},
{
x: x ,
y: y- height / 2,
x: x,
y: y + height / 2,
id: `${id}_left`,
type: "left"
}
type: "end",
className: "anchors-end",
},
];
return anchors;
}
@ -66,63 +75,64 @@ class RedNodeModel extends RectNodeModel {
*/
getOutlineStyle() {
const style = super.getOutlineStyle();
style.stroke = 'transparent';
style.hover.stroke = 'transparent';
style.stroke = "transparent";
style.hover.stroke = "transparent";
return style;
}
handleContextMenu(ev){
debugger
handleContextMenu(ev) {
debugger;
}
}
class RedNode extends RectNode {
/**
* 1.1.7版本后支持在view中重写锚点形状
* 重写锚点新增
*/
getAnchorShape(anchorData) {
const { x, y, type } = anchorData;
return h("rect", {
const { x, y, type, className } = anchorData;
if(type=="start"){
return h( "circle", {
cx: x - 0,
cy: y - 5,
r:6,
className: "custom-anchor " + className,
title:'开始'
});
}
return h( "rect", {
x: x - 5,
y: y - 5,
width: 10,
height: 10,
className: 'custom-anchor'
className: "custom-anchor " + className,
title:'结束'
});
}
getShape() {
const {
text,
x,
y,
width,
height,
radius
} = this.props.model;
const style = this.props.model.getNodeStyle()
const { text, x, y, width, height, radius } = this.props.model;
const style = this.props.model.getNodeStyle();
return h(
'g',
"g",
{
className: 'lf-ai-node'
className: "lf-ai-node",
},
[
h('rect', {
h("rect", {
...style,
x: x - width / 2,
y: y - height / 2,
width,
height,
rx: radius,
ry: radius
})
ry: radius,
}),
]
)
);
}
}
export default {
type: 'ai-node',
type: "ai-node",
model: RedNodeModel,
view: RedNode
}
view: RedNode,
};

View File

@ -109,7 +109,7 @@
</div>
</template>
<script lang='ts' setup>
<script setup>
import detailFlow from './detailFlow.vue';
import ConnApi from '@/api/connection'
const router = useRouter();

View File

@ -77,16 +77,29 @@
</div>
<div class="row">
<span class="sp-label">输入参数:</span>
<span class="sp-text">
<el-input v-model="selNode.info.inputParams" type="textarea" style="width:100%;"
:rows="4" @input="doFlowInput" />
<span class="sp-text sp-paramter scroll" @click="doEdit(selNode.info,'输入参数','i')">
<span v-for="(it,idx) in objToArr(selNode.info.inputParams) " :key="idx" class="param-item">
<span>{{ it.key }}:</span>
<span>{{ it.value }}</span>
</span>
</span>
</div>
<div class="row" style="margin-top:4px;">
<span class="sp-label">输出参数:</span>
<span class="sp-text">
<el-input v-model="selNode.info.outputParams" type="textarea" style="width:100%;"
:rows="4" @input="doFlowInput" />
<span class="sp-text sp-paramter scroll" @click="doEdit(selNode.info,'输出参数','o')">
<span v-for="(it,idx) in objToArr(selNode.info.outputParams) " :key="idx" class="param-item">
<span>{{ it.key }}:</span>
<span>{{ it.value }}</span>
</span>
</span>
</div>
<div class="row" style="margin-top:4px;">
<span class="sp-label">处理参数:</span>
<span class="sp-text sp-paramter scroll" @click="doEdit(selNode.info,'处理参数','p')">
<span v-for="(it,idx) in objToArr(selNode.info.process) " :key="idx" class="param-item">
<span>{{ it.key }}:</span>
<span>{{ it.value }}</span>
</span>
</span>
</div>
</div>
@ -97,6 +110,7 @@
<el-button type="primary" @click="doSave"></el-button>
<el-button @click="doCancel"></el-button>
</el-card>
<EditParamDlg ref="editDlg" @success="doEditSuccess"/>
</div>
</template>
@ -104,6 +118,7 @@
import nodePanel from './nodePanel.vue'
import editFlow from './editFlow.vue'
import ConnApi from '@/api/connection'
import EditParamDlg from './editParamDlg.vue'
const router = useRouter();
const uploadForm = ref(ElForm)
const route = useRoute()
@ -114,9 +129,11 @@ const upForm = reactive({
connection_label: '',
connection_desc: ''
});
const editDlg=ref()
const info = reactive({
connInfo: null,
nodes: [],
editObj:null,
})
const selNode = reactive({
info: null
@ -131,8 +148,48 @@ const doFlowInput = () => {
} else {
tmps[0].inputParams = selNode.info.inputParams;
tmps[0].outputParams = selNode.info.outputParams;
tmps[0].process = selNode.info.process;
}
}
const doEditSuccess=(obj)=>{
let t=info.editObj.type;
if(t=='i'){
selNode.info.inputParams=obj;
}
if(t=='o'){
selNode.info.outputParams=obj;
}
if(t=='p'){
selNode.info.process=obj;
}
let tmps = info.nodes.filter(d => d.id == selNode.info.id);
if (tmps.length == 0) {
info.nodes.push(selNode.info)
} else {
tmps[0].inputParams = selNode.info.inputParams;
tmps[0].outputParams = selNode.info.outputParams;
tmps[0].process = selNode.info.process;
}
};
const doEdit=(obj,title,t)=>{
info.editObj={
obj:obj,
title:title,
type:t
}
editDlg.value.showDialog({
obj:t=='i'?obj.inputParams:t=='o'?obj.outputParams:obj.process,
title:title
});
}
const objToArr=(obj,t)=>{
let arr=[];
for(let k in obj){
arr.push({key:k,value:obj[k]})
}
return arr;
}
const doUpdateNode = (data) => {
if (ndPanel && ndPanel.value) {
ndPanel.value.updateNode(data)
@ -147,6 +204,7 @@ const doNodeClick = (node) => {
} else {
selNode.info.inputParams = tmps[0].inputParams;
selNode.info.outputParams = tmps[0].outputParams;
selNode.info.process = tmps[0].process;
}
}
else {
@ -185,6 +243,22 @@ onMounted(() => {
align-items: center;
font-weight: bold;
}
:deep(.anchors-end){
fill:red;
}
:deep(.anchors-start){
fill:green;
}
.sp-paramter{
height: 60px;
border:solid 1px #409EFF;
overflow-y: auto;
padding:4px;
cursor: pointer;
.param-item{
display:block;
}
}
}
.card-footer {

View File

@ -4,7 +4,7 @@
</div>
</template>
<script lang='ts' setup>
<script setup>
import LogicFlow from '@logicflow/core';
//
import '@logicflow/core/dist/style/index.css';
@ -71,6 +71,9 @@ const initEvent=(lf)=>{
nodePropKey.value++
doUpdateState()
});
lf.on("connection:not-allowed",(a,b,c)=>{
ElMessage.error("开始节点只能连接结束节点!");
});
lf.on("node:delete",data=>{
if(data.data.text.value=="目标绘图"){
ElMessage.error("目标绘图节点不能删除");
@ -81,7 +84,7 @@ const initEvent=(lf)=>{
}
doUpdateState()
});
lf.on("node:contextmenu",(d,e,p)=>{
lf.on("node:contextmenu",(d)=>{
if(d.data.text.value=="目标绘图"){
setTimeout(()=>{
document.querySelector(".lf-menu").style.display="none";

View File

@ -0,0 +1,67 @@
<template>
<el-dialog v-model="dialog.show" :title="dialog.title"
:close-on-press-escape="false"
:close-on-click-modal="false" align-center append-to-body width="600px"
>
<div class="scroll " style="max-height: 400px;overflow-y: auto;overflow-x: hidden;">
<el-row v-for="(it,idx) in dialog.attrs" :key="idx" style="margin-bottom:4px;" gutter="2">
<el-col :span="8">
<el-input v-model="it.key" @input="inputKey"/>
</el-col>
<el-col :span="16">
<el-input v-model="it.value"/>
</el-col>
</el-row>
</div>
<template #footer>
<div style="text-align: center">
<el-button type="primary" @click="doOk"></el-button>
<el-button @click="doCancel"></el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
const emit=defineEmits("success");
const dialog = reactive({
show: false,
title: '',
editObj: null,
attrs: []
})
const doOk = () => {
let obj={};
dialog.attrs.forEach(d=>{
if(d.key && d.value){
obj[d.key]=d.value;
}
});
emit("success",obj);
dialog.show=false;
}
const doCancel=()=>{
dialog.show=false;
}
const showDialog = (opt) => {
dialog.show = true;
dialog.editObj = opt.obj;
dialog.title = opt.title;
dialog.attrs = [];
for (let k in opt.obj) {
dialog.attrs.push({ key: k, value: opt.obj[k] });
}
dialog.attrs.push({key:'',value:''});
}
const inputKey=(a,b)=>{
if(dialog.attrs[dialog.attrs.length-1].key){
dialog.attrs.push({key:'',value:''});
}
};
defineExpose({
showDialog
})
</script>
<style scoped lang='less'></style>

View File

@ -84,12 +84,12 @@ const list2 = reactive([
const updateNode = (nodes) => {
let nds = nodes.nodes.map(d => d.properties.node);
list2.forEach(d => {
d.show = nds.indexOf(d.id) == -1
})
list1.forEach(d => {
d.show = nds.indexOf(d.id) == -1
})
if(info.all){
info.all.forEach(d => {
d.show = nds.indexOf(d.id) == -1
});
}
}
const doEdit=(nd)=>{
@ -98,6 +98,7 @@ const doEdit=(nd)=>{
if(tmps.length>0){
tmps[0].inputParams=nd.inputParams;
tmps[0].outputParams=nd.inputParams;
tmps[0].process=nd.process;
}
}
defineExpose({
@ -111,8 +112,12 @@ const initData = () => {
it.show = true;
it.text = it.operator_name;
it.id = it.operator_id
it.inputParams="";
it.outputParams="";
it.inputParams={
a:10,b:20,c:30,d:40,e:50,
a2:10,b2:20,c2:30,d2:40,e2:50,
};
it.outputParams={};
it.process={};
return it;
});
info.all=tmps;