初始版本提交
This commit is contained in:
193
src/views/workflow/design/bpmn/config/formPermission.ts
Normal file
193
src/views/workflow/design/bpmn/config/formPermission.ts
Normal file
@ -0,0 +1,193 @@
|
||||
import { message } from 'ant-design-vue';
|
||||
import { FormType } from '/@/enums/workflowEnum';
|
||||
import { FormConfigItem, FormSettingItem, TableItem } from '/@/model/workflow/formSetting';
|
||||
import {
|
||||
getCustomJson,
|
||||
getSystemJson,
|
||||
importWorkflowPermission,
|
||||
} from '/@/utils/formSettings/formJson';
|
||||
import { randomTime } from '/@bpmn/util/random';
|
||||
import { updateFormFieldIdRelevance } from './useUpdateAllFormInfo';
|
||||
import { getWorkflowPermissionConfig } from '/@/hooks/web/useWorkFlowForm';
|
||||
export const visitorsBookType = 'opinion'; //意见簿类型
|
||||
export const hiddenComponentType = 'hiddenComponent'; //隐藏组件类型
|
||||
export const titleType = 'title'; //标题类型
|
||||
export const dividerType = 'divider'; //分割线类型
|
||||
export const infoType = 'info'; //信息体
|
||||
export const autoCodeType = 'auto-code'; //编码
|
||||
export const buttonType = 'button'; //按钮
|
||||
// 标题,分割线、信息体,按钮,编码,意见簿,只允许查看权限
|
||||
export const disableTypes = [
|
||||
visitorsBookType,
|
||||
titleType,
|
||||
dividerType,
|
||||
infoType,
|
||||
autoCodeType,
|
||||
'qrcode', //二维码组件
|
||||
]; //表单字段仅仅只有查看权限
|
||||
// 开关,滑块,颜色选择,评分,图片 组件权限中,必填权限为disable
|
||||
export const requiredDisabled = [
|
||||
visitorsBookType,
|
||||
titleType,
|
||||
dividerType,
|
||||
infoType,
|
||||
autoCodeType,
|
||||
buttonType,
|
||||
'switch',
|
||||
'slider',
|
||||
'rate',
|
||||
'picker-color',
|
||||
'image',
|
||||
];
|
||||
export const doNotShowControl = ['qrcode']; //表单设置不显示编辑和必填操作项的组件
|
||||
export const doNotTypes = [visitorsBookType, titleType, dividerType, 'image', 'qrcode']; //不需要考虑的类型
|
||||
export async function formPermissionList(list: Array<FormSettingItem>) {
|
||||
const returnList: Array<FormConfigItem> = [];
|
||||
if (list.length > 0) {
|
||||
for (let index = 0; index < list.length; index++) {
|
||||
const formConfig = await getFormConfig(list[index]);
|
||||
returnList.push(formConfig);
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
export async function getFormConfig(item: {
|
||||
key?: string;
|
||||
formId: string;
|
||||
formName: string;
|
||||
formType: FormType;
|
||||
name?: string;
|
||||
}) {
|
||||
const formId = item.formId;
|
||||
const formType = item.formType;
|
||||
const formName = item.formName;
|
||||
const name = item.name ? item.name : item.formName;
|
||||
const key = item.key ? item.key : 'form_' + item.formId + '_' + randomTime();
|
||||
const formConfig: FormConfigItem = {
|
||||
key,
|
||||
formType,
|
||||
formId,
|
||||
formName,
|
||||
name,
|
||||
showChildren: false,
|
||||
requiredAll: true,
|
||||
viewAll: true,
|
||||
editAll: true,
|
||||
children: [],
|
||||
};
|
||||
if (formType == FormType.CUSTOM) {
|
||||
const schema = await getSchemasList(formId, formType);
|
||||
if (schema.length > 0) {
|
||||
formConfig.children = getWorkflowPermissionConfig(schema);
|
||||
}
|
||||
} else if (formType == FormType.SYSTEM) {
|
||||
const systemJson = await getSchemasList(formId, formType);
|
||||
try {
|
||||
const val = await importWorkflowPermission(systemJson.systemComponent);
|
||||
formConfig.children = val.permissionList;
|
||||
} catch (error) {
|
||||
//兼容旧系统表单
|
||||
const schema = await getSchemasList(formId, 1);
|
||||
if (schema.length > 0) {
|
||||
formConfig.children = getWorkflowPermissionConfig(schema);
|
||||
}
|
||||
}
|
||||
}
|
||||
return formConfig;
|
||||
}
|
||||
// 删除表单:表单中字段被删除:删除已引用该表单数据字段的所有配置
|
||||
function updateFormDataRelevance(
|
||||
oldData: FormConfigItem,
|
||||
oldChildMap: Map<string, FormConfigItem>,
|
||||
newData: FormConfigItem,
|
||||
) {
|
||||
const formKey = oldData.key;
|
||||
const oldChild = oldData.children;
|
||||
const newChildMap = new Map();
|
||||
const newChild = newData?.children || [];
|
||||
if (newChild && Array.isArray(newChild)) {
|
||||
newChild.forEach((ele) => {
|
||||
if (ele.children.length > 0) {
|
||||
ele.children.forEach((item) => {
|
||||
newChildMap.set(item.tableName + item.key, item);
|
||||
});
|
||||
}
|
||||
newChildMap.set(ele.key, ele);
|
||||
});
|
||||
}
|
||||
|
||||
// 旧表单的字段有,却在新表单中被上删除了,那么就要查找然后删除对应关联了
|
||||
if (oldChild && Array.isArray(oldChild)) {
|
||||
oldChild.forEach((oldItem) => {
|
||||
if (oldChildMap.has(oldItem.key) && !newChildMap.has(oldItem.key)) {
|
||||
updateFormFieldIdRelevance(formKey, oldItem.key);
|
||||
}
|
||||
//子表不会被关联
|
||||
// if (newItem.children.length > 0) {
|
||||
// }
|
||||
});
|
||||
}
|
||||
}
|
||||
export function compareFormInfo(oldData: FormConfigItem, newData: FormConfigItem) {
|
||||
const oldChildMap = new Map();
|
||||
const oldChild = oldData.children;
|
||||
if (oldChild && Array.isArray(oldChild)) {
|
||||
oldChild.forEach((old) => {
|
||||
if (old.children.length > 0) {
|
||||
old.children.forEach((item) => {
|
||||
oldChildMap.set(item.tableName + item.key, item);
|
||||
});
|
||||
}
|
||||
oldChildMap.set(old.key, old);
|
||||
});
|
||||
}
|
||||
|
||||
const newChild = newData?.children || [];
|
||||
const children: Array<TableItem> = [];
|
||||
updateFormDataRelevance(oldData, oldChildMap, newData);
|
||||
if (newChild && Array.isArray(newChild)) {
|
||||
newChild.forEach((newItem) => {
|
||||
const tempChildren: Array<TableItem> = [];
|
||||
if (newItem.children.length > 0) {
|
||||
newItem.children.forEach((item) => {
|
||||
tempChildren.push(
|
||||
oldChildMap.has(item.tableName + item.key)
|
||||
? oldChildMap.get(item.tableName + item.key)
|
||||
: item,
|
||||
);
|
||||
});
|
||||
}
|
||||
newItem.children = tempChildren;
|
||||
newItem = oldChildMap.has(newItem.key)
|
||||
? oldChildMap.get(newItem.key).type == 'form'
|
||||
? newItem
|
||||
: oldChildMap.get(newItem.key)
|
||||
: newItem;
|
||||
children.push(newItem);
|
||||
});
|
||||
}
|
||||
newData.children = children;
|
||||
return newData;
|
||||
}
|
||||
export async function getSchemasList(formId: string, formType: FormType) {
|
||||
try {
|
||||
if (formType == FormType.CUSTOM) {
|
||||
const customJson: any = await getCustomJson(formId);
|
||||
if (customJson && customJson.schemas) {
|
||||
return customJson.schemas;
|
||||
}
|
||||
} else if (formType == FormType.SYSTEM) {
|
||||
const systemJson = await getSystemJson(formId);
|
||||
if (systemJson) {
|
||||
return systemJson;
|
||||
} else {
|
||||
message.error('读取系统表单失败');
|
||||
return [];
|
||||
}
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
} catch (error) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
539
src/views/workflow/design/bpmn/config/info.ts
Normal file
539
src/views/workflow/design/bpmn/config/info.ts
Normal file
@ -0,0 +1,539 @@
|
||||
import { InfoItem } from '/@/model/workflow/bpmnConfig';
|
||||
import { useBpmnStore } from '/@bpmn/store/bpmn';
|
||||
import { BpmnNodeKey, MultipleInstancesType } from '/@/enums/workflowEnum';
|
||||
import { FormFiledConfig, FormFiled } from '/@/model/workflow/memberSetting';
|
||||
import { TreeProps } from 'ant-design-vue';
|
||||
import { getNodeName } from './property';
|
||||
import { FormConfigItem } from '/@/model/workflow/formSetting';
|
||||
import { getDesignInfo } from '/@/api/workflow/design';
|
||||
import { doNotTypes, hiddenComponentType, visitorsBookType } from './formPermission';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
export const separator = '___';
|
||||
/**
|
||||
* 获取意见簿树
|
||||
* @param formConfigs 表单数据配置
|
||||
* @returns []
|
||||
*/
|
||||
export function getOpinionConfigTree(formConfigs: Array<FormConfigItem>) {
|
||||
const children: Array<FormFiled> = [];
|
||||
if (formConfigs && formConfigs.length > 0) {
|
||||
formConfigs.forEach((ele1) => {
|
||||
const formChildren: Array<FormFiled> = [];
|
||||
if (ele1.children && ele1.children.length > 0) {
|
||||
ele1.children.forEach((ele2) => {
|
||||
if (ele2.type == visitorsBookType) {
|
||||
const key = ele1.key + separator + ele2.key;
|
||||
formChildren.push({
|
||||
title: ele2.fieldName,
|
||||
key,
|
||||
formId: ele1.formId,
|
||||
formField: ele2.key,
|
||||
disabled: false,
|
||||
children: [],
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
children.push({
|
||||
title: ele1.formName,
|
||||
key: ele1.formId,
|
||||
formId: ele1.formId,
|
||||
formField: '',
|
||||
disabled: true,
|
||||
children: formChildren,
|
||||
});
|
||||
});
|
||||
}
|
||||
return children;
|
||||
}
|
||||
/**
|
||||
* 获取表单树
|
||||
* @param formConfigs 表单数据配置
|
||||
* @param nodeId 节点id
|
||||
* @param needHideComponents 是否需要隐藏组件
|
||||
* @returns []
|
||||
*/
|
||||
export function getFormSettingTree(
|
||||
formConfigs: Array<FormConfigItem>,
|
||||
nodeId = '',
|
||||
nodeName = '',
|
||||
needHideComponents = false,
|
||||
needSubTable = false,
|
||||
needMainTable = true,
|
||||
) {
|
||||
const store = useBpmnStore();
|
||||
const { infoId } = store;
|
||||
nodeId = nodeId ? nodeId : infoId;
|
||||
const children: Array<FormFiled> = [];
|
||||
if (formConfigs && formConfigs.length > 0) {
|
||||
formConfigs.forEach((ele1) => {
|
||||
const formChildren: Array<FormFiled> = [];
|
||||
if (ele1.children && ele1.children.length > 0) {
|
||||
ele1.children.forEach((ele2) => {
|
||||
if (ele2.isSubTable) {
|
||||
// 子表
|
||||
if (needSubTable) {
|
||||
const tabChildren: Array<FormFiled> = [];
|
||||
const key = nodeId + separator + ele1.key + separator + ele2.fieldId;
|
||||
ele2.children.forEach((ele3) => {
|
||||
if (doNotTypes.includes(ele3.type)) {
|
||||
// 剔除
|
||||
} else if (ele3.type === hiddenComponentType) {
|
||||
// 隐藏组件
|
||||
} else {
|
||||
const key =
|
||||
nodeId +
|
||||
separator +
|
||||
ele1.key +
|
||||
separator +
|
||||
ele2.fieldId +
|
||||
separator +
|
||||
ele3.fieldId;
|
||||
if (ele3.fieldId) {
|
||||
tabChildren.push({
|
||||
title: ele3.fieldName,
|
||||
label:
|
||||
nodeName +
|
||||
'-' +
|
||||
ele1.formName +
|
||||
'-' +
|
||||
ele2.fieldName +
|
||||
'-' +
|
||||
ele3.fieldName,
|
||||
key,
|
||||
formId: ele1.formId,
|
||||
formField: ele3.fieldId,
|
||||
disabled: false,
|
||||
children: [],
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
formChildren.push({
|
||||
title: ele2.fieldName,
|
||||
label: nodeName + '-' + ele1.formName + '-' + ele2.fieldName,
|
||||
key,
|
||||
formId: ele1.formId,
|
||||
formField: ele2.fieldId,
|
||||
disabled: true,
|
||||
children: tabChildren,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (needMainTable) {
|
||||
if (doNotTypes.includes(ele2.type)) {
|
||||
// 剔除
|
||||
} else if (ele2.type === hiddenComponentType) {
|
||||
// 隐藏组件
|
||||
if (needHideComponents) {
|
||||
const key = nodeId + separator + ele1.key + separator + ele2.fieldId;
|
||||
formChildren.push({
|
||||
title: ele2.fieldName,
|
||||
label: nodeName + '-' + ele1.formName + '-' + ele2.fieldName,
|
||||
key,
|
||||
formId: ele1.formId,
|
||||
formField: ele2.fieldId,
|
||||
disabled: false,
|
||||
children: [],
|
||||
});
|
||||
}
|
||||
} else {
|
||||
const key = nodeId + separator + ele1.key + separator + ele2.fieldId;
|
||||
if (ele2.fieldId) {
|
||||
formChildren.push({
|
||||
title: ele2.fieldName,
|
||||
label: nodeName + '-' + ele1.formName + '-' + ele2.fieldName,
|
||||
key,
|
||||
formId: ele1.formId,
|
||||
formField: ele2.fieldId,
|
||||
disabled: false,
|
||||
children: [],
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
children.push({
|
||||
title: ele1.formName,
|
||||
label: nodeName + '-' + ele1.formName,
|
||||
key: nodeId + separator + ele1.key,
|
||||
formId: ele1.formId,
|
||||
formField: '',
|
||||
disabled: true,
|
||||
children: formChildren,
|
||||
});
|
||||
});
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前流程变量数据树
|
||||
* @param parameter 参数配置
|
||||
{
|
||||
needUserNodeButton 是否需要按钮组 下面的按钮值列表[默认不需要,默认false]
|
||||
needHideComponents 是否需要隐藏组件[默认不需要,默认false]
|
||||
}
|
||||
* @returns []
|
||||
*/
|
||||
export function getVariablesTree(parameter?: {
|
||||
needUserNodeButton?: boolean;
|
||||
needHideComponents?: boolean;
|
||||
}): TreeProps['treeData'] {
|
||||
const params = {
|
||||
...{
|
||||
needUserNodeButton: false,
|
||||
needHideComponents: false,
|
||||
needSubTable: false,
|
||||
needMainTable: true,
|
||||
},
|
||||
...parameter,
|
||||
};
|
||||
const treeData: TreeProps['treeData'] = [];
|
||||
const store = useBpmnStore();
|
||||
const { info, processInfo } = store;
|
||||
const temp = parsingFormConfigJsonTree(info.values(), processInfo.processId, params);
|
||||
treeData.push(...temp);
|
||||
return treeData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取多实例,发起人配置中,只允许子表表单配置
|
||||
*/
|
||||
export function getVariablesSubTableTree(): TreeProps['treeData'] {
|
||||
const params = {
|
||||
...{
|
||||
needUserNodeButton: false,
|
||||
needHideComponents: false,
|
||||
needSubTable: true,
|
||||
needMainTable: false,
|
||||
},
|
||||
};
|
||||
const treeData: TreeProps['treeData'] = [];
|
||||
const store = useBpmnStore();
|
||||
const { info, processInfo } = store;
|
||||
const temp = parsingFormConfigJsonTree(info.values(), processInfo.processId, params);
|
||||
treeData.push(...temp);
|
||||
|
||||
return treeData;
|
||||
}
|
||||
// 根据json,以及主要流程Id,获取节点到表单到字段的树
|
||||
function parsingFormConfigJsonTree(
|
||||
info: any,
|
||||
mainProcessId: any,
|
||||
params: {
|
||||
needUserNodeButton: boolean;
|
||||
needHideComponents: boolean;
|
||||
needSubTable: boolean;
|
||||
needMainTable: boolean;
|
||||
},
|
||||
) {
|
||||
const list: TreeProps['treeData'] = [];
|
||||
|
||||
for (const item of info) {
|
||||
const showNodeTypes = [BpmnNodeKey.START, BpmnNodeKey.USER, BpmnNodeKey.CALLACTIVITY];
|
||||
if (showNodeTypes.includes(item.type) && item.parentId == mainProcessId) {
|
||||
const name = item.name ? item.name : item.type;
|
||||
const id = item.id;
|
||||
const children = getFormSettingTree(
|
||||
item.formConfigs,
|
||||
id,
|
||||
name,
|
||||
params.needHideComponents,
|
||||
params.needSubTable,
|
||||
params.needMainTable,
|
||||
);
|
||||
|
||||
const config: FormFiledConfig = {
|
||||
title: name,
|
||||
label: name,
|
||||
key: id,
|
||||
disabled: true,
|
||||
children,
|
||||
};
|
||||
// 按钮组
|
||||
if (item.type == BpmnNodeKey.USER && params.needUserNodeButton) {
|
||||
const variableValueList: Array<FormFiledConfig> = [];
|
||||
item.buttonConfigs.forEach((ele) => {
|
||||
if (ele.checked) {
|
||||
variableValueList.push({
|
||||
title: ele.buttonName,
|
||||
key: ele.buttonCode,
|
||||
disabled: false,
|
||||
children: [],
|
||||
buttons: [],
|
||||
});
|
||||
}
|
||||
});
|
||||
const buttonInfo = getButtonListChildren(id, name, variableValueList);
|
||||
config.children.push(buttonInfo);
|
||||
}
|
||||
//用户任务 多实例(会签) 审批结果
|
||||
if (
|
||||
item.type == BpmnNodeKey.USER &&
|
||||
item.countersignConfig.multipleInstancesType !== MultipleInstancesType.NONE
|
||||
) {
|
||||
config.children.push({
|
||||
title: t('按钮组'),
|
||||
label: name + '-' + t('审批结果'),
|
||||
key: id + separator + 'button' + separator + 'result',
|
||||
disabled: false,
|
||||
children: [],
|
||||
});
|
||||
}
|
||||
|
||||
// //外部流程 按钮组
|
||||
// if (item.type == BpmnNodeKey.CALLACTIVITY && params.needUserNodeButton) {
|
||||
// info.children.push({
|
||||
// title: t('按钮组'),
|
||||
// label: name + '-' + t('完成数量'),
|
||||
// key: id + separator + 'finish' + separator + 'count',
|
||||
// disabled: false,
|
||||
// children: [],
|
||||
// });
|
||||
// }
|
||||
|
||||
list.push(config);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
// 获取节点的按钮组
|
||||
const getButtonListChildren = (id: string, name: string, variableValueList) => {
|
||||
const buttons: Array<{
|
||||
title: string;
|
||||
key: string;
|
||||
disabled: boolean;
|
||||
children: [];
|
||||
}> = [];
|
||||
// const key = id + separator + 'button';
|
||||
variableValueList.forEach((element) => {
|
||||
buttons.push({
|
||||
title: element.title,
|
||||
key: element.key,
|
||||
disabled: false,
|
||||
children: [],
|
||||
});
|
||||
});
|
||||
return {
|
||||
title: t('按钮组'),
|
||||
label: name + '-' + t('按钮组'),
|
||||
key: id + separator + 'button',
|
||||
disabled: false,
|
||||
children: [],
|
||||
buttons,
|
||||
};
|
||||
};
|
||||
|
||||
// 获取所有节点列表数据 【只包含开始节点以及用户节点】
|
||||
export function getNodeList() {
|
||||
const list: Array<InfoItem> = [];
|
||||
const store = useBpmnStore();
|
||||
const { info } = store;
|
||||
for (const item of info.values()) {
|
||||
const showNodeTypes = [BpmnNodeKey.START, BpmnNodeKey.USER];
|
||||
if (showNodeTypes.includes(item.type)) {
|
||||
const name = item.name ? item.name : getNodeName(item.type);
|
||||
list.push({ ...item, name });
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
// 获取主流程的节点数据 【只包含开始节点以及用户节点】
|
||||
export function getMainProcessNodeList() {
|
||||
const list: Array<{ id: string; name: string }> = [];
|
||||
const store = useBpmnStore();
|
||||
const { info, processInfo } = store;
|
||||
const mainProcessId = processInfo.processId;
|
||||
for (const item of info.values()) {
|
||||
const showNodeTypes = [BpmnNodeKey.START, BpmnNodeKey.USER];
|
||||
if (showNodeTypes.includes(item.type) && item.parentId == mainProcessId) {
|
||||
const name = item.name ? item.name : getNodeName(item.type);
|
||||
list.push({ id: item.id, name });
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
// 获取流程参数
|
||||
export function getProcessParamConfigs() {
|
||||
const bpmnStore = useBpmnStore();
|
||||
return bpmnStore.processInfo.processParamConfigs;
|
||||
}
|
||||
//获取流程参数树
|
||||
function getProcessParameterTree(processParameter) {
|
||||
const treeList: TreeProps['treeData'] = [
|
||||
{
|
||||
title: t('流程参数'),
|
||||
key: 'processParameter',
|
||||
disabled: true,
|
||||
children: [],
|
||||
},
|
||||
];
|
||||
processParameter.forEach((ele) => {
|
||||
if (treeList && treeList[0] && treeList[0].children)
|
||||
treeList[0].children.push({
|
||||
title: ele.name,
|
||||
key: ele.id,
|
||||
disabled: false,
|
||||
children: [],
|
||||
});
|
||||
});
|
||||
return treeList;
|
||||
}
|
||||
//获取流程Json配置树【显示流程参数,以及所有节点表单配置】
|
||||
function parsingJson(
|
||||
info: any,
|
||||
processInfo: any,
|
||||
parameter?: {
|
||||
needUserNodeButton?: boolean;
|
||||
needHideComponents?: boolean;
|
||||
needSubTable?: boolean;
|
||||
},
|
||||
) {
|
||||
const params = {
|
||||
...{
|
||||
needUserNodeButton: false,
|
||||
needHideComponents: false,
|
||||
needSubTable: false,
|
||||
needMainTable: true,
|
||||
},
|
||||
...parameter,
|
||||
};
|
||||
const processParamConfigs = getProcessParamConfigs();
|
||||
const list: TreeProps['treeData'] = getProcessParameterTree(processParamConfigs);
|
||||
const temp: TreeProps['treeData'] = parsingFormConfigJsonTree(
|
||||
info,
|
||||
processInfo.processId,
|
||||
params,
|
||||
);
|
||||
list.push(...temp);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
// 外部流程-来源树
|
||||
export function getSourceList() {
|
||||
const store = useBpmnStore();
|
||||
const { info, processInfo } = store;
|
||||
return parsingJson(info.values(), processInfo);
|
||||
}
|
||||
// 外部流程-变量来源 主流程树 单实例
|
||||
|
||||
export function getSingleMainSourceList() {
|
||||
const store = useBpmnStore();
|
||||
const { info, processInfo } = store;
|
||||
return parsingJson(info.values(), processInfo, {
|
||||
needUserNodeButton: false,
|
||||
needHideComponents: true,
|
||||
needSubTable: false,
|
||||
});
|
||||
}
|
||||
// 外部流程-变量来源 主流程树 多实例
|
||||
|
||||
export function getMultipleMainSourceList() {
|
||||
const store = useBpmnStore();
|
||||
const { info, processInfo } = store;
|
||||
return parsingJson(info.values(), processInfo, {
|
||||
needUserNodeButton: false,
|
||||
needHideComponents: true,
|
||||
needSubTable: true,
|
||||
});
|
||||
}
|
||||
|
||||
// 外部流程-目标树
|
||||
export async function getTargetList(id: string) {
|
||||
const res = await getDesignInfo(id);
|
||||
const json = JSON.parse(res?.jsonContent);
|
||||
return parsingJson(json.childNodeConfig, json.processConfig);
|
||||
}
|
||||
/**
|
||||
* 获取Json,xml
|
||||
* @param id 流程模板id
|
||||
* @returns {json,xml}
|
||||
*/
|
||||
export async function getBpmnJsonAndXmlById(id: string) {
|
||||
const res = await getDesignInfo(id);
|
||||
const json = JSON.parse(res?.jsonContent);
|
||||
const xml = res?.xmlContent;
|
||||
return { json, xml };
|
||||
}
|
||||
|
||||
// 获取所有节点表单使用列表
|
||||
export function getUsedFormList() {
|
||||
const formKeyList = {};
|
||||
const formList = {};
|
||||
const store = useBpmnStore();
|
||||
const { info, infoId, getProperties } = store;
|
||||
let disabledIds: Array<string> = [];
|
||||
const val = getProperties(infoId);
|
||||
if (val && val.formConfigs && val.formConfigs.length > 0) {
|
||||
disabledIds = val.formConfigs.map((ele) => {
|
||||
return ele.formId;
|
||||
});
|
||||
}
|
||||
for (const item of info.values()) {
|
||||
const showNodeTypes = [BpmnNodeKey.START, BpmnNodeKey.USER];
|
||||
if (showNodeTypes.includes(item.type)) {
|
||||
if (item.formConfigs.length > 0) {
|
||||
item.formConfigs.forEach((element) => {
|
||||
if (formKeyList[element.key]) {
|
||||
if (formKeyList[element.key]['nodeIds']) {
|
||||
formKeyList[element.key]['nodeIds'].push(item.id);
|
||||
}
|
||||
} else {
|
||||
formKeyList[element.key] = element;
|
||||
formKeyList[element.key]['nodeIds'] = [item.id];
|
||||
}
|
||||
if (formList[element.formId]) {
|
||||
if (formList[element.formId] && !disabledIds.includes(element.formId)) {
|
||||
formList[element.formId].push(element.key);
|
||||
}
|
||||
} else {
|
||||
if (!disabledIds.includes(element.formId)) formList[element.formId] = [element.key];
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
const notRepeatedList: Array<any> = [];
|
||||
const repeatedList = {};
|
||||
for (const [key, value] of Object.entries(formList)) {
|
||||
if (value && Array.isArray(value)) {
|
||||
const setForms = [...new Set(value)];
|
||||
if (setForms.length == 1) {
|
||||
notRepeatedList.push(setForms[0]);
|
||||
} else {
|
||||
repeatedList[key] = setForms;
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
formKeyList,
|
||||
repeatedList,
|
||||
notRepeatedList,
|
||||
};
|
||||
}
|
||||
|
||||
// 获取所有节点表单使用列表
|
||||
export function getUsedFormIds() {
|
||||
const usedFormIds: Array<string> = [];
|
||||
const store = useBpmnStore();
|
||||
const { info } = store;
|
||||
for (const item of info.values()) {
|
||||
const showNodeTypes = [BpmnNodeKey.START, BpmnNodeKey.USER];
|
||||
if (showNodeTypes.includes(item.type)) {
|
||||
if (item.formConfigs.length > 0) {
|
||||
item.formConfigs.forEach((element) => {
|
||||
if (element.formId) {
|
||||
usedFormIds.push(element.formId);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return [...new Set(usedFormIds)];
|
||||
}
|
||||
175
src/views/workflow/design/bpmn/config/property.ts
Normal file
175
src/views/workflow/design/bpmn/config/property.ts
Normal file
@ -0,0 +1,175 @@
|
||||
import { useBpmnStore } from '/@bpmn/store/bpmn';
|
||||
import { BpmnNodeKey } from '/@/enums/workflowEnum';
|
||||
import { formPermissionList } from '/@bpmn/config/formPermission';
|
||||
import { InfoId, InfoItem, InfoType } from '/@/model/workflow/bpmnConfig';
|
||||
import { ChildNodeConfig, ProcessConfig } from '/@/model/workflow/workflowConfig';
|
||||
import { FormConfigItem } from '/@/model/workflow/formSetting';
|
||||
import {
|
||||
processConfig,
|
||||
defaultProperties,
|
||||
propertiesByType,
|
||||
nodeNameByType,
|
||||
} from './propertyConfig';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
// 流程模板默认属性
|
||||
export const getProcessConfig: ProcessConfig = processConfig;
|
||||
// 根据节点类型获取节点默认属性
|
||||
export const getDefaultProperties = function (type: InfoType) {
|
||||
return propertiesByType.has(type) ? propertiesByType.get(type) : defaultProperties;
|
||||
};
|
||||
// 根据节点类型获取节点名称
|
||||
export const getNodeName = (type: InfoType) => {
|
||||
return nodeNameByType.has(type) ? nodeNameByType.get(type) : '';
|
||||
};
|
||||
// 根据节点类型获取节点名称加随机数
|
||||
export const getLabelName = (type: InfoType) => {
|
||||
return getNodeName(type);
|
||||
// + 123;
|
||||
};
|
||||
// 初始化开始节点信息
|
||||
export const initStartProperties = () => {
|
||||
const bpmnStore = useBpmnStore();
|
||||
initProperties(getStartNodeId, BpmnNodeKey.START, t('开始节点'), bpmnStore.processInfo.processId);
|
||||
};
|
||||
// 修改流程属性
|
||||
export const changeProcessProperties = async (processConfig: ProcessConfig) => {
|
||||
const bpmnStore = useBpmnStore();
|
||||
if (processConfig.defaultFormList.length > 0) {
|
||||
const returnArr = await formPermissionList(processConfig.defaultFormList);
|
||||
setDefaultFormList(returnArr);
|
||||
}
|
||||
bpmnStore.setProcessInfo(processConfig);
|
||||
bpmnStore.setInfoId(processConfig.processId);
|
||||
};
|
||||
// 是否可以初始化节点属性【没有相关节点信息】
|
||||
export const CanInitializeProperties = (id: InfoId) => {
|
||||
return !hasProperties(id);
|
||||
};
|
||||
// 是否有节点信息缓存
|
||||
export const hasProperties = (id: InfoId) => {
|
||||
const bpmnStore = useBpmnStore();
|
||||
return bpmnStore.hasProperties(id);
|
||||
};
|
||||
// 设置节点信息缓存
|
||||
export const setProperties = (id: InfoId, element: InfoItem) => {
|
||||
const bpmnStore = useBpmnStore();
|
||||
bpmnStore.setProperties(id, element);
|
||||
};
|
||||
// 初始化节点信息缓存
|
||||
export const initProperties = (id: InfoId, type: InfoType, name: string, parentId: string) => {
|
||||
const bpmnStore = useBpmnStore();
|
||||
const { defaultFormList, processInfo } = bpmnStore;
|
||||
const properties = cloneDeep(getDefaultProperties(type));
|
||||
properties.id = id;
|
||||
properties.name = name;
|
||||
properties.type = type;
|
||||
properties.parentId = parentId;
|
||||
if (type == BpmnNodeKey.START || type == BpmnNodeKey.USER) {
|
||||
properties.formConfigs = cloneDeep(defaultFormList);
|
||||
}
|
||||
if (type == BpmnNodeKey.USER) {
|
||||
properties.autoAgreeRule = processInfo.autoAgreeRule;
|
||||
properties.noHandler = processInfo.noHandler;
|
||||
properties.isPrevChooseNext = processInfo.isPrevChooseNext;
|
||||
}
|
||||
|
||||
setProperties(id, properties);
|
||||
};
|
||||
// 移除节点信息缓存
|
||||
export const removeProperties = (id: InfoId) => {
|
||||
const bpmnStore = useBpmnStore();
|
||||
if (bpmnStore.hasProperties(id)) {
|
||||
bpmnStore.deleteProperties(id);
|
||||
}
|
||||
};
|
||||
// 修改节点parentId
|
||||
export const changePropertiesByParentId = (id: InfoId, parentId: InfoId) => {
|
||||
const bpmnStore = useBpmnStore();
|
||||
if (bpmnStore.hasProperties(id)) {
|
||||
const properties = bpmnStore.getProperties(id);
|
||||
if (properties) {
|
||||
properties.parentId = parentId;
|
||||
setProperties(id, properties);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//设置默认表单列表
|
||||
export const setDefaultFormList = (list: Array<FormConfigItem>) => {
|
||||
const bpmnStore = useBpmnStore();
|
||||
bpmnStore.setDefaultFormList(list);
|
||||
};
|
||||
//根据默认表单设置,追加所有表单节点的表单配置
|
||||
export const nodesAppendDefaultForm = (list: Array<FormConfigItem>) => {
|
||||
const bpmnStore = useBpmnStore();
|
||||
setDefaultFormList(cloneDeep(list));
|
||||
const { info } = bpmnStore;
|
||||
for (const [key, value] of info) {
|
||||
if (value.type == BpmnNodeKey.START || value.type == BpmnNodeKey.USER) {
|
||||
const properties = bpmnStore.getProperties(key);
|
||||
if (properties) {
|
||||
properties.formConfigs = [...properties.formConfigs, ...list];
|
||||
setProperties(key, properties);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
// 设置childNodes属性
|
||||
export const setChildNodesProperties = (childNodes: ChildNodeConfig) => {
|
||||
const bpmnStore = useBpmnStore();
|
||||
if (childNodes.length > 0) {
|
||||
childNodes.forEach((element: InfoItem) => {
|
||||
if (element.id && !bpmnStore.hasProperties(element.id)) {
|
||||
setProperties(element.id, element);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 获取缓存所有节点信息
|
||||
export const getBpmnJson = () => {
|
||||
const bpmnStore = useBpmnStore();
|
||||
const { info, processInfo } = bpmnStore;
|
||||
const childNodeConfig = [...info.values()];
|
||||
return { childNodeConfig, processConfig: processInfo };
|
||||
};
|
||||
|
||||
export const getStartNodeId = 'Event_start_node';
|
||||
export const getInitializeXml = (resourceId: string) => {
|
||||
return `
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1u51epq" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.2.0" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.17.0">
|
||||
<bpmn:process id="${resourceId}" name="${resourceId}" isExecutable="true">
|
||||
<bpmn:startEvent id="${getStartNodeId}" name="开始节点" />
|
||||
</bpmn:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1m1pmsz">
|
||||
<bpmndi:BPMNShape id="${getStartNodeId}_di" bpmnElement="${getStartNodeId}">
|
||||
<dc:Bounds x="159" y="359" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn:definitions>
|
||||
|
||||
`;
|
||||
|
||||
// return `<?xml version="1.0" encoding="UTF-8"?>
|
||||
// <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:flowable="http://flowable.org/bpmn" targetNamespace="http://www.flowable.org/processdef">
|
||||
// <process id="${resourceId}" name="${resourceId}" isExecutable="true">
|
||||
// <startEvent id="${getStartNodeId}" name="开始节点" />
|
||||
// </process>
|
||||
// <bpmndi:BPMNDiagram id="BPMNDiagram_flow">
|
||||
// <bpmndi:BPMNPlane id="BPMNPlane_flow" bpmnElement="process_drril0cw">
|
||||
// <bpmndi:BPMNShape id="${getStartNodeId}_di" bpmnElement="${getStartNodeId}">
|
||||
// <omgdc:Bounds x="-708" y="-208" width="36" height="36" />
|
||||
// <bpmndi:BPMNLabel>
|
||||
// <omgdc:Bounds x="-712" y="-165" width="44" height="14" />
|
||||
// </bpmndi:BPMNLabel>
|
||||
// </bpmndi:BPMNShape>
|
||||
// </bpmndi:BPMNPlane>
|
||||
// </bpmndi:BPMNDiagram>
|
||||
// </definitions>
|
||||
// `;
|
||||
};
|
||||
324
src/views/workflow/design/bpmn/config/propertyConfig.ts
Normal file
324
src/views/workflow/design/bpmn/config/propertyConfig.ts
Normal file
@ -0,0 +1,324 @@
|
||||
import {
|
||||
AddOrRemoveType,
|
||||
ApprovalOpinionDisplayType,
|
||||
AuthType,
|
||||
BpmnNodeKey,
|
||||
ButtonType,
|
||||
MultipleInstancesType,
|
||||
DesignatedApprover,
|
||||
ElectronicSignatureVerification,
|
||||
FormType,
|
||||
InstanceCompletionConditions,
|
||||
NoHandler,
|
||||
RecordType,
|
||||
RejectType,
|
||||
CallActivityType,
|
||||
FinishType,
|
||||
ExecutionType,
|
||||
MemberType,
|
||||
ApproveType,
|
||||
ApproveCode,
|
||||
TimeOutHandle,
|
||||
TimeOutRule,
|
||||
TimeOutType,
|
||||
} from '/@/enums/workflowEnum';
|
||||
import { InfoType } from '/@/model/workflow/bpmnConfig';
|
||||
import {
|
||||
CallActivityConfig,
|
||||
EndEventConfig,
|
||||
GatewayConfig,
|
||||
ProcessConfig,
|
||||
ScriptTaskConfig,
|
||||
SequenceFlowConfig,
|
||||
StartEventConfig,
|
||||
UserTaskConfig,
|
||||
} from '/@/model/workflow/workflowConfig';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
// 流程模板默认属性
|
||||
export const processConfig: ProcessConfig = {
|
||||
processId: '', //节点id
|
||||
type: BpmnNodeKey.PROCESS, //节点类型
|
||||
code: '', //模板编码
|
||||
name: '', //节点名称
|
||||
parentId: '', //父节点(流程id)
|
||||
category: undefined, //分类
|
||||
nameRule: '', //命名规则
|
||||
nameRuleConfigs: [], // 命名规则列表
|
||||
autoAgreeRule: [], //自动同意规则
|
||||
isPrevChooseNext: DesignatedApprover.NOT_SPECIFIED, //是否上一节点审批人指定下一节点审批人
|
||||
noHandler: NoHandler.ADMIN, //无对应处理人
|
||||
appShow: false, //移动端是否显示
|
||||
defaultFormList: [], //默认表单
|
||||
remark: '', //节点描述
|
||||
content: '', //xml
|
||||
authConfig: {
|
||||
//权限设置
|
||||
authType: AuthType.ALL,
|
||||
authMemberConfigs: [],
|
||||
},
|
||||
menuConfig: {
|
||||
//是否启用菜单
|
||||
enabled: false,
|
||||
code: '',
|
||||
name: '',
|
||||
system: undefined,
|
||||
parentId: undefined,
|
||||
icon: '',
|
||||
order: undefined,
|
||||
remark: '',
|
||||
},
|
||||
formInitConfig: {
|
||||
//表单发起流程
|
||||
enabled: false,
|
||||
formType: FormType.CUSTOM,
|
||||
formId: '',
|
||||
formName: '',
|
||||
},
|
||||
timeoutRemidConfig: {
|
||||
//超时提醒配置
|
||||
enabled: false,
|
||||
hour: undefined, //超时时间
|
||||
interval: undefined, //消息间隔
|
||||
pushHits: undefined, //推送次数
|
||||
pushMemberConfigs: [], //推送人
|
||||
},
|
||||
relationProcessConfigs: [], //关联任务
|
||||
processParamConfigs: [], //流程参数
|
||||
xmlContent: '',
|
||||
};
|
||||
// 默认属性
|
||||
export const defaultProperties = {
|
||||
id: '', //节点id
|
||||
type: BpmnNodeKey.EVENT, //节点类型
|
||||
name: '', //节点名称
|
||||
parentId: '', //父节点(流程id)
|
||||
remark: '', //节点描述
|
||||
};
|
||||
// 开始节点默认属性
|
||||
const StartProperties: StartEventConfig = {
|
||||
id: '', //节点id
|
||||
type: BpmnNodeKey.START, //节点类型
|
||||
name: '', //节点名称
|
||||
parentId: '', //父节点(流程id)
|
||||
remark: '', //节点描述
|
||||
formConfigs: [], //表单配置
|
||||
subProcessInitiator: '', //子流程开始节点发起人
|
||||
assignmentConfig: { formAssignmentConfigs: [], paramAssignmentConfigs: [] }, //参数操作
|
||||
startEventConfigs: [],
|
||||
endEventConfigs: [],
|
||||
};
|
||||
// 结束节点默认属性
|
||||
const EndProperties: EndEventConfig = {
|
||||
id: '', //节点id
|
||||
type: BpmnNodeKey.END, //节点类型
|
||||
name: '', //节点名称
|
||||
parentId: '', //父节点(流程id)
|
||||
remark: '', //节点描述
|
||||
noticePolicyConfigs: [], //通知策略
|
||||
startEventConfigs: [],
|
||||
endEventConfigs: [],
|
||||
};
|
||||
// 用户节点默认属性
|
||||
const UserProperties: UserTaskConfig = {
|
||||
id: '', //节点id
|
||||
type: BpmnNodeKey.USER, //节点类型
|
||||
currentProgress: undefined, //进度
|
||||
name: '', //节点名称
|
||||
parentId: '', //父节点(流程id)
|
||||
remark: '', //节点描述
|
||||
formConfigs: [], //表单配置
|
||||
noticePolicyConfigs: [], //通知策略
|
||||
approverConfigs: [], //审批人
|
||||
circulateConfigs: [], //传阅人
|
||||
autoAgreeRule: [], //自动同意规则
|
||||
isPrevChooseNext: DesignatedApprover.NOT_SPECIFIED, //是否上一节点审批人指定下一节点审批人
|
||||
provisionalApprover: false, //临时审批人
|
||||
noHandler: NoHandler.ADMIN, //无对应处理人
|
||||
countersignConfig: {
|
||||
multipleInstancesType: MultipleInstancesType.NONE, //多实例类型
|
||||
addOrRemove: AddOrRemoveType.ALLOW, //加签 或者 减签
|
||||
finishType: InstanceCompletionConditions.ALL, //完成条件 多实例
|
||||
percentage: 0,
|
||||
countersignList: [],
|
||||
}, //会签
|
||||
buttonConfigs: [
|
||||
{
|
||||
buttonType: ButtonType.DEFAULT, //按钮类型
|
||||
buttonName: t('同意'), //按钮名称
|
||||
buttonCode: ApproveCode.AGREE, //按钮编码
|
||||
approveType: ApproveType.AGREE, //
|
||||
checked: true, //选中
|
||||
},
|
||||
{
|
||||
buttonType: ButtonType.DEFAULT, //按钮类型
|
||||
buttonName: t('拒绝'), //按钮名称
|
||||
buttonCode: ApproveCode.DISAGREE, //按钮编码
|
||||
approveType: ApproveType.DISAGREE, //
|
||||
checked: true, //选中
|
||||
},
|
||||
{
|
||||
buttonType: ButtonType.DEFAULT, //按钮类型
|
||||
buttonName: t('驳回'), //按钮名称
|
||||
buttonCode: ApproveCode.REJECT, //按钮编码
|
||||
approveType: ApproveType.REJECT, //
|
||||
checked: true, //选中
|
||||
buttonOpera: RejectType.ALL,
|
||||
},
|
||||
{
|
||||
buttonType: ButtonType.DEFAULT, //按钮类型
|
||||
buttonName: t('结束'), //按钮名称
|
||||
buttonCode: ApproveCode.FINISH, //按钮编码
|
||||
approveType: ApproveType.FINISH, //
|
||||
checked: true, //选中
|
||||
},
|
||||
], //按钮配置
|
||||
opinionConfig: {
|
||||
enabled: false, //是否关联表单
|
||||
showType: ApprovalOpinionDisplayType.ALL, //审批意见展示类型 0 显示所有 1 显示最终结果
|
||||
signature: ElectronicSignatureVerification.NO_PASSWORD_REQUIRED, //电子签章验证
|
||||
component: [], //关联意见框组件
|
||||
},
|
||||
assignmentConfig: {
|
||||
formAssignmentConfigs: [],
|
||||
paramAssignmentConfigs: [],
|
||||
}, //参数操作
|
||||
timeOutHandle: {
|
||||
isHandle: TimeOutHandle.NO,
|
||||
rule: TimeOutRule.MAX,
|
||||
type: TimeOutType.AGREE,
|
||||
user: 1,
|
||||
auto: 1,
|
||||
}, //超时处理
|
||||
startEventConfigs: [],
|
||||
endEventConfigs: [],
|
||||
};
|
||||
// 脚本节点默认属性
|
||||
const ScriptProperties: ScriptTaskConfig = {
|
||||
id: '', //节点id
|
||||
type: BpmnNodeKey.SCRIPT, //节点类型
|
||||
// Recorded
|
||||
name: '', //节点名称
|
||||
parentId: '', //父节点(流程id)
|
||||
remark: '', //节点描述
|
||||
recordInfo: RecordType.RECORD,
|
||||
noticePolicyConfigs: [], //通知策略
|
||||
script: {
|
||||
enabled: false,
|
||||
scriptFormat: 'JavaScript', //脚本格式
|
||||
scriptContent: ' var a = 1', //脚本内容
|
||||
},
|
||||
api: {
|
||||
enabled: false,
|
||||
apiConfig: {
|
||||
id: '',
|
||||
name: '',
|
||||
method: '',
|
||||
requestParamsConfigs: [], //Query Params
|
||||
requestHeaderConfigs: [], //Header
|
||||
requestBodyConfigs: [], //Body
|
||||
},
|
||||
},
|
||||
assignmentConfig: { formAssignmentConfigs: [], paramAssignmentConfigs: [] }, //参数操作
|
||||
startEventConfigs: [],
|
||||
endEventConfigs: [],
|
||||
};
|
||||
// 连接线
|
||||
const SequenceFlowProperties: SequenceFlowConfig = {
|
||||
id: '', //节点id
|
||||
type: BpmnNodeKey.SEQUENCEFLOW, //节点类型
|
||||
name: '', //节点名称
|
||||
parentId: '', //父节点(流程id)
|
||||
remark: '', //节点描述
|
||||
conditionConfigs: [], //流转条件
|
||||
startEventConfigs: [],
|
||||
endEventConfigs: [],
|
||||
};
|
||||
// 子流程
|
||||
const SubProcessProperties = {
|
||||
id: '', //节点id
|
||||
type: BpmnNodeKey.SUB_PROCESS, //节点类型
|
||||
name: '', //节点名称
|
||||
parentId: '', //父节点(流程id)
|
||||
remark: '', //节点描述
|
||||
startEventConfigs: [],
|
||||
endEventConfigs: [],
|
||||
};
|
||||
// 外部流程
|
||||
const CallActivityProperties: CallActivityConfig = {
|
||||
id: '', //节点id
|
||||
type: BpmnNodeKey.CALLACTIVITY, //节点类型
|
||||
name: '', //节点名称
|
||||
parentId: '', //父节点(流程id)
|
||||
remark: '', //节点描述
|
||||
schemaId: '', //被调用元素(外部流程schemaId)
|
||||
schemaName: '', //被调用元素(外部流程名称)
|
||||
callActivityType: CallActivityType.SINGLE, // 调用类型
|
||||
finishType: FinishType.ALL, //完成条件
|
||||
percentOf: undefined, //百分比数值
|
||||
executionType: ExecutionType.SEQUENCE, //执行类型
|
||||
originatorNode: '', //如果调用类型为单实例 子流程发起人
|
||||
originatorType: MemberType.FORM_FIELD, //发起人类型
|
||||
originatorConfig: '', //表单数据
|
||||
inParams: [], //输入参数
|
||||
outParams: [], //输出参数
|
||||
startEventConfigs: [],
|
||||
endEventConfigs: [],
|
||||
};
|
||||
// 互斥网关
|
||||
const ExclusiveGatewayProperties: GatewayConfig = {
|
||||
id: '', //节点id
|
||||
type: BpmnNodeKey.EXCLUSIVE, //节点类型
|
||||
name: '', //节点名称
|
||||
parentId: '', //父节点(流程id)
|
||||
remark: '', //节点描述
|
||||
startEventConfigs: [],
|
||||
endEventConfigs: [],
|
||||
};
|
||||
// 相容网关
|
||||
const InclusiveGatewayProperties: GatewayConfig = {
|
||||
id: '', //节点id
|
||||
type: BpmnNodeKey.INCLUSIVE, //节点类型
|
||||
name: '', //节点名称
|
||||
parentId: '', //父节点(流程id)
|
||||
remark: '', //节点描述
|
||||
startEventConfigs: [],
|
||||
endEventConfigs: [],
|
||||
};
|
||||
// 并行网关
|
||||
const ParallelGatewayProperties: GatewayConfig = {
|
||||
id: '', //节点id
|
||||
type: BpmnNodeKey.PARALLEL, //节点类型
|
||||
name: '', //节点名称
|
||||
parentId: '', //父节点(流程id)
|
||||
remark: '', //节点描述
|
||||
startEventConfigs: [],
|
||||
endEventConfigs: [],
|
||||
};
|
||||
// 获取节点默认属性
|
||||
export const propertiesByType: Map<InfoType, any> = new Map([
|
||||
[BpmnNodeKey.START, StartProperties],
|
||||
[BpmnNodeKey.END, EndProperties],
|
||||
[BpmnNodeKey.USER, UserProperties],
|
||||
[BpmnNodeKey.SCRIPT, ScriptProperties],
|
||||
[BpmnNodeKey.EXCLUSIVE, ExclusiveGatewayProperties],
|
||||
[BpmnNodeKey.INCLUSIVE, InclusiveGatewayProperties],
|
||||
[BpmnNodeKey.PARALLEL, ParallelGatewayProperties],
|
||||
[BpmnNodeKey.SUB_PROCESS, SubProcessProperties],
|
||||
[BpmnNodeKey.CALLACTIVITY, CallActivityProperties],
|
||||
[BpmnNodeKey.SEQUENCEFLOW, SequenceFlowProperties],
|
||||
]);
|
||||
// 根据节点类型获取节点名称
|
||||
export const nodeNameByType: Map<InfoType, any> = new Map([
|
||||
[BpmnNodeKey.START, t('开始节点')],
|
||||
[BpmnNodeKey.END, t('结束节点')],
|
||||
[BpmnNodeKey.USER, t('用户节点')],
|
||||
[BpmnNodeKey.SCRIPT, t('脚本节点')],
|
||||
[BpmnNodeKey.EXCLUSIVE, t('互斥网关')],
|
||||
[BpmnNodeKey.INCLUSIVE, t('相容网关')],
|
||||
[BpmnNodeKey.PARALLEL, t('并行网关')],
|
||||
[BpmnNodeKey.SUB_PROCESS, t('子流程')],
|
||||
[BpmnNodeKey.CALLACTIVITY, t('外部流程')],
|
||||
[BpmnNodeKey.SEQUENCEFLOW, t('流程线')],
|
||||
[BpmnNodeKey.PROCESS, t('流程模板')],
|
||||
]);
|
||||
206
src/views/workflow/design/bpmn/config/rules.ts
Normal file
206
src/views/workflow/design/bpmn/config/rules.ts
Normal file
@ -0,0 +1,206 @@
|
||||
import type { TreeProps } from 'ant-design-vue';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
// 模板信息
|
||||
const template = {
|
||||
title: t('模板信息'),
|
||||
key: 'template',
|
||||
children: [
|
||||
{
|
||||
title: t('模板名称'),
|
||||
key: '#{template_name}#',
|
||||
},
|
||||
{
|
||||
title: t('模板编号'),
|
||||
key: '#{template_code}#',
|
||||
},
|
||||
{
|
||||
title: t('模板分类'),
|
||||
key: '#{template_category}#',
|
||||
},
|
||||
{
|
||||
title: t('模板备注'),
|
||||
key: '#{template_remark}#',
|
||||
},
|
||||
],
|
||||
};
|
||||
// 流程参数
|
||||
const templateOfProcessArgument = {
|
||||
title: t('模板信息'),
|
||||
key: 'template',
|
||||
children: [
|
||||
{
|
||||
title: t('模板名称'),
|
||||
key: '#{template_name}#',
|
||||
},
|
||||
{
|
||||
title: t('模板编号'),
|
||||
key: '#{template_code}#',
|
||||
},
|
||||
{
|
||||
title: t('模板分类'),
|
||||
key: '#{template_category}#',
|
||||
},
|
||||
{
|
||||
title: t('模板备注'),
|
||||
key: '#{template_remark}#',
|
||||
},
|
||||
],
|
||||
};
|
||||
// 流程信息
|
||||
const flow = {
|
||||
title: t('流程信息'),
|
||||
key: 'flow',
|
||||
children: [
|
||||
{
|
||||
title: t('全局流程流水号'),
|
||||
key: '#{serial_number}#',
|
||||
},
|
||||
],
|
||||
};
|
||||
//发起人信息
|
||||
const initiator = {
|
||||
title: t('发起人信息'),
|
||||
key: 'initiator',
|
||||
children: [
|
||||
{
|
||||
title: t('发起人id'),
|
||||
key: '#{initiator_id}#',
|
||||
},
|
||||
{
|
||||
title: t('发起人名称'),
|
||||
key: '#{initiator_user_name}#',
|
||||
},
|
||||
{
|
||||
title: t('发起人编码'),
|
||||
key: '#{initiator_code}#',
|
||||
},
|
||||
{
|
||||
title: t('发起人手机号码'),
|
||||
key: '#{initiator_mobile}#',
|
||||
},
|
||||
{
|
||||
title: t('发起人所属组织架构名称'),
|
||||
key: '#{initiator_dept_name}#',
|
||||
},
|
||||
],
|
||||
};
|
||||
// 流程命名变量 流程发起时间
|
||||
const namedVariableDatetime = {
|
||||
title: t('流程发起时间'),
|
||||
key: 'datetime',
|
||||
children: [
|
||||
{
|
||||
title: 'yyyyMMddHHmmss',
|
||||
key: '#{yyyy-MM-dd HH:mm:ss}#',
|
||||
},
|
||||
{
|
||||
title: 'yyyyMMdd',
|
||||
key: '#{yyyy-MM-dd}#',
|
||||
},
|
||||
{
|
||||
title: 'HHmmss',
|
||||
key: '#{HH:mm:ss}#',
|
||||
},
|
||||
],
|
||||
};
|
||||
// 流程参数变量 流程发起时间
|
||||
const procellvVariableDatetime = {
|
||||
title: t('流程发起时间'),
|
||||
key: 'datetime',
|
||||
children: [
|
||||
{
|
||||
title: 'yyyy-MM-dd HH-mm-ss',
|
||||
key: '#{yyyy-MM-dd HH:mm:ss}#',
|
||||
},
|
||||
{
|
||||
title: 'yyyy-MM-dd',
|
||||
key: '#{yyyy-MM-dd}#',
|
||||
},
|
||||
{
|
||||
title: 'HH:mm:ss',
|
||||
key: '#{HH:mm:ss}#',
|
||||
},
|
||||
],
|
||||
};
|
||||
// 流程命名变量
|
||||
export const ProcessNamedVariable: TreeProps['treeData'] = [
|
||||
template,
|
||||
flow,
|
||||
initiator,
|
||||
namedVariableDatetime,
|
||||
];
|
||||
// 流程参数 流程变量树
|
||||
export const ProcessArgumentTreeData: TreeProps['treeData'] = [
|
||||
templateOfProcessArgument,
|
||||
flow,
|
||||
initiator,
|
||||
procellvVariableDatetime,
|
||||
];
|
||||
// 流程数据变量
|
||||
export const ProcessDataVariable: TreeProps['treeData'] = [
|
||||
template,
|
||||
flow,
|
||||
initiator,
|
||||
namedVariableDatetime,
|
||||
];
|
||||
// 符号
|
||||
export const symbolRuleMap = new Map([
|
||||
[
|
||||
'-',
|
||||
{
|
||||
title: '-',
|
||||
key: '#{random_-}#',
|
||||
},
|
||||
],
|
||||
]);
|
||||
// 随机数
|
||||
export const randomNumberRuleList = [
|
||||
{
|
||||
title: t('4位随机数'),
|
||||
key: '#{random_4}#',
|
||||
},
|
||||
{
|
||||
title: t('4位随机数(数字+字母)'),
|
||||
key: '#{random_4_mix}#',
|
||||
},
|
||||
{
|
||||
title: t('6位随机数'),
|
||||
key: '#{random_6}#',
|
||||
},
|
||||
{
|
||||
title: t('6位随机数(数字+字母)'),
|
||||
key: '#{random_6_mix}#',
|
||||
},
|
||||
{
|
||||
title: t('8位随机数'),
|
||||
key: '#{random_8}#',
|
||||
},
|
||||
{
|
||||
title: t('8位随机数(数字+字母)'),
|
||||
key: '#{random_8_mix}#',
|
||||
},
|
||||
];
|
||||
// 流水号
|
||||
export const serialRuleList = [
|
||||
{
|
||||
title: t('4位流水号'),
|
||||
key: '#{serial_number_four}#',
|
||||
},
|
||||
{
|
||||
title: t('5位流水号'),
|
||||
key: '#{serial_number_five}#',
|
||||
},
|
||||
{
|
||||
title: t('6位流水号'),
|
||||
key: '#{serial_number_six}#',
|
||||
},
|
||||
{
|
||||
title: t('7位流水号'),
|
||||
key: '#{serial_number_seven}#',
|
||||
},
|
||||
{
|
||||
title: t('8位流水号'),
|
||||
key: '#{serial_number_eight}#',
|
||||
},
|
||||
];
|
||||
98
src/views/workflow/design/bpmn/config/sequenceConfig.ts
Normal file
98
src/views/workflow/design/bpmn/config/sequenceConfig.ts
Normal file
@ -0,0 +1,98 @@
|
||||
import { ApproveCode } from '/@/enums/workflowEnum';
|
||||
import { getVariablesTree } from '/@bpmn/config/info';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
// 运算变量
|
||||
export const getDataOfVariablesTree = () => {
|
||||
const res = getVariablesTree({ needUserNodeButton: true, needHideComponents: true });
|
||||
return res ? res : [];
|
||||
};
|
||||
// 运算符
|
||||
export const operators = [
|
||||
{
|
||||
value: '==',
|
||||
label: '==',
|
||||
},
|
||||
{
|
||||
value: '+',
|
||||
label: '+',
|
||||
},
|
||||
{
|
||||
value: '-',
|
||||
label: '-',
|
||||
},
|
||||
{
|
||||
value: '*',
|
||||
label: '*',
|
||||
},
|
||||
{
|
||||
value: '/',
|
||||
label: '/',
|
||||
},
|
||||
{
|
||||
value: '(',
|
||||
label: '(',
|
||||
},
|
||||
{
|
||||
value: ')',
|
||||
label: ')',
|
||||
},
|
||||
{
|
||||
value: '!=',
|
||||
label: '!=',
|
||||
},
|
||||
{
|
||||
value: '>',
|
||||
label: '>',
|
||||
},
|
||||
{
|
||||
value: '>=',
|
||||
label: '>=',
|
||||
},
|
||||
{
|
||||
value: '<',
|
||||
label: '<',
|
||||
},
|
||||
{
|
||||
value: '<=',
|
||||
label: '<=',
|
||||
},
|
||||
{
|
||||
value: '⊇',
|
||||
label: '⊇',
|
||||
},
|
||||
];
|
||||
|
||||
export const buttons = [
|
||||
{
|
||||
key: ApproveCode.AGREE,
|
||||
title: t('同意'),
|
||||
},
|
||||
{
|
||||
key: ApproveCode.REJECT,
|
||||
title: t('拒绝'),
|
||||
},
|
||||
];
|
||||
// 与或非
|
||||
export const andOrNotList = [
|
||||
{
|
||||
value: '&&',
|
||||
label: t('与'),
|
||||
},
|
||||
{
|
||||
value: '||',
|
||||
label: t('或'),
|
||||
},
|
||||
{
|
||||
value: '!=',
|
||||
label: t('非'),
|
||||
},
|
||||
];
|
||||
|
||||
//特殊值
|
||||
export const specialValues = [
|
||||
{
|
||||
value: 'null',
|
||||
label: 'null',
|
||||
},
|
||||
];
|
||||
196
src/views/workflow/design/bpmn/config/useUpdateAllFormInfo.ts
Normal file
196
src/views/workflow/design/bpmn/config/useUpdateAllFormInfo.ts
Normal file
@ -0,0 +1,196 @@
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { separator } from './info';
|
||||
import { BpmnNodeKey, ParamType } from '/@/enums/workflowEnum';
|
||||
import { InfoItem } from '/@/model/workflow/bpmnConfig';
|
||||
import { useBpmnStore } from '/@bpmn/store/bpmn';
|
||||
|
||||
// 删除参数:删除流程参数会清空已引用该参数的所有配置
|
||||
export function updateProcessParameterRelevance(formKey: string) {
|
||||
const bpmnStore = useBpmnStore();
|
||||
const { info } = storeToRefs(bpmnStore);
|
||||
for (const [key, item] of info.value) {
|
||||
if (
|
||||
item.type == BpmnNodeKey.START ||
|
||||
item.type == BpmnNodeKey.USER ||
|
||||
item.type == BpmnNodeKey.SCRIPT
|
||||
) {
|
||||
const element: null | InfoItem = changeProcessParamAssignmentConfig(formKey, item);
|
||||
if (element) {
|
||||
bpmnStore.setProperties(key, element);
|
||||
}
|
||||
} else if (item.type == BpmnNodeKey.CALLACTIVITY) {
|
||||
const element: null | InfoItem = callactivityInfoFromSearchKey(formKey, item);
|
||||
if (element) {
|
||||
bpmnStore.setProperties(key, element);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 删除表单:删除表单会清空已引用该表单数据的所有配置
|
||||
export function updateFormDataInfo(formKey: string) {
|
||||
const bpmnStore = useBpmnStore();
|
||||
const { info } = storeToRefs(bpmnStore);
|
||||
for (const [key, item] of info.value) {
|
||||
if (item.type == BpmnNodeKey.START || item.type == BpmnNodeKey.USER) {
|
||||
const element: null | InfoItem = changeFormInfoAssignmentConfig(formKey, item);
|
||||
if (element) {
|
||||
bpmnStore.setProperties(key, element);
|
||||
}
|
||||
} else if (item.type == BpmnNodeKey.SEQUENCEFLOW) {
|
||||
const element: null | InfoItem = sequenceInfoFromSearchKey(formKey, item);
|
||||
if (element) {
|
||||
bpmnStore.setProperties(key, element);
|
||||
}
|
||||
} else if (item.type == BpmnNodeKey.CALLACTIVITY) {
|
||||
const element: null | InfoItem = callactivityInfoFromSearchKey(formKey, item);
|
||||
if (element) {
|
||||
bpmnStore.setProperties(key, element);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 更新表单:表单字段在新表单中被删除了需要清空已引用该表单字段数据的所有配置
|
||||
export function updateFormFieldIdRelevance(formKey: string, field: string) {
|
||||
const bpmnStore = useBpmnStore();
|
||||
const { info } = storeToRefs(bpmnStore);
|
||||
|
||||
for (const [key, item] of info.value) {
|
||||
const filedKey = item.id + separator + formKey + separator + field;
|
||||
if (item.type == BpmnNodeKey.START || item.type == BpmnNodeKey.USER) {
|
||||
const element: null | InfoItem = changeFormInfoAssignmentConfig(filedKey, item);
|
||||
if (element) {
|
||||
bpmnStore.setProperties(key, element);
|
||||
}
|
||||
} else if (item.type == BpmnNodeKey.SEQUENCEFLOW) {
|
||||
const element: null | InfoItem = sequenceInfoFromSearchKey(filedKey, item);
|
||||
if (element) {
|
||||
bpmnStore.setProperties(key, element);
|
||||
}
|
||||
} else if (item.type == BpmnNodeKey.CALLACTIVITY) {
|
||||
const element: null | InfoItem = callactivityInfoFromSearchKey(filedKey, item);
|
||||
if (element) {
|
||||
bpmnStore.setProperties(key, element);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 节点,剔除已经配置了此流程参数的数据【参数操作】
|
||||
function changeProcessParamAssignmentConfig(formKey: string, element: InfoItem): null | InfoItem {
|
||||
let needChange = false;
|
||||
if (
|
||||
element.assignmentConfig &&
|
||||
element.assignmentConfig.formAssignmentConfigs &&
|
||||
element.assignmentConfig.formAssignmentConfigs.length > 0
|
||||
) {
|
||||
element.assignmentConfig.formAssignmentConfigs =
|
||||
element.assignmentConfig.formAssignmentConfigs.filter((item) => {
|
||||
if (item.source === formKey) {
|
||||
needChange = true; // 删除
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (
|
||||
element.assignmentConfig &&
|
||||
element.assignmentConfig.paramAssignmentConfigs &&
|
||||
element.assignmentConfig.paramAssignmentConfigs.length > 0
|
||||
) {
|
||||
element.assignmentConfig.paramAssignmentConfigs =
|
||||
element.assignmentConfig.paramAssignmentConfigs.filter((item) => {
|
||||
if (item.target === formKey) {
|
||||
needChange = true; // 删除
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
return needChange ? element : null;
|
||||
}
|
||||
// 节点,剔除已经配置了此表单的的表单数据【参数操作】
|
||||
function changeFormInfoAssignmentConfig(formKey: string, element: InfoItem): null | InfoItem {
|
||||
let needChange = false;
|
||||
if (
|
||||
element.assignmentConfig &&
|
||||
element.assignmentConfig.formAssignmentConfigs &&
|
||||
element.assignmentConfig.formAssignmentConfigs.length > 0
|
||||
) {
|
||||
element.assignmentConfig.formAssignmentConfigs =
|
||||
element.assignmentConfig.formAssignmentConfigs.filter((item) => {
|
||||
if (item.target['key'].includes(formKey)) {
|
||||
needChange = true; // 删除
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (
|
||||
element.assignmentConfig &&
|
||||
element.assignmentConfig.paramAssignmentConfigs &&
|
||||
element.assignmentConfig.paramAssignmentConfigs.length > 0
|
||||
) {
|
||||
element.assignmentConfig.paramAssignmentConfigs =
|
||||
element.assignmentConfig.paramAssignmentConfigs.filter((item) => {
|
||||
if (item.type === ParamType.FORM_DATA && item.formConfig['key'].includes(formKey)) {
|
||||
needChange = true; // 删除
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
return needChange ? element : null;
|
||||
}
|
||||
|
||||
// 流程线,剔除已经配置了此表单的的表单数据【流转条件】
|
||||
function sequenceInfoFromSearchKey(formKey: string, element: InfoItem): null | InfoItem {
|
||||
let needChange = false;
|
||||
if (element.conditionConfigs && element.conditionConfigs.length > 0) {
|
||||
element.conditionConfigs = element.conditionConfigs.filter((item) => {
|
||||
if (item['value'].includes(formKey)) {
|
||||
needChange = true; // 删除
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (needChange) {
|
||||
element.conditionConfigs = [];
|
||||
}
|
||||
return needChange ? element : null;
|
||||
}
|
||||
// 外部流程,剔除已经配置了此表单的的表单数据【输入参数,输出参数】
|
||||
function callactivityInfoFromSearchKey(formKey: string, element: InfoItem) {
|
||||
let needChange = false;
|
||||
if (element.inParams && element.inParams.length > 0) {
|
||||
element.inParams = element.inParams.filter((item) => {
|
||||
if (
|
||||
(item.source && item.source.includes(formKey)) ||
|
||||
(item.target && item.target.includes(formKey))
|
||||
) {
|
||||
needChange = true; // 删除
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (element.outParams && element.outParams.length > 0) {
|
||||
element.outParams = element.outParams.filter((item) => {
|
||||
if (
|
||||
(item.source && item.source.includes(formKey)) ||
|
||||
(item.target && item.target.includes(formKey))
|
||||
) {
|
||||
needChange = true; // 删除
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
return needChange ? element : null;
|
||||
}
|
||||
Reference in New Issue
Block a user