Skip to content

Commit 728cf15

Browse files
committed
BPM:增加「发起人自选」的任务审批人的分配策略
1 parent 48f6624 commit 728cf15

File tree

7 files changed

+182
-29
lines changed

7 files changed

+182
-29
lines changed

src/api/bpm/definition/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import request from '@/config/axios'
22

3-
export const getProcessDefinitionBpmnXML = async (id: number) => {
3+
export const getProcessDefinition = async (id: number, key: string) => {
44
return await request.get({
5-
url: '/bpm/process-definition/get-bpmn-xml?id=' + id
5+
url: '/bpm/process-definition/get',
6+
params: { id, key }
67
})
78
}
89

src/components/bpmnProcessDesigner/package/penal/task/task-components/UserTask.vue

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,7 @@
6565
</el-select>
6666
</el-form-item>
6767
<el-form-item
68-
v-if="
69-
userTaskForm.candidateStrategy == 30 ||
70-
userTaskForm.candidateStrategy == 31 ||
71-
userTaskForm.candidateStrategy == 32
72-
"
68+
v-if="userTaskForm.candidateStrategy == 30"
7369
label="指定用户"
7470
prop="candidateParam"
7571
span="24"

src/views/bpm/definition/index.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@
7272
<Dialog title="流程图" v-model="bpmnDetailVisible" width="800">
7373
<MyProcessViewer
7474
key="designer"
75-
v-model="bpmnXML"
76-
:value="bpmnXML as any"
75+
v-model="bpmnXml"
76+
:value="bpmnXml as any"
7777
v-bind="bpmnControlForm"
7878
:prefix="bpmnControlForm.prefix"
7979
/>
@@ -133,12 +133,12 @@ const handleFormDetail = async (row) => {
133133
134134
/** 流程图的详情按钮操作 */
135135
const bpmnDetailVisible = ref(false)
136-
const bpmnXML = ref(null)
136+
const bpmnXml = ref(null)
137137
const bpmnControlForm = ref({
138138
prefix: 'flowable'
139139
})
140140
const handleBpmnDetail = async (row) => {
141-
bpmnXML.value = await DefinitionApi.getProcessDefinitionBpmnXML(row.id)
141+
bpmnXml.value = (await DefinitionApi.getProcessDefinition(row.id))?.bpmnXml
142142
bpmnDetailVisible.value = true
143143
}
144144

src/views/bpm/oa/leave/create.vue

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,36 @@
3737
<el-form-item label="原因" prop="reason">
3838
<el-input v-model="formData.reason" placeholder="请输请假原因" type="textarea" />
3939
</el-form-item>
40+
<el-col v-if="startUserSelectTasks.length > 0">
41+
<el-card class="mb-10px">
42+
<template #header>指定审批人</template>
43+
<el-form
44+
:model="startUserSelectAssignees"
45+
:rules="startUserSelectAssigneesFormRules"
46+
ref="startUserSelectAssigneesFormRef"
47+
>
48+
<el-form-item
49+
v-for="userTask in startUserSelectTasks"
50+
:key="userTask.id"
51+
:label="`任务【${userTask.name}】`"
52+
:prop="userTask.id"
53+
>
54+
<el-select
55+
v-model="startUserSelectAssignees[userTask.id]"
56+
multiple
57+
placeholder="请选择审批人"
58+
>
59+
<el-option
60+
v-for="user in userList"
61+
:key="user.id"
62+
:label="user.nickname"
63+
:value="user.id"
64+
/>
65+
</el-select>
66+
</el-form-item>
67+
</el-form>
68+
</el-card>
69+
</el-col>
4070
<el-form-item>
4171
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
4272
</el-form-item>
@@ -46,10 +76,15 @@
4676
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
4777
import * as LeaveApi from '@/api/bpm/leave'
4878
import { useTagsViewStore } from '@/store/modules/tagsView'
79+
import * as DefinitionApi from '@/api/bpm/definition'
80+
import * as UserApi from '@/api/system/user'
4981
5082
defineOptions({ name: 'BpmOALeaveCreate' })
5183
5284
const message = useMessage() // 消息弹窗
85+
const { delView } = useTagsViewStore() // 视图操作
86+
const { push, currentRoute } = useRouter() // 路由
87+
5388
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
5489
const formData = ref({
5590
type: undefined,
@@ -64,18 +99,34 @@ const formRules = reactive({
6499
endTime: [{ required: true, message: '请假结束时间不能为空', trigger: 'change' }]
65100
})
66101
const formRef = ref() // 表单 Ref
67-
const { delView } = useTagsViewStore() // 视图操作
68-
const { push, currentRoute } = useRouter() // 路由
102+
103+
// 指定审批人
104+
const processDefineKey = 'oa_leave' // 流程定义 Key
105+
const startUserSelectTasks = ref([]) // 发起人需要选择审批人的用户任务列表
106+
const startUserSelectAssignees = ref({}) // 发起人选择审批人的数据
107+
const startUserSelectAssigneesFormRef = ref() // 发起人选择审批人的表单 Ref
108+
const startUserSelectAssigneesFormRules = ref({}) // 发起人选择审批人的表单 Rules
109+
const userList = ref<any[]>([]) // 用户列表
110+
69111
/** 提交表单 */
70112
const submitForm = async () => {
71113
// 校验表单
72114
if (!formRef) return
73115
const valid = await formRef.value.validate()
74116
if (!valid) return
117+
// 校验指定审批人
118+
if (startUserSelectTasks.value?.length > 0) {
119+
await startUserSelectAssigneesFormRef.value.validate()
120+
}
121+
75122
// 提交请求
76123
formLoading.value = true
77124
try {
78-
const data = formData.value as unknown as LeaveApi.LeaveVO
125+
const data = { ...formData.value } as unknown as LeaveApi.LeaveVO
126+
// 设置指定审批人
127+
if (startUserSelectTasks.value?.length > 0) {
128+
data.startUserSelectAssignees = startUserSelectAssignees.value
129+
}
79130
await LeaveApi.createLeave(data)
80131
message.success('发起成功')
81132
// 关闭当前 Tab
@@ -85,4 +136,29 @@ const submitForm = async () => {
85136
formLoading.value = false
86137
}
87138
}
139+
140+
/** 初始化 */
141+
onMounted(async () => {
142+
const processDefinitionDetail = await DefinitionApi.getProcessDefinition(
143+
undefined,
144+
processDefineKey
145+
)
146+
if (!processDefinitionDetail) {
147+
message.error('OA 请假的流程模型未配置,请检查!')
148+
return
149+
}
150+
startUserSelectTasks.value = processDefinitionDetail.startUserSelectTasks
151+
// 设置指定审批人
152+
if (startUserSelectTasks.value?.length > 0) {
153+
// 设置校验规则
154+
for (const userTask of startUserSelectTasks.value) {
155+
startUserSelectAssignees.value[userTask.id] = []
156+
startUserSelectAssigneesFormRules.value[userTask.id] = [
157+
{ required: true, message: '请选择审批人', trigger: 'blur' }
158+
]
159+
}
160+
// 加载用户列表
161+
userList.value = await UserApi.getSimpleUserList()
162+
}
163+
})
88164
</script>

src/views/bpm/processInstance/create/index.vue

Lines changed: 80 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,40 @@
5454
v-model="detailForm.value"
5555
:option="detailForm.option"
5656
@submit="submitForm"
57-
/>
57+
>
58+
<template #type-startUserSelect>
59+
<el-col :span="24">
60+
<el-card class="mb-10px">
61+
<template #header>指定审批人</template>
62+
<el-form
63+
:model="startUserSelectAssignees"
64+
:rules="startUserSelectAssigneesFormRules"
65+
ref="startUserSelectAssigneesFormRef"
66+
>
67+
<el-form-item
68+
v-for="userTask in startUserSelectTasks"
69+
:key="userTask.id"
70+
:label="`任务【${userTask.name}】`"
71+
:prop="userTask.id"
72+
>
73+
<el-select
74+
v-model="startUserSelectAssignees[userTask.id]"
75+
multiple
76+
placeholder="请选择审批人"
77+
>
78+
<el-option
79+
v-for="user in userList"
80+
:key="user.id"
81+
:label="user.nickname"
82+
:value="user.id"
83+
/>
84+
</el-select>
85+
</el-form-item>
86+
</el-form>
87+
</el-card>
88+
</el-col>
89+
</template>
90+
</form-create>
5891
</el-col>
5992
</el-card>
6093
<!-- 流程图预览 -->
@@ -69,6 +102,7 @@ import type { ApiAttrs } from '@form-create/element-ui/types/config'
69102
import ProcessInstanceBpmnViewer from '../detail/ProcessInstanceBpmnViewer.vue'
70103
import { CategoryApi } from '@/api/bpm/category'
71104
import { useTagsViewStore } from '@/store/modules/tagsView'
105+
import * as UserApi from '@/api/system/user'
72106
73107
defineOptions({ name: 'BpmProcessInstanceCreate' })
74108
@@ -124,7 +158,6 @@ const categoryProcessDefinitionList = computed(() => {
124158
})
125159
126160
// ========== 表单相关 ==========
127-
const bpmnXML = ref(null) // BPMN 数据
128161
const fApi = ref<ApiAttrs>()
129162
const detailForm = ref({
130163
rule: [],
@@ -133,17 +166,53 @@ const detailForm = ref({
133166
}) // 流程表单详情
134167
const selectProcessDefinition = ref() // 选择的流程定义
135168
169+
// 指定审批人
170+
const bpmnXML = ref(null) // BPMN 数据
171+
const startUserSelectTasks = ref([]) // 发起人需要选择审批人的用户任务列表
172+
const startUserSelectAssignees = ref({}) // 发起人选择审批人的数据
173+
const startUserSelectAssigneesFormRef = ref() // 发起人选择审批人的表单 Ref
174+
const startUserSelectAssigneesFormRules = ref({}) // 发起人选择审批人的表单 Rules
175+
const userList = ref<any[]>([]) // 用户列表
176+
136177
/** 处理选择流程的按钮操作 **/
137178
const handleSelect = async (row, formVariables) => {
138179
// 设置选择的流程
139180
selectProcessDefinition.value = row
140181
182+
// 重置指定审批人
183+
startUserSelectTasks.value = []
184+
startUserSelectAssignees.value = {}
185+
startUserSelectAssigneesFormRules.value = {}
186+
141187
// 情况一:流程表单
142188
if (row.formType == 10) {
143189
// 设置表单
144190
setConfAndFields2(detailForm, row.formConf, row.formFields, formVariables)
145191
// 加载流程图
146-
bpmnXML.value = await DefinitionApi.getProcessDefinitionBpmnXML(row.id)
192+
const processDefinitionDetail = await DefinitionApi.getProcessDefinition(row.id)
193+
if (processDefinitionDetail) {
194+
bpmnXML.value = processDefinitionDetail.bpmnXml
195+
startUserSelectTasks.value = processDefinitionDetail.startUserSelectTasks
196+
197+
// 设置指定审批人
198+
if (startUserSelectTasks.value?.length > 0) {
199+
detailForm.value.rule.push({
200+
type: 'startUserSelect',
201+
props: {
202+
title: '指定审批人'
203+
}
204+
})
205+
// 设置校验规则
206+
for (const userTask of startUserSelectTasks.value) {
207+
startUserSelectAssignees.value[userTask.id] = []
208+
startUserSelectAssigneesFormRules.value[userTask.id] = [
209+
{ required: true, message: '请选择审批人', trigger: 'blur' }
210+
]
211+
}
212+
// 加载用户列表
213+
userList.value = await UserApi.getSimpleUserList()
214+
}
215+
}
147216
// 情况二:业务表单
148217
} else if (row.formCustomCreatePath) {
149218
await push({
@@ -158,19 +227,25 @@ const submitForm = async (formData) => {
158227
if (!fApi.value || !selectProcessDefinition.value) {
159228
return
160229
}
230+
// 如果有指定审批人,需要校验
231+
if (startUserSelectTasks.value?.length > 0) {
232+
await startUserSelectAssigneesFormRef.value.validate()
233+
}
234+
161235
// 提交请求
162236
fApi.value.btn.loading(true)
163237
try {
164238
await ProcessInstanceApi.createProcessInstance({
165239
processDefinitionId: selectProcessDefinition.value.id,
166-
variables: formData
240+
variables: formData,
241+
startUserSelectAssignees: startUserSelectAssignees.value
167242
})
168243
// 提示
169244
message.success('发起流程成功')
170245
// 跳转回去
171246
delView(unref(currentRoute))
172247
await push({
173-
name: 'BpmProcessInstance'
248+
name: 'BpmProcessInstanceMy'
174249
})
175250
} finally {
176251
fApi.value.btn.loading(false)

src/views/bpm/processInstance/detail/ProcessInstanceBpmnViewer.vue

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,17 @@ const bpmnControlForm = ref({
3434
})
3535
const activityList = ref([]) // 任务列表
3636
37-
/** 初始化 */
38-
onMounted(async () => {
39-
if (props.id) {
40-
activityList.value = await ActivityApi.getActivityList({
41-
processInstanceId: props.id
42-
})
37+
/** 只有 loading 完成时,才去加载流程列表 */
38+
watch(
39+
() => props.loading,
40+
async (value) => {
41+
if (value && props.id) {
42+
activityList.value = await ActivityApi.getActivityList({
43+
processInstanceId: props.id
44+
})
45+
}
4346
}
44-
})
47+
)
4548
</script>
4649
<style>
4750
.box-card {

src/views/bpm/processInstance/detail/index.vue

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@
115115
<!-- 高亮流程图 -->
116116
<ProcessInstanceBpmnViewer
117117
:id="`${id}`"
118-
:bpmn-xml="bpmnXML"
118+
:bpmn-xml="bpmnXml"
119119
:loading="processInstanceLoading"
120120
:process-instance="processInstance"
121121
:tasks="tasks"
@@ -158,7 +158,7 @@ const userId = useUserStore().getUser.id // 当前登录的编号
158158
const id = query.id as unknown as string // 流程实例的编号
159159
const processInstanceLoading = ref(false) // 流程实例的加载中
160160
const processInstance = ref<any>({}) // 流程实例
161-
const bpmnXML = ref('') // BPMN XML
161+
const bpmnXml = ref('') // BPMN XML
162162
const tasksLoad = ref(true) // 任务的加载中
163163
const tasks = ref<any[]>([]) // 任务列表
164164
// ========== 审批信息 ==========
@@ -290,7 +290,9 @@ const getProcessInstance = async () => {
290290
}
291291
292292
// 加载流程图
293-
bpmnXML.value = await DefinitionApi.getProcessDefinitionBpmnXML(processDefinition.id as number)
293+
bpmnXml.value = (
294+
await DefinitionApi.getProcessDefinition(processDefinition.id as number)
295+
)?.bpmnXml
294296
} finally {
295297
processInstanceLoading.value = false
296298
}

0 commit comments

Comments
 (0)