BPM:重构审批人的分配规则实现,移除 bpm_task_assign_rule 表,存储在 bpmn 的 userTask 中

This commit is contained in:
YunaiV
2024-03-13 21:18:26 +08:00
parent c89941d435
commit feadd022e7
13 changed files with 210 additions and 530 deletions

View File

@ -332,6 +332,16 @@
"name": "multiinstance_condition",
"isAttr": true,
"type": "String"
},
{
"name": "assignType",
"isAttr": true,
"type": "String"
},
{
"name": "assignOptions",
"isAttr": true,
"type": "String"
}
]
},

View File

@ -319,6 +319,16 @@
"name": "priority",
"isAttr": true,
"type": "String"
},
{
"name": "assignType",
"isAttr": true,
"type": "String"
},
{
"name": "assignOptions",
"isAttr": true,
"type": "String"
}
]
},

View File

@ -319,6 +319,16 @@
"name": "priority",
"isAttr": true,
"type": "String"
},
{
"name": "assignType",
"isAttr": true,
"type": "String"
},
{
"name": "assignOptions",
"isAttr": true,
"type": "String"
}
]
},

View File

@ -32,7 +32,7 @@
替代提供更好的表单设计功能
</el-collapse-item>
<el-collapse-item name="task" v-if="elementType.indexOf('Task') !== -1" key="task">
<template #title><Icon icon="ep:checked" />任务</template>
<template #title><Icon icon="ep:checked" />任务审批人</template>
<element-task :id="elementId" :type="elementType" />
</el-collapse-item>
<el-collapse-item
@ -40,7 +40,7 @@
v-if="elementType.indexOf('Task') !== -1"
key="multiInstance"
>
<template #title><Icon icon="ep:help-filled" />多实例</template>
<template #title><Icon icon="ep:help-filled" />多实例会签配置</template>
<element-multi-instance :business-object="elementBusinessObject" :type="elementType" />
</el-collapse-item>
<el-collapse-item name="listeners" key="listeners">

View File

@ -138,6 +138,8 @@ const updateBaseInfo = (key) => {
bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), attrObj)
}
}
// TODO 芋艿:这里延迟,可能存在覆盖 userTask 的问题。。例如说,打开的时候,立马选中某个 usertask则它的 id 会被覆盖。。。
onMounted(() => {
// 针对上传的 bpmn 流程图时,需要延迟 1 秒的时间,保证 key 和 name 的更新
setTimeout(() => {

View File

@ -1,7 +1,8 @@
<template>
<div class="panel-tab__content">
<el-form size="small" label-width="90px">
<el-form-item label="异步延续">
<!-- add by 芋艿由于异步延续暂时用不到所以这里 display none -->
<el-form-item label="异步延续" style="display: none">
<el-checkbox
v-model="taskConfigForm.asyncBefore"
label="异步前"

View File

@ -1,85 +1,183 @@
<template>
<div style="margin-top: 16px">
<!-- <el-form-item label="处理用户">-->
<!-- <el-select v-model="userTaskForm.assignee" @change="updateElementTask('assignee')">-->
<!-- <el-option v-for="ak in mockData" :key="'ass-' + ak" :label="`用户${ak}`" :value="`user${ak}`" />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="候选用户">-->
<!-- <el-select v-model="userTaskForm.candidateUsers" multiple collapse-tags @change="updateElementTask('candidateUsers')">-->
<!-- <el-option v-for="uk in mockData" :key="'user-' + uk" :label="`用户${uk}`" :value="`user${uk}`" />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="候选分组">-->
<!-- <el-select v-model="userTaskForm.candidateGroups" multiple collapse-tags @change="updateElementTask('candidateGroups')">-->
<!-- <el-option v-for="gk in mockData" :key="'ass-' + gk" :label="`分组${gk}`" :value="`group${gk}`" />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<el-form-item label="到期时间">
<el-input v-model="userTaskForm.dueDate" clearable @change="updateElementTask('dueDate')" />
</el-form-item>
<el-form-item label="跟踪时间">
<el-input
v-model="userTaskForm.followUpDate"
<el-form label-width="100px">
<el-form-item label="规则类型" prop="assignType">
<el-select
v-model="userTaskForm.assignType"
clearable
@change="updateElementTask('followUpDate')"
style="width: 100%"
@change="changeAssignType"
>
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.BPM_TASK_ASSIGN_RULE_TYPE)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item v-if="userTaskForm.assignType == 10" label="指定角色" prop="assignOptions">
<el-select
v-model="userTaskForm.assignOptions"
clearable
multiple
style="width: 100%"
@change="updateElementTask"
>
<el-option v-for="item in roleOptions" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item
v-if="userTaskForm.assignType == 20 || userTaskForm.assignType == 21"
label="指定部门"
prop="assignOptions"
span="24"
>
<el-tree-select
ref="treeRef"
v-model="userTaskForm.assignOptions"
:data="deptTreeOptions"
:props="defaultProps"
empty-text="加载中请稍后"
multiple
node-key="id"
show-checkbox
@change="updateElementTask"
/>
</el-form-item>
<el-form-item label="优先级">
<el-input v-model="userTaskForm.priority" clearable @change="updateElementTask('priority')" />
<el-form-item
v-if="userTaskForm.assignType == 22"
label="指定岗位"
prop="assignOptions"
span="24"
>
<el-select
v-model="userTaskForm.assignOptions"
clearable
multiple
style="width: 100%"
@change="updateElementTask"
>
<el-option v-for="item in postOptions" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
友情提示任务的分配规则使用
<router-link target="_blank" :to="{ path: '/bpm/manager/model' }"
><el-link type="danger">流程模型</el-link>
</router-link>
下的分配规则替代提供指定角色部门负责人部门成员岗位工作组自定义脚本等 7
种维护的任务分配维度更加灵活
</div>
<el-form-item
v-if="
userTaskForm.assignType == 30 ||
userTaskForm.assignType == 31 ||
userTaskForm.assignType == 32
"
label="指定用户"
prop="assignOptions"
span="24"
>
<el-select
v-model="userTaskForm.assignOptions"
clearable
multiple
style="width: 100%"
@change="updateElementTask"
>
<el-option
v-for="item in userOptions"
:key="item.id"
:label="item.nickname"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item v-if="userTaskForm.assignType === 40" label="指定用户组" prop="assignOptions">
<el-select
v-model="userTaskForm.assignOptions"
clearable
multiple
style="width: 100%"
@change="updateElementTask"
>
<el-option
v-for="item in userGroupOptions"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item v-if="userTaskForm.assignType === 50" label="指定脚本" prop="assignOptions">
<el-select
v-model="userTaskForm.assignOptions"
clearable
multiple
style="width: 100%"
@change="updateElementTask"
>
<el-option
v-for="dict in taskAssignScriptDictDatas"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-form>
</template>
<script lang="ts" setup>
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { defaultProps, handleTree } from '@/utils/tree'
import * as RoleApi from '@/api/system/role'
import * as DeptApi from '@/api/system/dept'
import * as PostApi from '@/api/system/post'
import * as UserApi from '@/api/system/user'
import * as UserGroupApi from '@/api/bpm/userGroup'
defineOptions({ name: 'UserTask' })
const props = defineProps({
id: String,
type: String
})
const defaultTaskForm = ref({
assignee: '',
candidateUsers: [],
candidateGroups: [],
dueDate: '',
followUpDate: '',
priority: ''
const userTaskForm = ref({
assignType: undefined, // 分配规则
assignOptions: [] // 分配选项
})
const userTaskForm = ref<any>({})
// const mockData=ref([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
const bpmnElement = ref()
const bpmnInstances = () => (window as any)?.bpmnInstances
const roleOptions = ref<RoleApi.RoleVO[]>([]) // 角色列表
const deptTreeOptions = ref() // 部门树
const postOptions = ref<PostApi.PostVO[]>([]) // 岗位列表
const userOptions = ref<UserApi.UserVO[]>([]) // 用户列表
const userGroupOptions = ref<UserGroupApi.UserGroupVO[]>([]) // 用户组列表
const taskAssignScriptDictDatas = getIntDictOptions(DICT_TYPE.BPM_TASK_ASSIGN_SCRIPT)
const resetTaskForm = () => {
for (let key in defaultTaskForm.value) {
let value
if (key === 'candidateUsers' || key === 'candidateGroups') {
value = bpmnElement.value?.businessObject[key]
? bpmnElement.value.businessObject[key].split(',')
: []
} else {
value = bpmnElement.value?.businessObject[key] || defaultTaskForm.value[key]
}
userTaskForm.value[key] = value
const businessObject = bpmnElement.value.businessObject
if (!businessObject) {
return
}
if (businessObject.assignType != undefined) {
userTaskForm.value.assignType = parseInt(businessObject.assignType) as any
} else {
userTaskForm.value.assignType = undefined
}
if (businessObject.assignOptions && businessObject.assignOptions.length > 0) {
userTaskForm.value.assignOptions = businessObject.assignOptions?.split(',').map((item) => +item)
} else {
userTaskForm.value.assignOptions = []
}
}
const updateElementTask = (key) => {
const taskAttr = Object.create(null)
if (key === 'candidateUsers' || key === 'candidateGroups') {
taskAttr[key] =
userTaskForm.value[key] && userTaskForm.value[key].length
? userTaskForm.value[key].join()
: null
} else {
taskAttr[key] = userTaskForm.value[key] || null
}
bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), taskAttr)
/** 更新 assignType 字段时,需要清空 assignOptions并触发 bpmn 图更新 */
const changeAssignType = () => {
userTaskForm.value.assignOptions = []
updateElementTask()
}
/** 选中某个 options 时候,更新 bpmn 图 */
const updateElementTask = () => {
bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), {
assignType: userTaskForm.value.assignType,
assignOptions: userTaskForm.value.assignOptions.join(',')
})
}
watch(
@ -92,6 +190,21 @@ watch(
},
{ immediate: true }
)
onMounted(async () => {
// 获得角色列表
roleOptions.value = await RoleApi.getSimpleRoleList()
// 获得部门列表
const deptOptions = await DeptApi.getSimpleDeptList()
deptTreeOptions.value = handleTree(deptOptions, 'id')
// 获得岗位列表
postOptions.value = await PostApi.getSimplePostList()
// 获得用户列表
userOptions.value = await UserApi.getSimpleUserList()
// 获得用户组列表
userGroupOptions.value = await UserGroupApi.getSimpleUserGroupList()
})
onBeforeUnmount(() => {
bpmnElement.value = null
})