Showing
2 changed files
with
125 additions
and
85 deletions
| ... | @@ -459,7 +459,7 @@ import type { FormInstance, FormRules } from 'element-plus' | ... | @@ -459,7 +459,7 @@ import type { FormInstance, FormRules } from 'element-plus' |
| 459 | import qs from 'qs' | 459 | import qs from 'qs' |
| 460 | import { after } from 'lodash-es'; | 460 | import { after } from 'lodash-es'; |
| 461 | // import { VueSpinner } from 'vue3-spinners'; | 461 | // import { VueSpinner } from 'vue3-spinners'; |
| 462 | -import { flowVersionAPI, saveFlowAPI, flowNodesAPI, enableFlowVersionAPI, flowNodePropertyAPI, saveFlowNodePropertyAPI, saveAllFlowNodePropertyAPI } from "./api"; | 462 | +import { flowVersionAPI, saveFlowAPI, flowNodesAPI, enableFlowVersionAPI, flowNodePropertyAPI, checkAllFlowNodePropertyAPI, saveAllFlowNodePropertyAPI } from "./api"; |
| 463 | 463 | ||
| 464 | const G6 = (window as any).G6.default as any | 464 | const G6 = (window as any).G6.default as any |
| 465 | 465 | ||
| ... | @@ -718,6 +718,7 @@ export default { | ... | @@ -718,6 +718,7 @@ export default { |
| 718 | } | 718 | } |
| 719 | 719 | ||
| 720 | /************************ 页面操作超时 ****************************/ | 720 | /************************ 页面操作超时 ****************************/ |
| 721 | + // TAG: 页面操作超时 | ||
| 721 | var timeoutId; | 722 | var timeoutId; |
| 722 | var timeoutDuration = 60 * 60 * 1000; // 设置超时时间,单位为毫秒 | 723 | var timeoutDuration = 60 * 60 * 1000; // 设置超时时间,单位为毫秒 |
| 723 | 724 | ||
| ... | @@ -885,6 +886,10 @@ export default { | ... | @@ -885,6 +886,10 @@ export default { |
| 885 | state.select_flow_version = ele.code; // 选中新增的版本 | 886 | state.select_flow_version = ele.code; // 选中新增的版本 |
| 886 | } | 887 | } |
| 887 | }); | 888 | }); |
| 889 | + // 内部刷新graph数据 | ||
| 890 | + nextTick(() => { | ||
| 891 | + editor.editorState.graph.read(flowData.value) | ||
| 892 | + }); | ||
| 888 | } | 893 | } |
| 889 | } | 894 | } |
| 890 | } | 895 | } |
| ... | @@ -1089,7 +1094,7 @@ export default { | ... | @@ -1089,7 +1094,7 @@ export default { |
| 1089 | 1094 | ||
| 1090 | // 修改缓存树的字段权限 | 1095 | // 修改缓存树的字段权限 |
| 1091 | if (state.node_tree[state.detailModel?.id]) { | 1096 | if (state.node_tree[state.detailModel?.id]) { |
| 1092 | - state.node_tree[state.detailModel.id].field = _.cloneDeep(state.field_auths); | 1097 | + state.node_tree[state.detailModel.id].field_auths = _.cloneDeep(state.field_auths); |
| 1093 | } | 1098 | } |
| 1094 | } | 1099 | } |
| 1095 | 1100 | ||
| ... | @@ -1230,6 +1235,7 @@ export default { | ... | @@ -1230,6 +1235,7 @@ export default { |
| 1230 | graph: { | 1235 | graph: { |
| 1231 | removeItem: any | 1236 | removeItem: any |
| 1232 | save: () => { nodes: any; edges: any } | 1237 | save: () => { nodes: any; edges: any } |
| 1238 | + read: any | ||
| 1233 | } | 1239 | } |
| 1234 | } | 1240 | } |
| 1235 | } | 1241 | } |
| ... | @@ -1269,6 +1275,8 @@ export default { | ... | @@ -1269,6 +1275,8 @@ export default { |
| 1269 | state.detailModel = model; | 1275 | state.detailModel = model; |
| 1270 | 1276 | ||
| 1271 | state.search_auth_value = ''; | 1277 | state.search_auth_value = ''; |
| 1278 | + state.auth_all_checked = false; | ||
| 1279 | + state.auth_all_edit = false; | ||
| 1272 | 1280 | ||
| 1273 | // 判断是否是流程节点 | 1281 | // 判断是否是流程节点 |
| 1274 | let model_id = model.id; | 1282 | let model_id = model.id; |
| ... | @@ -1320,20 +1328,25 @@ export default { | ... | @@ -1320,20 +1328,25 @@ export default { |
| 1320 | state.node_name = state.node_tree[state.detailModel.id].name; | 1328 | state.node_name = state.node_tree[state.detailModel.id].name; |
| 1321 | state.userTags = state.node_tree[state.detailModel.id].user; | 1329 | state.userTags = state.node_tree[state.detailModel.id].user; |
| 1322 | state.dialogUserTags = state.node_tree[state.detailModel.id].user; | 1330 | state.dialogUserTags = state.node_tree[state.detailModel.id].user; |
| 1323 | - state.field_auths = state.node_tree[state.detailModel.id].field; | 1331 | + state.field_auths = state.node_tree[state.detailModel.id].field_auths; |
| 1324 | state.more_attr = state.node_tree[state.detailModel.id].property; | 1332 | state.more_attr = state.node_tree[state.detailModel.id].property; |
| 1325 | 1333 | ||
| 1326 | // 初始化表单数据比较结构 | 1334 | // 初始化表单数据比较结构 |
| 1327 | state.field_extend.forEach(ele => { | 1335 | state.field_extend.forEach(ele => { |
| 1328 | state.field_auths.forEach(auth => { | 1336 | state.field_auths.forEach(auth => { |
| 1329 | if (ele.field_id === auth.field_id) { | 1337 | if (ele.field_id === auth.field_id) { |
| 1330 | - ele.field_extend.visibled = auth.visible.checked; | 1338 | + ele.field_extend.visibled = auth.visible?.checked; |
| 1331 | - ele.field_extend.editabled = auth.editable.checked; | 1339 | + ele.field_extend.editabled = auth.editable?.checked; |
| 1332 | - ele.field_extend.readonly = auth.editable.disabled; | 1340 | + ele.field_extend.readonly = auth.editable?.disabled; |
| 1333 | } | 1341 | } |
| 1334 | auth.show = true; | 1342 | auth.show = true; |
| 1335 | }) | 1343 | }) |
| 1336 | }); | 1344 | }); |
| 1345 | + | ||
| 1346 | + // 检查字段权限选中情况 | ||
| 1347 | + checkAuthAll('visible'); | ||
| 1348 | + checkAuthAll('editable'); | ||
| 1349 | + | ||
| 1337 | editor.openModel(); | 1350 | editor.openModel(); |
| 1338 | return; | 1351 | return; |
| 1339 | } | 1352 | } |
| ... | @@ -1400,7 +1413,7 @@ export default { | ... | @@ -1400,7 +1413,7 @@ export default { |
| 1400 | { | 1413 | { |
| 1401 | name: _.cloneDeep(state.node_name), | 1414 | name: _.cloneDeep(state.node_name), |
| 1402 | user: model_id === 'start-node' ? '' : _.cloneDeep(state.userTags), // 开始节点没有负责人 | 1415 | user: model_id === 'start-node' ? '' : _.cloneDeep(state.userTags), // 开始节点没有负责人 |
| 1403 | - field: _.cloneDeep(state.field_auths), | 1416 | + field_auths: _.cloneDeep(state.field_auths), |
| 1404 | field_extend: _.cloneDeep(state.field_extend), | 1417 | field_extend: _.cloneDeep(state.field_extend), |
| 1405 | property: _.cloneDeep(state.more_attr), | 1418 | property: _.cloneDeep(state.more_attr), |
| 1406 | model | 1419 | model |
| ... | @@ -1498,16 +1511,18 @@ export default { | ... | @@ -1498,16 +1511,18 @@ export default { |
| 1498 | state.main_attr_set = true; | 1511 | state.main_attr_set = true; |
| 1499 | } | 1512 | } |
| 1500 | 1513 | ||
| 1501 | - const checkSaveNodeTree = () => { // 检查需要保存的节点树属性 | 1514 | + const checkSaveNodeTree = () => { // 检查点击过的节点是否有问题 |
| 1502 | - let models = []; | 1515 | + let { nodes } = editor.editorState.graph.save(); |
| 1516 | + | ||
| 1517 | + let models = []; // 未通过的节点ID集合 | ||
| 1503 | for (const key in state.node_tree) { | 1518 | for (const key in state.node_tree) { |
| 1504 | const element = state.node_tree[key]; | 1519 | const element = state.node_tree[key]; |
| 1505 | - let avail_visible_count = element.field.filter((ele) => { | 1520 | + let avail_visible_count = element.field_auths.filter((ele) => { |
| 1506 | if (ele.visible.checked && !ele.visible.disabled) { | 1521 | if (ele.visible.checked && !ele.visible.disabled) { |
| 1507 | return ele; | 1522 | return ele; |
| 1508 | } | 1523 | } |
| 1509 | }); | 1524 | }); |
| 1510 | - let avail_editable_count = element.field.filter((ele) => { | 1525 | + let avail_editable_count = element.field_auths.filter((ele) => { |
| 1511 | if (ele.editable.checked && !ele.editable.disabled) { | 1526 | if (ele.editable.checked && !ele.editable.disabled) { |
| 1512 | return ele; | 1527 | return ele; |
| 1513 | } | 1528 | } |
| ... | @@ -1527,14 +1542,17 @@ export default { | ... | @@ -1527,14 +1542,17 @@ export default { |
| 1527 | type: 'error', | 1542 | type: 'error', |
| 1528 | message: '流程配置不完善,请点击节点红点完善。', | 1543 | message: '流程配置不完善,请点击节点红点完善。', |
| 1529 | }); | 1544 | }); |
| 1545 | + // 批量新增节点提示 | ||
| 1546 | + nodes.forEach((ele: any, idx: number) => { | ||
| 1547 | + models.forEach((model) => { | ||
| 1548 | + if (ele.id === model.id) { | ||
| 1549 | + ele.desc = 'https://cdn.ipadbiz.cn/oa/flow/icons-error1.png'; | ||
| 1550 | + editor.updateModel(ele); // 更新流程图信息 | ||
| 1551 | + } | ||
| 1552 | + }) | ||
| 1553 | + }); | ||
| 1530 | } | 1554 | } |
| 1531 | 1555 | ||
| 1532 | - // 批量新增节点提示 | ||
| 1533 | - models.forEach(ele => { | ||
| 1534 | - ele.desc = 'https://cdn.ipadbiz.cn/oa/flow/icons-error1.png'; | ||
| 1535 | - editor.updateModel(ele); // 更新流程图信息 | ||
| 1536 | - }); | ||
| 1537 | - | ||
| 1538 | return models; | 1556 | return models; |
| 1539 | } | 1557 | } |
| 1540 | 1558 | ||
| ... | @@ -1543,11 +1561,11 @@ export default { | ... | @@ -1543,11 +1561,11 @@ export default { |
| 1543 | const element = state.node_tree[key]; | 1561 | const element = state.node_tree[key]; |
| 1544 | // 调整数据结构 | 1562 | // 调整数据结构 |
| 1545 | element.field_extend.forEach(ele => { | 1563 | element.field_extend.forEach(ele => { |
| 1546 | - element.field.forEach(auth => { | 1564 | + element.field_auths.forEach(auth => { |
| 1547 | if (ele.field_id === auth.field_id) { | 1565 | if (ele.field_id === auth.field_id) { |
| 1548 | - ele.field_extend.visibled = auth.visible.checked; | 1566 | + ele.field_extend.visibled = auth.visible?.checked; |
| 1549 | - ele.field_extend.editabled = auth.editable.checked; | 1567 | + ele.field_extend.editabled = auth.editable?.checked; |
| 1550 | - ele.field_extend.readonly = auth.editable.disabled; | 1568 | + ele.field_extend.readonly = auth.editable?.disabled; |
| 1551 | } | 1569 | } |
| 1552 | }) | 1570 | }) |
| 1553 | }); | 1571 | }); |
| ... | @@ -1563,35 +1581,9 @@ export default { | ... | @@ -1563,35 +1581,9 @@ export default { |
| 1563 | // TAG: 保存表单信息 | 1581 | // TAG: 保存表单信息 |
| 1564 | const { code, data } = await saveAllFlowNodePropertyAPI({ flow_id: +flow_id, data: JSON.stringify(state.node_tree) }) | 1582 | const { code, data } = await saveAllFlowNodePropertyAPI({ flow_id: +flow_id, data: JSON.stringify(state.node_tree) }) |
| 1565 | if (code) { | 1583 | if (code) { |
| 1566 | - state.node_tree = {}; // 清空节点树缓存 | ||
| 1567 | editor.closeModel(); | 1584 | editor.closeModel(); |
| 1568 | - | 1585 | + state.node_tree = {}; // 清空节点树缓存 |
| 1569 | - // TODO: 节点错误提示测试 | 1586 | + saveFlowData(); |
| 1570 | - // let node_keys = ['start-node']; // 后端返回的未通过的节点key | ||
| 1571 | - // let { nodes } = editor.editorState.graph.save(); | ||
| 1572 | - // if (node_keys.length) { | ||
| 1573 | - // ElMessage({ | ||
| 1574 | - // type: 'error', | ||
| 1575 | - // message: '流程配置不完善,请点击节点红点完善。', | ||
| 1576 | - // }); | ||
| 1577 | - // nodes.forEach((ele: any, idx: number) => { | ||
| 1578 | - // node_keys.forEach((key: string) => { | ||
| 1579 | - // if (ele.id === key) { | ||
| 1580 | - // ele.desc = 'https://cdn.ipadbiz.cn/oa/flow/icons-error1.png'; | ||
| 1581 | - // editor.updateModel(ele); // 更新流程图信息 | ||
| 1582 | - // } | ||
| 1583 | - // }) | ||
| 1584 | - // }); | ||
| 1585 | - // } else { | ||
| 1586 | - // ElMessage({ | ||
| 1587 | - // type: 'success', | ||
| 1588 | - // message: '保存流程图成功', | ||
| 1589 | - // }); | ||
| 1590 | - // } | ||
| 1591 | - ElMessage({ | ||
| 1592 | - type: 'success', | ||
| 1593 | - message: '保存流程图成功', | ||
| 1594 | - }); | ||
| 1595 | } | 1587 | } |
| 1596 | } | 1588 | } |
| 1597 | 1589 | ||
| ... | @@ -1638,12 +1630,10 @@ export default { | ... | @@ -1638,12 +1630,10 @@ export default { |
| 1638 | if (code) { | 1630 | if (code) { |
| 1639 | updateFlowId(data); // 更新缓存flow_id | 1631 | updateFlowId(data); // 更新缓存flow_id |
| 1640 | console.log(paths); // 输出满足条件的路径结果数组 | 1632 | console.log(paths); // 输出满足条件的路径结果数组 |
| 1641 | - if (type === 'single') { | 1633 | + ElMessage({ |
| 1642 | - ElMessage({ | 1634 | + type: 'success', |
| 1643 | - type: 'success', | 1635 | + message: '保存流程图成功', |
| 1644 | - message: '保存流程图成功', | 1636 | + }); |
| 1645 | - }); | ||
| 1646 | - } | ||
| 1647 | } | 1637 | } |
| 1648 | } else { | 1638 | } else { |
| 1649 | ElNotification.error('缺少一条从开始节点到结束节点的完整流程!'); | 1639 | ElNotification.error('缺少一条从开始节点到结束节点的完整流程!'); |
| ... | @@ -1937,42 +1927,84 @@ export default { | ... | @@ -1937,42 +1927,84 @@ export default { |
| 1937 | * @return {void} No return value. | 1927 | * @return {void} No return value. |
| 1938 | */ | 1928 | */ |
| 1939 | const saveData = async () => { | 1929 | const saveData = async () => { |
| 1930 | + // 清空错误提示 | ||
| 1931 | + let { nodes } = editor.editorState.graph.save(); | ||
| 1932 | + | ||
| 1933 | + nodes.forEach((ele: any, idx: number) => { | ||
| 1934 | + ele.desc = ''; | ||
| 1935 | + editor.updateModel(ele); // 更新流程图信息 | ||
| 1936 | + }); | ||
| 1937 | + | ||
| 1938 | + // 未点击任何节点时,提示促使用户点击节点 | ||
| 1939 | + if (_.isEmpty(state.node_tree)) { | ||
| 1940 | + // TAG: 检查节点是否完整 | ||
| 1941 | + const checkResult = await checkAllFlowNodePropertyAPI({ flow_id: +flow_id }) | ||
| 1942 | + if (checkResult.code) { | ||
| 1943 | + let result = checkResult.data; | ||
| 1944 | + if (result.length) { | ||
| 1945 | + ElMessage({ | ||
| 1946 | + type: 'error', | ||
| 1947 | + message: '流程配置不完善,请点击节点红点完善。', | ||
| 1948 | + }); | ||
| 1949 | + nodes.forEach((ele: any, idx: number) => { | ||
| 1950 | + result.forEach((key: string) => { | ||
| 1951 | + if (ele.id === key) { | ||
| 1952 | + ele.desc = 'https://cdn.ipadbiz.cn/oa/flow/icons-error1.png'; | ||
| 1953 | + editor.updateModel(ele); // 更新流程图信息 | ||
| 1954 | + } | ||
| 1955 | + }) | ||
| 1956 | + }); | ||
| 1957 | + return; | ||
| 1958 | + } | ||
| 1959 | + } else { | ||
| 1960 | + // 保存流程图结构 | ||
| 1961 | + saveFlowData(); | ||
| 1962 | + } | ||
| 1963 | + } | ||
| 1964 | + | ||
| 1965 | + // 节点点击后,使用本地数据检查 | ||
| 1940 | if (checkSaveNodeTree().length) { | 1966 | if (checkSaveNodeTree().length) { |
| 1941 | return; | 1967 | return; |
| 1942 | } | 1968 | } |
| 1943 | 1969 | ||
| 1944 | - if (_.isEmpty(state.node_tree)) { | 1970 | + // TAG: 检查节点是否完整 |
| 1945 | - ElMessageBox.confirm( | 1971 | + const checkResult = await checkAllFlowNodePropertyAPI({ flow_id: +flow_id }) |
| 1946 | - '是否确定保存流程?', | 1972 | + if (checkResult.code) { |
| 1947 | - '温馨提示', | 1973 | + let raw_keys = checkResult.data; |
| 1948 | - { | 1974 | + let node_keys = Object.keys(state.node_tree); // 现在本地的ID都是有效的值 |
| 1949 | - confirmButtonText: '确认', | 1975 | + let result = _.difference(raw_keys, node_keys); |
| 1950 | - cancelButtonText: '取消', | 1976 | + if (result.length) { |
| 1951 | - type: 'warning', | 1977 | + ElMessage({ |
| 1952 | - } | 1978 | + type: 'error', |
| 1953 | - ) | 1979 | + message: '流程配置不完善,请点击节点红点完善。', |
| 1954 | - .then(async () => { | ||
| 1955 | - saveFlowData('single'); | ||
| 1956 | - }) | ||
| 1957 | - .catch(() => { | ||
| 1958 | }); | 1980 | }); |
| 1959 | - } else { | 1981 | + let { nodes } = editor.editorState.graph.save(); |
| 1960 | - ElMessageBox.confirm( | 1982 | + nodes.forEach((ele: any, idx: number) => { |
| 1961 | - '是否确定保存流程?', | 1983 | + result.forEach((key: string) => { |
| 1962 | - '温馨提示', | 1984 | + if (ele.id === key) { |
| 1963 | - { | 1985 | + ele.desc = 'https://cdn.ipadbiz.cn/oa/flow/icons-error1.png'; |
| 1964 | - confirmButtonText: '确认', | 1986 | + editor.updateModel(ele); // 更新流程图信息 |
| 1965 | - cancelButtonText: '取消', | 1987 | + } |
| 1966 | - type: 'warning', | 1988 | + }) |
| 1967 | - } | ||
| 1968 | - ) | ||
| 1969 | - .then(async () => { | ||
| 1970 | - batchSaveForm(); | ||
| 1971 | - saveFlowData(); | ||
| 1972 | - }) | ||
| 1973 | - .catch(() => { | ||
| 1974 | }); | 1989 | }); |
| 1990 | + return; | ||
| 1991 | + } | ||
| 1975 | } | 1992 | } |
| 1993 | + | ||
| 1994 | + ElMessageBox.confirm( | ||
| 1995 | + '是否确定保存流程?', | ||
| 1996 | + '温馨提示', | ||
| 1997 | + { | ||
| 1998 | + confirmButtonText: '确认', | ||
| 1999 | + cancelButtonText: '取消', | ||
| 2000 | + type: 'warning', | ||
| 2001 | + } | ||
| 2002 | + ) | ||
| 2003 | + .then(async () => { | ||
| 2004 | + batchSaveForm(); | ||
| 2005 | + }) | ||
| 2006 | + .catch(() => { | ||
| 2007 | + }); | ||
| 1976 | } | 2008 | } |
| 1977 | 2009 | ||
| 1978 | const startFlow = () => { // 启用流程图 | 2010 | const startFlow = () => { // 启用流程图 | ... | ... |
| 1 | /* | 1 | /* |
| 2 | * @Date: 2023-11-30 10:34:01 | 2 | * @Date: 2023-11-30 10:34:01 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2023-12-06 11:36:04 | 4 | + * @LastEditTime: 2023-12-08 13:11:15 |
| 5 | * @FilePath: /vue-flow-editor/doc/api/index.js | 5 | * @FilePath: /vue-flow-editor/doc/api/index.js |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | */ | 7 | */ |
| ... | @@ -15,6 +15,7 @@ const Api = { | ... | @@ -15,6 +15,7 @@ const Api = { |
| 15 | FLOW_NODE_PROPERTY: '/admin/?a=flow_node_property', | 15 | FLOW_NODE_PROPERTY: '/admin/?a=flow_node_property', |
| 16 | SAVE_FLOW_NODE_PROPERTY: '/admin/?a=save_node_property', | 16 | SAVE_FLOW_NODE_PROPERTY: '/admin/?a=save_node_property', |
| 17 | SAVE_ALL_FLOW_NODE_PROPERTY: '/admin/?a=save_all_node_property', | 17 | SAVE_ALL_FLOW_NODE_PROPERTY: '/admin/?a=save_all_node_property', |
| 18 | + CHECK_ALL_FLOW_NODE_PROPERTY: '/admin/?a=check_all_node_property', | ||
| 18 | } | 19 | } |
| 19 | 20 | ||
| 20 | /** | 21 | /** |
| ... | @@ -73,3 +74,10 @@ export const saveFlowNodePropertyAPI = (params) => fn(fetch.stringifyPost(Api.SA | ... | @@ -73,3 +74,10 @@ export const saveFlowNodePropertyAPI = (params) => fn(fetch.stringifyPost(Api.SA |
| 73 | * @returns | 74 | * @returns |
| 74 | */ | 75 | */ |
| 75 | export const saveAllFlowNodePropertyAPI = (params) => fn(fetch.stringifyPost(Api.SAVE_ALL_FLOW_NODE_PROPERTY, params)); | 76 | export const saveAllFlowNodePropertyAPI = (params) => fn(fetch.stringifyPost(Api.SAVE_ALL_FLOW_NODE_PROPERTY, params)); |
| 77 | + | ||
| 78 | +/** | ||
| 79 | + * @description: 检查流程在库节点属性是否完整 | ||
| 80 | + * @param {*} flow_id 流程 ID | ||
| 81 | + * @returns | ||
| 82 | + */ | ||
| 83 | +export const checkAllFlowNodePropertyAPI = (params) => fn(fetch.get(Api.CHECK_ALL_FLOW_NODE_PROPERTY, params)); | ... | ... |
-
Please register or login to post a comment