add 添加流程设计
This commit is contained in:
parent
cc0f5b9b3b
commit
9e2e5c897d
@ -45,7 +45,9 @@
|
||||
"vue-i18n": "9.10.2",
|
||||
"vue-router": "4.3.2",
|
||||
"vue-types": "5.1.1",
|
||||
"vxe-table": "4.5.22"
|
||||
"vxe-table": "4.5.22",
|
||||
"@logicflow/core": "^1.2.15",
|
||||
"@logicflow/extension": "^1.2.16"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify/json": "2.2.201",
|
||||
|
@ -11,6 +11,17 @@ export const listDept = (query?: DeptQuery) => {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 通过deptIds查询部门
|
||||
* @param deptIds
|
||||
*/
|
||||
export const optionSelect = (deptIds: (number | string)[]): AxiosPromise<DeptVO[]> => {
|
||||
return request({
|
||||
url: '/system/dept/optionselect?deptIds=' + deptIds,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
// 查询部门列表(排除节点)
|
||||
export const listDeptExcludeChild = (deptId: string | number): AxiosPromise<DeptVO[]> => {
|
||||
return request({
|
||||
|
@ -26,16 +26,6 @@ export const getHisListByKey = (flowCode: string) => {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 通过流程定义id获取流程图
|
||||
*/
|
||||
export const definitionImage = (definitionId: string): AxiosPromise<any> => {
|
||||
return request({
|
||||
url: `/workflow/definition/definitionImage/${definitionId}` + '?t' + Math.random(),
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 通过流程定义id获取xml
|
||||
* @param definitionId 流程定义id
|
||||
@ -72,18 +62,6 @@ export const updateDefinitionState = (definitionId: string, activityStatus: bool
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 流程定义转换为模型
|
||||
* @param definitionId 流程定义id
|
||||
* @returns
|
||||
*/
|
||||
export const convertToModel = (definitionId: string) => {
|
||||
return request({
|
||||
url: `/workflow/definition/convertToModel/${definitionId}`,
|
||||
method: 'put'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 通过zip或xml部署流程定义
|
||||
* @returns
|
||||
@ -99,19 +77,6 @@ export function importDefinition(data: any) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 迁移流程
|
||||
* @param currentdefinitionId
|
||||
* @param fromdefinitionId
|
||||
* @returns
|
||||
*/
|
||||
export const migrationDefinition = (currentdefinitionId: string, fromdefinitionId: string) => {
|
||||
return request({
|
||||
url: `/workflow/definition/migrationDefinition/${currentdefinitionId}/${fromdefinitionId}`,
|
||||
method: 'put'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 发布流程定义
|
||||
* @param id 流程定义id
|
||||
@ -135,3 +100,15 @@ export const unPublish = (id: string) => {
|
||||
method: 'put'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取流程定义xml字符串
|
||||
* @param id 流程定义id
|
||||
* @returns
|
||||
*/
|
||||
export const xmlString = (id: string) => {
|
||||
return request({
|
||||
url: `/workflow/definition/xmlString/${id}`,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
267
src/components/WarmFlow/PropertySetting/between.vue
Normal file
267
src/components/WarmFlow/PropertySetting/between.vue
Normal file
@ -0,0 +1,267 @@
|
||||
<template>
|
||||
<div class="between">
|
||||
<el-form ref="form" :model="form" label-width="120px" :rules="rules" size="small" :disabled="disabled">
|
||||
<slot name="form-item-task-nodeCode" :model="form" field="nodeCode">
|
||||
<el-form-item label="节点编码">
|
||||
<el-input v-model="form.nodeCode" :disabled="disabled"></el-input>
|
||||
</el-form-item>
|
||||
</slot>
|
||||
<slot name="form-item-task-nodeName" :model="form" field="nodeName">
|
||||
<el-form-item label="节点名称">
|
||||
<el-input v-model="form.nodeName" :disabled="disabled"></el-input>
|
||||
</el-form-item>
|
||||
</slot>
|
||||
<slot name="form-item-task-collaborativeWay" :model="form" field="collaborativeWay">
|
||||
<el-form-item label="协作方式">
|
||||
<el-radio-group v-model="form.collaborativeWay" @change="collaborativeWayChange">
|
||||
<el-radio v-if="form.collaborativeWay === '1'" label="1">
|
||||
或签
|
||||
<el-tooltip class="item" effect="dark" content="只需一个人审批">
|
||||
<i class="el-icon-question" style="color: #000"></i>
|
||||
</el-tooltip>
|
||||
</el-radio>
|
||||
<el-radio v-if="form.collaborativeWay === '2'" label="2">
|
||||
票签
|
||||
<el-tooltip class="item" effect="dark" content="部分办理人审批,只支持选择用户">
|
||||
<i class="el-icon-question" style="color: #000"></i>
|
||||
</el-tooltip>
|
||||
</el-radio>
|
||||
<el-radio v-if="form.collaborativeWay === '3'" label="3">
|
||||
会签
|
||||
<el-tooltip class="item" effect="dark" content="所有办理都需要审批,只支持选择用户">
|
||||
<i class="el-icon-question" style="color: #000"></i>
|
||||
</el-tooltip>
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</slot>
|
||||
<slot v-if="form.collaborativeWay === '2'" name="form-item-task-nodeRatio" :model="form" field="nodeRatio">
|
||||
<el-form-item label="票签占比" prop="nodeRatio">
|
||||
<el-input v-model="form.nodeRatio" type="number" placeholder="请输入"></el-input>
|
||||
<div class="placeholder">票签比例范围:(0-100)的值</div>
|
||||
</el-form-item>
|
||||
</slot>
|
||||
<slot name="form-item-task-permissionFlag" :model="form" field="permissionFlag">
|
||||
<el-tooltip effect="dark" :content="userNameList" :disabled="!disabled">
|
||||
<el-form-item label="办理人选择">
|
||||
<el-select
|
||||
v-if="form.collaborativeWay === '1'"
|
||||
v-model="form.permissionFlag"
|
||||
multiple
|
||||
collapse-tags
|
||||
:disabled="disabled"
|
||||
allow-create
|
||||
:clearable="!disabled"
|
||||
filterable
|
||||
>
|
||||
<el-option-group v-for="groupOption in groupOptions" :key="groupOption.label" :label="groupOption.label" :disabled="disabled">
|
||||
<el-option v-for="item in groupOption.options" :key="item.value" :label="item.label" :value="item.value"> </el-option>
|
||||
</el-option-group>
|
||||
</el-select>
|
||||
<el-select
|
||||
v-else
|
||||
v-model="form.permissionFlag"
|
||||
multiple
|
||||
collapse-tags
|
||||
:disabled="disabled"
|
||||
:clearable="!disabled"
|
||||
popper-class="dialogSelect"
|
||||
:popper-append-to-body="false"
|
||||
@focus="initUser"
|
||||
>
|
||||
<el-option v-for="item in form.permissionFlag" :key="item" :label="item" :value="item"> </el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-tooltip>
|
||||
</slot>
|
||||
<slot name="form-item-task-listenerType" :model="form" field="listenerType">
|
||||
<el-form-item label="监听器类型">
|
||||
<el-select v-model="form.listenerType" multiple>
|
||||
<el-option label="任务创建" value="create"></el-option>
|
||||
<el-option label="任务开始办理" value="start"></el-option>
|
||||
<el-option label="分派监听器" value="assignment"></el-option>
|
||||
<el-option label="任务完成" value="finish"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</slot>
|
||||
<slot name="form-item-task-listenerPath" :model="form" field="listenerPath">
|
||||
<el-form-item label="监听器路径" description="输入监听器的路径,以@@分隔,顺序与监听器类型一致">
|
||||
<el-input v-model="form.listenerPath" type="textarea" rows="8"></el-input>
|
||||
<el-tooltip class="item" effect="dark" content="输入监听器的路径,以@@分隔,顺序与监听器类型一致">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</el-form-item>
|
||||
</slot>
|
||||
<slot name="form-item-task-formCustom" :model="form" field="formCustom">
|
||||
<el-form-item label="审批表单是否自定义">
|
||||
<el-select v-model="form.formCustom">
|
||||
<el-option label="使用流程表单" :value="''"></el-option>
|
||||
<!-- <el-option label="节点自定义表单" value="Y"></el-option> -->
|
||||
<el-option label="节点表单路径" value="N"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</slot>
|
||||
<slot v-if="form.formCustom === 'N'" name="form-item-task-formPath" :model="form" field="formPath">
|
||||
<el-form-item label="审批表单路径">
|
||||
<el-input v-model="form.formPath"></el-input>
|
||||
</el-form-item>
|
||||
</slot>
|
||||
</el-form>
|
||||
|
||||
<!-- 权限标识:会签票签选择用户 -->
|
||||
<el-dialog v-model:visible="userVisible" title="用户选择" width="80%" append-to-body>
|
||||
<!-- <selectUser v-model:select-user="form.permissionFlag" v-model:user-visible="userVisible" @handle-user-select="handleUserSelect"></selectUser> -->
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { optionSelect as listRole } from '@/api/system/role';
|
||||
import { optionSelect as listUser } from '@/api/system/user';
|
||||
import { optionSelect as listDept } from '@/api/system/dept';
|
||||
//import selectUser from '@/views/components/selectUser';
|
||||
|
||||
export default {
|
||||
name: 'Between',
|
||||
components: {
|
||||
//selectUser
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
disabled: {
|
||||
// 是否禁止
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: this.value,
|
||||
userNameList: '',
|
||||
groupOptions: [],
|
||||
rules: {
|
||||
nodeRatio: [
|
||||
{ required: false, message: '请输入', trigger: 'change' },
|
||||
{ pattern: /^(?:[1-9]\d?|0\.\d{1,3}|[1-9]\d?\.\d{1,3})$/, message: '请输入(0, 100)的值,最多保留三位小数', trigger: ['change', 'blur'] }
|
||||
]
|
||||
},
|
||||
userVisible: false
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
form: {
|
||||
handler(n) {
|
||||
this.$emit('change', n);
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (this.form.permissionFlag) {
|
||||
this.form.permissionFlag = this.form.permissionFlag.split(',');
|
||||
}
|
||||
if (this.form.listenerType) {
|
||||
this.form.listenerType = this.form.listenerType.split(',');
|
||||
}
|
||||
this.getPermissionFlag();
|
||||
if (this.disabled) this.getIdReverseDisplayName();
|
||||
},
|
||||
methods: {
|
||||
// 根据id查用户名
|
||||
getIdReverseDisplayName() {
|
||||
if (this.form.collaborativeWay !== '1') {
|
||||
idReverseDisplayName(this.form.permissionFlag.join(',')).then((res) => {
|
||||
this.userNameList = res.data ? res.data.map((e) => e.nickName).join(',') : '';
|
||||
});
|
||||
}
|
||||
},
|
||||
/** 选择角色权限范围触发 */
|
||||
getPermissionFlag() {
|
||||
let groupOptionCreateBy = {
|
||||
label: '创建人',
|
||||
options: [
|
||||
{
|
||||
value: 'warmFlowInitiator',
|
||||
label: '流程发起人'
|
||||
}
|
||||
]
|
||||
};
|
||||
this.groupOptions.push(groupOptionCreateBy);
|
||||
listRole([]).then((response) => {
|
||||
let groupOption = {
|
||||
label: '角色',
|
||||
options: response.data.map((item) => {
|
||||
return {
|
||||
value: 'role:' + item.roleId,
|
||||
label: item.roleName
|
||||
};
|
||||
})
|
||||
};
|
||||
this.groupOptions.push(groupOption);
|
||||
listUser([]).then((response) => {
|
||||
let groupOption = {
|
||||
label: '用户',
|
||||
options: response.data.map((item) => {
|
||||
return {
|
||||
value: item.userId,
|
||||
label: item.nickName
|
||||
};
|
||||
})
|
||||
};
|
||||
this.groupOptions.push(groupOption);
|
||||
listDept([]).then((response) => {
|
||||
let groupOption = {
|
||||
label: '部门',
|
||||
options: response.data.map((item) => {
|
||||
return {
|
||||
value: 'dept:' + item.deptId,
|
||||
label: item.deptName
|
||||
};
|
||||
})
|
||||
};
|
||||
this.groupOptions.push(groupOption);
|
||||
if (this.disabled && this.form.collaborativeWay === '1') {
|
||||
let userNameList = [];
|
||||
this.groupOptions.forEach((e) => {
|
||||
e.options.forEach((o) => {
|
||||
if (this.form.permissionFlag.includes(o.value)) userNameList.push(o.label);
|
||||
});
|
||||
});
|
||||
this.userNameList = userNameList.join(',');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
collaborativeWayChange(val) {
|
||||
this.form.permissionFlag = [];
|
||||
this.$set(this.form, 'nodeRatio', val === '1' ? '0.000' : val === '3' ? '100.000' : '');
|
||||
},
|
||||
// 打开用户选择弹窗
|
||||
initUser() {
|
||||
this.userVisible = true;
|
||||
},
|
||||
// 获取选中用户数据
|
||||
handleUserSelect(checkedItemList) {
|
||||
this.form.permissionFlag = checkedItemList.map((e) => {
|
||||
return e.userId;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.dialogSelect {
|
||||
display: none;
|
||||
}
|
||||
.placeholder {
|
||||
color: #828f9e;
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
52
src/components/WarmFlow/PropertySetting/end.vue
Normal file
52
src/components/WarmFlow/PropertySetting/end.vue
Normal file
@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form ref="form" :model="form" label-width="120px" size="small" :disabled="disabled">
|
||||
<slot name="form-item-task-name" :model="form" field="nodeCode">
|
||||
<el-form-item label="节点编码">
|
||||
<el-input v-model="form.nodeCode" :disabled="disabled"></el-input>
|
||||
</el-form-item>
|
||||
</slot>
|
||||
<slot name="form-item-task-name" :model="form" field="nodeName">
|
||||
<el-form-item label="节点名称">
|
||||
<el-input v-model="form.nodeName" :disabled="disabled"></el-input>
|
||||
</el-form-item>
|
||||
</slot>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'End',
|
||||
props: {
|
||||
value: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
disabled: {
|
||||
// 是否禁止
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: this.value
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
form: {
|
||||
handler(n) {
|
||||
this.$emit('change', n);
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
methods: {}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
246
src/components/WarmFlow/PropertySetting/index.vue
Normal file
246
src/components/WarmFlow/PropertySetting/index.vue
Normal file
@ -0,0 +1,246 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-drawer ref="drawer" v-model="drawer" :title="title" destroy-on-close direction="rtl" :append-to-body="true" :before-close="handleClose">
|
||||
<component
|
||||
:is="node ? node.type : ''"
|
||||
:ref="node ? node.type : ''"
|
||||
v-model="form"
|
||||
:disabled="disabled"
|
||||
:skip-condition-show="skipConditionShow"
|
||||
>
|
||||
<template v-for="(item, key) in $slots" #[key]="data">
|
||||
<slot :name="key" v-bind="data || {}"></slot>
|
||||
</template>
|
||||
</component>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Start from './start.vue';
|
||||
import Between from './between.vue';
|
||||
import Serial from './serial.vue';
|
||||
import Parallel from './parallel.vue';
|
||||
import End from './end.vue';
|
||||
import Skip from './skip.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Start,
|
||||
Between,
|
||||
Serial,
|
||||
Parallel,
|
||||
End,
|
||||
Skip
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
node: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
lf: {
|
||||
type: Object,
|
||||
default() {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
disabled: {
|
||||
// 是否禁止
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
skipConditionShow: {
|
||||
// 是否显示跳转条件
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
drawer: false,
|
||||
form: {},
|
||||
objId: undefined,
|
||||
nodeCode: null
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
title() {
|
||||
if (this.node && this.node.type === 'skip') {
|
||||
return '设置边属性';
|
||||
} else if (this.node && this.node.type === 'serial') {
|
||||
return '设置串行网关属性';
|
||||
} else if (this.node && this.node.type === 'parallel') {
|
||||
return '设置并行网关属性';
|
||||
} else if (this.node && this.node.type === 'start') {
|
||||
return '设置开始属性';
|
||||
} else if (this.node && this.node.type === 'end') {
|
||||
return '设置结束属性';
|
||||
}
|
||||
return '设置中间属性';
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
node(n) {
|
||||
if (n) {
|
||||
this.objId = n.id;
|
||||
let skipCondition = n.properties.skipCondition;
|
||||
let conditionSpl = skipCondition ? skipCondition.split('@@|') : [];
|
||||
let conditionSplTwo = conditionSpl && conditionSpl.length > 0 ? conditionSpl[1] : [];
|
||||
let condition,
|
||||
conditionType,
|
||||
conditionValue = '';
|
||||
if (conditionSpl && conditionSpl.length > 0 && conditionSpl[0] === '@@spel') {
|
||||
conditionType = 'spel';
|
||||
conditionValue = conditionSplTwo;
|
||||
} else if (conditionSpl && conditionSpl.length > 0 && conditionSpl[0] !== '@@spel') {
|
||||
condition = conditionSplTwo && conditionSplTwo.length > 0 ? conditionSplTwo.split('@@')[0] : '';
|
||||
conditionType = conditionSplTwo && conditionSplTwo.length > 0 ? conditionSplTwo.split('@@')[1] : '';
|
||||
conditionValue = conditionSplTwo && conditionSplTwo.length > 0 ? conditionSplTwo.split('@@')[2] : '';
|
||||
}
|
||||
if (n.type === 'skip') {
|
||||
this.form = {
|
||||
nodeType: n.type,
|
||||
skipType: n.properties.skipType,
|
||||
skipName: n.properties.skipName,
|
||||
skipCondition: skipCondition,
|
||||
condition: condition,
|
||||
conditionType: conditionType,
|
||||
conditionValue: conditionValue
|
||||
};
|
||||
} else {
|
||||
let nodeRatio = n.properties.nodeRatio || '';
|
||||
if (!n.properties.collaborativeWay) {
|
||||
n.properties.collaborativeWay = nodeRatio === '0.000' ? '1' : nodeRatio === '100.000' ? '3' : nodeRatio ? '2' : '1';
|
||||
}
|
||||
n.properties.formCustom = JSON.stringify(n.properties) === '{}' ? 'N' : n.properties.formCustom || '';
|
||||
this.form = {
|
||||
nodeType: n.type,
|
||||
nodeCode: n.id,
|
||||
nodeName: n.text instanceof Object ? n.text.value : n.text,
|
||||
...n.properties
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
'form.nodeCode'(n) {
|
||||
this.nodeCode = n;
|
||||
},
|
||||
'form.skipType'(n) {
|
||||
// 监听跳转属性变化并更新
|
||||
this.lf.setProperties(this.objId, {
|
||||
skipType: n
|
||||
});
|
||||
},
|
||||
'form.nodeName'(n) {
|
||||
// 监听节点名称变化并更新
|
||||
this.lf.updateText(this.objId, n);
|
||||
// 监听节点名称变化并更新
|
||||
this.lf.setProperties(this.objId, {
|
||||
nodeName: n
|
||||
});
|
||||
},
|
||||
'form.collaborativeWay'(n) {
|
||||
this.lf.setProperties(this.objId, {
|
||||
nodeRatio: n === '1' ? '0.000' : n === '3' ? '100.000' : ''
|
||||
});
|
||||
},
|
||||
'form.nodeRatio'(n) {
|
||||
this.lf.setProperties(this.objId, {
|
||||
nodeRatio: n
|
||||
});
|
||||
},
|
||||
'form.permissionFlag'(n) {
|
||||
// 监听节点属性变化并更新
|
||||
this.lf.setProperties(this.objId, {
|
||||
permissionFlag: Array.isArray(n) ? n.join(',') : n
|
||||
});
|
||||
},
|
||||
'form.skipAnyNode'(n) {
|
||||
// 监听跳转属性变化并更新
|
||||
this.lf.setProperties(this.objId, {
|
||||
skipAnyNode: n
|
||||
});
|
||||
},
|
||||
'form.listenerType'(n) {
|
||||
// 监听监听器类型变化并更新
|
||||
this.lf.setProperties(this.objId, {
|
||||
listenerType: Array.isArray(n) ? n.join(',') : n
|
||||
});
|
||||
},
|
||||
'form.listenerPath'(n) {
|
||||
// 监听监听器路径变化并更新
|
||||
this.lf.setProperties(this.objId, {
|
||||
listenerPath: n
|
||||
});
|
||||
},
|
||||
'form.formCustom'(n) {
|
||||
this.lf.setProperties(this.objId, {
|
||||
formCustom: n || ''
|
||||
});
|
||||
},
|
||||
'form.formPath'(n) {
|
||||
this.lf.setProperties(this.objId, {
|
||||
formPath: n
|
||||
});
|
||||
},
|
||||
'form.skipCondition'(n) {
|
||||
// 监听跳转属性变化并更新
|
||||
this.lf.setProperties(this.objId, {
|
||||
skipCondition: n
|
||||
});
|
||||
},
|
||||
'form.skipName'(n) {
|
||||
if (['skip'].includes(this.node.type)) {
|
||||
debugger;
|
||||
// 监听跳转名称变化并更新
|
||||
this.lf.updateText(this.objId, n);
|
||||
// 监听跳转属性变化并更新
|
||||
this.lf.setProperties(this.objId, {
|
||||
skipName: n
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
show() {
|
||||
this.drawer = true;
|
||||
},
|
||||
handleClose() {
|
||||
// 监听节点编码变量并更新
|
||||
if (this.nodeCode && this.objId) {
|
||||
if (['skip'].includes(this.node?.type)) {
|
||||
if (!this.lf.getEdgeModelById(this.nodeCode)) {
|
||||
this.lf.changeEdgeId(this.objId, this.nodeCode);
|
||||
}
|
||||
} else {
|
||||
if (!this.lf.getNodeModelById(this.nodeCode)) {
|
||||
this.lf.changeNodeId(this.objId, this.nodeCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.node?.type === 'between') {
|
||||
this.$refs.between.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.drawer = false;
|
||||
}
|
||||
});
|
||||
} else this.drawer = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.el-drawer__container ::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
52
src/components/WarmFlow/PropertySetting/parallel.vue
Normal file
52
src/components/WarmFlow/PropertySetting/parallel.vue
Normal file
@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form ref="form" :model="form" label-width="120px" size="small" :disabled="disabled">
|
||||
<slot name="form-item-task-name" :model="form" field="nodeCode">
|
||||
<el-form-item label="节点编码">
|
||||
<el-input v-model="form.nodeCode" :disabled="disabled"></el-input>
|
||||
</el-form-item>
|
||||
</slot>
|
||||
<slot name="form-item-task-name" :model="form" field="nodeName">
|
||||
<el-form-item label="节点名称">
|
||||
<el-input v-model="form.nodeName" :disabled="disabled"></el-input>
|
||||
</el-form-item>
|
||||
</slot>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Parallel',
|
||||
props: {
|
||||
value: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
disabled: {
|
||||
// 是否禁止
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: this.value
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
form: {
|
||||
handler(n) {
|
||||
this.$emit('change', n);
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
methods: {}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
52
src/components/WarmFlow/PropertySetting/serial.vue
Normal file
52
src/components/WarmFlow/PropertySetting/serial.vue
Normal file
@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form ref="form" :model="form" label-width="120px" size="small" :disabled="disabled">
|
||||
<slot name="form-item-task-name" :model="form" field="nodeCode">
|
||||
<el-form-item label="节点编码">
|
||||
<el-input v-model="form.nodeCode" :disabled="disabled"></el-input>
|
||||
</el-form-item>
|
||||
</slot>
|
||||
<slot name="form-item-task-name" :model="form" field="nodeName">
|
||||
<el-form-item label="节点名称">
|
||||
<el-input v-model="form.nodeName" :disabled="disabled"></el-input>
|
||||
</el-form-item>
|
||||
</slot>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Serial',
|
||||
props: {
|
||||
value: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
disabled: {
|
||||
// 是否禁止
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: this.value
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
form: {
|
||||
handler(n) {
|
||||
this.$emit('change', n);
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
methods: {}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
93
src/components/WarmFlow/PropertySetting/skip.vue
Normal file
93
src/components/WarmFlow/PropertySetting/skip.vue
Normal file
@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form ref="form" :model="form" label-width="120px" size="small" :disabled="disabled">
|
||||
<slot v-if="skipConditionShow" name="form-item-task-skipName" :model="form" field="skipName">
|
||||
<el-form-item label="跳转名称">
|
||||
<el-input v-model="form.skipName" placeholder="跳转名称" />
|
||||
</el-form-item>
|
||||
</slot>
|
||||
<slot name="form-item-task-skipType" :model="form" field="skipType">
|
||||
<el-form-item label="跳转类型">
|
||||
<el-select v-model="form.skipType">
|
||||
<el-option sel label="审批通过" value="PASS" />
|
||||
<el-option label="退回" value="REJECT" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</slot>
|
||||
<slot v-if="skipConditionShow" name="form-item-task-skipCondition" :model="form" field="skipCondition">
|
||||
<el-form-item label="跳转条件">
|
||||
<el-input v-if="!spelFlag" v-model="form.condition" placeholder="条件名" style="width: 20%" />
|
||||
<el-select v-model="form.conditionType" placeholder="请选择条件方式" style="width: 35%; margin-left: 1%" @change="changeOper">
|
||||
<el-option label="大于" value="gt" />
|
||||
<el-option label="大于等于" value="ge" />
|
||||
<el-option label="等于" value="eq" />
|
||||
<el-option label="不等于" value="ne" />
|
||||
<el-option label="小于" value="lt" />
|
||||
<el-option label="小于等于" value="le" />
|
||||
<el-option label="包含" value="like" />
|
||||
<el-option label="不包含" value="notNike" />
|
||||
<el-option label="spel表达式" value="spel" />
|
||||
</el-select>
|
||||
<el-input v-model="form.conditionValue" placeholder="条件值" style="width: 42%; margin-left: 1%; margin-right: 1%" />
|
||||
</el-form-item>
|
||||
</slot>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Skip',
|
||||
props: {
|
||||
value: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
disabled: {
|
||||
// 是否禁止
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
skipConditionShow: {
|
||||
// 是否显示跳转条件
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
spelFlag: false,
|
||||
form: this.value
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
form: {
|
||||
handler(n) {
|
||||
let skipCondition = n.skipCondition;
|
||||
skipCondition = '@@' + n.conditionType + '@@|';
|
||||
if (n.conditionType !== 'spel') {
|
||||
skipCondition = skipCondition + (n.condition ? n.condition : '') + '@@' + n.conditionType + '@@';
|
||||
}
|
||||
n.skipCondition = skipCondition + (n.conditionValue ? n.conditionValue : '');
|
||||
|
||||
this.$emit('change', n);
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (this.value.conditionType === 'spel') {
|
||||
this.spelFlag = true;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
changeOper(obj) {
|
||||
this.spelFlag = obj === 'spel';
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
75
src/components/WarmFlow/PropertySetting/start.vue
Normal file
75
src/components/WarmFlow/PropertySetting/start.vue
Normal file
@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form ref="form" :model="form" label-width="120px" size="small" :disabled="disabled">
|
||||
<slot name="form-item-task-name" :model="form" field="nodeCode">
|
||||
<el-form-item label="节点编码">
|
||||
<el-input v-model="form.nodeCode" :disabled="disabled"></el-input>
|
||||
</el-form-item>
|
||||
</slot>
|
||||
<slot name="form-item-task-name" :model="form" field="nodeName">
|
||||
<el-form-item label="节点名称">
|
||||
<el-input v-model="form.nodeName" :disabled="disabled"></el-input>
|
||||
</el-form-item>
|
||||
</slot>
|
||||
<slot name="form-item-task-listenerType" :model="form" field="listenerType">
|
||||
<el-form-item label="监听器类型">
|
||||
<el-select v-model="form.listenerType" multiple>
|
||||
<el-option label="任务创建" value="create"></el-option>
|
||||
<el-option label="任务开始办理" value="start"></el-option>
|
||||
<el-option label="分派监听器" value="assignment"></el-option>
|
||||
<el-option label="权限认证" value="permission"></el-option>
|
||||
<el-option label="任务完成" value="finish"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</slot>
|
||||
<slot name="form-item-task-listenerPath" :model="form" field="listenerPath">
|
||||
<el-form-item label="监听器路径" description="输入监听器的路径,以@@分隔,顺序与监听器类型一致">
|
||||
<el-input v-model="form.listenerPath" type="textarea" rows="8"></el-input>
|
||||
<el-tooltip class="item" effect="dark" content="输入监听器的路径,以@@分隔,顺序与监听器类型一致">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</el-form-item>
|
||||
</slot>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Start',
|
||||
props: {
|
||||
value: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
disabled: {
|
||||
// 是否禁止
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: this.value
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
form: {
|
||||
handler(n) {
|
||||
this.$emit('change', n);
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (this.form.listenerType) {
|
||||
this.form.listenerType = this.form.listenerType.split(',');
|
||||
}
|
||||
},
|
||||
methods: {}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
23
src/components/WarmFlow/js/between.js
Normal file
23
src/components/WarmFlow/js/between.js
Normal file
@ -0,0 +1,23 @@
|
||||
import { RectNode, RectNodeModel } from "@logicflow/core";
|
||||
|
||||
class BetweenModel extends RectNodeModel {
|
||||
|
||||
initNodeData(data) {
|
||||
super.initNodeData(data);
|
||||
this.width = 100;
|
||||
this.height = 80;
|
||||
this.radius = 5;
|
||||
}
|
||||
getNodeStyle() {
|
||||
const style = super.getNodeStyle();
|
||||
return style
|
||||
}
|
||||
}
|
||||
|
||||
class BetweenView extends RectNode {}
|
||||
|
||||
export default {
|
||||
type: "between",
|
||||
model: BetweenModel,
|
||||
view: BetweenView,
|
||||
};
|
139
src/components/WarmFlow/js/data.js
Normal file
139
src/components/WarmFlow/js/data.js
Normal file
@ -0,0 +1,139 @@
|
||||
// 测试数据
|
||||
const graphData = {
|
||||
flowName: "请假流程-串行1",
|
||||
flowCode: "leaveFlow-serial1",
|
||||
version: "1.0",
|
||||
formCustom: "N",
|
||||
formPath: "test/leave/approve",
|
||||
nodes: [
|
||||
{
|
||||
id: "node_id_1",
|
||||
type: "start",
|
||||
x: 200,
|
||||
y: 200,
|
||||
text: { x: 200, y: 200, value: "开始" },
|
||||
properties: {
|
||||
status: "approval"
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "node_id_2",
|
||||
type: "between",
|
||||
x: 400,
|
||||
y: 200,
|
||||
text: { x: 400, y: 200, value: "待提交" },
|
||||
properties: {
|
||||
status: "pass"
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "node_id_3",
|
||||
type: "between",
|
||||
x: 600,
|
||||
y: 200,
|
||||
text: { x: 600, y: 200, value: "组长审批" },
|
||||
properties: {
|
||||
status: "approval"
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "node_id_4",
|
||||
type: "between",
|
||||
x: 800,
|
||||
y: 200,
|
||||
text: { x: 800, y: 200, value: "部门审批" },
|
||||
properties: {
|
||||
status: "approval"
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "node_id_5",
|
||||
type: "between",
|
||||
x: 1000,
|
||||
y: 200,
|
||||
text: { x: 1000, y: 200, value: "hr审批" },
|
||||
properties: {
|
||||
status: "approval"
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "node_id_6",
|
||||
type: "end",
|
||||
x: 1200,
|
||||
y: 200,
|
||||
text: { x: 1200, y: 200, value: "结束" },
|
||||
properties: {},
|
||||
},
|
||||
],
|
||||
edges: [
|
||||
{
|
||||
id: "edge_id",
|
||||
type: "skip",
|
||||
sourceNodeId: "node_id_1",
|
||||
targetNodeId: "node_id_2",
|
||||
text: { x: 280, y: 200, value: "通过" },
|
||||
startPoint: { x: 220, y: 200 },
|
||||
endPoint: { x: 350, y: 200 },
|
||||
properties: {},
|
||||
},
|
||||
{
|
||||
id: "edge_id",
|
||||
type: "skip",
|
||||
sourceNodeId: "node_id_2",
|
||||
targetNodeId: "node_id_3",
|
||||
text: { x: 500, y: 200, value: "通过" },
|
||||
startPoint: { x: 450, y: 200 },
|
||||
endPoint: { x: 550, y: 200 },
|
||||
properties: {},
|
||||
},
|
||||
{
|
||||
id: "edge_id",
|
||||
type: "skip",
|
||||
sourceNodeId: "node_id_3",
|
||||
targetNodeId: "node_id_4",
|
||||
text: { x: 700, y: 200, value: "通过" },
|
||||
startPoint: { x: 650, y: 200 },
|
||||
endPoint: { x: 750, y: 200 },
|
||||
properties: {},
|
||||
},
|
||||
{
|
||||
id: "edge_id",
|
||||
type: "skip",
|
||||
sourceNodeId: "node_id_4",
|
||||
targetNodeId: "node_id_5",
|
||||
text: { x: 900, y: 200, value: "通过" },
|
||||
startPoint: { x: 850, y: 200 },
|
||||
endPoint: { x: 950, y: 200 },
|
||||
properties: {},
|
||||
},
|
||||
{
|
||||
id: "edge_id",
|
||||
type: "skip",
|
||||
sourceNodeId: "node_id_5",
|
||||
targetNodeId: "node_id_6",
|
||||
text: { x: 1120, y: 200, value: "通过" },
|
||||
startPoint: { x: 1050, y: 200 },
|
||||
endPoint: { x: 1180, y: 200 },
|
||||
properties: {},
|
||||
},
|
||||
|
||||
{
|
||||
id: "edge_id",
|
||||
type: "skip",
|
||||
sourceNodeId: "node_id_4",
|
||||
targetNodeId: "node_id_2",
|
||||
text: { x: 600, y: 100, value: "退回" },
|
||||
startPoint: { x: 800, y: 160 },
|
||||
endPoint: { x: 400, y: 160 },
|
||||
pointsList: [
|
||||
{ x: 800, y: 160 },
|
||||
{ x: 800, y: 100 },
|
||||
{ x: 400, y: 100 },
|
||||
{ x: 400, y: 160 },
|
||||
],
|
||||
properties: {},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default graphData
|
17
src/components/WarmFlow/js/end.js
Normal file
17
src/components/WarmFlow/js/end.js
Normal file
@ -0,0 +1,17 @@
|
||||
import { CircleNode, CircleNodeModel } from "@logicflow/core";
|
||||
|
||||
class endModel extends CircleNodeModel {
|
||||
|
||||
initNodeData(data) {
|
||||
super.initNodeData(data);
|
||||
this.r = 20
|
||||
}
|
||||
}
|
||||
|
||||
class endView extends CircleNode {}
|
||||
|
||||
export default {
|
||||
type: "end",
|
||||
model: endModel,
|
||||
view: endView,
|
||||
};
|
57
src/components/WarmFlow/js/parallel.js
Normal file
57
src/components/WarmFlow/js/parallel.js
Normal file
@ -0,0 +1,57 @@
|
||||
import { h, PolygonNode, PolygonNodeModel } from '@logicflow/core'
|
||||
|
||||
class ParallelModel extends PolygonNodeModel {
|
||||
static extendKey = 'ParallelModel';
|
||||
constructor (data, graphModel) {
|
||||
if (!data.text) {
|
||||
data.text = ''
|
||||
}
|
||||
if (data.text && typeof data.text === 'string') {
|
||||
data.text = {
|
||||
value: data.text,
|
||||
x: data.x,
|
||||
y: data.y + 40
|
||||
}
|
||||
}
|
||||
super(data, graphModel)
|
||||
this.points = [
|
||||
[25, 0],
|
||||
[50, 25],
|
||||
[25, 50],
|
||||
[0, 25]
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ParallelView extends PolygonNode {
|
||||
static extendKey = 'ParallelNode';
|
||||
getShape () {
|
||||
const { model } = this.props
|
||||
const { x, y, width, height, points } = model
|
||||
const style = model.getNodeStyle()
|
||||
return h(
|
||||
'g',
|
||||
{
|
||||
transform: `matrix(1 0 0 1 ${x - width / 2} ${y - height / 2})`
|
||||
},
|
||||
h('polygon', {
|
||||
...style,
|
||||
x,
|
||||
y,
|
||||
points
|
||||
}),
|
||||
h('path', {
|
||||
d:
|
||||
'm 23,10 0,12.5 -12.5,0 0,5 12.5,0 0,12.5 5,0 0,-12.5 12.5,0 0,-5 -12.5,0 0,-12.5 -5,0 z',
|
||||
...style
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
type: 'parallel',
|
||||
view: ParallelView,
|
||||
model: ParallelModel
|
||||
};
|
57
src/components/WarmFlow/js/serial.js
Normal file
57
src/components/WarmFlow/js/serial.js
Normal file
@ -0,0 +1,57 @@
|
||||
import { h, PolygonNode, PolygonNodeModel } from '@logicflow/core'
|
||||
|
||||
class SerialModel extends PolygonNodeModel {
|
||||
static extendKey = 'SerialModel';
|
||||
constructor (data, graphModel) {
|
||||
if (!data.text) {
|
||||
data.text = ''
|
||||
}
|
||||
if (data.text && typeof data.text === 'string') {
|
||||
data.text = {
|
||||
value: data.text,
|
||||
x: data.x,
|
||||
y: data.y + 40
|
||||
}
|
||||
}
|
||||
super(data, graphModel)
|
||||
this.points = [
|
||||
[25, 0],
|
||||
[50, 25],
|
||||
[25, 50],
|
||||
[0, 25]
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class SerialView extends PolygonNode {
|
||||
static extendKey = 'SerialNode';
|
||||
getShape () {
|
||||
const { model } = this.props
|
||||
const { x, y, width, height, points } = model
|
||||
const style = model.getNodeStyle()
|
||||
return h(
|
||||
'g',
|
||||
{
|
||||
transform: `matrix(1 0 0 1 ${x - width / 2} ${y - height / 2})`
|
||||
},
|
||||
h('polygon', {
|
||||
...style,
|
||||
x,
|
||||
y,
|
||||
points
|
||||
}),
|
||||
h('path', {
|
||||
d:
|
||||
'm 16,15 7.42857142857143,9.714285714285715 -7.42857142857143,9.714285714285715 3.428571428571429,0 5.714285714285715,-7.464228571428572 5.714285714285715,7.464228571428572 3.428571428571429,0 -7.42857142857143,-9.714285714285715 7.42857142857143,-9.714285714285715 -3.428571428571429,0 -5.714285714285715,7.464228571428572 -5.714285714285715,-7.464228571428572 -3.428571428571429,0 z',
|
||||
...style
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
type: 'serial',
|
||||
view: SerialView,
|
||||
model: SerialModel
|
||||
};
|
33
src/components/WarmFlow/js/skip.js
Normal file
33
src/components/WarmFlow/js/skip.js
Normal file
@ -0,0 +1,33 @@
|
||||
import { PolylineEdge, PolylineEdgeModel } from "@logicflow/core";
|
||||
|
||||
class SkipModel extends PolylineEdgeModel {
|
||||
setAttributes() {
|
||||
this.offset = 20;
|
||||
}
|
||||
|
||||
getEdgeStyle() {
|
||||
const style = super.getEdgeStyle();
|
||||
const { properties } = this;
|
||||
if (properties.isActived) {
|
||||
style.strokeDasharray = "4 4";
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
||||
/**
|
||||
* 重写此方法,使保存数据是能带上锚点数据。
|
||||
*/
|
||||
getData() {
|
||||
const data = super.getData();
|
||||
data.sourceAnchorId = this.sourceAnchorId;
|
||||
data.targetAnchorId = this.targetAnchorId;
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default {
|
||||
type: "skip",
|
||||
view: PolylineEdge,
|
||||
model: SkipModel,
|
||||
};
|
17
src/components/WarmFlow/js/start.js
Normal file
17
src/components/WarmFlow/js/start.js
Normal file
@ -0,0 +1,17 @@
|
||||
import { CircleNode, CircleNodeModel } from "@logicflow/core";
|
||||
|
||||
class StartModel extends CircleNodeModel {
|
||||
|
||||
initNodeData(data) {
|
||||
super.initNodeData(data);
|
||||
this.r = 20
|
||||
}
|
||||
}
|
||||
|
||||
class StartView extends CircleNode {}
|
||||
|
||||
export default {
|
||||
type: "start",
|
||||
model: StartModel,
|
||||
view: StartView,
|
||||
};
|
356
src/components/WarmFlow/js/tool.js
Normal file
356
src/components/WarmFlow/js/tool.js
Normal file
@ -0,0 +1,356 @@
|
||||
/**
|
||||
* 节点样式处理方法
|
||||
* @param _this
|
||||
* @param style
|
||||
* @returns {*}
|
||||
*/
|
||||
export const nodeStyleHandle = (_this, style) => {
|
||||
if (_this.properties.status === "pass") {
|
||||
style.stroke = "green";
|
||||
} else if (_this.properties.status === "reject") {
|
||||
style.stroke = "#ffba00";
|
||||
} else if (_this.properties.status === "approval") {
|
||||
style.stroke = "red";
|
||||
} else {
|
||||
style.stroke = "#909399";
|
||||
}
|
||||
return style
|
||||
}
|
||||
|
||||
/**
|
||||
* 节点大小处理方法
|
||||
* @param _this
|
||||
* @param style
|
||||
* @returns {*}
|
||||
*/
|
||||
export const nodeSizeHandle = (_this) => {
|
||||
_this.width = 120;
|
||||
_this.height = 80;
|
||||
_this.radius = 5;
|
||||
}
|
||||
|
||||
/**
|
||||
* 节点大小处理方法
|
||||
* @param _this
|
||||
* @param style
|
||||
* @returns {*}
|
||||
*/
|
||||
export const skipText = (skipType) => {
|
||||
let text = ''
|
||||
if (skipType && skipType === 'PASS') {
|
||||
text = '审批通过'
|
||||
} else if (skipType && skipType === 'REJECT') {
|
||||
text = '退回'
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 解析xml成Dom对象
|
||||
* @param {} xml
|
||||
* @returns
|
||||
*/
|
||||
export const parseXml2Dom = (xml) => {
|
||||
let xmlDoc = null
|
||||
if (window.DOMParser) {
|
||||
const parser = new DOMParser()
|
||||
xmlDoc = parser.parseFromString(xml, 'text/xml')
|
||||
} else { // Internet Explorer
|
||||
// eslint-disable-next-line no-undef
|
||||
xmlDoc = new ActiveXObject('Microsoft.XMLDOM')
|
||||
xmlDoc.async = false
|
||||
xmlDoc.loadXML(xml)
|
||||
}
|
||||
return xmlDoc
|
||||
}
|
||||
|
||||
// 节点标签
|
||||
const NODE_NAMES = ['start', 'between', 'serial', 'parallel', 'end']
|
||||
// 流程节点属性
|
||||
const DEFINITION_KEYS = ['flowCode', 'flowName', 'version', 'formCustom', 'formPath']
|
||||
// 节点属性
|
||||
const NODE_ATTR_KEYS = ['nodeType', 'nodeCode', 'nodeName', 'coordinate', 'nodeRatio', 'permissionFlag', "skipAnyNode"
|
||||
, "listenerType", "listenerPath", "formCustom", "formPath"]
|
||||
// 变迁节点属性
|
||||
const SKIP_ATTR_KEYS = ['skipName', 'skipType', 'coordinate', 'skipCondition']
|
||||
|
||||
/**
|
||||
* 将warm-flow的定义文件转成LogicFlow支持的数据格式
|
||||
* @param {*} xml
|
||||
* @returns
|
||||
*/
|
||||
export const snakerXml2LogicFlowJson = (xml) => {
|
||||
const graphData = {
|
||||
nodes: [],
|
||||
edges: []
|
||||
}
|
||||
const xmlDoc = parseXml2Dom(xml)
|
||||
const definitionDom = xmlDoc.getElementsByTagName('definition')
|
||||
if (!definitionDom.length) {
|
||||
return graphData
|
||||
}
|
||||
let value = null
|
||||
// 解析definition属性
|
||||
DEFINITION_KEYS.forEach(key => {
|
||||
value = definitionDom[0].getAttribute(key)
|
||||
if (value) {
|
||||
graphData[key] = value
|
||||
}
|
||||
})
|
||||
let nodeEles = null
|
||||
let node = null
|
||||
let lfNode = {}
|
||||
// 解析节点
|
||||
nodeEles = definitionDom[0].getElementsByTagName("node")
|
||||
if (nodeEles.length) {
|
||||
for (var i = 0, len = nodeEles.length; i < len; i++) {
|
||||
node = nodeEles[i]
|
||||
lfNode = {
|
||||
text:{},
|
||||
properties: {}
|
||||
}
|
||||
// 处理节点
|
||||
NODE_ATTR_KEYS.forEach(attrKey => {
|
||||
value = node.getAttribute(attrKey)
|
||||
if (value) {
|
||||
if (attrKey === 'nodeType') {
|
||||
lfNode.type = value
|
||||
} else if (attrKey === 'nodeCode') {
|
||||
lfNode.id = value
|
||||
} else if (attrKey === 'coordinate') {
|
||||
const attr = value.split('|')
|
||||
const nodeXy = attr[0].split(',')
|
||||
lfNode.x = parseInt(nodeXy[0])
|
||||
lfNode.y = parseInt(nodeXy[1])
|
||||
if (attr.length === 2) {
|
||||
const textXy = attr[1].split(',')
|
||||
lfNode.text.x = parseInt(textXy[0])
|
||||
lfNode.text.y = parseInt(textXy[1])
|
||||
}
|
||||
} else if (attrKey === 'nodeName') {
|
||||
lfNode.text.value = value
|
||||
} else {
|
||||
lfNode.properties[attrKey] = value
|
||||
}
|
||||
}
|
||||
})
|
||||
graphData.nodes.push(lfNode)
|
||||
// 处理边
|
||||
let skipEles = null
|
||||
let skipEle = null
|
||||
let edge = {}
|
||||
skipEles = node.getElementsByTagName('skip')
|
||||
for (var j = 0, lenn = skipEles.length; j < lenn; j++) {
|
||||
skipEle = skipEles[j]
|
||||
edge = {
|
||||
text: {},
|
||||
properties: {},
|
||||
}
|
||||
edge.id = skipEle.getAttribute('id')
|
||||
edge.type = 'skip'
|
||||
edge.sourceNodeId = lfNode.id
|
||||
edge.targetNodeId = skipEle.textContent
|
||||
edge.text = {
|
||||
value: skipEle.getAttribute('skipName')
|
||||
}
|
||||
edge.properties.skipCondition = skipEle.getAttribute('skipCondition')
|
||||
edge.properties.skipName = skipEle.getAttribute('skipName')
|
||||
edge.properties.skipType = skipEle.getAttribute('skipType')
|
||||
const expr = skipEle.getAttribute('expr')
|
||||
if (expr) {
|
||||
edge.properties.expr = expr
|
||||
}
|
||||
const coordinate = skipEle.getAttribute('coordinate')
|
||||
if (coordinate) {
|
||||
const coordinateXy = coordinate.split('|')
|
||||
edge.pointsList = []
|
||||
coordinateXy[0].split(';').forEach((item) => {
|
||||
const pointArr = item.split(',')
|
||||
edge.pointsList.push({
|
||||
x: parseInt(pointArr[0]),
|
||||
y: parseInt(pointArr[1])
|
||||
})
|
||||
})
|
||||
edge.startPoint = edge.pointsList[0]
|
||||
edge.endPoint = edge.pointsList[edge.pointsList.length - 1]
|
||||
if (coordinateXy.length > 1) {
|
||||
let textXy = coordinateXy[1].split(",");
|
||||
edge.text.x = parseInt(textXy[0])
|
||||
edge.text.y = parseInt(textXy[1])
|
||||
}
|
||||
}
|
||||
graphData.edges.push(edge)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return graphData
|
||||
}
|
||||
|
||||
/**
|
||||
* 将LogicFlow的数据转成warm-flow的定义文件
|
||||
* @param {*} data(...definitionInfo,nodes,edges)
|
||||
* @returns
|
||||
*/
|
||||
export const logicFlowJsonToFlowXml = (data) => {
|
||||
let xml = ''
|
||||
// data的数据由流程定义文件信息+logicFlow数据构成
|
||||
// 先构建成流程对象
|
||||
const definitionObj = {
|
||||
flowCode: data.flowCode, // 流程定义编码
|
||||
flowName: data.flowName, // 流程定义名称
|
||||
version: data.version, // 流程定义版本号
|
||||
formCustom: data.formCustom, // 表单自定义
|
||||
formPath: data.formPath, // 表单自定义路径
|
||||
}
|
||||
/**
|
||||
* 获取开始节点
|
||||
* @returns
|
||||
*/
|
||||
const getStartNode = () => {
|
||||
return data.nodes.find((node) => {
|
||||
return node.type === 'start'
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 获取当前节点的所有下一个节点集合
|
||||
* @param {*} id 当前节点名称
|
||||
* @returns
|
||||
*/
|
||||
const getNextNodes = (id) => {
|
||||
return data.edges.filter(edge => {
|
||||
return edge.sourceNodeId === id
|
||||
}).map(edge => {
|
||||
return data.nodes.find((node) => {
|
||||
return node.id === edge.targetNodeId
|
||||
})
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 获取节点所有跳转
|
||||
* @param {*} id
|
||||
* @returns
|
||||
*/
|
||||
const getSkip = (id) => {
|
||||
return data.edges.filter((edge) => {
|
||||
return edge.sourceNodeId === id
|
||||
}).map(edge => {
|
||||
let coordinate = ''
|
||||
for (let i = 0; i < edge.pointsList.length; i++) {
|
||||
coordinate = coordinate + parseInt(edge.pointsList[i].x) + ',' + parseInt(edge.pointsList[i].y)
|
||||
if (i !== edge.pointsList.length - 1) {
|
||||
coordinate = coordinate + ';'
|
||||
}
|
||||
}
|
||||
if (edge.text) {
|
||||
coordinate = coordinate + '|' + parseInt(edge.text.x) + ',' + parseInt(edge.text.y)
|
||||
}
|
||||
return {
|
||||
skipType: edge.properties.skipType,
|
||||
skipCondition: edge.properties.skipCondition,
|
||||
skipName: edge.properties.skipName,
|
||||
textContent: edge.targetNodeId, // 目地节点id
|
||||
coordinate: coordinate,
|
||||
}
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 构建节点属性
|
||||
* @param {} node
|
||||
* @returns
|
||||
*/
|
||||
const buildNode = (node) => {
|
||||
let textXy = '';
|
||||
if (node.text) {
|
||||
textXy = '|' + node.text.x + ',' + node.text.y;
|
||||
}
|
||||
return {
|
||||
nodeType: node.type,
|
||||
nodeCode: node.id,
|
||||
nodeName: (node.text instanceof String || node.text === undefined) ? node.text : node.text.value,
|
||||
permissionFlag: node.properties.permissionFlag,
|
||||
nodeRatio: node.properties.nodeRatio,
|
||||
skipAnyNode: node.properties.skipAnyNode,
|
||||
listenerType: node.properties.listenerType,
|
||||
listenerPath: node.properties.listenerPath,
|
||||
coordinate: node.x + ',' + node.y + textXy,
|
||||
skip: getSkip(node.id),
|
||||
formCustom: node.properties.formCustom,
|
||||
formPath: node.properties.formPath,
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 特殊字符转义
|
||||
* @param {*} text
|
||||
* @returns
|
||||
*/
|
||||
const textEncode = (text) => {
|
||||
text = text.replace(/&/g, '&')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
return text
|
||||
}
|
||||
/**
|
||||
* 递归构建节点属性
|
||||
* @param {} node
|
||||
*/
|
||||
const recursionBuildNode = (node) => {
|
||||
const nodeName = node.type
|
||||
if (!definitionObj[nodeName + '_' + node.id]) {
|
||||
definitionObj[nodeName + '_' + node.id] = buildNode(node)
|
||||
const nextNodes = getNextNodes(node.id)
|
||||
nextNodes.forEach(nextNode => {
|
||||
recursionBuildNode(nextNode)
|
||||
})
|
||||
}
|
||||
}
|
||||
const startNode = getStartNode()
|
||||
if (!startNode) {
|
||||
// 开始节点不存在,xml不合法
|
||||
return ''
|
||||
}
|
||||
recursionBuildNode(startNode)
|
||||
xml = '<?xml version="1.0" encoding="UTF-8"?>\n'
|
||||
xml += '<definition'
|
||||
Object.keys(definitionObj).forEach(key => {
|
||||
const value = definitionObj[key]
|
||||
if (DEFINITION_KEYS.includes(key) && value) {
|
||||
xml += ' ' + key + '=' + '"' + textEncode(value) + '"'
|
||||
}
|
||||
})
|
||||
xml += '>\n'
|
||||
// 生成节点xml
|
||||
Object.keys(definitionObj).forEach(key => {
|
||||
const value = definitionObj[key]
|
||||
let nodeName = key.split('_')[0]
|
||||
if (NODE_NAMES.includes(nodeName)) {
|
||||
xml += '\t<node'
|
||||
// 构造属性
|
||||
Object.keys(value).forEach(nodeAttrKey => {
|
||||
if (NODE_ATTR_KEYS.includes(nodeAttrKey) && value[nodeAttrKey]) {
|
||||
xml += ' ' + nodeAttrKey + '=' + '"' + textEncode(value[nodeAttrKey]) + '"'
|
||||
}
|
||||
})
|
||||
xml += '>\n\t'
|
||||
// 构建skip
|
||||
if (value.skip) {
|
||||
value.skip.forEach(skip => {
|
||||
xml += '\t<skip'
|
||||
// skip属性
|
||||
Object.keys(skip).forEach(skipAttrKey => {
|
||||
if (SKIP_ATTR_KEYS.includes(skipAttrKey) && skip[skipAttrKey]) {
|
||||
xml += ' ' + skipAttrKey + '=' + '"' + textEncode(skip[skipAttrKey]) + '"'
|
||||
}
|
||||
})
|
||||
xml += '>'
|
||||
xml += skip['textContent'] + '</skip>\n'
|
||||
})
|
||||
}
|
||||
xml += '\t</node>\n'
|
||||
}
|
||||
})
|
||||
xml += '</definition>'
|
||||
return xml
|
||||
}
|
@ -176,6 +176,20 @@ export const dynamicRoutes: RouteRecordRaw[] = [
|
||||
meta: { title: '请假申请', activeMenu: '/workflow/leave', noCache: true }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/workflow/modelDesign',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['workflow:leave:edit'],
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
component: () => import('@/views/workflow/processDefinition/modelDesign.vue'),
|
||||
name: 'modelDesign',
|
||||
meta: { title: '请假申请', activeMenu: '/workflow/processDefinition', noCache: true }
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -112,6 +112,9 @@
|
||||
<el-col :span="1.5">
|
||||
<el-button link type="primary" size="small" icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button link type="primary" icon="Delete" size="small" @click="design(scope.row)">设计</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@ -534,4 +537,12 @@ const handlerSaveForm = async () => {
|
||||
}
|
||||
});
|
||||
};
|
||||
const design = async (row: FlowDefinitionVo) => {
|
||||
proxy.$router.push({
|
||||
path: `/workflow/modelDesign/index`,
|
||||
query: {
|
||||
id: row.id
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
287
src/views/workflow/processDefinition/modelDesign.vue
Normal file
287
src/views/workflow/processDefinition/modelDesign.vue
Normal file
@ -0,0 +1,287 @@
|
||||
<template>
|
||||
<div ref="container" class="container">
|
||||
<PropertySetting
|
||||
ref="propertySetting"
|
||||
v-model="processForm"
|
||||
:node="nodeClick"
|
||||
:lf="lf"
|
||||
:disabled="disabled"
|
||||
:skip-condition-show="skipConditionShow"
|
||||
>
|
||||
<template v-for="(item, key) in $slots" #[key]="data">
|
||||
<slot :name="key" v-bind="data || {}"></slot>
|
||||
</template>
|
||||
</PropertySetting>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LogicFlow from '@logicflow/core';
|
||||
import '@logicflow/core/dist/style/index.css';
|
||||
import { Control, DndPanel, Menu, SelectionSelect } from '@logicflow/extension';
|
||||
import '@logicflow/extension/lib/style/index.css';
|
||||
import Start from '@/components/WarmFlow/js/start';
|
||||
import Between from '@/components/WarmFlow/js/between';
|
||||
import Serial from '@/components/WarmFlow/js/serial';
|
||||
import Parallel from '@/components/WarmFlow/js/parallel';
|
||||
import End from '@/components/WarmFlow/js/end';
|
||||
import Skip from '@/components/WarmFlow/js/skip';
|
||||
import PropertySetting from '@/components/WarmFlow/PropertySetting/index.vue';
|
||||
import { xmlString } from '@/api/workflow/definition';
|
||||
import { logicFlowJsonToFlowXml, skipText, snakerXml2LogicFlowJson } from '@/components/WarmFlow/js/tool';
|
||||
|
||||
export default {
|
||||
name: 'Design',
|
||||
components: {
|
||||
PropertySetting
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
lf: null,
|
||||
nodeClick: null,
|
||||
// 是否禁用表单
|
||||
disabled: false,
|
||||
processForm: {},
|
||||
value: {},
|
||||
xmlString: '',
|
||||
skipConditionShow: true
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
this.definitionId = this.$route.query.id && this.$route.query.id;
|
||||
if (this.$route.query.disabled == 'true') {
|
||||
this.disabled = true;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.use();
|
||||
this.lf = new LogicFlow({ container: this.$refs.container, grid: true });
|
||||
this.register();
|
||||
this.initDndPanel();
|
||||
this.initControl();
|
||||
this.initMenu();
|
||||
this.initEvent();
|
||||
if (this.definitionId) {
|
||||
xmlString(this.definitionId).then((res) => {
|
||||
this.xmlString = res.data;
|
||||
if (this.xmlString) {
|
||||
this.value = snakerXml2LogicFlowJson(this.xmlString);
|
||||
this.lf.render(this.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
/**
|
||||
* 初始化拖拽面板
|
||||
*/
|
||||
initDndPanel() {
|
||||
this.lf.extension.dndPanel.setPatternItems([
|
||||
{
|
||||
type: 'start',
|
||||
text: '开始',
|
||||
label: '开始节点',
|
||||
icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAABGdBTUEAALGPC/xhBQAAAnBJREFUOBGdVL1rU1EcPfdGBddmaZLiEhdx1MHZQXApraCzQ7GKLgoRBxMfcRELuihWKcXFRcEWF8HBf0DdDCKYRZpnl7p0svLe9Zzbd29eQhTbC8nv+9zf130AT63jvooOGS8Vf9Nt5zxba7sXQwODfkWpkbjTQfCGUd9gIp3uuPP8bZ946g56dYQvnBg+b1HB8VIQmMFrazKcKSvFW2dQTxJnJdQ77urmXWOMBCmXM2Rke4S7UAW+/8ywwFoewmBps2tu7mbTdp8VMOkIRAkKfrVawalJTtIliclFbaOBqa0M2xImHeVIfd/nKAfVq/LGnPss5Kh00VEdSzfwnBXPUpmykNss4lUI9C1ga+8PNrBD5YeqRY2Zz8PhjooIbfJXjowvQJBqkmEkVnktWhwu2SM7SMx7Cj0N9IC0oQXRo8xwAGzQms+xrB/nNSUWVveI48ayrFGyC2+E2C+aWrZHXvOuz+CiV6iycWe1Rd1Q6+QUG07nb5SbPrL4426d+9E1axKjY3AoRrlEeSQo2Eu0T6BWAAr6COhTcWjRaYfKG5csnvytvUr/WY4rrPMB53Uo7jZRjXaG6/CFfNMaXEu75nG47X+oepU7PKJvvzGDY1YLSKHJrK7vFUwXKkaxwhCW3u+sDFMVrIju54RYYbFKpALZAo7sB6wcKyyrd+aBMryMT2gPyD6GsQoRFkGHr14TthZni9ck0z+Pnmee460mHXbRAypKNy3nuMdrWgVKj8YVV8E7PSzp1BZ9SJnJAsXdryw/h5ctboUVi4AFiCd+lQaYMw5z3LGTBKjLQOeUF35k89f58Vv/tGh+l+PE/wG0rgfIUbZK5AAAAABJRU5ErkJggg=='
|
||||
},
|
||||
{
|
||||
type: 'between',
|
||||
text: '中间节点-或签',
|
||||
label: '中间节点-或签',
|
||||
icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAEFVwZaAAAABGdBTUEAALGPC/xhBQAAAqlJREFUOBF9VM9rE0EUfrMJNUKLihGbpLGtaCOIR8VjQMGDePCgCCIiCNqzCAp2MyYUCXhUtF5E0D+g1t48qAd7CCLqQUQKEWkStcEfVGlLdp/fm3aW2QQdyLzf33zz5m2IsAZ9XhDpyaaIZkTS4ASzK41TFao88GuJ3hsr2pAbipHxuSYyKRugagICGANkfFnNh3HeE2N0b3nN2cgnpcictw5veJIzxmDamSlxxQZicq/mflxhbaH8BLRbuRwNtZp0JAhoplVRUdzmCe/vO27wFuuA3S5qXruGdboy5/PRGFsbFGKo/haRtQHIrM83bVeTrOgNhZReWaYGnE4aUQgTJNvijJFF4jQ8BxJE5xfKatZWmZcTQ+BVgh7s8SgPlCkcec4mGTmieTP4xd7PcpIEg1TX6gdeLW8rTVMVLVvb7ctXoH0Cydl2QOPJBG21STE5OsnbweVYzAnD3A7PVILuY0yiiyDwSm2g441r6rMSgp6iK42yqroI2QoXeJVeA+YeZSa47gZdXaZWQKTrG93rukk/l2Al6Kzh5AZEl7dDQy+JjgFahQjRopSxPbrbvK7GRe9ePWBo1wcU7sYrFZtavXALwGw/7Dnc50urrHJuTPSoO2IMV3gUQGNg87IbSOIY9BpiT9HV7FCZ94nPXb3MSnwHn/FFFE1vG6DTby+r31KAkUktB3Qf6ikUPWxW1BkXSPQeMHHiW0+HAd2GelJsZz1OJegCxqzl+CLVHa/IibuHeJ1HAKzhuDR+ymNaRFM+4jU6UWKXorRmbyqkq/D76FffevwdCp+jN3UAN/C9JRVTDuOxC/oh+EdMnqIOrlYteKSfadVRGLJFJPSB/ti/6K8f0CNymg/iH2gO/f0DwE0yjAFO6l8JaR5j0VPwPwfaYHqOqrCI319WzwhwzNW/aQAAAABJRU5ErkJggg==',
|
||||
className: 'important-node',
|
||||
properties: { collaborativeWay: '1' }
|
||||
},
|
||||
{
|
||||
type: 'between',
|
||||
text: '中间节点-票签',
|
||||
label: '中间节点-票签',
|
||||
icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAEFVwZaAAAABGdBTUEAALGPC/xhBQAAAqlJREFUOBF9VM9rE0EUfrMJNUKLihGbpLGtaCOIR8VjQMGDePCgCCIiCNqzCAp2MyYUCXhUtF5E0D+g1t48qAd7CCLqQUQKEWkStcEfVGlLdp/fm3aW2QQdyLzf33zz5m2IsAZ9XhDpyaaIZkTS4ASzK41TFao88GuJ3hsr2pAbipHxuSYyKRugagICGANkfFnNh3HeE2N0b3nN2cgnpcictw5veJIzxmDamSlxxQZicq/mflxhbaH8BLRbuRwNtZp0JAhoplVRUdzmCe/vO27wFuuA3S5qXruGdboy5/PRGFsbFGKo/haRtQHIrM83bVeTrOgNhZReWaYGnE4aUQgTJNvijJFF4jQ8BxJE5xfKatZWmZcTQ+BVgh7s8SgPlCkcec4mGTmieTP4xd7PcpIEg1TX6gdeLW8rTVMVLVvb7ctXoH0Cydl2QOPJBG21STE5OsnbweVYzAnD3A7PVILuY0yiiyDwSm2g441r6rMSgp6iK42yqroI2QoXeJVeA+YeZSa47gZdXaZWQKTrG93rukk/l2Al6Kzh5AZEl7dDQy+JjgFahQjRopSxPbrbvK7GRe9ePWBo1wcU7sYrFZtavXALwGw/7Dnc50urrHJuTPSoO2IMV3gUQGNg87IbSOIY9BpiT9HV7FCZ94nPXb3MSnwHn/FFFE1vG6DTby+r31KAkUktB3Qf6ikUPWxW1BkXSPQeMHHiW0+HAd2GelJsZz1OJegCxqzl+CLVHa/IibuHeJ1HAKzhuDR+ymNaRFM+4jU6UWKXorRmbyqkq/D76FffevwdCp+jN3UAN/C9JRVTDuOxC/oh+EdMnqIOrlYteKSfadVRGLJFJPSB/ti/6K8f0CNymg/iH2gO/f0DwE0yjAFO6l8JaR5j0VPwPwfaYHqOqrCI319WzwhwzNW/aQAAAABJRU5ErkJggg==',
|
||||
className: 'important-node',
|
||||
properties: { collaborativeWay: '2' }
|
||||
},
|
||||
{
|
||||
type: 'between',
|
||||
text: '中间节点-会签',
|
||||
label: '中间节点-会签',
|
||||
icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAEFVwZaAAAABGdBTUEAALGPC/xhBQAAAqlJREFUOBF9VM9rE0EUfrMJNUKLihGbpLGtaCOIR8VjQMGDePCgCCIiCNqzCAp2MyYUCXhUtF5E0D+g1t48qAd7CCLqQUQKEWkStcEfVGlLdp/fm3aW2QQdyLzf33zz5m2IsAZ9XhDpyaaIZkTS4ASzK41TFao88GuJ3hsr2pAbipHxuSYyKRugagICGANkfFnNh3HeE2N0b3nN2cgnpcictw5veJIzxmDamSlxxQZicq/mflxhbaH8BLRbuRwNtZp0JAhoplVRUdzmCe/vO27wFuuA3S5qXruGdboy5/PRGFsbFGKo/haRtQHIrM83bVeTrOgNhZReWaYGnE4aUQgTJNvijJFF4jQ8BxJE5xfKatZWmZcTQ+BVgh7s8SgPlCkcec4mGTmieTP4xd7PcpIEg1TX6gdeLW8rTVMVLVvb7ctXoH0Cydl2QOPJBG21STE5OsnbweVYzAnD3A7PVILuY0yiiyDwSm2g441r6rMSgp6iK42yqroI2QoXeJVeA+YeZSa47gZdXaZWQKTrG93rukk/l2Al6Kzh5AZEl7dDQy+JjgFahQjRopSxPbrbvK7GRe9ePWBo1wcU7sYrFZtavXALwGw/7Dnc50urrHJuTPSoO2IMV3gUQGNg87IbSOIY9BpiT9HV7FCZ94nPXb3MSnwHn/FFFE1vG6DTby+r31KAkUktB3Qf6ikUPWxW1BkXSPQeMHHiW0+HAd2GelJsZz1OJegCxqzl+CLVHa/IibuHeJ1HAKzhuDR+ymNaRFM+4jU6UWKXorRmbyqkq/D76FffevwdCp+jN3UAN/C9JRVTDuOxC/oh+EdMnqIOrlYteKSfadVRGLJFJPSB/ti/6K8f0CNymg/iH2gO/f0DwE0yjAFO6l8JaR5j0VPwPwfaYHqOqrCI319WzwhwzNW/aQAAAABJRU5ErkJggg==',
|
||||
className: 'important-node',
|
||||
properties: { collaborativeWay: '3' }
|
||||
},
|
||||
{
|
||||
type: 'serial',
|
||||
text: '',
|
||||
label: '互斥网关',
|
||||
properties: {},
|
||||
icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAYAAAHeEJUAAAAABGdBTUEAALGPC/xhBQAAAvVJREFUOBGNVEFrE0EU/mY3bQoiFlOkaUJrQUQoWMGePLX24EH0IIoHKQiCV0G8iE1covgLiqA/QTzVm1JPogc9tIJYFaQtlhQxqYjSpunu+L7JvmUTU3AgmTfvffPNN++9WSA1DO182f6xwILzD5btfAoQmwL5KJEwiQyVbSVZ0IgRyV6PTpIJ81E5ZvqfHQR0HUOBHW4L5Et2kQ6Zf7iAOhTFAA8s0pEP7AXO1uAA52SbqGk6h/6J45LaLhO64ByfcUzM39V7ZiAdS2yCePPEIQYvTUHqM/n7dgQNfBKWPjpF4ISk8q3J4nB11qw6X8l+FsF3EhlkEMfrjIer3wJTLwS2aCNcj4DbGxXTw00JmAuO+Ni6bBxVUCvS5d9aa04+so4pHW5jLTywuXAL7jJ+D06sl82Sgl2JuVBQn498zkc2bGKxULHjCnSMadBKYDYYHAtsby1EQ5lNGrQd4Y3v4Zo0XdGEmDno46yCM9Tk+RiJmUYHS/aXHPNTcjxcbTFna000PFJHIVZ5lFRqRpJWk9/+QtlOUYJj9HG5pVFEU7zqIYDVsw2s+AJaD8wTd2umgSCCyUxgGsS1Y6TBwXQQTFuZaHcd8gAGioE90hlsY+wMcs30RduYtxanjMGal8H5dMW67dmT1JFtYUEe8LiQLRsPZ6IIc7A4J5tqco3T0pnv/4u0kyzrYUq7gASuEyI8VXKvB9Odytv6jS/PNaZBln0nioJG/AVQRZvApOdhjj3Jt8QC8Im09SafwdBdvIpztpxWxpeKCC+EsFdS8DCyuCn2munFpL7ctHKp+Xc5cMybeIyMAN33SPL3ZR9QV1XVwLyzHm6Iv0/yeUuUb7PPlZC4D4HZkeu6dpF4v9j9MreGtMbxMMRLIcjJic9yHi7WQ3yVKzZVWUr5UrViJvn1FfUlwe/KYVfYyWRLSGNu16hR01U9IacajXPei0wx/5BqgInvJN+MMNtNme7ReU9SBbgntovn0kKHpFg7UogZvaZiOue/q1SBo9ktHzQAAAAASUVORK5CYII='
|
||||
},
|
||||
{
|
||||
type: 'parallel',
|
||||
text: '',
|
||||
label: '并行网关',
|
||||
properties: {},
|
||||
icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAYAAAHeEJUAAAAABGdBTUEAALGPC/xhBQAAAvVJREFUOBGNVEFrE0EU/mY3bQoiFlOkaUJrQUQoWMGePLX24EH0IIoHKQiCV0G8iE1covgLiqA/QTzVm1JPogc9tIJYFaQtlhQxqYjSpunu+L7JvmUTU3AgmTfvffPNN++9WSA1DO182f6xwILzD5btfAoQmwL5KJEwiQyVbSVZ0IgRyV6PTpIJ81E5ZvqfHQR0HUOBHW4L5Et2kQ6Zf7iAOhTFAA8s0pEP7AXO1uAA52SbqGk6h/6J45LaLhO64ByfcUzM39V7ZiAdS2yCePPEIQYvTUHqM/n7dgQNfBKWPjpF4ISk8q3J4nB11qw6X8l+FsF3EhlkEMfrjIer3wJTLwS2aCNcj4DbGxXTw00JmAuO+Ni6bBxVUCvS5d9aa04+so4pHW5jLTywuXAL7jJ+D06sl82Sgl2JuVBQn498zkc2bGKxULHjCnSMadBKYDYYHAtsby1EQ5lNGrQd4Y3v4Zo0XdGEmDno46yCM9Tk+RiJmUYHS/aXHPNTcjxcbTFna000PFJHIVZ5lFRqRpJWk9/+QtlOUYJj9HG5pVFEU7zqIYDVsw2s+AJaD8wTd2umgSCCyUxgGsS1Y6TBwXQQTFuZaHcd8gAGioE90hlsY+wMcs30RduYtxanjMGal8H5dMW67dmT1JFtYUEe8LiQLRsPZ6IIc7A4J5tqco3T0pnv/4u0kyzrYUq7gASuEyI8VXKvB9Odytv6jS/PNaZBln0nioJG/AVQRZvApOdhjj3Jt8QC8Im09SafwdBdvIpztpxWxpeKCC+EsFdS8DCyuCn2munFpL7ctHKp+Xc5cMybeIyMAN33SPL3ZR9QV1XVwLyzHm6Iv0/yeUuUb7PPlZC4D4HZkeu6dpF4v9j9MreGtMbxMMRLIcjJic9yHi7WQ3yVKzZVWUr5UrViJvn1FfUlwe/KYVfYyWRLSGNu16hR01U9IacajXPei0wx/5BqgInvJN+MMNtNme7ReU9SBbgntovn0kKHpFg7UogZvaZiOue/q1SBo9ktHzQAAAAASUVORK5CYII='
|
||||
},
|
||||
{
|
||||
type: 'end',
|
||||
text: '结束',
|
||||
label: '结束节点',
|
||||
icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAABGdBTUEAALGPC/xhBQAAA1BJREFUOBFtVE1IVUEYPXOf+tq40Y3vPcmFIdSjIorWoRG0ERWUgnb5FwVhYQSl72oUoZAboxKNFtWiwKRN0M+jpfSzqJAQclHo001tKkjl3emc8V69igP3znzfnO/M9zcDcKT67azmjYWTwl9Vn7Vumeqzj1DVb6cleQY4oAVnIOPb+mKAGxQmKI5CWNJ2aLPatxWa3aB9K7/fB+/Z0jUF6TmMlFLQqrkECWQzOZxYGjTlOl8eeKaIY5yHnFn486xBustDjWT6dG7pmjHOJd+33t0iitTPkK6tEvjxq4h2MozQ6WFSX/LkDUGfFwfhEZj1Auz/U4pyAi5Sznd7uKzznXeVHlI/Aywmk6j7fsUsEuCGADrWARXXwjxWQsUbIupDHJI7kF5dRktg0eN81IbiZXiTESic50iwS+t1oJgL83jAiBupLDCQqwziaWSoAFSeIR3P5Xv5az00wyIn35QRYTwdSYbz8pH8fxUUAtxnFvYmEmgI0wYXUXcCCSpeEVpXlsRhBnCEATxWylL9+EKCAYhe1NGstUa6356kS9NVvt3DU2fd+Wtbm/+lSbylJqsqkSm9CRhvoJVlvKPvF1RKY/FcPn5j4UfIMLn8D4UYb54BNsilTDXKnF4CfTobA0FpoW/LSp306wkXM+XaOJhZaFkcNM82ASNAWMrhrUbRfmyeI1FvRBTpN06WKxa9BK0o2E4Pd3zfBBEwPsv9sQBnmLVbLEIZ/Xe9LYwJu/Er17W6HYVBc7vmuk0xUQ+pqxdom5Fnp55SiytXLPYoMXNM4u4SNSCFWnrVIzKG3EGyMXo6n/BQOe+bX3FClY4PwydVhthOZ9NnS+ntiLh0fxtlUJHAuGaFoVmttpVMeum0p3WEXbcll94l1wM/gZ0Ccczop77VvN2I7TlsZCsuXf1WHvWEhjO8DPtyOVg2/mvK9QqboEth+7pD6NUQC1HN/TwvydGBARi9MZSzLE4b8Ru3XhX2PBxf8E1er2A6516o0w4sIA+lwURhAON82Kwe2iDAC1Watq4XHaGQ7skLcFOtI5lDxuM2gZe6WFIotPAhbaeYlU4to5cuarF1QrcZ/lwrLaCJl66JBocYZnrNlvm2+MBCTmUymPrYZVbjdlr/BxlMjmNmNI3SAAAAAElFTkSuQmCC'
|
||||
}
|
||||
]);
|
||||
},
|
||||
/**
|
||||
* 初始化控制面板
|
||||
*/
|
||||
initControl() {
|
||||
if (!this.disabled) {
|
||||
// 控制面板-清空画布
|
||||
this.lf.extension.control.addItem({
|
||||
iconClass: 'lf-control-clear',
|
||||
title: 'clear',
|
||||
text: '清空',
|
||||
onClick: (lf, ev) => {
|
||||
lf.clearData();
|
||||
}
|
||||
});
|
||||
// 控制面板-清空画布
|
||||
this.lf.extension.control.addItem({
|
||||
iconClass: 'lf-control-save',
|
||||
title: '',
|
||||
text: '保存',
|
||||
onClick: (lf, ev) => {
|
||||
this.graphData = lf.getGraphData();
|
||||
this.value['nodes'] = this.graphData['nodes'];
|
||||
this.value['edges'] = this.graphData['edges'];
|
||||
console.log('this.value:', this.value);
|
||||
let xmlString = logicFlowJsonToFlowXml(this.value);
|
||||
console.log('this.xmlString:', xmlString);
|
||||
let data = {
|
||||
xmlString: xmlString,
|
||||
id: this.definitionId
|
||||
};
|
||||
// saveXml(data).then((response) => {
|
||||
// this.$modal.msgSuccess('保存成功');
|
||||
// if (response.code === 200) {
|
||||
// this.close();
|
||||
// }
|
||||
// });
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 初始化菜单
|
||||
*/
|
||||
initMenu() {
|
||||
// 为菜单追加选项(必须在 lf.render() 之前设置)
|
||||
this.lf.extension.menu.addMenuConfig({
|
||||
nodeMenu: [
|
||||
{
|
||||
text: '属性',
|
||||
callback(node) {
|
||||
alert(`
|
||||
节点id:${node.id}
|
||||
节点类型:${node.type}
|
||||
节点坐标:(x: ${node.x}, y: ${node.y})
|
||||
文本坐标:(x: ${node.text.x}, y: ${node.text.y})`);
|
||||
}
|
||||
}
|
||||
],
|
||||
edgeMenu: [
|
||||
{
|
||||
text: '属性',
|
||||
callback(edge) {
|
||||
alert(`
|
||||
边id:${edge.id}
|
||||
边类型:${edge.type}
|
||||
边坐标:(x: ${edge.x}, y: ${edge.y})
|
||||
文本坐标:(x: ${edge.text.x}, y: ${edge.text.y})
|
||||
源节点id:${edge.sourceNodeId}
|
||||
目标节点id:${edge.targetNodeId}`);
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 注册自定义节点和边
|
||||
*/
|
||||
register() {
|
||||
this.lf.register(Start);
|
||||
this.lf.register(Between);
|
||||
this.lf.register(Serial);
|
||||
this.lf.register(Parallel);
|
||||
this.lf.register(End);
|
||||
this.lf.register(Skip);
|
||||
},
|
||||
/**
|
||||
* 添加扩展
|
||||
*/
|
||||
use() {
|
||||
LogicFlow.use(DndPanel);
|
||||
LogicFlow.use(SelectionSelect);
|
||||
LogicFlow.use(Control);
|
||||
LogicFlow.use(Menu);
|
||||
},
|
||||
initEvent() {
|
||||
const { eventCenter } = this.lf.graphModel;
|
||||
eventCenter.on('node:click', (args) => {
|
||||
this.nodeClick = args.data;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.propertySetting.show();
|
||||
});
|
||||
});
|
||||
|
||||
eventCenter.on('edge:click', (args) => {
|
||||
this.nodeClick = args.data;
|
||||
const nodeModel = this.lf.getNodeModelById(this.nodeClick.sourceNodeId);
|
||||
this.skipConditionShow = nodeModel.type === 'serial';
|
||||
this.$nextTick(() => {
|
||||
this.$refs.propertySetting.show(nodeModel.nodeType === 'serial');
|
||||
});
|
||||
});
|
||||
|
||||
eventCenter.on('edge:add', (args) => {
|
||||
this.lf.changeEdgeType(args.data.id, 'skip');
|
||||
// 修改边类型
|
||||
this.lf.setProperties(args.data.id, {
|
||||
skipType: 'PASS'
|
||||
});
|
||||
});
|
||||
|
||||
eventCenter.on('blank:click', (args) => {
|
||||
this.nodeClick = null;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.propertySetting.handleClose();
|
||||
});
|
||||
});
|
||||
},
|
||||
/** 关闭按钮 */
|
||||
close() {
|
||||
const obj = { path: '/flow/definition', query: { t: Date.now(), pageNum: this.$route.query.pageNum } };
|
||||
this.$tab.closeOpenPage(obj);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 800px;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.lf-control-see {
|
||||
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNjQ1NjgyNDM0MzQxIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjEzNzgiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+PGRlZnM+PHN0eWxlIHR5cGU9InRleHQvY3NzIj48L3N0eWxlPjwvZGVmcz48cGF0aCBkPSJNNTEyIDE3MS4yODM2OTJjLTI1NS4wNTQ3NjkgMC00ODUuOTI3Mzg1IDMxMi40MzgxNTQtNDk2Ljc5NzUzOCAzMjcuMzI1NTM4bDAgMC42MzAxNTRDMjYuMDcyNjE1IDUxNC4xMjY3NjkgMjU2Ljk0NTIzMSA4MjYuNDg2MTU0IDUxMiA4MjYuNDg2MTU0YzI1NS4wMTUzODUgMCA0ODUuODg4LTMxMi4zOTg3NjkgNDk2Ljc5NzUzOC0zMjcuMzI1NTM4bDAtMC42MzAxNTRDOTk3LjkyNzM4NSA0ODMuNjgyNDYyIDc2Ny4wMTUzODUgMTcxLjI4MzY5MiA1MTIgMTcxLjI4MzY5Mkw1MTIgMTcxLjI4MzY5MnpNNTEyIDI5MS4yMDk4NDZjMTE0LjU2OTg0NiAwIDIwNy43NTM4NDYgOTMuMTA1MjMxIDIwNy43NTM4NDYgMjA3LjY3NTA3N1M2MjYuNTY5ODQ2IDcwNi42Mzg3NjkgNTEyIDcwNi42Mzg3NjljLTExNC41MzA0NjIgMC0yMDcuNzUzODQ2LTkzLjE4NC0yMDcuNzUzODQ2LTIwNy43NTM4NDZTMzk3LjQ2OTUzOCAyOTEuMjA5ODQ2IDUxMiAyOTEuMjA5ODQ2TTUxMiAzOTUuMjI0NjE1Yy01Ny4yNjUyMzEgMC0xMDMuNjYwMzA4IDQ2LjQzNDQ2Mi0xMDMuNjYwMzA4IDEwMy42NjAzMDhzNDYuMzk1MDc3IDEwMy42NjAzMDggMTAzLjY2MDMwOCAxMDMuNjYwMzA4YzU3LjIyNTg0NiAwIDEwMy42MjA5MjMtNDYuNDM0NDYyIDEwMy42MjA5MjMtMTAzLjY2MDMwOFM1NjkuMjI1ODQ2IDM5NS4yMjQ2MTUgNTEyIDM5NS4yMjQ2MTV6IiBwLWlkPSIxMzc5Ij48L3BhdGg+PC9zdmc+');
|
||||
}
|
||||
|
||||
.lf-control-save {
|
||||
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNjQ1Nzg5MTgwOTgzIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjI4NDMiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+PGRlZnM+PHN0eWxlIHR5cGU9InRleHQvY3NzIj48L3N0eWxlPjwvZGVmcz48cGF0aCBkPSJNNDI2LjY2NjY2NyAxMjhoLTE0OS4zMzMzMzR2MjM0LjQ1MzMzM2MwIDEyLjA3NDY2NyA5LjQ1MDY2NyAyMS41NDY2NjcgMjEuMjA1MzM0IDIxLjU0NjY2N2gyOTguOTIyNjY2YzExLjYyNjY2NyAwIDIxLjIwNTMzMy05LjYgMjEuMjA1MzM0LTIxLjU0NjY2N1YxMjhoLTY0djE0OS41MDRjMCAyMy40NjY2NjctMTkuMTU3MzMzIDQyLjQ5Ni00Mi42MjQgNDIuNDk2aC00Mi43NTJBNDIuNjY2NjY3IDQyLjY2NjY2NyAwIDAgMSA0MjYuNjY2NjY3IDI3Ny41MDRWMTI4ek0xOTIgODk2VjY2MS41NDY2NjdDMTkyIDYwMi40NzQ2NjcgMjM5Ljc4NjY2NyA1NTQuNjY2NjY3IDI5OC44MzczMzMgNTU0LjY2NjY2N2g0MjYuMzI1MzM0QTEwNi43MDkzMzMgMTA2LjcwOTMzMyAwIDAgMSA4MzIgNjYxLjU0NjY2N1Y4OTZoNDIuNTE3MzMzQTIxLjMxMiAyMS4zMTIgMCAwIDAgODk2IDg3NC43NTJWMjczLjY2NEw3NTAuMzM2IDEyOEg3MDR2MjM0LjQ1MzMzM2MwIDU4Ljk2NTMzMy00Ny43MDEzMzMgMTA2Ljg4LTEwNi41Mzg2NjcgMTA2Ljg4SDI5OC41Mzg2NjdBMTA2LjU2IDEwNi41NiAwIDAgMSAxOTIgMzYyLjQ1MzMzM1YxMjhIMTQ5LjI0OEEyMS4yNjkzMzMgMjEuMjY5MzMzIDAgMCAwIDEyOCAxNDkuNDgyNjY3djcyNS4wMzQ2NjZDMTI4IDg4Ni40MjEzMzMgMTM3LjU3ODY2NyA4OTYgMTQ5LjQ4MjY2NyA4OTZIMTkyek00Mi42NjY2NjcgMTQ5LjQ4MjY2N0ExMDYuNjAyNjY3IDEwNi42MDI2NjcgMCAwIDEgMTQ5LjI0OCA0Mi42NjY2NjdINzY4YTQyLjY2NjY2NyA0Mi42NjY2NjcgMCAwIDEgMzAuMTY1MzMzIDEyLjUwMTMzM2wxNzAuNjY2NjY3IDE3MC42NjY2NjdBNDIuNjY2NjY3IDQyLjY2NjY2NyAwIDAgMSA5ODEuMzMzMzMzIDI1NnY2MTguNzUyQTEwNi42NDUzMzMgMTA2LjY0NTMzMyAwIDAgMSA4NzQuNTE3MzMzIDk4MS4zMzMzMzNIMTQ5LjQ4MjY2N0ExMDYuNzUyIDEwNi43NTIgMCAwIDEgNDIuNjY2NjY3IDg3NC41MTczMzNWMTQ5LjQ4MjY2N3ogbTcwNCA1MTIuMDQyNjY2YzAtMTIuMDEwNjY3LTkuNTM2LTIxLjUyNTMzMy0yMS41MDQtMjEuNTI1MzMzSDI5OC44MzczMzNDMjg2LjkzMzMzMyA2NDAgMjc3LjMzMzMzMyA2NDkuNiAyNzcuMzMzMzMzIDY2MS41NDY2NjdWODk2aDQ2OS4zMzMzMzRWNjYxLjU0NjY2N3oiIGZpbGw9IiMwMDAwMDAiIHAtaWQ9IjI4NDQiPjwvcGF0aD48L3N2Zz4=');
|
||||
}
|
||||
.lf-control-clear {
|
||||
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNjQ1Nzg5MTYyODczIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjIwNDYiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+PGRlZnM+PHN0eWxlIHR5cGU9InRleHQvY3NzIj48L3N0eWxlPjwvZGVmcz48cGF0aCBkPSJNODk5LjEgODY5LjZsLTUzLTMwNS42SDg2NGMxNC40IDAgMjYtMTEuNiAyNi0yNlYzNDZjMC0xNC40LTExLjYtMjYtMjYtMjZINjE4VjEzOGMwLTE0LjQtMTEuNi0yNi0yNi0yNkg0MzJjLTE0LjQgMC0yNiAxMS42LTI2IDI2djE4MkgxNjBjLTE0LjQgMC0yNiAxMS42LTI2IDI2djE5MmMwIDE0LjQgMTEuNiAyNiAyNiAyNmgxNy45bC01MyAzMDUuNmMtMC4zIDEuNS0wLjQgMy0wLjQgNC40IDAgMTQuNCAxMS42IDI2IDI2IDI2aDcyM2MxLjUgMCAzLTAuMSA0LjQtMC40IDE0LjItMi40IDIzLjctMTUuOSAyMS4yLTMwek0yMDQgMzkwaDI3MlYxODJoNzJ2MjA4aDI3MnYxMDRIMjA0VjM5MHogbTQ2OCA0NDBWNjc0YzAtNC40LTMuNi04LTgtOGgtNDhjLTQuNCAwLTggMy42LTggOHYxNTZINDE2VjY3NGMwLTQuNC0zLjYtOC04LThoLTQ4Yy00LjQgMC04IDMuNi04IDh2MTU2SDIwMi44bDQ1LjEtMjYwSDc3Nmw0NS4xIDI2MEg2NzJ6IiBwLWlkPSIyMDQ3Ij48L3BhdGg+PC9zdmc+');
|
||||
}
|
||||
</style>
|
@ -203,8 +203,7 @@ const deleteReason = ref('');
|
||||
const queryParams = ref<ProcessInstanceQuery>({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
name: undefined,
|
||||
key: undefined,
|
||||
flowCode: undefined,
|
||||
categoryCode: undefined
|
||||
});
|
||||
|
||||
@ -307,11 +306,11 @@ const changeTab = async (data: string) => {
|
||||
};
|
||||
/** 作废按钮操作 */
|
||||
const handleInvalid = async (row: ProcessInstanceVO) => {
|
||||
await proxy?.$modal.confirm('是否确认作废业务id为【' + row.businessKey + '】的数据项?');
|
||||
await proxy?.$modal.confirm('是否确认作废业务id为【' + row.businessId + '】的数据项?');
|
||||
loading.value = true;
|
||||
if ('running' === tab.value) {
|
||||
let param = {
|
||||
businessKey: row.businessKey,
|
||||
businessKey: row.businessId,
|
||||
deleteReason: deleteReason.value
|
||||
};
|
||||
await deleteRunInstance(param).finally(() => (loading.value = false));
|
||||
@ -322,18 +321,6 @@ const handleInvalid = async (row: ProcessInstanceVO) => {
|
||||
const cancelPopover = async (index: any) => {
|
||||
(proxy?.$refs[`popoverRef${index}`] as any).hide(); //关闭弹窗
|
||||
};
|
||||
//获取流程定义
|
||||
const getProcessDefinitionHitoryList = (id: string, key: string) => {
|
||||
processDefinitionDialog.visible = true;
|
||||
processDefinitionId.value = id;
|
||||
loading.value = true;
|
||||
getListByKey(key).then((resp) => {
|
||||
if (resp.data && resp.data.length > 0) {
|
||||
processDefinitionHistoryList.value = resp.data.filter((item: any) => item.id !== id);
|
||||
}
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
//切换流程版本
|
||||
const handleChange = async (id: string) => {
|
||||
await proxy?.$modal.confirm('是否确认切换?');
|
||||
|
Loading…
x
Reference in New Issue
Block a user