fix: 修复流程设计时多实例数据回显问题

rf
tony 2022-12-18 13:37:59 +08:00
parent 9436bb4154
commit 1486beb897
5 changed files with 73 additions and 49 deletions

View File

@ -10,7 +10,6 @@
:groups="groups" :groups="groups"
:exps="exps" :exps="exps"
:categorys="categorys" :categorys="categorys"
@dataType="dataType"
/> />
</div> </div>
</template> </template>
@ -141,10 +140,6 @@ export default {
} }
}) })
}, },
/** 获取数据类型 */
dataType(data){
this.$emit('dataType', data)
}
} }
} }
</script> </script>
@ -156,6 +151,7 @@ export default {
.el-form--label-top .el-form-item__label { .el-form--label-top .el-form-item__label {
padding: 0; padding: 0;
} }
//
.el-form-item { .el-form-item {
margin-bottom: 6px; margin-bottom: 6px;
} }

View File

@ -3,41 +3,36 @@
<el-dialog <el-dialog
title="多实例配置" title="多实例配置"
:visible.sync="dialogVisible" :visible.sync="dialogVisible"
width="500px" width="600px"
:close-on-click-modal="false" :close-on-click-modal="false"
:close-on-press-escape="false" :close-on-press-escape="false"
:show-close="false"
class="muti-instance" class="muti-instance"
@closed="$emit('close')" @closed="$emit('close')"
> >
<el-alert <el-descriptions :column="1" size="mini" border>
type="info" <el-descriptions-item label="使用说明">按照BPMN2.0规范的要求用于为每个实例创建执行的父执行会提供下列变量:</el-descriptions-item>
:closable="false" <el-descriptions-item label="nrOfInstances">实例总数</el-descriptions-item>
show-icon <el-descriptions-item label="nrOfActiveInstances">当前活动的即未完成的实例数量对于顺序多实例这个值总为1</el-descriptions-item>
style="margin-bottom: 20px" <el-descriptions-item label="nrOfCompletedInstances">已完成的实例数量</el-descriptions-item>
> <el-descriptions-item label="loopCounter">给定实例在for-each循环中的index</el-descriptions-item>
<template #title> </el-descriptions>
按照BPMN2.0规范的要求用于为每个实例创建执行的父执行会提供下列变量:<br> <div class="app-container">
nrOfInstances实例总数<br> <x-form ref="xForm" v-model="formData" :config="formConfig" />
nrOfActiveInstances当前活动的即未完成的实例数量对于顺序多实例这个值总为1<br> </div>
nrOfCompletedInstances已完成的实例数量<br>
loopCounter给定实例在for-each循环中的index<br>
</template>
</el-alert>
<x-form ref="xForm" v-model="formData" :config="formConfig" />
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
<script> <script>
import mixinPanel from '../../../common/mixinPanel' import mixinPanel from '@/components/Process/common/mixinPanel'
import { formatJsonKeyValue } from '../../../common/parseElement' import { formatJsonKeyValue } from '@/components/Process/common/parseElement'
export default { export default {
mixins: [mixinPanel], mixins: [mixinPanel],
data() { data() {
return { return {
dialogVisible: true, dialogVisible: true,
formData: {} formData: {},
prefix: 'flowable:',
} }
}, },
computed: { computed: {
@ -50,25 +45,30 @@ export default {
xType: 'input', xType: 'input',
name: 'collection', name: 'collection',
label: '集合', label: '集合',
tooltip: '属性会作为表达式进行解析。如果表达式解析为字符串而不是一个集合,<br />不论是因为本身配置的就是静态字符串值,还是表达式计算结果为字符串,<br />这个字符串都会被当做变量名,并从流程变量中用于获取实际的集合。' tooltip: 'collection: 属性会作为表达式进行解析。如果表达式解析为字符串而不是一个集合,<br />不论是因为本身配置的就是静态字符串值,还是表达式计算结果为字符串,<br />这个字符串都会被当做变量名,并从流程变量中用于获取实际的集合。',
rules: [{ required: true, message: '请输入集合名称', trigger: ['blur', 'change'] }]
}, },
{ {
xType: 'input', xType: 'input',
name: 'elementVariable', name: 'elementVariable',
label: '元素变量', label: '元素变量',
tooltip: '每创建一个用户任务前先以该元素变量为label集合中的一项为value<br />创建(局部)流程变量,该局部流程变量被用于指派用户任务。<br />一般来说,该字符串应与指定人员变量相同。' tooltip: 'elementVariable: 每创建一个用户任务前先以该元素变量为label集合中的一项为value<br />创建(局部)流程变量,该局部流程变量被用于指派用户任务。<br />一般来说,该字符串应与指定人员变量相同。',
rules: [{ required: true, message: '请输入元素变量', trigger: ['blur', 'change'] }]
}, },
{ {
xType: 'radio', xType: 'select',
name: 'isSequential', name: 'isSequential',
label: '执行方式', label: '执行方式',
dic: [{ label: '串行', value: true }, { label: '并行', value: false }] tooltip: '并行会签parallel、串行会签(sequential),其中并行会签的意思是 多个人同时执行任务。串行会签是按顺序执行任务。',
dic: [{label: '串行', value: true}, {label: '并行', value: false}],
rules: [{ required: true, message: '请选择执行方式', trigger: ['blur', 'change'] }]
}, },
{ {
xType: 'input', xType: 'input',
name: 'completionCondition', name: 'completionCondition',
label: '完成条件', label: '完成条件',
tooltip: '多实例活动在所有实例都完成时结束,然而也可以指定一个表达式,在每个实例<br />结束时进行计算。当表达式计算为true时将销毁所有剩余的实例并结束多实例<br />活动,继续执行流程。例如 ${nrOfCompletedInstances/nrOfInstances >= 0.6 }<br />表示当任务完成60%时,该节点就算完成' tooltip: 'completionCondition: 多实例活动在所有实例都完成时结束,然而也可以指定一个表达式,在每个实例<br />结束时进行计算。当表达式计算为true时将销毁所有剩余的实例并结束多实例<br />活动,继续执行流程。例如 ${nrOfCompletedInstances/nrOfInstances >= 0.6 }<br />表示当任务完成60%时,该节点就算完成',
rules: [{ required: true, message: '请输入完成条件', trigger: ['blur', 'change'] }]
} }
], ],
operate: [ operate: [
@ -81,30 +81,44 @@ export default {
mounted() { mounted() {
const cache = JSON.parse(JSON.stringify(this.element.businessObject.loopCharacteristics ?? {})) const cache = JSON.parse(JSON.stringify(this.element.businessObject.loopCharacteristics ?? {}))
cache.completionCondition = cache.completionCondition?.body cache.completionCondition = cache.completionCondition?.body
//
Object.assign(cache,this.element.businessObject.loopCharacteristics.$attrs)
this.formData = formatJsonKeyValue(cache) this.formData = formatJsonKeyValue(cache)
}, },
methods: { methods: {
updateElement() { updateElement() {
if (this.formData.isSequential !== null && this.formData.isSequential !== undefined) { if (this.formData.isSequential !== null && this.formData.isSequential !== undefined) {
const model = this.modeler.get('moddle');
let loopCharacteristics = this.element.businessObject.get('loopCharacteristics') let loopCharacteristics = this.element.businessObject.get('loopCharacteristics')
if (!loopCharacteristics) { if (!loopCharacteristics) {
loopCharacteristics = this.modeler.get('moddle').create('bpmn:MultiInstanceLoopCharacteristics') loopCharacteristics = model.create('bpmn:MultiInstanceLoopCharacteristics')
} }
loopCharacteristics['isSequential'] = this.formData.isSequential loopCharacteristics['isSequential'] = this.formData.isSequential
loopCharacteristics['collection'] = this.formData.collection loopCharacteristics['collection'] = this.formData.collection
loopCharacteristics['elementVariable'] = this.formData.elementVariable loopCharacteristics['elementVariable'] = this.formData.elementVariable
// let loopCardinality = model.create("bpmn:Expression",{
// body: "4"
// });
// loopCharacteristics['loopCardinality'] = loopCardinality
loopCharacteristics.$attrs['isSequential'] = this.formData.isSequential
loopCharacteristics.$attrs[this.prefix + 'collection'] = this.formData.collection
loopCharacteristics.$attrs[this.prefix + 'elementVariable'] = this.formData.elementVariable
if (this.formData.completionCondition) { if (this.formData.completionCondition) {
const completionCondition = this.modeler.get('moddle').create('bpmn:Expression', { body: this.formData.completionCondition }) const completionCondition = model.create('bpmn:Expression', {body: this.formData.completionCondition})
loopCharacteristics['completionCondition'] = completionCondition loopCharacteristics['completionCondition'] = completionCondition
} }
this.updateProperties({ loopCharacteristics: loopCharacteristics }) this.updateProperties({loopCharacteristics: loopCharacteristics})
} else { } else {
delete this.element.businessObject.loopCharacteristics delete this.element.businessObject.loopCharacteristics
} }
}, },
save() { save() {
this.updateElement() this.$refs['xForm'].validate().then(() => {
this.dialogVisible = false this.updateElement()
this.dialogVisible = false
}).catch(e => console.error(e));
} }
} }
} }

View File

@ -155,10 +155,6 @@ export default {
{ label: '候选人员', value: 'candidateUsers' }, { label: '候选人员', value: 'candidateUsers' },
{ label: '候选角色', value: 'candidateGroups' } { label: '候选角色', value: 'candidateGroups' }
], ],
dataTypeOption: [
{ label: '固定', value: 'fixed' },
{ label: '动态', value: 'dynamic' }
],
dialogName: '', dialogName: '',
executionListenerLength: 0, executionListenerLength: 0,
taskListenerLength: 0, taskListenerLength: 0,
@ -166,9 +162,11 @@ export default {
userVisible: false, userVisible: false,
roleVisible: false, roleVisible: false,
expVisible: false, expVisible: false,
formData: {}, formData: {
userTypeOption: 'assignee',
},
assignee: null, assignee: null,
candidateUsers: "", candidateUsers: null,
candidateGroups: null, candidateGroups: null,
// //
checkType: 'single', checkType: 'single',
@ -178,7 +176,9 @@ export default {
selectValues: null, selectValues: null,
// //
userList: this.users, userList: this.users,
//
groupList: this.groups, groupList: this.groups,
//
expList: this.exps, expList: this.exps,
// //
expType: null, expType: null,
@ -223,6 +223,7 @@ export default {
name: 'userType', name: 'userType',
label: '用户类型', label: '用户类型',
dic: _this.userTypeOption, dic: _this.userTypeOption,
// rules: [{ required: true, message: '' }],
show: !!_this.showConfig.userType show: !!_this.showConfig.userType
}, },
{ {
@ -236,12 +237,14 @@ export default {
xType: 'slot', xType: 'slot',
name: 'checkMultipleUser', name: 'checkMultipleUser',
label: '候选人员', label: '候选人员',
// rules: [{ required: true, message: '' }],
show: !!_this.showConfig.candidateUsers && _this.formData.userType === 'candidateUsers' show: !!_this.showConfig.candidateUsers && _this.formData.userType === 'candidateUsers'
}, },
{ {
xType: 'slot', xType: 'slot',
name: 'checkRole', name: 'checkRole',
label: '候选角色', label: '候选角色',
// rules: [{ required: true, message: '' }],
show: !!_this.showConfig.candidateGroups && _this.formData.userType === 'candidateGroups' show: !!_this.showConfig.candidateGroups && _this.formData.userType === 'candidateGroups'
}, },
{ {
@ -351,6 +354,7 @@ export default {
delete this.formData[type] delete this.formData[type]
}) })
} }
// userTypexml
this.updateProperties({'flowable:userType': val}) this.updateProperties({'flowable:userType': val})
}, },
'formData.async': function(val) { 'formData.async': function(val) {
@ -413,7 +417,7 @@ export default {
this.computedExecutionListenerLength() this.computedExecutionListenerLength()
this.computedTaskListenerLength() this.computedTaskListenerLength()
this.computedHasMultiInstance() this.computedHasMultiInstance()
this.getCheckValues() this.checkValuesEcho()
}, },
methods: { methods: {
computedExecutionListenerLength() { computedExecutionListenerLength() {
@ -432,11 +436,11 @@ export default {
} }
}, },
// //
getCheckValues(){ checkValuesEcho(){
const that = this; const that = this;
// console.log(that.element.businessObject,"this.element.businessObject")
const attrs = that.element.businessObject.$attrs; const attrs = that.element.businessObject.$attrs;
const businessObject = that.element.businessObject; const businessObject = that.element.businessObject;
console.log(that.element.businessObject,"this.element.businessObject")
// //
if (attrs.hasOwnProperty("flowable:assignee")) { if (attrs.hasOwnProperty("flowable:assignee")) {
const val = attrs["flowable:assignee"]; const val = attrs["flowable:assignee"];
@ -459,9 +463,9 @@ export default {
this.checkValues = newArr.map(item => item.nickName).join(','); this.checkValues = newArr.map(item => item.nickName).join(',');
this.selectValues = newArr.map(item => item.userId).join(','); this.selectValues = newArr.map(item => item.userId).join(',');
} }
} else if (businessObject.hasOwnProperty("candidateGroups")) { } else if (businessObject.hasOwnProperty("candidateGroups") || attrs.hasOwnProperty("flowable:candidateGroups") ) {
// //
const val = businessObject["candidateGroups"]; const val = businessObject["candidateGroups"] || attrs["flowable:candidateGroups"];
if (attrs["flowable:dataType"] === "dynamic") { if (attrs["flowable:dataType"] === "dynamic") {
this.checkValues = that.expList.find(item => item.expression == val).name; this.checkValues = that.expList.find(item => item.expression == val).name;
this.selectValues = that.expList.filter(item => item.expression == val).id; this.selectValues = that.expList.filter(item => item.expression == val).id;

View File

@ -844,6 +844,16 @@
"isAttr": true, "isAttr": true,
"type": "Boolean" "type": "Boolean"
}, },
{
"name": "collection",
"isAttr": true,
"type": "String"
},
{
"name": "elementVariable",
"isAttr": true,
"type": "String"
},
{ {
"name": "behavior", "name": "behavior",
"type": "MultiInstanceBehavior", "type": "MultiInstanceBehavior",
@ -1191,4 +1201,4 @@
} }
], ],
"emumerations": [] "emumerations": []
} }

View File

@ -82,7 +82,7 @@ export default {
const deployId = this.$route.query && this.$route.query.deployId; const deployId = this.$route.query && this.$route.query.deployId;
// xml // xml
if (deployId) { if (deployId) {
this.getModelDetail(deployId); this.getXmlData(deployId);
} }
this.getDicts("sys_process_category").then(res => { this.getDicts("sys_process_category").then(res => {
this.categorys = res.data; this.categorys = res.data;
@ -91,7 +91,7 @@ export default {
}, },
methods: { methods: {
/** xml 文件 */ /** xml 文件 */
getModelDetail(deployId) { getXmlData(deployId) {
// xml // xml
readXml(deployId).then(res =>{ readXml(deployId).then(res =>{
this.xml = res.data; this.xml = res.data;