<template>
|
<el-form label-width="120px">
|
<el-form-item label="规则类型" prop="candidateStrategy">
|
<el-select
|
v-model="userTaskForm.candidateStrategy"
|
clearable
|
style="width: 100%"
|
@change="changeCandidateStrategy"
|
>
|
<el-option
|
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 == CandidateStrategy.ROLE"
|
label="指定角色"
|
prop="candidateParam"
|
>
|
<el-select
|
v-model="userTaskForm.candidateParam"
|
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.candidateStrategy == CandidateStrategy.DEPT_MEMBER ||
|
userTaskForm.candidateStrategy == CandidateStrategy.DEPT_LEADER ||
|
userTaskForm.candidateStrategy == CandidateStrategy.MULTI_LEVEL_DEPT_LEADER
|
"
|
label="指定部门"
|
prop="candidateParam"
|
span="24"
|
>
|
<el-tree-select
|
ref="treeRef"
|
v-model="userTaskForm.candidateParam"
|
:data="deptTreeOptions"
|
:props="defaultProps"
|
empty-text="加载中,请稍后"
|
multiple
|
node-key="id"
|
show-checkbox
|
@change="updateElementTask"
|
/>
|
</el-form-item>
|
<el-form-item
|
v-if="userTaskForm.candidateStrategy == CandidateStrategy.POST"
|
label="指定岗位"
|
prop="candidateParam"
|
span="24"
|
>
|
<el-select
|
v-model="userTaskForm.candidateParam"
|
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>
|
<el-form-item
|
v-if="userTaskForm.candidateStrategy == CandidateStrategy.USER"
|
label="指定用户"
|
prop="candidateParam"
|
span="24"
|
>
|
<el-select
|
v-model="userTaskForm.candidateParam"
|
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.candidateStrategy === CandidateStrategy.USER_GROUP"
|
label="指定用户组"
|
prop="candidateParam"
|
>
|
<el-select
|
v-model="userTaskForm.candidateParam"
|
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.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"
|
>
|
<el-input
|
type="textarea"
|
v-model="userTaskForm.candidateParam[0]"
|
clearable
|
style="width: 100%"
|
@change="updateElementTask"
|
/>
|
<XButton
|
class="!w-1/1 mt-5px"
|
type="success"
|
preIcon="ep:select"
|
title="选择表达式"
|
size="small"
|
@click="openProcessExpressionDialog"
|
/>
|
<!-- 选择弹窗 -->
|
<ProcessExpressionDialog ref="processExpressionDialogRef" @select="selectProcessExpression" />
|
</el-form-item>
|
</el-form>
|
</template>
|
|
<script lang="ts" setup>
|
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'
|
import * as PostApi from '@/api/system/post'
|
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({
|
id: String,
|
type: String
|
})
|
const prefix = inject('prefix')
|
const userTaskForm = ref({
|
candidateStrategy: undefined, // 分配规则
|
candidateParam: [] // 分配选项
|
})
|
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 { 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 = () => {
|
const businessObject = bpmnElement.value.businessObject
|
if (!businessObject) {
|
return
|
}
|
|
const extensionElements =
|
businessObject?.extensionElements ??
|
bpmnInstances().moddle.create('bpmn:ExtensionElements', { values: [] })
|
userTaskForm.value.candidateStrategy = extensionElements.values?.filter(
|
(ex) => ex.$type === `${prefix}:CandidateStrategy`
|
)?.[0]?.value
|
const candidateParamStr = extensionElements.values?.filter(
|
(ex) => ex.$type === `${prefix}:CandidateParam`
|
)?.[0]?.value
|
if (candidateParamStr && candidateParamStr.length > 0) {
|
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) => {
|
// 如果数字超出了最大安全整数范围,则将其作为字符串处理
|
let num = Number(item)
|
return num > Number.MAX_SAFE_INTEGER || num < -Number.MAX_SAFE_INTEGER ? item : num
|
})
|
}
|
} else {
|
userTaskForm.value.candidateParam = []
|
}
|
|
otherExtensions.value =
|
extensionElements.values?.filter(
|
(ex) => ex.$type !== `${prefix}:CandidateStrategy` && ex.$type !== `${prefix}:CandidateParam`
|
) ?? []
|
|
// 改用通过extensionElements来存储数据
|
return
|
if (businessObject.candidateStrategy != undefined) {
|
userTaskForm.value.candidateStrategy = parseInt(businessObject.candidateStrategy) as any
|
} else {
|
userTaskForm.value.candidateStrategy = undefined
|
}
|
if (businessObject.candidateParam && businessObject.candidateParam.length > 0) {
|
if (userTaskForm.value.candidateStrategy === 60) {
|
// 特殊:流程表达式,只有一个 input 输入框
|
userTaskForm.value.candidateParam = [businessObject.candidateParam]
|
} else {
|
userTaskForm.value.candidateParam = businessObject.candidateParam
|
.split(',')
|
.map((item) => item)
|
}
|
} else {
|
userTaskForm.value.candidateParam = []
|
}
|
}
|
|
/** 更新 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,
|
bpmnInstances().moddle.create(`${prefix}:CandidateStrategy`, {
|
value: userTaskForm.value.candidateStrategy
|
}),
|
bpmnInstances().moddle.create(`${prefix}:CandidateParam`, {
|
value: candidateParam
|
})
|
]
|
})
|
bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), {
|
extensionElements: extensions
|
})
|
|
// 改用通过extensionElements来存储数据
|
return
|
bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), {
|
candidateStrategy: userTaskForm.value.candidateStrategy,
|
candidateParam: userTaskForm.value.candidateParam.join(',')
|
})
|
}
|
|
// 打开监听器弹窗
|
const processExpressionDialogRef = ref()
|
const openProcessExpressionDialog = async () => {
|
processExpressionDialogRef.value.open()
|
}
|
const selectProcessExpression = (expression: ProcessExpressionVO) => {
|
userTaskForm.value.candidateParam = [expression.expression]
|
updateElementTask()
|
}
|
|
const handleFormUserChange = (e) => {
|
if (e === 'PROCESS_START_USER_ID') {
|
userTaskForm.value.candidateParam = []
|
userTaskForm.value.candidateStrategy = CandidateStrategy.START_USER
|
}
|
updateElementTask()
|
}
|
|
watch(
|
() => props.id,
|
() => {
|
bpmnElement.value = bpmnInstances().bpmnElement
|
nextTick(() => {
|
resetTaskForm()
|
})
|
},
|
{ 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.getUserGroupSimpleList()
|
})
|
|
onBeforeUnmount(() => {
|
bpmnElement.value = null
|
})
|
</script>
|