Showing
2 changed files
with
105 additions
and
20 deletions
| ... | @@ -23,7 +23,6 @@ | ... | @@ -23,7 +23,6 @@ |
| 23 | :toolbarButtonHandler="toolbarButtonHandler" | 23 | :toolbarButtonHandler="toolbarButtonHandler" |
| 24 | > | 24 | > |
| 25 | <!-- :activityConfig="state.activityConfig" --> | 25 | <!-- :activityConfig="state.activityConfig" --> |
| 26 | - <!-- @click-node="onClickNode" --> | ||
| 27 | <!-- 左侧菜单 --> | 26 | <!-- 左侧菜单 --> |
| 28 | <template v-slot:menu> | 27 | <template v-slot:menu> |
| 29 | <!-- <vue-flow-edit-menu-group label="活动节点" value> | 28 | <!-- <vue-flow-edit-menu-group label="活动节点" value> |
| ... | @@ -120,7 +119,14 @@ | ... | @@ -120,7 +119,14 @@ |
| 120 | </el-form-item> | 119 | </el-form-item> |
| 121 | <el-form-item v-if="state.attr_radio === '基础属性'" prop=""> | 120 | <el-form-item v-if="state.attr_radio === '基础属性'" prop=""> |
| 122 | <div slot="label"> | 121 | <div slot="label"> |
| 123 | - 字段权限 <span style="color: red;">*</span> | 122 | + <div style="display: flex; align-items: center; justify-content: space-between;width:266px; margin-bottom: 15px;"> |
| 123 | + <div> | ||
| 124 | + 字段权限 <span style="color: red;">*</span> | ||
| 125 | + </div> | ||
| 126 | + <div> | ||
| 127 | + <el-input v-model="state.search_auth_value" @input="onSearchAuthInput" size="small" placeholder="搜索" /> | ||
| 128 | + </div> | ||
| 129 | + </div> | ||
| 124 | </div> | 130 | </div> |
| 125 | <el-row | 131 | <el-row |
| 126 | style="width: 100%; background-color: #f0f1f4; padding-left: 10px;" | 132 | style="width: 100%; background-color: #f0f1f4; padding-left: 10px;" |
| ... | @@ -150,9 +156,9 @@ | ... | @@ -150,9 +156,9 @@ |
| 150 | v-for="(field, index) in state.field_auths" | 156 | v-for="(field, index) in state.field_auths" |
| 151 | :key="index" | 157 | :key="index" |
| 152 | style="width: 100%; padding-left: 10px;" | 158 | style="width: 100%; padding-left: 10px;" |
| 153 | - > | 159 | + > |
| 154 | - <el-col :span="12" style="">{{ field.name }}</el-col> | 160 | + <el-col v-if="field.show" :span="12">{{ field.name }}</el-col> |
| 155 | - <el-col :span="6" style="padding-left: 5px;" | 161 | + <el-col v-if="field.show" :span="6" style="padding-left: 5px;" |
| 156 | ><el-checkbox | 162 | ><el-checkbox |
| 157 | v-model="field.visible.checked" | 163 | v-model="field.visible.checked" |
| 158 | :disabled="field.visible.disabled" | 164 | :disabled="field.visible.disabled" |
| ... | @@ -160,7 +166,7 @@ | ... | @@ -160,7 +166,7 @@ |
| 160 | size="large" | 166 | size="large" |
| 161 | @change="onAuthVisibleChange(field, index)" | 167 | @change="onAuthVisibleChange(field, index)" |
| 162 | /></el-col> | 168 | /></el-col> |
| 163 | - <el-col :span="6" style="padding-left: 5px;" | 169 | + <el-col v-if="field.show" :span="6" style="padding-left: 5px;" |
| 164 | ><el-checkbox | 170 | ><el-checkbox |
| 165 | v-model="field.editable.checked" | 171 | v-model="field.editable.checked" |
| 166 | :disabled="field.editable.disabled" | 172 | :disabled="field.editable.disabled" |
| ... | @@ -453,6 +459,7 @@ export default { | ... | @@ -453,6 +459,7 @@ export default { |
| 453 | img: 'https://cdn.ipadbiz.cn/oa/crowd-node.svg', | 459 | img: 'https://cdn.ipadbiz.cn/oa/crowd-node.svg', |
| 454 | }, | 460 | }, |
| 455 | }, | 461 | }, |
| 462 | + search_auth_value: '', | ||
| 456 | dialogUserFormVisible: false, | 463 | dialogUserFormVisible: false, |
| 457 | activeName: 'node', | 464 | activeName: 'node', |
| 458 | attr_radio: '基础属性', | 465 | attr_radio: '基础属性', |
| ... | @@ -482,6 +489,7 @@ export default { | ... | @@ -482,6 +489,7 @@ export default { |
| 482 | checked: false, | 489 | checked: false, |
| 483 | disabled: true, | 490 | disabled: true, |
| 484 | }, | 491 | }, |
| 492 | + show: true, | ||
| 485 | }, | 493 | }, |
| 486 | { | 494 | { |
| 487 | name: '字段2', | 495 | name: '字段2', |
| ... | @@ -493,6 +501,7 @@ export default { | ... | @@ -493,6 +501,7 @@ export default { |
| 493 | checked: false, | 501 | checked: false, |
| 494 | disabled: false, | 502 | disabled: false, |
| 495 | }, | 503 | }, |
| 504 | + show: true, | ||
| 496 | }, | 505 | }, |
| 497 | { | 506 | { |
| 498 | name: '字段3', | 507 | name: '字段3', |
| ... | @@ -504,6 +513,7 @@ export default { | ... | @@ -504,6 +513,7 @@ export default { |
| 504 | checked: false, | 513 | checked: false, |
| 505 | disabled: false, | 514 | disabled: false, |
| 506 | }, | 515 | }, |
| 516 | + show: true, | ||
| 507 | }, | 517 | }, |
| 508 | ], | 518 | ], |
| 509 | }) | 519 | }) |
| ... | @@ -634,6 +644,16 @@ export default { | ... | @@ -634,6 +644,16 @@ export default { |
| 634 | }) | 644 | }) |
| 635 | } | 645 | } |
| 636 | } | 646 | } |
| 647 | + | ||
| 648 | + const onSearchAuthInput = (val: string) => { | ||
| 649 | + state.field_auths.forEach((ele) => { | ||
| 650 | + if (ele.name.indexOf(val) > -1) { | ||
| 651 | + ele.show = true; | ||
| 652 | + } else { | ||
| 653 | + ele.show = false; | ||
| 654 | + } | ||
| 655 | + }) | ||
| 656 | + } | ||
| 637 | /******************* END *******************/ | 657 | /******************* END *******************/ |
| 638 | 658 | ||
| 639 | /****** 用户选择控件弹框 ******/ | 659 | /****** 用户选择控件弹框 ******/ |
| ... | @@ -689,16 +709,23 @@ export default { | ... | @@ -689,16 +709,23 @@ export default { |
| 689 | } | 709 | } |
| 690 | 710 | ||
| 691 | /** | 711 | /** |
| 692 | - * 点击节点回调 | 712 | + * 单击节点回调 |
| 693 | * | 713 | * |
| 694 | * @param {Event} e - The event object representing the click event. | 714 | * @param {Event} e - The event object representing the click event. |
| 695 | */ | 715 | */ |
| 696 | function onClickNode(e: myEvent) { | 716 | function onClickNode(e: myEvent) { |
| 697 | - const model = G6.Util.clone(e.item.get('model')) | 717 | + const model = G6.Util.clone(e.item.get('model')); // 节点的基本属性 |
| 698 | model.style = model.style || {} | 718 | model.style = model.style || {} |
| 699 | model.labelCfg = model.labelCfg || { style: {} } | 719 | model.labelCfg = model.labelCfg || { style: {} } |
| 700 | 720 | ||
| 701 | - model.data = model.data ? model.data : {} | 721 | + model.data = model.data ? model.data : {}; |
| 722 | + // 查询节点的属性 | ||
| 723 | + // 节点名称 state.node_name,节点负责人 state.userTags,基础属性 state.field_auths,更多属性 state.more_attr | ||
| 724 | + console.warn('节点名称', state.node_name); | ||
| 725 | + console.warn('节点负责人', state.userTags); | ||
| 726 | + console.warn('基础属性', state.field_auths); | ||
| 727 | + console.warn('更多属性', state.more_attr); // 非结束节点才显示 | ||
| 728 | + | ||
| 702 | state.detailModel = model | 729 | state.detailModel = model |
| 703 | 730 | ||
| 704 | // 判断是否是流程节点 | 731 | // 判断是否是流程节点 |
| ... | @@ -978,19 +1005,17 @@ export default { | ... | @@ -978,19 +1005,17 @@ export default { |
| 978 | * @param {type} type - The type of the event. | 1005 | * @param {type} type - The type of the event. |
| 979 | */ | 1006 | */ |
| 980 | function handleAfterAdd(model: myObj, type: string) { | 1007 | function handleAfterAdd(model: myObj, type: string) { |
| 981 | - // console.log('handleAfterAdd', model); | ||
| 982 | if (type === 'node') { | 1008 | if (type === 'node') { |
| 983 | console.log(`新增节点`) | 1009 | console.log(`新增节点`) |
| 984 | // TODO: 测试更新ID,窗口变化时连接线会消失,但是只有单独操作一次的时候才会发生,如果多次生成连接线不会发生。 | 1010 | // TODO: 测试更新ID,窗口变化时连接线会消失,但是只有单独操作一次的时候才会发生,如果多次生成连接线不会发生。 |
| 985 | model.id = String(new Date().getTime()); | 1011 | model.id = String(new Date().getTime()); |
| 986 | editor.updateModel(model); | 1012 | editor.updateModel(model); |
| 1013 | + state.data.nodes = editor.editorState.graph.save().nodes | ||
| 987 | } | 1014 | } |
| 988 | if (type === 'edge') { | 1015 | if (type === 'edge') { |
| 989 | console.log(`新增连接线`) | 1016 | console.log(`新增连接线`) |
| 1017 | + state.data.edges = editor.editorState.graph.save().edges | ||
| 990 | } | 1018 | } |
| 991 | - | ||
| 992 | - state.data.nodes = editor.editorState.graph.save().nodes | ||
| 993 | - state.data.edges = editor.editorState.graph.save().edges | ||
| 994 | } | 1019 | } |
| 995 | 1020 | ||
| 996 | function onClickCanvas(e: myEvent) { | 1021 | function onClickCanvas(e: myEvent) { |
| ... | @@ -1079,12 +1104,19 @@ export default { | ... | @@ -1079,12 +1104,19 @@ export default { |
| 1079 | } | 1104 | } |
| 1080 | ) | 1105 | ) |
| 1081 | .then(() => { | 1106 | .then(() => { |
| 1082 | - ElMessage({ | 1107 | + // 检查路径有效性 |
| 1083 | - type: 'success', | 1108 | + // let { edges } = editor.editorState.graph.save() |
| 1084 | - message: '保存流程图成功', | 1109 | + const paths = []; |
| 1085 | - }) | 1110 | + findPathsToEndNode(edges, 'start-node', [], paths); |
| 1086 | - console.log(nodes) | 1111 | + console.log(paths); // 输出满足条件的路径结果数组 |
| 1087 | - console.log(edges) | 1112 | + if (paths.length) { |
| 1113 | + ElMessage({ | ||
| 1114 | + type: 'success', | ||
| 1115 | + message: '保存流程图成功', | ||
| 1116 | + }); | ||
| 1117 | + } else { | ||
| 1118 | + ElNotification.error('缺少一条从开始节点到结束节点的完整流程!'); | ||
| 1119 | + } | ||
| 1088 | }) | 1120 | }) |
| 1089 | .catch(() => { | 1121 | .catch(() => { |
| 1090 | }); | 1122 | }); |
| ... | @@ -1106,6 +1138,38 @@ export default { | ... | @@ -1106,6 +1138,38 @@ export default { |
| 1106 | return map | 1138 | return map |
| 1107 | } | 1139 | } |
| 1108 | 1140 | ||
| 1141 | + /** | ||
| 1142 | + * 查找从开始节点到结束节点的完整路径 | ||
| 1143 | + * 1. 如果当前节点为 'end-node',表示找到了一条完整的路径,将当前路径 currentPath 添加到结果数组 paths 中。 | ||
| 1144 | + * 2. 使用 filter 方法找到源属性为当前节点的子对象,并将它们存储在 nextObjs 数组中。 | ||
| 1145 | + * 3. 如果 nextObjs 数组为空,表示没有符合条件的子对象,直接返回。 | ||
| 1146 | + * 4. 遍历 nextObjs 数组,依次将每个子对象添加到 currentPath 中,然后递归调用 findPathsToEndNode 函数,继续查找下一个节点。 | ||
| 1147 | + * 5. 在递归调用结束后,将最后添加的子对象从 currentPath 中移除,以便尝试其他可能的路径。 | ||
| 1148 | + * 最终,将空的结果数组 paths 传递给递归函数,并在递归结束后打印结果数组 paths,即可得到满足条件的所有路径的数组。 | ||
| 1149 | + * 函数将返回一个包含两个子数组的结果数组,每个子数组代表一条满足条件的路径。如果没有找到满足条件的路径,结果数组将为空 []。 | ||
| 1150 | + * @param data 数据数组 | ||
| 1151 | + * @param currentNode 当前节点 | ||
| 1152 | + * @param currentPath 当前路径 | ||
| 1153 | + * @param paths 结果数组 | ||
| 1154 | + */ | ||
| 1155 | + function findPathsToEndNode(data, currentNode, currentPath, paths) { | ||
| 1156 | + if (currentNode === 'end-node') { | ||
| 1157 | + paths.push(currentPath.slice()); // 将当前路径添加到结果数组中 | ||
| 1158 | + return; | ||
| 1159 | + } | ||
| 1160 | + | ||
| 1161 | + const nextObjs = data.filter(obj => obj.source === currentNode); | ||
| 1162 | + if (nextObjs.length === 0) { | ||
| 1163 | + return; | ||
| 1164 | + } | ||
| 1165 | + | ||
| 1166 | + for (const nextObj of nextObjs) { | ||
| 1167 | + currentPath.push(nextObj); | ||
| 1168 | + findPathsToEndNode(data, nextObj.target, currentPath, paths); | ||
| 1169 | + currentPath.pop(); | ||
| 1170 | + } | ||
| 1171 | + } | ||
| 1172 | + | ||
| 1109 | return { | 1173 | return { |
| 1110 | state, | 1174 | state, |
| 1111 | rules, | 1175 | rules, |
| ... | @@ -1134,6 +1198,7 @@ export default { | ... | @@ -1134,6 +1198,7 @@ export default { |
| 1134 | onAuthEditableChange, | 1198 | onAuthEditableChange, |
| 1135 | onAuthAllChange, | 1199 | onAuthAllChange, |
| 1136 | onAuthAllEditChange, | 1200 | onAuthAllEditChange, |
| 1201 | + onSearchAuthInput, | ||
| 1137 | 1202 | ||
| 1138 | openUserForm, | 1203 | openUserForm, |
| 1139 | onCloseUserView, | 1204 | onCloseUserView, | ... | ... |
| 1 | /* | 1 | /* |
| 2 | * @Date: 2023-10-27 09:29:48 | 2 | * @Date: 2023-10-27 09:29:48 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2023-11-17 15:08:51 | 4 | + * @LastEditTime: 2023-11-20 13:54:00 |
| 5 | * @FilePath: /vue-flow-editor/doc/data.js | 5 | * @FilePath: /vue-flow-editor/doc/data.js |
| 6 | * @Description: 初始化结构,数据都是固定的 | 6 | * @Description: 初始化结构,数据都是固定的 |
| 7 | */ | 7 | */ |
| ... | @@ -23,6 +23,14 @@ export const AppData = { | ... | @@ -23,6 +23,14 @@ export const AppData = { |
| 23 | desc: '', | 23 | desc: '', |
| 24 | control: 'flow', | 24 | control: 'flow', |
| 25 | }, | 25 | }, |
| 26 | + // { | ||
| 27 | + // id: '1700459406515', | ||
| 28 | + // x: -25, | ||
| 29 | + // y: 260, | ||
| 30 | + // text: '流程节点test', | ||
| 31 | + // desc: '', | ||
| 32 | + // control: 'flow', | ||
| 33 | + // }, | ||
| 26 | { | 34 | { |
| 27 | id: '1700204887203', | 35 | id: '1700204887203', |
| 28 | x: 465, | 36 | x: 465, |
| ... | @@ -59,5 +67,17 @@ export const AppData = { | ... | @@ -59,5 +67,17 @@ export const AppData = { |
| 59 | target: '1700204887203', | 67 | target: '1700204887203', |
| 60 | targetAnchor: 1, | 68 | targetAnchor: 1, |
| 61 | }, | 69 | }, |
| 70 | + // { | ||
| 71 | + // source : "start-node", | ||
| 72 | + // sourceAnchor : 1, | ||
| 73 | + // target : "1700459406515", | ||
| 74 | + // targetAnchor : 0 | ||
| 75 | + // }, | ||
| 76 | + // { | ||
| 77 | + // source : "1700459406515", | ||
| 78 | + // sourceAnchor : 2, | ||
| 79 | + // target : "end-node", | ||
| 80 | + // targetAnchor : 1 | ||
| 81 | + // } | ||
| 62 | ], | 82 | ], |
| 63 | } | 83 | } | ... | ... |
-
Please register or login to post a comment