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

View File

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

View File

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

View File

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

View File

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