!614 bpm设计器优化

Merge pull request !614 from Lesan/feature/bpm
This commit is contained in:
芋道源码 2024-12-11 04:40:11 +00:00 committed by Gitee
commit bfb9e2e77f
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
2 changed files with 198 additions and 81 deletions

View File

@ -4,9 +4,24 @@
3. 审批人为空时
4. 操作按钮
5. 字段权限
6. 审批类型
-->
<template>
<div>
<el-divider content-position="left">审批类型</el-divider>
<el-form-item prop="approveType">
<el-radio-group v-model="approveType.value">
<el-radio
v-for="(item, index) in APPROVE_TYPE"
:key="index"
:value="item.value"
:label="item.value"
>
{{ item.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-divider content-position="left">审批人拒绝时</el-divider>
<el-form-item prop="rejectHandlerType">
<el-radio-group
@ -158,10 +173,13 @@ import {
AssignEmptyHandlerType,
OPERATION_BUTTON_NAME,
DEFAULT_BUTTON_SETTING,
FieldPermissionType
FieldPermissionType,
APPROVE_TYPE,
ApproveType,
ButtonSetting
} from '@/components/SimpleProcessDesignerV2/src/consts'
import * as UserApi from '@/api/system/user'
import { cloneDeep } from 'lodash-es'
import { useFormFieldsPermission } from '@/components/SimpleProcessDesignerV2/src/node'
defineOptions({ name: 'ElementCustomConfig4UserTask' })
const props = defineProps({
@ -189,8 +207,7 @@ const assignEmptyUserIds = ref()
//
const buttonsSettingEl = ref()
const { buttonsSetting, btnDisplayNameEdit, changeBtnDisplayName, btnDisplayNameBlurEvent } =
useButtonsSetting()
const { btnDisplayNameEdit, changeBtnDisplayName, btnDisplayNameBlurEvent } = useButtonsSetting()
//
const fieldsPermissionEl = ref([])
@ -198,6 +215,9 @@ const { formType, fieldsPermissionConfig, getNodeConfigFormFields } = useFormFie
FieldPermissionType.READ
)
//
const approveType = ref({ value: ApproveType.USER })
const elExtensionElements = ref()
const otherExtensions = ref()
const bpmnElement = ref()
@ -217,6 +237,11 @@ const resetCustomConfigList = () => {
bpmnElement.value.businessObject?.extensionElements ??
bpmnInstances().moddle.create('bpmn:ExtensionElements', { values: [] })
//
approveType.value =
elExtensionElements.value.values?.filter((ex) => ex.$type === `${prefix}:ApproveType`)?.[0] ||
bpmnInstances().moddle.create(`${prefix}:ApproveType`, { value: ApproveType.USER })
//
assignStartUserHandlerTypeEl.value =
elExtensionElements.value.values?.filter(
@ -275,6 +300,8 @@ const resetCustomConfigList = () => {
)
fieldsPermissionEl.value = []
getNodeConfigFormFields()
//
fieldsPermissionConfig.value = fieldsPermissionConfig.value.slice(1)
fieldsPermissionConfig.value.forEach((element) => {
element.permission =
fieldsPermissionList?.find((obj) => obj.field === element.field)?.permission ?? '1'
@ -294,7 +321,8 @@ const resetCustomConfigList = () => {
ex.$type !== `${prefix}:AssignEmptyHandlerType` &&
ex.$type !== `${prefix}:AssignEmptyUserIds` &&
ex.$type !== `${prefix}:ButtonsSetting` &&
ex.$type !== `${prefix}:FieldsPermission`
ex.$type !== `${prefix}:FieldsPermission` &&
ex.$type !== `${prefix}:ApproveType`
) ?? []
//
@ -343,6 +371,7 @@ const updateElementExtensions = () => {
returnNodeIdEl.value,
assignEmptyHandlerTypeEl.value,
assignEmptyUserIdsEl.value,
approveType.value,
...buttonsSettingEl.value,
...fieldsPermissionEl.value
]
@ -427,69 +456,6 @@ function useButtonsSetting() {
}
}
//
function useFormFieldsPermission(defaultPermission) {
// . field, title, permissioin
const fieldsPermissionConfig = ref<Array<Record<string, string>>>([])
const formType = inject<Ref<number>>('formType') //
const formFields = inject<Ref<string[]>>('formFields') //
const getNodeConfigFormFields = (nodeFormFields?: Array<Record<string, string>>) => {
nodeFormFields = toRaw(nodeFormFields)
fieldsPermissionConfig.value =
cloneDeep(nodeFormFields) || getDefaultFieldsPermission(unref(formFields))
}
//
const getDefaultFieldsPermission = (formFields?: string[]) => {
const defaultFieldsPermission: Array<Record<string, string>> = []
if (formFields) {
formFields.forEach((fieldStr: string) => {
parseFieldsSetDefaultPermission(JSON.parse(fieldStr), defaultFieldsPermission)
})
}
return defaultFieldsPermission
}
//
const parseFieldsSetDefaultPermission = (
rule: Record<string, any>,
fieldsPermission: Array<Record<string, string>>,
parentTitle: string = ''
) => {
const { /**type,*/ field, title: tempTitle, children } = rule
if (field && tempTitle) {
let title = tempTitle
if (parentTitle) {
title = `${parentTitle}.${tempTitle}`
}
fieldsPermission.push({
field,
title,
permission: defaultPermission
})
// TODO
// if (type === 'group' && rule.props?.rule && Array.isArray(rule.props.rule)) {
// //
// rule.props.rule.forEach((item) => {
// parseFieldsSetDefaultPermission(item, fieldsPermission, title)
// })
// }
}
if (children && Array.isArray(children)) {
children.forEach((rule) => {
parseFieldsSetDefaultPermission(rule, fieldsPermission)
})
}
}
return {
formType,
fieldsPermissionConfig,
getNodeConfigFormFields
}
}
const userOptions = ref<UserApi.UserVO[]>([]) //
onMounted(async () => {
//

View File

@ -1,5 +1,5 @@
<template>
<el-form label-width="100px">
<el-form label-width="120px">
<el-form-item label="规则类型" prop="candidateStrategy">
<el-select
v-model="userTaskForm.candidateStrategy"
@ -8,15 +8,15 @@
@change="changeCandidateStrategy"
>
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.BPM_TASK_CANDIDATE_STRATEGY)"
:key="dict.value"
v-for="(dict, index) in CANDIDATE_STRATEGY"
:key="index"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item
v-if="userTaskForm.candidateStrategy == 10"
v-if="userTaskForm.candidateStrategy == CandidateStrategy.ROLE"
label="指定角色"
prop="candidateParam"
>
@ -31,7 +31,11 @@
</el-select>
</el-form-item>
<el-form-item
v-if="userTaskForm.candidateStrategy == 20 || userTaskForm.candidateStrategy == 21"
v-if="
userTaskForm.candidateStrategy == CandidateStrategy.DEPT_MEMBER ||
userTaskForm.candidateStrategy == CandidateStrategy.DEPT_LEADER ||
userTaskForm.candidateStrategy == CandidateStrategy.MULTI_LEVEL_DEPT_LEADER
"
label="指定部门"
prop="candidateParam"
span="24"
@ -49,7 +53,7 @@
/>
</el-form-item>
<el-form-item
v-if="userTaskForm.candidateStrategy == 22"
v-if="userTaskForm.candidateStrategy == CandidateStrategy.POST"
label="指定岗位"
prop="candidateParam"
span="24"
@ -65,7 +69,7 @@
</el-select>
</el-form-item>
<el-form-item
v-if="userTaskForm.candidateStrategy == 30"
v-if="userTaskForm.candidateStrategy == CandidateStrategy.USER"
label="指定用户"
prop="candidateParam"
span="24"
@ -86,7 +90,7 @@
</el-select>
</el-form-item>
<el-form-item
v-if="userTaskForm.candidateStrategy === 40"
v-if="userTaskForm.candidateStrategy === CandidateStrategy.USER_GROUP"
label="指定用户组"
prop="candidateParam"
>
@ -106,7 +110,67 @@
</el-select>
</el-form-item>
<el-form-item
v-if="userTaskForm.candidateStrategy === 60"
v-if="userTaskForm.candidateStrategy === CandidateStrategy.FORM_USER"
label="表单内用户字段"
prop="formUser"
>
<el-select
v-model="userTaskForm.candidateParam"
clearable
style="width: 100%"
@change="handleFormUserChange"
>
<el-option
v-for="(item, idx) in userFieldOnFormOptions"
:key="idx"
:label="item.title"
:value="item.field"
:disabled="!item.required"
/>
</el-select>
</el-form-item>
<el-form-item
v-if="userTaskForm.candidateStrategy === CandidateStrategy.FORM_DEPT_LEADER"
label="表单内部门字段"
prop="formDept"
>
<el-select
v-model="userTaskForm.candidateParam"
clearable
style="width: 100%"
@change="updateElementTask"
>
<el-option
v-for="(item, idx) in deptFieldOnFormOptions"
:key="idx"
:label="item.title"
:value="item.field"
:disabled="!item.required"
/>
</el-select>
</el-form-item>
<el-form-item
v-if="
userTaskForm.candidateStrategy == CandidateStrategy.MULTI_LEVEL_DEPT_LEADER ||
userTaskForm.candidateStrategy == CandidateStrategy.START_USER_DEPT_LEADER ||
userTaskForm.candidateStrategy == CandidateStrategy.START_USER_MULTI_LEVEL_DEPT_LEADER ||
userTaskForm.candidateStrategy == CandidateStrategy.FORM_DEPT_LEADER
"
:label="deptLevelLabel!"
prop="deptLevel"
span="24"
>
<el-select v-model="deptLevel" clearable @change="updateElementTask">
<el-option
v-for="(item, index) in MULTI_LEVEL_DEPT"
:key="index"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item
v-if="userTaskForm.candidateStrategy === CandidateStrategy.EXPRESSION"
label="流程表达式"
prop="candidateParam"
>
@ -127,7 +191,12 @@
</template>
<script lang="ts" setup>
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import {
CANDIDATE_STRATEGY,
CandidateStrategy,
FieldPermissionType,
MULTI_LEVEL_DEPT
} from '@/components/SimpleProcessDesignerV2/src/consts'
import { defaultProps, handleTree } from '@/utils/tree'
import * as RoleApi from '@/api/system/role'
import * as DeptApi from '@/api/system/dept'
@ -136,6 +205,7 @@ import * as UserApi from '@/api/system/user'
import * as UserGroupApi from '@/api/bpm/userGroup'
import ProcessExpressionDialog from './ProcessExpressionDialog.vue'
import { ProcessExpressionVO } from '@/api/bpm/processExpression'
import { useFormFieldsPermission } from '@/components/SimpleProcessDesignerV2/src/node'
defineOptions({ name: 'UserTask' })
const props = defineProps({
@ -155,6 +225,30 @@ const deptTreeOptions = ref() // 部门树
const postOptions = ref<PostApi.PostVO[]>([]) //
const userOptions = ref<UserApi.UserVO[]>([]) //
const userGroupOptions = ref<UserGroupApi.UserGroupVO[]>([]) //
const { formFieldOptions } = useFormFieldsPermission(FieldPermissionType.READ)
// ,
const userFieldOnFormOptions = computed(() => {
return formFieldOptions.filter((item) => item.type === 'UserSelect')
})
// ,
const deptFieldOnFormOptions = computed(() => {
return formFieldOptions.filter((item) => item.type === 'DeptSelect')
})
const deptLevel = ref(1)
const deptLevelLabel = computed(() => {
let label = '部门负责人来源'
if (userTaskForm.value.candidateStrategy == CandidateStrategy.MULTI_LEVEL_DEPT_LEADER) {
label = label + '(指定部门向上)'
} else if (userTaskForm.value.candidateStrategy == CandidateStrategy.FORM_DEPT_LEADER) {
label = label + '(表单内部门向上)'
} else {
label = label + '(发起人部门向上)'
}
return label
})
const otherExtensions = ref()
const resetTaskForm = () => {
@ -163,7 +257,9 @@ const resetTaskForm = () => {
return
}
const extensionElements = businessObject?.extensionElements ?? bpmnInstances().moddle.create('bpmn:ExtensionElements', { values: [] })
const extensionElements =
businessObject?.extensionElements ??
bpmnInstances().moddle.create('bpmn:ExtensionElements', { values: [] })
userTaskForm.value.candidateStrategy = extensionElements.values?.filter(
(ex) => ex.$type === `${prefix}:CandidateStrategy`
)?.[0]?.value
@ -171,9 +267,29 @@ const resetTaskForm = () => {
(ex) => ex.$type === `${prefix}:CandidateParam`
)?.[0]?.value
if (candidateParamStr && candidateParamStr.length > 0) {
if (userTaskForm.value.candidateStrategy === 60) {
if (userTaskForm.value.candidateStrategy === CandidateStrategy.EXPRESSION) {
// input
userTaskForm.value.candidateParam = [candidateParamStr]
} else if (userTaskForm.value.candidateStrategy == CandidateStrategy.MULTI_LEVEL_DEPT_LEADER) {
// '|'
userTaskForm.value.candidateParam = candidateParamStr
.split('|')[0]
.split(',')
.map((item) => {
//
let num = Number(item)
return num > Number.MAX_SAFE_INTEGER || num < -Number.MAX_SAFE_INTEGER ? item : num
})
deptLevel.value = +candidateParamStr.split('|')[1]
} else if (
userTaskForm.value.candidateStrategy == CandidateStrategy.START_USER_DEPT_LEADER ||
userTaskForm.value.candidateStrategy == CandidateStrategy.START_USER_MULTI_LEVEL_DEPT_LEADER
) {
userTaskForm.value.candidateParam = +candidateParamStr
deptLevel.value = +candidateParamStr
} else if (userTaskForm.value.candidateStrategy == CandidateStrategy.FORM_DEPT_LEADER) {
userTaskForm.value.candidateParam = candidateParamStr.split('|')[0]
deptLevel.value = +candidateParamStr.split('|')[1]
} else {
userTaskForm.value.candidateParam = candidateParamStr.split(',').map((item) => {
//
@ -214,11 +330,38 @@ const resetTaskForm = () => {
/** 更新 candidateStrategy 字段时,需要清空 candidateParam并触发 bpmn 图更新 */
const changeCandidateStrategy = () => {
userTaskForm.value.candidateParam = []
deptLevel.value = 1
if (userTaskForm.value.candidateStrategy === CandidateStrategy.FORM_USER) {
//
if (!userFieldOnFormOptions.value || userFieldOnFormOptions.value.length <= 1) {
userTaskForm.value.candidateStrategy = CandidateStrategy.START_USER
}
}
updateElementTask()
}
/** 选中某个 options 时候,更新 bpmn 图 */
const updateElementTask = () => {
let candidateParam =
userTaskForm.value.candidateParam instanceof Array
? userTaskForm.value.candidateParam.join(',')
: userTaskForm.value.candidateParam
//
if (
userTaskForm.value.candidateStrategy == CandidateStrategy.MULTI_LEVEL_DEPT_LEADER ||
userTaskForm.value.candidateStrategy == CandidateStrategy.FORM_DEPT_LEADER
) {
candidateParam += '|' + deptLevel.value
}
//
if (
userTaskForm.value.candidateStrategy == CandidateStrategy.START_USER_DEPT_LEADER ||
userTaskForm.value.candidateStrategy == CandidateStrategy.START_USER_MULTI_LEVEL_DEPT_LEADER
) {
candidateParam = deptLevel.value + ''
}
const extensions = bpmnInstances().moddle.create('bpmn:ExtensionElements', {
values: [
...otherExtensions.value,
@ -226,7 +369,7 @@ const updateElementTask = () => {
value: userTaskForm.value.candidateStrategy
}),
bpmnInstances().moddle.create(`${prefix}:CandidateParam`, {
value: userTaskForm.value.candidateParam.join(',')
value: candidateParam
})
]
})
@ -252,6 +395,14 @@ const selectProcessExpression = (expression: ProcessExpressionVO) => {
updateElementTask()
}
const handleFormUserChange = (e) => {
if (e === 'PROCESS_START_USER_ID') {
userTaskForm.value.candidateParam = []
userTaskForm.value.candidateStrategy = CandidateStrategy.START_USER
}
updateElementTask()
}
watch(
() => props.id,
() => {