!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. 审批人为空时 3. 审批人为空时
4. 操作按钮 4. 操作按钮
5. 字段权限 5. 字段权限
6. 审批类型
--> -->
<template> <template>
<div> <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-divider content-position="left">审批人拒绝时</el-divider>
<el-form-item prop="rejectHandlerType"> <el-form-item prop="rejectHandlerType">
<el-radio-group <el-radio-group
@ -158,10 +173,13 @@ import {
AssignEmptyHandlerType, AssignEmptyHandlerType,
OPERATION_BUTTON_NAME, OPERATION_BUTTON_NAME,
DEFAULT_BUTTON_SETTING, DEFAULT_BUTTON_SETTING,
FieldPermissionType FieldPermissionType,
APPROVE_TYPE,
ApproveType,
ButtonSetting
} from '@/components/SimpleProcessDesignerV2/src/consts' } from '@/components/SimpleProcessDesignerV2/src/consts'
import * as UserApi from '@/api/system/user' import * as UserApi from '@/api/system/user'
import { cloneDeep } from 'lodash-es' import { useFormFieldsPermission } from '@/components/SimpleProcessDesignerV2/src/node'
defineOptions({ name: 'ElementCustomConfig4UserTask' }) defineOptions({ name: 'ElementCustomConfig4UserTask' })
const props = defineProps({ const props = defineProps({
@ -189,8 +207,7 @@ const assignEmptyUserIds = ref()
// //
const buttonsSettingEl = ref() const buttonsSettingEl = ref()
const { buttonsSetting, btnDisplayNameEdit, changeBtnDisplayName, btnDisplayNameBlurEvent } = const { btnDisplayNameEdit, changeBtnDisplayName, btnDisplayNameBlurEvent } = useButtonsSetting()
useButtonsSetting()
// //
const fieldsPermissionEl = ref([]) const fieldsPermissionEl = ref([])
@ -198,6 +215,9 @@ const { formType, fieldsPermissionConfig, getNodeConfigFormFields } = useFormFie
FieldPermissionType.READ FieldPermissionType.READ
) )
//
const approveType = ref({ value: ApproveType.USER })
const elExtensionElements = ref() const elExtensionElements = ref()
const otherExtensions = ref() const otherExtensions = ref()
const bpmnElement = ref() const bpmnElement = ref()
@ -217,6 +237,11 @@ const resetCustomConfigList = () => {
bpmnElement.value.businessObject?.extensionElements ?? bpmnElement.value.businessObject?.extensionElements ??
bpmnInstances().moddle.create('bpmn:ExtensionElements', { values: [] }) 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 = assignStartUserHandlerTypeEl.value =
elExtensionElements.value.values?.filter( elExtensionElements.value.values?.filter(
@ -275,6 +300,8 @@ const resetCustomConfigList = () => {
) )
fieldsPermissionEl.value = [] fieldsPermissionEl.value = []
getNodeConfigFormFields() getNodeConfigFormFields()
//
fieldsPermissionConfig.value = fieldsPermissionConfig.value.slice(1)
fieldsPermissionConfig.value.forEach((element) => { fieldsPermissionConfig.value.forEach((element) => {
element.permission = element.permission =
fieldsPermissionList?.find((obj) => obj.field === element.field)?.permission ?? '1' fieldsPermissionList?.find((obj) => obj.field === element.field)?.permission ?? '1'
@ -294,7 +321,8 @@ const resetCustomConfigList = () => {
ex.$type !== `${prefix}:AssignEmptyHandlerType` && ex.$type !== `${prefix}:AssignEmptyHandlerType` &&
ex.$type !== `${prefix}:AssignEmptyUserIds` && ex.$type !== `${prefix}:AssignEmptyUserIds` &&
ex.$type !== `${prefix}:ButtonsSetting` && ex.$type !== `${prefix}:ButtonsSetting` &&
ex.$type !== `${prefix}:FieldsPermission` ex.$type !== `${prefix}:FieldsPermission` &&
ex.$type !== `${prefix}:ApproveType`
) ?? [] ) ?? []
// //
@ -343,6 +371,7 @@ const updateElementExtensions = () => {
returnNodeIdEl.value, returnNodeIdEl.value,
assignEmptyHandlerTypeEl.value, assignEmptyHandlerTypeEl.value,
assignEmptyUserIdsEl.value, assignEmptyUserIdsEl.value,
approveType.value,
...buttonsSettingEl.value, ...buttonsSettingEl.value,
...fieldsPermissionEl.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[]>([]) // const userOptions = ref<UserApi.UserVO[]>([]) //
onMounted(async () => { onMounted(async () => {
// //

View File

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