姜玉琦 2024-07-10 02:00:35 +08:00
commit 31207a7fa5
5 changed files with 175 additions and 63 deletions

View File

@ -1,18 +1,26 @@
import { PolylineEdge, PolylineEdgeModel } from "@logicflow/core";
class FlowLinkModel extends PolylineEdgeModel {
getEdgeStyle() {
getEdgeStyle() {
const style = super.getEdgeStyle();
style.strokeWidth = 1;
style.stroke = this.isSelected ? '#ff7f0e' : '#999';
style.stroke = this.isSelected ? "#ff7f0e" : "#999";
return style;
}
setAttributes() {
this.isAnimation = true;
}
getEdgeAnimationStyle() {
const style = super.getEdgeAnimationStyle();
style.strokeDasharray = "5 5";
style.animationDuration = "60s";
return style;
}
}
class FlowLink extends PolylineEdge {}
export default {
type: 'ai-link',
type: "ai-link",
view: FlowLink,
model: FlowLinkModel
}
model: FlowLinkModel,
};

View File

@ -8,7 +8,7 @@ class RedNodeModel extends RectNodeModel {
initNodeData(data) {
super.initNodeData(data);
this.width = 200;
this.height = 30;
this.height = 36;
this.radius = 5;
this.text.x = this.x + 10;
this.defaultFill = data.fill || "rgb(253, 208, 162)";
@ -51,7 +51,7 @@ class RedNodeModel extends RectNodeModel {
* 重写定义锚点
*/
getDefaultAnchor() {
const { x, y, id, width, height } = this;
const { x, y, id, width, height } = this;
const anchors = [
{
x: x,
@ -91,14 +91,28 @@ class RedNode extends RectNode {
getAnchorShape(anchorData) {
const { x, y, type, className } = anchorData;
if(type=="start"){
return h("svg",{
viewBox:"0 0 1139 1024" ,
width:20,
height:20,
x: x - 8,
y: y - 16,
},
h("path",{
fill:"#0bdd0b",
d:"M0 512.007221a511.992418 511.992418 0 1 1 511.631351 511.992418A512.353484 512.353484 0 0 1 0 512.007221z m730.437702 120.235173c0-97.126911-62.464519-131.06717-146.593034-161.75783l-66.797318-25.996794c-53.437855-20.941862-87.378114-38.273058-87.378114-77.629316 0-45.133323 36.106659-70.046917 93.155179-70.046917a227.471949 227.471949 0 0 1 139.732769 54.521054l57.04852-72.213317a298.963132 298.963132 0 0 0-196.059156-72.213317c-121.318373 0-206.530087 63.547719-206.530086 164.285296 0 84.128514 67.880518 128.900771 144.426634 157.425031l67.880518 27.079994c49.105056 18.775462 86.294914 36.106659 86.294914 84.489581s-36.106659 74.379717-100.737578 74.379717a269.355672 269.355672 0 0 1-173.673027-70.046918L285.242602 722.50904a344.096456 344.096456 0 0 0 225.305549 81.962115c136.844236-0.361067 219.88955-74.740783 219.889551-172.228761z"
}),
)
/*
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,
@ -106,7 +120,19 @@ class RedNode extends RectNode {
height: 10,
className: "custom-anchor " + className,
title:'结束'
});
});*/
return h("svg",{
viewBox:"0 0 1139 1024" ,
width:24,
height:24,
x: x - 10,
y: y - 8,
},
h("path",{
fill:"#ffb01f",
d:"M810.667 128H213.333C166.187 128 128 166.187 128 213.333v597.334C128 857.813 166.187 896 213.333 896h597.334C857.813 896 896 857.813 896 810.667V213.333C896 166.187 857.813 128 810.667 128zM640 384H469.333v85.333H640v85.334H469.333V640H640v85.333H384V298.667h256V384z"
}),
)
}
getShape() {
const { text, x, y, width, height, radius } = this.props.model;

View File

@ -4,7 +4,7 @@
<template #header>
互联信息</template>
<el-form ref="uploadForm" :model="upForm" label-width="120">
<el-form ref="editForm" :model="upForm" :rules="upRules" label-width="120">
<el-row>
<el-col :span="12">
<el-form-item label="模型名称">
@ -19,19 +19,19 @@
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="互联名称">
<el-form-item label="互联名称" prop="connection_name">
<el-input v-model="upForm.connection_name" placeholder="请输入互联名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="标签">
<el-form-item label="标签" prop="connection_label">
<el-input v-model="upForm.connection_label" placeholder="请输入标签" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="互联说明">
<el-form-item label="互联说明" prop="connection_desc">
<el-input v-model="upForm.connection_desc" type="textarea" style="width:100%;" :rows="4"
placeholder="请输入互联说明" />
</el-form-item>
@ -77,8 +77,9 @@
</div>
<div class="row">
<span class="sp-label">输入参数:</span>
<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 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>
@ -86,8 +87,9 @@
</div>
<div class="row" style="margin-top:4px;">
<span class="sp-label">输出参数:</span>
<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 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>
@ -95,8 +97,8 @@
</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 class="sp-text sp-paramter scroll" @click="doEdit(selNode.info, '处理参数', 'p')">
<span v-for="(it, idx) in objToArr(selNode.info.processParams) " :key="idx" class="param-item">
<span>{{ it.key }}:</span>
<span>{{ it.value }}</span>
</span>
@ -110,7 +112,7 @@
<el-button type="primary" @click="doSave"></el-button>
<el-button @click="doCancel"></el-button>
</el-card>
<EditParamDlg ref="editDlg" @success="doEditSuccess"/>
<EditParamDlg ref="editDlg" @success="doEditSuccess" />
</div>
</template>
@ -120,7 +122,7 @@ import editFlow from './editFlow.vue'
import ConnApi from '@/api/connection'
import EditParamDlg from './editParamDlg.vue'
const router = useRouter();
const uploadForm = ref(ElForm)
const editForm = ref(ElForm)
const route = useRoute()
const upForm = reactive({
model_name: '',
@ -129,11 +131,18 @@ const upForm = reactive({
connection_label: '',
connection_desc: ''
});
const editDlg=ref()
const upRules = computed(() => {
return {
connection_name: [{ required: true, trigger: "blur", message: "请输入互联名称", },],
connection_label: [{ required: true, trigger: "blur", message: "请输入标签", },],
connection_desc: [{ required: true, trigger: "blur", message: "请输入互联说明", },],
}
});
const editDlg = ref()
const info = reactive({
connInfo: null,
nodes: [],
editObj:null,
editObj: null,
})
const selNode = reactive({
info: null
@ -148,20 +157,20 @@ const doFlowInput = () => {
} else {
tmps[0].inputParams = selNode.info.inputParams;
tmps[0].outputParams = selNode.info.outputParams;
tmps[0].process = selNode.info.process;
tmps[0].processParams = selNode.info.processParams;
}
}
const doEditSuccess=(obj)=>{
let t=info.editObj.type;
if(t=='i'){
selNode.info.inputParams=obj;
const doEditSuccess = (obj) => {
let t = info.editObj.type;
if (t == 'i') {
selNode.info.inputParams = obj;
}
if(t=='o'){
selNode.info.outputParams=obj;
if (t == 'o') {
selNode.info.outputParams = obj;
}
if(t=='p'){
selNode.info.process=obj;
if (t == 'p') {
selNode.info.processParams = obj;
}
let tmps = info.nodes.filter(d => d.id == selNode.info.id);
if (tmps.length == 0) {
@ -169,24 +178,24 @@ const doEditSuccess=(obj)=>{
} else {
tmps[0].inputParams = selNode.info.inputParams;
tmps[0].outputParams = selNode.info.outputParams;
tmps[0].process = selNode.info.process;
tmps[0].processParams = selNode.info.processParams;
}
};
const doEdit=(obj,title,t)=>{
info.editObj={
obj:obj,
title:title,
type:t
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
obj: t == 'i' ? obj.inputParams : t == 'o' ? obj.outputParams : obj.processParams,
title: title
});
}
const objToArr=(obj,t)=>{
let arr=[];
for(let k in obj){
arr.push({key:k,value:obj[k]})
const objToArr = (obj, t) => {
let arr = [];
for (let k in obj) {
arr.push({ key: k, value: obj[k] })
}
return arr;
}
@ -204,7 +213,7 @@ const doNodeClick = (node) => {
} else {
selNode.info.inputParams = tmps[0].inputParams;
selNode.info.outputParams = tmps[0].outputParams;
selNode.info.process = tmps[0].process;
selNode.info.processParams = tmps[0].processParams;
}
}
else {
@ -215,7 +224,66 @@ const doInitLf = (o) => {
lf.value = o.value
}
const doSave = () => {
router.replace({ path: "/connection/index" })
let flowData = lf.value.getGraphData();
if (flowData.nodes.length < 3) {
ElMessage.error("请绘制算子互联流程图!");
return;
}
debugger
let isNoConnect=false;
let nodeObj={};
let operator_list=[];
flowData.nodes.forEach(n=>{
nodeObj[n.id]=n.properties.data;
let node=info.nodes.filter(nd=>nd.id==n.properties.data.id);
let oper={
operator_id:n.properties.data.id,
parameters:{}
}
if(node.length>0){
oper.parameters.inputParams=node[0].inputParams;
oper.parameters.outputParams=node[0].outputParams;
oper.parameters.processParams=node[0].processParams;
}
operator_list.push(oper);
let tmps=flowData.edges.filter(e=>e.sourceNodeId==n.id||e.targetNodeId==n.id);
if(tmps.length==0){
isNoConnect=true;
}
});
if(isNoConnect){
ElMessage.error("请在流程图中连接各个算子!");
return;
}
let operator_connection_list=[];
flowData.edges.forEach(e=>{
operator_connection_list.push({
start_oper_id:nodeObj[e.sourceNodeId].id,
end_oper_id:nodeObj[e.targetNodeId].id,
});
});
editForm.value?.validate(valid => {
if (valid) {
let postData={
connection_name:upForm.connection_name,
connection_label:upForm.connection_label,
connection_desc:upForm.connection_desc,
operator_list:operator_list,
operator_connection_list:operator_connection_list,
operator_connection_nodes:flowData.nodes,
operator_connection_edges:flowData.edges
};
ConnApi.add(postData).then(d=>{
if(d.data.code==0){
ElMessage.success("增加模型成功!");
router.replace({ path: "/connection/index" })
}
});
}
});
}
const doCancel = () => {
router.replace({ path: "/connection/index" })
@ -243,20 +311,24 @@ onMounted(() => {
align-items: center;
font-weight: bold;
}
:deep(.anchors-end){
fill:red;
:deep(.anchors-end) {
fill: red;
}
:deep(.anchors-start){
fill:green;
:deep(.anchors-start) {
fill: green;
}
.sp-paramter{
.sp-paramter {
height: 60px;
border:solid 1px #409EFF;
border: solid 1px #409EFF;
overflow-y: auto;
padding:4px;
padding: 4px;
cursor: pointer;
.param-item{
display:block;
.param-item {
display: block;
}
}
}

View File

@ -99,15 +99,17 @@ const doUpdateState=()=>{
//nodePanel.value.updateNode(lf.value.getGraphData());
emit("updateNode",lf.value.getGraphData())
}
defineExpose({
doEdit,
})
const getFLowData=()=>{
return lf.value.getGraphData();
}
onMounted(() => {
const logicFlow = new LogicFlow({
...config,
container: flow.value
})
lf.value = logicFlow
logicFlow.setDefaultEdgeType("ai-link");
RegisteMenu(logicFlow)
initEvent(logicFlow);
emit("initLf",lf);
@ -141,8 +143,12 @@ onMounted(() => {
]
})
doUpdateState();
doUpdateState();
});
defineExpose({
doEdit,
getFLowData
})
</script>
<style scoped lang='scss'>
.flow-demo1 {

View File

@ -98,7 +98,7 @@ const doEdit=(nd)=>{
if(tmps.length>0){
tmps[0].inputParams=nd.inputParams;
tmps[0].outputParams=nd.inputParams;
tmps[0].process=nd.process;
tmps[0].processParams=nd.processParams;
}
}
defineExpose({
@ -117,7 +117,7 @@ const initData = () => {
a2:10,b2:20,c2:30,d2:40,e2:50,
};
it.outputParams={};
it.process={};
it.processParams={};
return it;
});
info.all=tmps;