hookehuyr

节点是否填写完整性检查

......@@ -459,7 +459,7 @@ import type { FormInstance, FormRules } from 'element-plus'
import qs from 'qs'
import { after } from 'lodash-es';
// import { VueSpinner } from 'vue3-spinners';
import { flowVersionAPI, saveFlowAPI, flowNodesAPI, enableFlowVersionAPI, flowNodePropertyAPI, saveFlowNodePropertyAPI, saveAllFlowNodePropertyAPI } from "./api";
import { flowVersionAPI, saveFlowAPI, flowNodesAPI, enableFlowVersionAPI, flowNodePropertyAPI, checkAllFlowNodePropertyAPI, saveAllFlowNodePropertyAPI } from "./api";
const G6 = (window as any).G6.default as any
......@@ -718,6 +718,7 @@ export default {
}
/************************ 页面操作超时 ****************************/
// TAG: 页面操作超时
var timeoutId;
var timeoutDuration = 60 * 60 * 1000; // 设置超时时间,单位为毫秒
......@@ -885,6 +886,10 @@ export default {
state.select_flow_version = ele.code; // 选中新增的版本
}
});
// 内部刷新graph数据
nextTick(() => {
editor.editorState.graph.read(flowData.value)
});
}
}
}
......@@ -1089,7 +1094,7 @@ export default {
// 修改缓存树的字段权限
if (state.node_tree[state.detailModel?.id]) {
state.node_tree[state.detailModel.id].field = _.cloneDeep(state.field_auths);
state.node_tree[state.detailModel.id].field_auths = _.cloneDeep(state.field_auths);
}
}
......@@ -1230,6 +1235,7 @@ export default {
graph: {
removeItem: any
save: () => { nodes: any; edges: any }
read: any
}
}
}
......@@ -1269,6 +1275,8 @@ export default {
state.detailModel = model;
state.search_auth_value = '';
state.auth_all_checked = false;
state.auth_all_edit = false;
// 判断是否是流程节点
let model_id = model.id;
......@@ -1320,20 +1328,25 @@ export default {
state.node_name = state.node_tree[state.detailModel.id].name;
state.userTags = state.node_tree[state.detailModel.id].user;
state.dialogUserTags = state.node_tree[state.detailModel.id].user;
state.field_auths = state.node_tree[state.detailModel.id].field;
state.field_auths = state.node_tree[state.detailModel.id].field_auths;
state.more_attr = state.node_tree[state.detailModel.id].property;
// 初始化表单数据比较结构
state.field_extend.forEach(ele => {
state.field_auths.forEach(auth => {
if (ele.field_id === auth.field_id) {
ele.field_extend.visibled = auth.visible.checked;
ele.field_extend.editabled = auth.editable.checked;
ele.field_extend.readonly = auth.editable.disabled;
ele.field_extend.visibled = auth.visible?.checked;
ele.field_extend.editabled = auth.editable?.checked;
ele.field_extend.readonly = auth.editable?.disabled;
}
auth.show = true;
})
});
// 检查字段权限选中情况
checkAuthAll('visible');
checkAuthAll('editable');
editor.openModel();
return;
}
......@@ -1400,7 +1413,7 @@ export default {
{
name: _.cloneDeep(state.node_name),
user: model_id === 'start-node' ? '' : _.cloneDeep(state.userTags), // 开始节点没有负责人
field: _.cloneDeep(state.field_auths),
field_auths: _.cloneDeep(state.field_auths),
field_extend: _.cloneDeep(state.field_extend),
property: _.cloneDeep(state.more_attr),
model
......@@ -1498,16 +1511,18 @@ export default {
state.main_attr_set = true;
}
const checkSaveNodeTree = () => { // 检查需要保存的节点树属性
let models = [];
const checkSaveNodeTree = () => { // 检查点击过的节点是否有问题
let { nodes } = editor.editorState.graph.save();
let models = []; // 未通过的节点ID集合
for (const key in state.node_tree) {
const element = state.node_tree[key];
let avail_visible_count = element.field.filter((ele) => {
let avail_visible_count = element.field_auths.filter((ele) => {
if (ele.visible.checked && !ele.visible.disabled) {
return ele;
}
});
let avail_editable_count = element.field.filter((ele) => {
let avail_editable_count = element.field_auths.filter((ele) => {
if (ele.editable.checked && !ele.editable.disabled) {
return ele;
}
......@@ -1527,14 +1542,17 @@ export default {
type: 'error',
message: '流程配置不完善,请点击节点红点完善。',
});
// 批量新增节点提示
nodes.forEach((ele: any, idx: number) => {
models.forEach((model) => {
if (ele.id === model.id) {
ele.desc = 'https://cdn.ipadbiz.cn/oa/flow/icons-error1.png';
editor.updateModel(ele); // 更新流程图信息
}
})
});
}
// 批量新增节点提示
models.forEach(ele => {
ele.desc = 'https://cdn.ipadbiz.cn/oa/flow/icons-error1.png';
editor.updateModel(ele); // 更新流程图信息
});
return models;
}
......@@ -1543,11 +1561,11 @@ export default {
const element = state.node_tree[key];
// 调整数据结构
element.field_extend.forEach(ele => {
element.field.forEach(auth => {
element.field_auths.forEach(auth => {
if (ele.field_id === auth.field_id) {
ele.field_extend.visibled = auth.visible.checked;
ele.field_extend.editabled = auth.editable.checked;
ele.field_extend.readonly = auth.editable.disabled;
ele.field_extend.visibled = auth.visible?.checked;
ele.field_extend.editabled = auth.editable?.checked;
ele.field_extend.readonly = auth.editable?.disabled;
}
})
});
......@@ -1563,35 +1581,9 @@ export default {
// TAG: 保存表单信息
const { code, data } = await saveAllFlowNodePropertyAPI({ flow_id: +flow_id, data: JSON.stringify(state.node_tree) })
if (code) {
state.node_tree = {}; // 清空节点树缓存
editor.closeModel();
// TODO: 节点错误提示测试
// let node_keys = ['start-node']; // 后端返回的未通过的节点key
// let { nodes } = editor.editorState.graph.save();
// if (node_keys.length) {
// ElMessage({
// type: 'error',
// message: '流程配置不完善,请点击节点红点完善。',
// });
// nodes.forEach((ele: any, idx: number) => {
// node_keys.forEach((key: string) => {
// if (ele.id === key) {
// ele.desc = 'https://cdn.ipadbiz.cn/oa/flow/icons-error1.png';
// editor.updateModel(ele); // 更新流程图信息
// }
// })
// });
// } else {
// ElMessage({
// type: 'success',
// message: '保存流程图成功',
// });
// }
ElMessage({
type: 'success',
message: '保存流程图成功',
});
state.node_tree = {}; // 清空节点树缓存
saveFlowData();
}
}
......@@ -1638,12 +1630,10 @@ export default {
if (code) {
updateFlowId(data); // 更新缓存flow_id
console.log(paths); // 输出满足条件的路径结果数组
if (type === 'single') {
ElMessage({
type: 'success',
message: '保存流程图成功',
});
}
ElMessage({
type: 'success',
message: '保存流程图成功',
});
}
} else {
ElNotification.error('缺少一条从开始节点到结束节点的完整流程!');
......@@ -1937,42 +1927,84 @@ export default {
* @return {void} No return value.
*/
const saveData = async () => {
// 清空错误提示
let { nodes } = editor.editorState.graph.save();
nodes.forEach((ele: any, idx: number) => {
ele.desc = '';
editor.updateModel(ele); // 更新流程图信息
});
// 未点击任何节点时,提示促使用户点击节点
if (_.isEmpty(state.node_tree)) {
// TAG: 检查节点是否完整
const checkResult = await checkAllFlowNodePropertyAPI({ flow_id: +flow_id })
if (checkResult.code) {
let result = checkResult.data;
if (result.length) {
ElMessage({
type: 'error',
message: '流程配置不完善,请点击节点红点完善。',
});
nodes.forEach((ele: any, idx: number) => {
result.forEach((key: string) => {
if (ele.id === key) {
ele.desc = 'https://cdn.ipadbiz.cn/oa/flow/icons-error1.png';
editor.updateModel(ele); // 更新流程图信息
}
})
});
return;
}
} else {
// 保存流程图结构
saveFlowData();
}
}
// 节点点击后,使用本地数据检查
if (checkSaveNodeTree().length) {
return;
}
if (_.isEmpty(state.node_tree)) {
ElMessageBox.confirm(
'是否确定保存流程?',
'温馨提示',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(async () => {
saveFlowData('single');
})
.catch(() => {
// TAG: 检查节点是否完整
const checkResult = await checkAllFlowNodePropertyAPI({ flow_id: +flow_id })
if (checkResult.code) {
let raw_keys = checkResult.data;
let node_keys = Object.keys(state.node_tree); // 现在本地的ID都是有效的值
let result = _.difference(raw_keys, node_keys);
if (result.length) {
ElMessage({
type: 'error',
message: '流程配置不完善,请点击节点红点完善。',
});
} else {
ElMessageBox.confirm(
'是否确定保存流程?',
'温馨提示',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(async () => {
batchSaveForm();
saveFlowData();
})
.catch(() => {
let { nodes } = editor.editorState.graph.save();
nodes.forEach((ele: any, idx: number) => {
result.forEach((key: string) => {
if (ele.id === key) {
ele.desc = 'https://cdn.ipadbiz.cn/oa/flow/icons-error1.png';
editor.updateModel(ele); // 更新流程图信息
}
})
});
return;
}
}
ElMessageBox.confirm(
'是否确定保存流程?',
'温馨提示',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(async () => {
batchSaveForm();
})
.catch(() => {
});
}
const startFlow = () => { // 启用流程图
......
/*
* @Date: 2023-11-30 10:34:01
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-12-06 11:36:04
* @LastEditTime: 2023-12-08 13:11:15
* @FilePath: /vue-flow-editor/doc/api/index.js
* @Description: 文件描述
*/
......@@ -15,6 +15,7 @@ const Api = {
FLOW_NODE_PROPERTY: '/admin/?a=flow_node_property',
SAVE_FLOW_NODE_PROPERTY: '/admin/?a=save_node_property',
SAVE_ALL_FLOW_NODE_PROPERTY: '/admin/?a=save_all_node_property',
CHECK_ALL_FLOW_NODE_PROPERTY: '/admin/?a=check_all_node_property',
}
/**
......@@ -73,3 +74,10 @@ export const saveFlowNodePropertyAPI = (params) => fn(fetch.stringifyPost(Api.SA
* @returns
*/
export const saveAllFlowNodePropertyAPI = (params) => fn(fetch.stringifyPost(Api.SAVE_ALL_FLOW_NODE_PROPERTY, params));
/**
* @description: 检查流程在库节点属性是否完整
* @param {*} flow_id 流程 ID
* @returns
*/
export const checkAllFlowNodePropertyAPI = (params) => fn(fetch.get(Api.CHECK_ALL_FLOW_NODE_PROPERTY, params));
......